cableswig-0.1.0+git20150808.orig/0002755000175000000620000000000012561312227015027 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/0002755000175000000620000000000012561312227015600 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/CMakeLists.txt0000644000175000000620000001321312561312226020335 0ustar stevestaffCMAKE_MINIMUM_REQUIRED(VERSION 1.8) PROJECT(SWIG) INCLUDE(${SWIG_SOURCE_DIR}/CMake/Macros.cmake) SET(-swig_lib- ${SWIG_SOURCE_DIR}/Lib) SET(SWIG_MAJOR_VERSION 3) SET(SWIG_MINOR_VERSION 20) SET(SWIG_VERSION 1.${SWIG_MAJOR_VERSION}.${SWIG_MINOR_VERSION}) SET(SWIG_SPIN 0) SET(VERSION "\"${SWIG_VERSION}\"") SET(PACKAGE "\"swig\"") SET(PACKAGE_NAME ${PACKAGE}) SET(PACKAGE_TARNAME ${PACKAGE}) SET(PACKAGE_VERSION ${VERSION}) SET(PACKAGE_STRING "\"swig ${SWIG_VERSION}\"") SET(PACKAGE_BUGREPORT "\"http://www.swig.org\"") SET(RELEASE_SUFFIX "\"\"") SET(SWIG_DIR "${SWIG_BINARY_DIR}") SET(SWIG_LIBDIR "${CMAKE_INSTALL_PREFIX}/lib") SET(LIBDIR "\"${SWIG_LIBDIR}\"") SET(SWIG_LIB "\"${SWIG_SOURCE_DIR}/Lib\"") SET(SWIG_CXX "\"${CMAKE_CXX_COMPILER}\"") SET(SWIG_PLATFORM "\"${CMAKE_SYSTEM}-${CMAKE_C_COMPILER}\"") SET(SWIG_LIB_INSTALL ${CMAKE_INSTALL_PREFIX}/${CableSwig_INSTALL_ROOT}lib/CableSwig/SWIGLib) INCLUDE (${CMAKE_ROOT}/Modules/CheckIncludeFiles.cmake) INCLUDE (${CMAKE_ROOT}/Modules/CheckLibraryExists.cmake) OPTION(SWIG_BUILD_EXAMPLES "Build some examples" OFF) OPTION(BUILD_TESTING "Perform tests of swig" OFF) IF(BUILD_TESTING) ENABLE_TESTING() INCLUDE (${CMAKE_ROOT}/Modules/Dart.cmake) MARK_AS_ADVANCED(DART_ROOT) ENDIF(BUILD_TESTING) # if examples or testing is on then try and find all # the extra stuff SET(SWIG_FIND_LANGS) IF(BUILD_TESTING) SET(SWIG_FIND_LANGS 1) ENDIF(BUILD_TESTING) IF(SWIG_BUILD_EXAMPLES) SET(SWIG_FIND_LANGS 1) ENDIF(SWIG_BUILD_EXAMPLES) # Check if header file exists and add it to the list. MACRO(CHECK_INCLUDE_FILE_CONCAT FILE VARIABLE) CHECK_INCLUDE_FILES("${PROJECT_INCLUDES};${FILE}" ${VARIABLE}) IF(${VARIABLE}) SET(PROJECT_INCLUDES ${PROJECT_INCLUDES} ${FILE}) ENDIF(${VARIABLE}) ENDMACRO(CHECK_INCLUDE_FILE_CONCAT) IF("HAVE_BOOL" MATCHES "^HAVE_BOOL$") MESSAGE(STATUS "Checking support for C++ type bool") TRY_COMPILE(HAVE_BOOL ${SWIG_BINARY_DIR}/CMakeTmp/Bool ${SWIG_SOURCE_DIR}/CMake/swigTestBoolType.cxx OUTPUT_VARIABLE OUTPUT) IF(HAVE_BOOL) MESSAGE(STATUS "Checking support for C++ type bool -- yes") SET(HAVE_BOOL 1 CACHE INTERNAL "Support for C++ type bool") ELSE(HAVE_BOOL) MESSAGE(STATUS "Checking support for C++ type bool -- no") SET(HAVE_BOOL 0 CACHE INTERNAL "Support for C++ type bool") WRITE_FILE(${CMAKE_BINARY_DIR}/CMakeError.log "Determining if the C++ compiler supports type bool " "failed with the following output:\n" "${OUTPUT}\n" APPEND) ENDIF(HAVE_BOOL) ENDIF("HAVE_BOOL" MATCHES "^HAVE_BOOL$") # Check for include files CHECK_INCLUDE_FILE_CONCAT("dlfcn.h" HAVE_DLFCN_H) CHECK_INCLUDE_FILE_CONCAT("inttypes.h" HAVE_INTTYPES_H) CHECK_INCLUDE_FILE_CONCAT("memory.h" HAVE_MEMORY_H) CHECK_INCLUDE_FILE_CONCAT("stdint.h" HAVE_STDINT_H) CHECK_INCLUDE_FILE_CONCAT("stdlib.h" HAVE_STDLIB_H) CHECK_INCLUDE_FILE_CONCAT("stdarg.h" HAVE_STDARG_H) CHECK_INCLUDE_FILE_CONCAT("float.h" HAVE_FLOAT_H) CHECK_INCLUDE_FILE_CONCAT("string.h" HAVE_STRING_H) CHECK_INCLUDE_FILE_CONCAT("strings.h" HAVE_STRINGS_H) CHECK_INCLUDE_FILE_CONCAT("unistd.h" HAVE_UNISTD_H) CHECK_INCLUDE_FILE_CONCAT("sys/types.h" HAVE_SYS_TYPES_H) CHECK_INCLUDE_FILE_CONCAT("sys/stat.h" HAVE_SYS_STAT_H) SET(STDC_HEADERS 0) IF(HAVE_STDLIB_H AND HAVE_STDARG_H) IF(HAVE_STRING_H AND HAVE_FLOAT_H) SET(STDC_HEADERS 1) ENDIF(HAVE_STRING_H AND HAVE_FLOAT_H) ENDIF(HAVE_STDLIB_H AND HAVE_STDARG_H) # This macro checks if the symbol exists in the library and if it # does, it appends library to the list. SET(project_LIBS "") MACRO(CHECK_LIBRARY_EXISTS_CONCAT LIBRARY SYMBOL VARIABLE) CHECK_LIBRARY_EXISTS("${LIBRARY};${project_LIBS}" ${SYMBOL} "" ${VARIABLE}) IF(${VARIABLE}) SET(project_LIBS ${project_LIBS} ${LIBRARY}) ENDIF(${VARIABLE}) ENDMACRO(CHECK_LIBRARY_EXISTS_CONCAT) CHECK_LIBRARY_EXISTS_CONCAT("dl" dlopen HAVE_LIBDL) CHECK_LIBRARY_EXISTS_CONCAT("dld" dlopen HAVE_LIBDLD) CONFIGURE_FILE( ${SWIG_SOURCE_DIR}/Source/Include/swigconfig.h.cmake.in ${SWIG_BINARY_DIR}/Source/Include/swigconfig.h) SET(SWIG_MODULES_PATH ${SWIG_SOURCE_DIR}/CMake) IF(SWIG_FIND_LANGS) FIND_PROGRAM(PYTHON_EXECUTABLE NAMES python python2.3 python2.2 python2.1 python2.0 python1.6 python1.5 PATHS [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.3\\InstallPath] [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.2\\InstallPath] [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.1\\InstallPath] [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.0\\InstallPath] [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\1.6\\InstallPath] [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\1.5\\InstallPath] ) SET(CMAKE_MODULE_PATH ${SWIG_MODULES_PATH}) FIND_PACKAGE(Java) FIND_PACKAGE(JNI) FIND_PACKAGE(PythonLibs) FIND_PACKAGE(TCL) FIND_PACKAGE(Guile) FIND_PACKAGE(PHP4) FIND_PACKAGE(PerlLibs) FIND_PACKAGE(Pike) FIND_PACKAGE(Ruby) ENDIF(SWIG_FIND_LANGS) #SET(LIBRARY_OUTPUT_PATH ${SWIG_BINARY_DIR}/bin CACHE PATH "Single output directory for building all libraries." FORCE) #SET(EXECUTABLE_OUTPUT_PATH ${SWIG_BINARY_DIR}/bin CACHE PATH "Single output directory for building all executables." FORCE) SET(SWIG_EXECUTABLE "${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/swig") SET(SWIG_LIB_DIR "${SWIG_SOURCE_DIR}/Lib") SET(SWIG_COMMON_INCLUDES "${SWIG_LIB_DIR}") # Build swig wrapper SUBDIRS(Source) # Prepare find/use files SET(SWIG_USE_FILE ${SWIG_SOURCE_DIR}/UseSWIG.cmake) SET(SWIG_USING_SWIG ${SWIG_SOURCE_DIR}/CMake/UsingSwig.cmake) CONFIGURE_FILE(${SWIG_SOURCE_DIR}/SWIGConfig.cmake.in ${SWIG_BINARY_DIR}/SWIGConfig.cmake @ONLY IMMEDIATE) # Install support library. SUBDIRS(Lib) cableswig-0.1.0+git20150808.orig/SWIG/TODO0000644000175000000620000005024612561312227016275 0ustar stevestaffSWIG TO-DO Release: SWIG-1.3.20 /cvsroot/SWIG/TODO,v 1.37 2003/12/28 21:49:16 cheetah Exp ----------------------------------------------------------------------------- **** = High Priority *** = Implement if possible. ** = Will implement if time. * = Implement if bored (or deemed necessary). defer = Implement in next version CORE: **** Add support for nested classes. The type system should be defer ready to go. The primary obstacle lies in the target language modules (which were never programmed with nested classes in mind). There are also issues with nested C structures. For example: struct Foo { struct { int x,y; } z; }; This is one of the last remaining "hard" problems in the SWIG core, but it is important that we solve it. **** Typemap environments. Stay tuned. [DONE] Merge "in" and "ignore" typemaps into a single "in" typemap. This would solve a variety of subtle problems with multiple argument typemaps and other typemap code. I propose to merge the typemaps by making "ignore" a typemap attribute. For example: %typemap(in,ignore="1") int *OUTPUT (int temp) { $1 = &temp; } This merging makes a lot of sense because "in" and "ignore" typemaps both deal with input argument handling and they are meant to be mutually exclusive of each other. By unifying into a single typemap, you fix the mutual exclusion problem (since there is only one typemap). I also think it makes more sense to think of an "ignored" argument as a input value property. Update: Matthias proposes a generalization in which the number of input arguments could be specified. For example: %typemap(in,numinputs="0") int *OUTPUT (int temp) { $1 = &temp; } This seems to be a better solution. **** Implement "throws" typemaps for all of the target languages. Partly implemented for Tcl, Perl, Python, Ruby, Java. *** "Nested" typemaps. The basic idea is similar to allowing one to use $descriptor(T) for any T, rather than just $descriptor for the type currently being typemapped. In short (ha!), given a previously defined typemap: %typemap(in) Foo { // whatever it takes to initialize $1 from $input } it would be possible to inline its code inside another typemap. While the syntax is still to be defined, the use would be along the lines of: template class vector { %typemap(in) vector { ... for (int i=0; i $typemap(in, input=x) ( int FIRST = foo, double SECOND = bar ); The advantage of this syntax would be that the formal arguments (int FIRST, double SECOND) are close to the actual arguments (foo, bar). Comment by beazley $typemap(in, input=x) int = foo; is a little bit hard to parse in terms of variable substitution. I'm considering something like this: $typemap(in,1=int foo, input=x) *** Add attributes to the %feature directive. Something like: %feature("except", throws="OutOfMemoryException") *** Implement $fail special variable substitution in wrappers. Used to properly transfer control out of a wrapper function while reclaiming resources. *** Better targeting of output typemaps. For example: It is not possible to target an output typemap for function Foo::func() and not Bar::func(). Output typemaps need to support syntax something along the lines of: %typemap(out) int *Foo::func { ... } *** Rewrite declaration annotation to better unify %rename and related directives. Add a selector mechanism that allows specific parse tree nodes to be identified. For example: %feature("foo", nodetype="class") Foo { ... some code ... }; Also desirable for the Java module to specify the classes to go in the throw clause: %feature("except", throws="OutOfMemoryException") Foo { ... code which throws the OutOfMemoryException ... }; Consider use of wildcards. Namespace/nested scope support in %feature is currently weak. It works, but is fragile. Consider an implementation that is better integrated with symbol table management. Continue to consolidate SWIG directives to %feature. *** Bring Aquinas' contract/assertion checking code online. *** Add more intelligent information related to object ownership. SWIG should be able to automatically strip ownership from objects when they are assigned to pointer variables and structure members as well as stored in a container (i.e., an array of pointers). [ Partially finished for Tcl/Python. ] [DONE] Modify smart pointer handling to properly handle inheritance. For example: %ignore Foo; class Foo { public: Blah *operator->(); }; class Bar : public Foo { } Bar should still allow access to Blah * through operator->(). [DONE] Virtual function optimization. If you have two classes like this: class Foo { public: virtual int blah(int); }; class Bar : public Foo { public: virtual int blah(int); }; Then SWIG ought to be able to reuse the wrapper for Foo::blah as Bar::blah. This should result in much smaller extension modules. This feature is now enabled using the -fvirtual option. ** Restoration of the documentation system. ** Restoration of Objective-C support. ** Unification of symbol tables and type system scopes. In a sense they capture the same information so it is not necessary to have both. The existence of two symbol management systems is mostly historical. ** Add a warning for uninstantiated templates. For example, if a function using a template type, but that type hasn't been instantiated using %template. * Fix template partial specialization matching rules. SWIG does not implement the proper C++ type deduction rules, but it does handle the most common cases. This is likely to be hard and implementing it would really only be for completeness. Build ----- **** Make sure there are tests for *ALL* library files in the test-suite. A number of files appear to be broken in SWIG-1.3.13. [DONE] Move the Source/Modules1.1 directory into the Source/Modules directory and deprecate Modules1.1. Library ------- **** Add more support for the C++ standard library. std::complex and other core datatypes. Refine support for STL vector. Add more STL objects. **** Continue to expand the set of recognized typemaps. Windows ------- [DONE] Visual C++ Project files / Makefiles for building the runtime libraries. Will require libtool mods to work under Cygwin. All language modules -------------------- Python ------ *** Ability to wrap certain classes as Python built-in types. Perl ---- **** Rewrite runtime pointer type checking to better integrate shadow classes. Creation of shadow classes should be done in C instead of Perl. This will fix a number of problems related to typemaps and reduce the amount of Perl wrapper code. **** Create tests for existing support for operator overloading Tcl --- Ruby ---- **** Add Ruby support for Mark Rose's polymorphism code. **** The "Resource Management in Proxies" section of the "SWIG and C++" chapter discusses how proxies' ownership of their associated C++ object can change, and the use of the special disown() and acquire() methods to change this ownership status. Need to address this for Ruby as well. [DONE] Investigate the new object allocation framework that has been implemented for Ruby 1.8 and determine what (if anything) needs to be changed for the wrapper code generated by SWIG. For background see ruby-talk messages 23358 and 38856 (and related threads). *** Add support for keyword arguments (by collecting them in a hash?). [DONE] Add support for defining nested modules. This should work like it does for the SWIG Perl module. [DONE] In a post to the SWIG users' mailing list (June 5: "Multiple Inheritance and Ruby"), Brett Williams suggested a workaround for supporting multiple inheritance in the Ruby module. I'm quoting it here since the idea may be best implemented at the core level for reuse by other language modules that have limited support for MI: """ While it makes for longer generated wrapper code, you can easily generate wrappers as Ruby methods on the derived class in these cases, i.e.: class Base1; class Base2; class Derived : public Base1, public Base2; class OtherDerived : public Base2; This would mean that for class Derived, the methods for Base2 would be generated as methods on class Derived as opposed to a superclass. For class OtherDerived, things work as normal, and any other derived class from Base2 would still work as they currently are, unless other derived classes also use MI. The exception and extra wrapper generation would only kick in with the use of multiple inheritance where the base class information is available to SWIG. The feature could be turned on and off, and doesn't have to be default if necessary. I was under the impression that the Tcl module, until a few releases ago, did all inheritance this way (generating wrappers for superclass methods in all derived classes). It does bloat the wrapper code, but in this case it would only be causing more bloat in cases where the alternative is no support. What is missing with this? Hmmmm... if Base2 implements a method that is overridden by Derived, then you could not get at Base2::Method() via the super keyword... what else am I missing? Again, the alternative is no support for MI at all unless you want to get fancy with mixins. I'm not sure how good of an idea that is or even if it is workable. """ Another problem (which we can't really get around anyways) is that basic inheritance relationships wouldn't be true at the Ruby level, e.g. Derived#is_a?(Base1) would return true but Derived#is_a?(Base2) would return false. * Add some special directives to automatically rename declarations to or from CamelCase. [DONE] Consider adding a switch to define everything in the global (Kernel) module instead of nested in a user-defined module, but only if it comes up. Java ---- **** Default argument support. Default arguments are effectively ignored at present. An overridden method for each default argument could be generated thereby enabling one to call methods with default arguments. [DONE] Implement idea from Dave Dribin email to the swig mailing list, 2 April 2003, where the global enums and constants are placed in an interface so that they can be implemented by other Java classes. This will allow improved syntax when referring to the enums/constants: int foo = enumname; instead of int foo = ModuleName.enumname; C# -- [DONE] Need a way to throw a C# exception from the PINVOKE C/C++ code. [DONE] The correct override/virtual keywords not always emitted for polymorphic methods. It currently works with 'virtual' is specified in a derived C++ class function. A polymorphic method need not specify 'virtual' in C++. **** Wrap C/C++ enums with C# enums, currently they are wrapped with a C# int. **** Implement director support for C# so that virtual methods work seemlessly when mixing C# and C++ code. PHP --- ** When returning wrapped objects via alternate constructors if that pointer value already exists "out there" as a resource we should use the same resource, we can't have multiple ref-counted resources mapping to the same object in case it gets twice destroyed. And check if ref count destroying is even working, see smart_pointer_rename * Work out how classes without even inherited constructors should interact with the php "new " notation. See: abstract_inherit_wrap.cpptest ** Look at pass by point and passby ref, Make sometype** to be auto allocated Make sometype& and sometype* to be autoallocated IF THEY ARE NOT ALREADY swigtype wrapped. * Overloading, callbacks, really review to see what else is missed Guile ----- ** Maybe rename slot setters from CLASS-SLOT-set to CLASS-SLOT-set! to match Scheme convention for naming of mutators. ** Support keyword args. [DONE] Support GOOPS shadow classes. ** Director Support! ** Cleaner handling of multiple values. Use a typemap keyword argument "numoutputs" of "out" and "argout" to indicate how many values are returned. [DONE] Support garbage collection. ** Make SWIG's types first-class by using a separate smob type for SWIG type descriptors; enable reflection on types. (Maybe GOOPS metaclasses?) ** Maybe communicate the type system between object modules via Scheme variables, rather than a shared object. This would remove the need of a shared SWIG runtime library. ** Provide a clean way to construct type predicates. ** In GOOPS mode, maybe make overloaded functions methods. ** Increase the safety of destructor functions. John Lenz suggests: I think the best way of doing this would be to use %feature to mark which classes allow for "normal" smobs to be deleted explicitly. We separate pointers into two classes, those that can be deleted from scheme and those that can't. The pointers that can be deleted use the smob and those that can not be deleted use the smob. A user can specify which type of each object they want with %newobject and the CONSUMED typemap. By default, the exported destructor will only accept smobs, because by definition, collectable-swig smobs are those that can be deleted from scheme. This allows for the user to implement protection. In the interface file, the user has complete control over which objects can and can not be deleted, and can guarantee that objects that should not be deleted can not be deleted, and that objects that should eventually be deleted will be garbage collected. This protection can then be overridden with a %feature directive, something like %feature("guile_allow_destroy_all","1") Foo::~Foo; I don't know what word we want to use, guile_allow_destroy_all is kinda bad. This feature would then allow for a smob to be deleted by passing it to the destructor. This would allow users to maintain the protection on other classes, only manually overriding the protection on the classes that need it. Mzscheme -------- ** Port list-vector.i and pointer-in-out.i from Guile. ** Add shadow class support for the Swindle system. Pike ---- * Decide how to handle global variables (probably using something like the Python module's cvar). Affects Examples/pike/simple. * Decide how to handle static class member functions and member variables. * Should investigate the possibility of generating .cmod files in addition to straight C/C++ code for extensions. Common Lisp ----------- * Random thoughts by mkoeppe on supporting Common Lisp implementations: There are many different Foreign Function Interfaces (FFI) for the various CL implementations. Probably SWIG should interface to UFFI, a least-common-denominator FFI that supports many implementations. Via the s-expression SWIG module we can export SWIG's parse tree and import it into CL. It remains to check if all relevant information is dumped (for instance, the type information). Experimental code is available to generate low-level UFFI declarations from this parse tree. However, for wrapping C++, we also need to create C wrappers because most FFIs cannot directly import C++. A CL SWIG module could be exporting both these wrappers and UFFI declarations. I have experimental code (not checked in yet) that does this. This is fine for generating low-level wrappers. But how do we support user typemaps (like converting lists and vectors to C arrays on input)? We have to generate Lisp code that does the conversion and then calls the low-level wrapper. If we generate Lisp code, it should be beautiful and readable. Therefore, we need at least a Lisp pretty printer. A Lisp pretty printer works best when the Lisp program is represented not as text but as Lisp data. Moreover, typemap writers will feel very much constrained by SWIG's capabilities for generating wrapper code, when compared to writing Lisp macros. Thus we would need half a re-implementation of Lisp in SWIG to make users happy. The solution could be the following: ** Build a SWIG library (again) and load it into a Common Lisp implementation. The FFI declarations could be written manually, or this could be bootstrapped via the s-expression module or the primitive UFFI wrappers. This should be easy because SWIG's API is quite simple. The embedded SWIG would be driven by a CL program. High-level typemaps would be written as Lisp programs that generate Lisp code. Ocaml ----- ** I've been working with my camlp4 module and type information from the compiler. When I'm done, the user will have access to type inference when writing code, when the inference is unambiguous. This allows the user to write x = _foo 1.0 instead of x = get_float (_foo (C_float 1.0)). It's not as easy as it sounds, because O'caml doesn't keep type information at run time, and doesn't really have a mechanism for doing what I need. However, it's possible to write a preprocessor that inserts correct type info at compile time. That having been said, the program must compile for type info to be available, so I need to attend to a lot of details; The program must compile both with and without type augmentation. Xml --- Documentation ------------- **** Extending SWIG (and internals). *** Perl, Python, Tcl modules. *** add section for Perl module support for operator overloading ** Add section on WAD. Other ----- ***** Learn more wicked Jazz chords. (in progress) cableswig-0.1.0+git20150808.orig/SWIG/Tools/0002755000175000000620000000000012561312227016700 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Tools/mkdist.py0000755000175000000620000000226612561312227020554 0ustar stevestaff#!/usr/local/bin/python # This script builds a SWIG1.3 distribution. # Usage : mkdist.py dirname import sys import string try: dirname = sys.argv[1] except: print "Usage: mkdist.py directory" sys.exit(0) # If directory exists, remove it import os print "Removing ", dirname os.system("rm -rf "+dirname) # Do a CVS export on the directory name print "Checking out SWIG" os.system("cvs export -D now -d "+dirname+ " SWIG") # Remove the debian directory -- it's not official os.system("rm -Rf "+dirname+"/debian"); # Blow away all .cvsignore files print "Blowing away .cvsignore files" os.system("find "+dirname+" -name .cvsignore -exec rm {} \\;"); # Go build the system os.system("cd "+dirname+"; ./autogen.sh") os.system("cd "+dirname+"/Tools/WAD; autoconf") os.system("cd "+dirname+"/Source/CParse; bison -y -d parser.y; mv y.tab.c parser.c; mv y.tab.h parser.h") # Remove autoconf files os.system("find "+dirname+" -name autom4te.cache -exec rm -rf {} \\;"); # Build documentation os.system("cd "+dirname+"/Doc/Manual; python maketoc.py; rm *.bak") # Build the tar-ball os.system("tar -cf "+string.lower(dirname)+".tar "+dirname) os.system("gzip "+string.lower(dirname)+".tar") cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/0002755000175000000620000000000012561312227017313 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Tcl/0002755000175000000620000000000012561312227020035 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Tcl/wadtcl.c0000644000175000000620000000632012561312227021456 0ustar stevestaff/* ----------------------------------------------------------------------------- * 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[] = "/cvsroot/SWIG/Tools/WAD/Tcl/wadtcl.c,v 1.4 2001/06/26 15:54:53 beazley Exp"; /* 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; } cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Tcl/Makefile.in0000644000175000000620000000174712561312227022111 0ustar stevestaff####################################################################### # 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 *~ cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Tcl/wadtclinit.cxx0000644000175000000620000000267412561312227022732 0ustar stevestaff/* ----------------------------------------------------------------------------- * 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[] = "/cvsroot/SWIG/Tools/WAD/Tcl/wadtclinit.cxx,v 1.4 2001/06/24 20:06:27 beazley Exp"; 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; cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Papers/0002755000175000000620000000000012561312227020545 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Papers/README0000644000175000000620000000011612561312227021421 0ustar stevestaffPapers about WAD can be obtained at: http://systems.cs.uchicago.edu/wad cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Python/0002755000175000000620000000000012561312227020574 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Python/type.c0000644000175000000620000001576612561312227021736 0ustar stevestaff/* ----------------------------------------------------------------------------- * 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[] = "/cvsroot/SWIG/Tools/WAD/Python/type.c,v 1.7 2001/06/20 15:12:52 beazley Exp"; 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) { PyMem_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 */ }; cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Python/Makefile.in0000644000175000000620000000175712561312227022651 0ustar stevestaff####################################################################### # 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 *~ cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Python/wadpyinit.cxx0000644000175000000620000000303312561312227023325 0ustar stevestaff/* ----------------------------------------------------------------------------- * 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[] = "/cvsroot/SWIG/Tools/WAD/Python/wadpyinit.cxx,v 1.4 2001/06/20 15:12:53 beazley Exp"; 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; cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Python/python.c0000644000175000000620000001341312561312227022261 0ustar stevestaff/* ----------------------------------------------------------------------------- * 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[] = "/cvsroot/SWIG/Tools/WAD/Python/python.c,v 1.8 2001/06/20 15:12:52 beazley Exp"; /* 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); } cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Makefile.in0000644000175000000620000000152012561312227021354 0ustar stevestaff# 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 cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Include/0002755000175000000620000000000012561312227020676 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Include/wad.h0000644000175000000620000002155612561312227021631 0ustar stevestaff/* ----------------------------------------------------------------------------- * wad.h * * WAD header file (obviously) * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 2001. University of Chicago. All rights reserved. * * /cvsroot/SWIG/Tools/WAD/Include/wad.h,v 1.26 2001/06/24 20:01:03 beazley Exp * ----------------------------------------------------------------------------- */ #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 cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/HACK0000644000175000000620000000547112561312227017751 0ustar stevestaffThe WAD Developers Guide David Beazley (beazley@cs.uchicago.edu) /cvsroot/SWIG/Tools/WAD/HACK,v 1.1 2001/03/12 17:59:39 beazley Exp 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. cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/COPYING0000644000175000000620000006347612561312227020364 0ustar stevestaff 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! cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/configure.in0000644000175000000620000002173212561312227021627 0ustar stevestaffdnl 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 cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/CHANGES0000644000175000000620000000116412561312227020306 0ustar stevestaffWAD 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. cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Prebuilt/0002755000175000000620000000000012561312227021101 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Prebuilt/solaris/0002755000175000000620000000000012561312227022555 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Prebuilt/solaris/Makefile.in0000644000175000000620000000033312561312227024617 0ustar stevestaff# 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 cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Prebuilt/linux/0002755000175000000620000000000012561312227022240 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Prebuilt/linux/Makefile.in0000644000175000000620000000033312561312227024302 0ustar stevestaff# 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 cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Wad/0002755000175000000620000000000012561312227020026 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Wad/default.c0000644000175000000620000001743112561312227021622 0ustar stevestaff/* ----------------------------------------------------------------------------- * 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[] = "/cvsroot/SWIG/Tools/WAD/Wad/default.c,v 1.16 2001/06/24 20:01:03 beazley Exp"; #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); } cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Wad/Makefile.in0000644000175000000620000000271712561312227022100 0ustar stevestaff####################################################################### # 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 *~ cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Wad/string.c0000644000175000000620000000647212561312227021507 0ustar stevestaff/* ----------------------------------------------------------------------------- * 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[] = "/cvsroot/SWIG/Tools/WAD/Wad/string.c,v 1.4 2001/06/20 15:12:53 beazley Exp"; /* 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; } cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Wad/main.cxx0000644000175000000620000000027212561312227021475 0ustar stevestaffextern "C" { #include "wad.h" } /* This is a sick hack to force initialization upon loading */ class StartDebug { public: StartDebug() { wad_init(); } }; static StartDebug s; cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Wad/elf.c0000644000175000000620000003072312561312227020743 0ustar stevestaff/* ----------------------------------------------------------------------------- * 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[] = "/cvsroot/SWIG/Tools/WAD/Wad/elf.c,v 1.14 2001/06/20 15:12:53 beazley Exp"; #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; */ } cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Wad/demangle.c0000644000175000000620000000263412561312227021751 0ustar stevestaff/* ----------------------------------------------------------------------------- * 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[] = "/cvsroot/SWIG/Tools/WAD/Wad/demangle.c,v 1.3 2001/06/20 15:12:53 beazley Exp"; char *wad_cplus_demangle(WadSymbol *ws) { static char buffer[4096]; strcpy(buffer,ws->name); return buffer; } cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Wad/wadpl.cxx0000644000175000000620000000737512561312227021673 0ustar stevestaff/* ----------------------------------------------------------------------------- * 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); } cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Wad/stab.c0000644000175000000620000004236612561312227021134 0ustar stevestaff/* ----------------------------------------------------------------------------- * 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[] = "/cvsroot/SWIG/Tools/WAD/Wad/stab.c,v 1.22 2001/06/20 15:12:53 beazley Exp"; /* 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; } cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Wad/makehandler.py0000755000175000000620000000053312561312227022655 0ustar stevestaff#!/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() cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Wad/vars.c0000644000175000000620000001543112561312227021147 0ustar stevestaff/* ----------------------------------------------------------------------------- * 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[] = "/cvsroot/SWIG/Tools/WAD/Wad/vars.c,v 1.8 2001/06/20 15:12:53 beazley Exp"; /* ----------------------------------------------------------------------------- * 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; } cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Wad/wadhandler.pl0000644000175000000620000000204112561312227022467 0ustar stevestaffpackage 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; } cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Wad/signal.c0000644000175000000620000003326512561312227021456 0ustar stevestaff/* ----------------------------------------------------------------------------- * 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[] = "/cvsroot/SWIG/Tools/WAD/Wad/signal.c,v 1.32 2001/06/24 20:01:03 beazley Exp"; 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); } cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Wad/libwadpl.pm0000644000175000000620000000022212561312227022154 0ustar stevestaffpackage libwadpl; require Exporter; require DynaLoader; @ISA = qw(Exporter DynaLoader); package libwadpl; bootstrap libwadpl; @EXPORT = qw( ); 1; cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Wad/return.c0000644000175000000620000000431312561312227021510 0ustar stevestaff/* ----------------------------------------------------------------------------- * 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[] = "/cvsroot/SWIG/Tools/WAD/Wad/return.c,v 1.7 2001/06/20 15:12:53 beazley Exp"; /* 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; } cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Wad/io.c0000644000175000000620000000531512561312227020603 0ustar stevestaff/* ----------------------------------------------------------------------------- * 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[] = "/cvsroot/SWIG/Tools/WAD/Wad/io.c,v 1.5 2001/06/20 15:12:53 beazley Exp"; /* 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); } cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Wad/init.c0000644000175000000620000000543312561312227021140 0ustar stevestaff/* ----------------------------------------------------------------------------- * 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[] = "/cvsroot/SWIG/Tools/WAD/Wad/init.c,v 1.17 2001/06/20 15:12:53 beazley Exp"; /* 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; } cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Wad/memory.c0000644000175000000620000001346512561312227021511 0ustar stevestaff/* ----------------------------------------------------------------------------- * 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[] = "/cvsroot/SWIG/Tools/WAD/Wad/memory.c,v 1.10 2001/06/20 15:12:53 beazley Exp"; 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); } } cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Wad/debug.c0000644000175000000620000000342512561312227021262 0ustar stevestaff#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); } cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Wad/object.c0000644000175000000620000002156312561312227021445 0ustar stevestaff/* ----------------------------------------------------------------------------- * 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[] = "/cvsroot/SWIG/Tools/WAD/Wad/object.c,v 1.12 2001/06/20 15:12:53 beazley Exp"; #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; } cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Wad/stack.c0000644000175000000620000002153312561312227021301 0ustar stevestaff/* ----------------------------------------------------------------------------- * 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[] = "/cvsroot/SWIG/Tools/WAD/Wad/stack.c,v 1.24 2001/06/20 15:12:53 beazley Exp"; /* ----------------------------------------------------------------------------- * 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; } cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Wad/segment.c0000644000175000000620000001435712561312227021644 0ustar stevestaff/* ----------------------------------------------------------------------------- * 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[] = "/cvsroot/SWIG/Tools/WAD/Wad/segment.c,v 1.18 2001/06/20 15:12:53 beazley Exp"; /* 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; } cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Misc/0002755000175000000620000000000012561312227020206 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Misc/fileheader0000644000175000000620000000247212561312227022224 0ustar stevestaff/* ----------------------------------------------------------------------------- * 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. * ----------------------------------------------------------------------------- */ cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/README0000644000175000000620000003300312561312227020170 0ustar stevestaffWAD (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. /cvsroot/SWIG/Tools/WAD/README,v 1.21 2002/11/30 22:10:17 beazley Exp !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!! 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 cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Test/0002755000175000000620000000000012561312227020232 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Test/Makefile.in0000644000175000000620000000212112561312227022271 0ustar stevestaff####################################################################### # 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* cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Test/debug.tcl0000644000175000000620000000135212561312227022023 0ustar stevestaff# 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 cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Test/debug.py0000644000175000000620000000133612561312227021673 0ustar stevestaff# 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) cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Test/death.tcl0000644000175000000620000000223612561312227022024 0ustar stevestaffload ./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" cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Test/wpm.py0000644000175000000620000001623512561312227021414 0ustar stevestaff# ----------------------------------------------------------------------------- # 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) cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Test/death.py0000644000175000000620000000261112561312227021667 0ustar stevestaffimport 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() cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Test/foo.py0000644000175000000620000000034012561312227021362 0ustar stevestaffimport 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() cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Test/debug.c0000644000175000000620000000433712561312227021471 0ustar stevestaff/* ----------------------------------------------------------------------------- * 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 cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Test/wadpm.py0000644000175000000620000000200312561312227021705 0ustar stevestaff# ----------------------------------------------------------------------------- # 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() cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Test/debug.i0000644000175000000620000000040312561312227021465 0ustar stevestaff%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); cableswig-0.1.0+git20150808.orig/SWIG/Tools/WAD/Test/README0000644000175000000620000000025412561312227021111 0ustar stevestaffSimple 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). cableswig-0.1.0+git20150808.orig/SWIG/Tools/setup.py.tmpl0000755000175000000620000001125712561312227021374 0ustar stevestaff#!@PYTHON@ '''A setup.py script with better SWIG support. To use it, either rename it to setup.py.in and have it pe processed by your configure script (you will need to define @PYTHON@), or replace the @*@ strings by hand. Copyright 2001, Anthony Joseph Seward''' from distutils.core import setup, Extension ############################################################################### ## Start of better Swig support ############################################################################### from distutils.command.build_ext import build_ext import os import string class build_swig_ext(build_ext): '''Better swig support for Distutils''' ## __ Tell Distutils about the options user_options = build_ext.user_options boolean_options = build_ext.boolean_options user_options.append( ('swig-doc=', None, 'what type of documentation should SWIG produce (default: none)') ) user_options.append( ('swig-inc=', None, 'a list of directories to add to the SWIG include path' + "(separated by ':')(default: SWIG)") ) user_options.append( ('swig-shadow', None, 'have SWIG create shadow classes' + ' (also adds docstrings to the shadow classes') ) boolean_options.append('swig-shadow') def initialize_options(self): '''Initialize the new options after the inherited ones''' build_ext.initialize_options(self) self.swig_doc = 'none' self.swig_inc = 'SWIG' self.swig_shadow = None def swig_sources(self, sources): """Override the definition of 'swig_sources' in build_ext. This is essentially the same function but with better swig support. I will now quote the original docstring: Walk the list of source files in 'sources', looking for SWIG interface (.i) files. Run SWIG on all that are found, and return a modified 'sources' list with SWIG source files replaced by the generated C (or C++) files. """ new_sources = [] swig_sources = [] swig_targets = {} # XXX this drops generated C/C++ files into the source tree, which # is fine for developers who want to distribute the generated # source -- but there should be an option to put SWIG output in # the temp dir. if self.swig_cpp: target_ext = '.cpp' else: target_ext = '.c' for source in sources: (base, ext) = os.path.splitext(source) if ext == ".i": # SWIG interface file new_sources.append(base + target_ext) swig_sources.append(source) swig_targets[source] = new_sources[-1] else: new_sources.append(source) if not swig_sources: return new_sources includes = self.swig_inc if type(includes) is type(''): includes = string.split(includes, ':') includes = map(lambda x: '-I'+x, includes) includes = string.join(includes) swig = self.find_swig() ## swig_cmd = [swig, "-python", "-d%s" % self.swig_doc, includes] swig_cmd = [swig, '-v', '-python', '-d%s' % self.swig_doc, includes] if self.swig_cpp: swig_cmd.append('-c++') if self.swig_shadow: swig_cmd.append('-shadow') ## swig1.1 swig_cmd.append('-docstring') for source in swig_sources: target = swig_targets[source] self.announce('swigging %s to %s' % (source, target)) self.spawn(swig_cmd + ['-o', target, source]) return new_sources # swig_sources () ############################################################################### ## End of improved swig support ############################################################################### package = '@PACKAGE@' version = '@VERSION@' include_dirs = ['@top_srcdir@'] lib_dirs = ['@top_srcdir@/@PACKAGE@'] libraries = ['@PACKAGE@', 'stdc++'] setup(name = package, version = version, description = '', author = '', author_email = '', url = 'http://', cmdclass = {'build_ext': build_swig_ext}, ext_modules = [Extension(package+'cmodule', [package+'.i'], include_dirs=include_dirs, library_dirs=lib_dirs, libraries=libraries, )], options = {'build_ext': {'swig_doc': 'html', 'swig_cpp': not None, 'swig_shadow': not None} } ) cableswig-0.1.0+git20150808.orig/SWIG/Tools/.cvsignore0000644000175000000620000000000012561312227020664 0ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Tools/config/0002755000175000000620000000000012561312227020145 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Tools/config/.cvsignore0000644000175000000620000000012312561312227022137 0ustar stevestaffcompile config.guess config.sub depcomp install-sh ltmain.sh missing mkinstalldirs cableswig-0.1.0+git20150808.orig/SWIG/Tools/config/ac_compile_warnings.m40000644000175000000620000000153012561312227024407 0ustar stevestaffdnl Available from the GNU Autoconf Macro Archive at: dnl http://www.gnu.org/software/ac-archive/htmldoc/ac_compile_warnings.html dnl dnl Modified from original to increase the warning levels from -Wall AC_DEFUN([AC_COMPILE_WARNINGS], [AC_MSG_CHECKING(maximum warning verbosity option) if test -n "$CXX" then if test "$GXX" = "yes" then ac_compile_warnings_opt='-Wall -ansi -pedantic' fi CXXFLAGS="$CXXFLAGS $ac_compile_warnings_opt" ac_compile_warnings_msg="$ac_compile_warnings_opt for C++" fi if test -n "$CC" then if test "$GCC" = "yes" then ac_compile_warnings_opt='-Wall -ansi -pedantic' fi CFLAGS="$CFLAGS $ac_compile_warnings_opt" ac_compile_warnings_msg="$ac_compile_warnings_msg $ac_compile_warnings_opt for C" fi AC_MSG_RESULT($ac_compile_warnings_msg) unset ac_compile_warnings_msg unset ac_compile_warnings_opt ]) cableswig-0.1.0+git20150808.orig/SWIG/Tools/config/ac_define_dir.m40000644000175000000620000000072012561312227023137 0ustar stevestaffdnl Available from the GNU Autoconf Macro Archive at: dnl http://www.gnu.org/software/ac-archive/htmldoc/ac_define_dir.html dnl AC_DEFUN([AC_DEFINE_DIR], [ test "x$prefix" = xNONE && prefix="$ac_default_prefix" test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' ac_define_dir=`eval echo [$]$2` ac_define_dir=`eval echo [$]ac_define_dir` ifelse($3, , AC_DEFINE_UNQUOTED($1, "$ac_define_dir"), AC_DEFINE_UNQUOTED($1, "$ac_define_dir", $3)) ]) cableswig-0.1.0+git20150808.orig/SWIG/Tools/config/swig.m40000644000175000000620000001114012561312227021353 0ustar stevestaff# Contributed by Sebastian Huber # SWIG_PROG([required-version = N[.N[.N]]]) # # Checks for the SWIG program. If found you can (and should) call # SWIG via $(SWIG). You can use the optional first argument to check # if the version of the available SWIG is greater than or equal to the # value of the argument. It should have the format: N[.N[.N]] (N is a # number between 0 and 999. Only the first N is mandatory.) AC_DEFUN([SWIG_PROG],[ AC_PATH_PROG([SWIG],[swig]) if test -z "$SWIG" ; then AC_MSG_WARN([cannot find 'swig' program, you may have a look at http://www.swig.org]) SWIG='echo "error: SWIG is not installed, you may have a look at http://www.swig.org" ; false' elif test -n "$1" ; then AC_MSG_CHECKING([for SWIG version]) [swig_version=`$SWIG -version 2>&1 | grep 'SWIG Version' | sed 's/.*\([0-9]\+\.[0-9]\+\.[0-9]\+\).*/\1/g'`] AC_MSG_RESULT([$swig_version]) if test -n "$swig_version" ; then # Calculate the required version number [swig_tmp=( `echo $1 | sed 's/[^0-9]\+/ /g'` )] [swig_required_version=$(( 1000000 * ${swig_tmp[0]:-0} + 1000 * ${swig_tmp[1]:-0} + ${swig_tmp[2]:-0} ))] # Calculate the available version number [swig_tmp=( `echo $swig_version | sed 's/[^0-9]\+/ /g'` )] [swig_tmp=$(( 1000000 * ${swig_tmp[0]:-0} + 1000 * ${swig_tmp[1]:-0} + ${swig_tmp[2]:-0} ))] if test $swig_required_version -gt $swig_tmp ; then AC_MSG_WARN([SWIG version $1 is required, you have $swig_version]) fi else AC_MSG_WARN([cannot determine SWIG version]) fi SWIG_RUNTIME_LIBS_DIR="${SWIG%/bin*}/lib" AC_MSG_NOTICE([SWIG runtime library directory is '$SWIG_RUNTIME_LIBS_DIR']) fi AC_SUBST([SWIG_RUNTIME_LIBS_DIR]) ]) # SWIG_ENABLE_CXX() # # Enable SWIG C++ support. This effects all invocations of $(SWIG). AC_DEFUN([SWIG_ENABLE_CXX],[ AC_REQUIRE([SWIG_PROG]) AC_REQUIRE([AC_PROG_CXX]) SWIG="$SWIG -c++" ]) # SWIG_MULTI_MODULE_SUPPORT() # # Enable support for multiple modules. This effects all invocations # of $(SWIG). You have to link all generated modules against the # appropriate SWIG runtime library. If you want to build Python # modules for example, use the SWIG_PYTHON() macro and link the # modules against $(SWIG_PYTHON_LIBS). AC_DEFUN([SWIG_MULTI_MODULE_SUPPORT],[ AC_REQUIRE([SWIG_PROG]) SWIG="$SWIG -c" ]) # SWIG_PYTHON([use-shadow-classes = {no, yes}]) # # Checks for Python and provides the $(SWIG_PYTHON_CPPFLAGS), # $(SWIG_PYTHON_LIBS) and $(SWIG_PYTHON_OPT) output variables. # $(SWIG_PYTHON_OPT) contains all necessary SWIG options to generate # code for Python. Shadow classes are enabled unless the value of the # optional first argument is exactly 'no'. If you need multi module # support (provided by the SWIG_MULTI_MODULE_SUPPORT() macro) use # $(SWIG_PYTHON_LIBS) to link against the appropriate library. It # contains the SWIG Python runtime library that is needed by the type # check system for example. AC_DEFUN([SWIG_PYTHON],[ AC_REQUIRE([SWIG_PROG]) AC_REQUIRE([PYTHON_DEVEL]) test "x$1" != "xno" || swig_shadow=" -noproxy" AC_SUBST([SWIG_PYTHON_OPT],[-python$swig_shadow]) AC_SUBST([SWIG_PYTHON_CPPFLAGS],[$PYTHON_CPPFLAGS]) AC_SUBST([SWIG_PYTHON_LIBS],["$SWIG_RUNTIME_LIBS_DIR -lswigpy"]) ]) # PYTHON_DEVEL() # # Checks for Python and tries to get the include path to 'Python.h'. # It provides the $(PYTHON_CPPFLAGS) and $(PYTHON_LDFLAGS) output variable. AC_DEFUN([PYTHON_DEVEL],[ AC_REQUIRE([AM_PATH_PYTHON]) # Check for Python include path AC_MSG_CHECKING([for Python include path]) python_path=${PYTHON%/bin*} for i in "$python_path/include/python$PYTHON_VERSION/" "$python_path/include/python/" "$python_path/" ; do python_path=`find $i -type f -name Python.h -print` if test -n "$python_path" ; then break fi done for i in $python_path ; do python_path=${python_path%/Python.h} break done AC_MSG_RESULT([$python_path]) if test -z "$python_path" ; then AC_MSG_ERROR([cannot find Python include path]) fi AC_SUBST([PYTHON_CPPFLAGS],[-I$python_path]) # Check for Python library path AC_MSG_CHECKING([for Python library path]) python_path=${PYTHON%/bin*} for i in "$python_path/lib/python$PYTHON_VERSION/config/" "$python_path/lib/python$PYTHON_VERSION/" "$python_path/lib/python/config/" "$python_path/lib/python/" "$python_path/" ; do python_path=`find $i -type f -name libpython$PYTHON_VERSION.* -print` if test -n "$python_path" ; then break fi done for i in $python_path ; do python_path=${python_path%/libpython*} break done AC_MSG_RESULT([$python_path]) if test -z "$python_path" ; then AC_MSG_ERROR([cannot find Python library path]) fi AC_SUBST([PYTHON_LDFLAGS],["-L$python_path -lpython$PYTHON_VERSION"]) ]) cableswig-0.1.0+git20150808.orig/SWIG/Tools/capitalize0000755000175000000620000000034712561312227020755 0ustar stevestaff#!/bin/sh # usage: capitalize word # write word to stdout w/ first character upcased first_char=`echo $1 | sed 's/^\(.\).*/\1/' | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ` echo ${first_char}`echo $1 | sed 's/^.//'` cableswig-0.1.0+git20150808.orig/SWIG/Tools/check-include-path.pike0000644000175000000620000000110712561312227023177 0ustar stevestaff/** * This is a helper script to identify the proper include path * for Pike header files. It should be run with the full path * to the Pike executable as its single argument, e.g. * * pike check-include-path.pike /usr/local/bin/pike * * and its output should be the correct path to the header * files, e.g. * * /usr/local/pike/7.2.239/include/pike * */ int main(int argc, array(string) argv) { string prefix = replace(argv[1], "/bin/pike", ""); write(prefix + "/pike/" + __MAJOR__ + "." + __MINOR__ + "." + __BUILD__ + "/include/pike"); return 0; } cableswig-0.1.0+git20150808.orig/SWIG/Tools/swig.spec.10000644000175000000620000000176512561312227020673 0ustar stevestaff%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 cableswig-0.1.0+git20150808.orig/SWIG/Source/0002755000175000000620000000000012561312227017040 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Source/Preprocessor/0002755000175000000620000000000012561312227021526 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Source/Preprocessor/preprocessor.h0000644000175000000620000000226712561312227024432 0ustar stevestaff/* ----------------------------------------------------------------------------- * preprocessor.h * * SWIG preprocessor module. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * * /cvsroot/SWIG/Source/Preprocessor/preprocessor.h,v 1.9 2004/01/15 22:46:06 cheetah Exp * ----------------------------------------------------------------------------- */ #ifndef PREPROCESSOR_H_ #define PREPROCESSOR_H_ #include "swigwarn.h" #ifdef __cplusplus extern "C" { #endif extern int Preprocessor_expr(String *s, int *error); extern char *Preprocessor_expr_error(void); extern Hash *Preprocessor_define(const String_or_char *str, int swigmacro); extern void Preprocessor_undef(const String_or_char *name); extern void Preprocessor_init(void); extern String *Preprocessor_parse(String *s); extern void Preprocessor_include_all(int); extern void Preprocessor_import_all(int); extern void Preprocessor_ignore_missing(int); extern List *Preprocessor_depend(void); extern void Preprocessor_expr_init(void); #ifdef __cplusplus } #endif #endif cableswig-0.1.0+git20150808.orig/SWIG/Source/Preprocessor/.cvsignore0000644000175000000620000000002012561312227023514 0ustar stevestaff.deps .dirstamp cableswig-0.1.0+git20150808.orig/SWIG/Source/Preprocessor/expr.c0000644000175000000620000002560212561312227022653 0ustar stevestaff/* ----------------------------------------------------------------------------- * expr.c * * Integer arithmetic expression evaluator used to handle expressions * encountered during preprocessing. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_expr_c[] = "/cvsroot/SWIG/Source/Preprocessor/expr.c,v 1.10 2004/01/15 00:58:13 beazley Exp"; #include "swig.h" #include "preprocessor.h" static SwigScanner *scan = 0; typedef struct { int op; long value; String *svalue; } exprval; #define EXPR_TOP 1 #define EXPR_VALUE 2 #define EXPR_OP 3 #define EXPR_GROUP 4 #define EXPR_UMINUS 100 static exprval stack[256]; /* Parsing stack */ static int sp = 0; /* Stack pointer */ static int prec[256]; /* Precedence rules */ static int expr_init = 0; /* Initialization flag */ static char *errmsg = 0; /* Parsing error */ /* Initialize the precedence table for various operators. Low values have higher precedence */ static void init_precedence() { prec[SWIG_TOKEN_NOT] = 10; prec[EXPR_UMINUS] = 10; prec[SWIG_TOKEN_STAR] = 20; prec[SWIG_TOKEN_SLASH] = 20; prec[SWIG_TOKEN_PERCENT] = 20; prec[SWIG_TOKEN_PLUS] = 30; prec[SWIG_TOKEN_MINUS] = 30; prec[SWIG_TOKEN_LSHIFT] = 40; prec[SWIG_TOKEN_RSHIFT] = 40; prec[SWIG_TOKEN_AND] = 50; prec[SWIG_TOKEN_XOR] = 60; prec[SWIG_TOKEN_OR] = 70; prec[SWIG_TOKEN_EQUALTO] = 80; prec[SWIG_TOKEN_NOTEQUAL] = 80; prec[SWIG_TOKEN_LESSTHAN] = 80; prec[SWIG_TOKEN_GREATERTHAN] = 80; prec[SWIG_TOKEN_LTEQUAL] = 80; prec[SWIG_TOKEN_GTEQUAL] = 80; prec[SWIG_TOKEN_LNOT] = 90; prec[SWIG_TOKEN_LAND] = 100; prec[SWIG_TOKEN_LOR] = 110; expr_init = 1; } /* Reduce a single operator on the stack */ static void reduce_op() { if (stack[sp-1].op != EXPR_OP) { errmsg = "Missing operator"; sp = 0; return; } if (stack[sp-2].svalue || stack[sp].svalue) { /* A string expression */ if (!(stack[sp-2].svalue && stack[sp].svalue)) { errmsg = "Can't mix strings and integers in expression"; sp = 0; return; } switch(stack[sp-1].value) { case SWIG_TOKEN_EQUALTO: stack[sp-2].value = (Strcmp(stack[sp-2].svalue,stack[sp].svalue) == 0); Delete(stack[sp-2].svalue); Delete(stack[sp].svalue); sp -= 2; break; case SWIG_TOKEN_NOTEQUAL: stack[sp-2].value = (Strcmp(stack[sp-2].svalue,stack[sp].svalue) != 0); Delete(stack[sp-2].svalue); Delete(stack[sp].svalue); sp -= 2; break; default: errmsg = "Syntax error"; sp = 0; break; } } else { switch(stack[sp-1].value) { case SWIG_TOKEN_STAR: stack[sp-2].value = stack[sp-2].value * stack[sp].value; sp -= 2; break; case SWIG_TOKEN_EQUALTO: stack[sp-2].value = stack[sp-2].value == stack[sp].value; sp -= 2; break; case SWIG_TOKEN_NOTEQUAL: stack[sp-2].value = stack[sp-2].value != stack[sp].value; sp -= 2; break; case SWIG_TOKEN_PLUS: stack[sp-2].value = stack[sp-2].value + stack[sp].value; sp -= 2; break; case SWIG_TOKEN_MINUS: stack[sp-2].value = stack[sp-2].value - stack[sp].value; sp -= 2; break; case SWIG_TOKEN_AND: stack[sp-2].value = stack[sp-2].value & stack[sp].value; sp -= 2; break; case SWIG_TOKEN_LAND: stack[sp-2].value = stack[sp-2].value && stack[sp].value; sp -= 2; break; case SWIG_TOKEN_OR: stack[sp-2].value = stack[sp-2].value | stack[sp].value; sp -= 2; break; case SWIG_TOKEN_LOR: stack[sp-2].value = stack[sp-2].value || stack[sp].value; sp -= 2; break; case SWIG_TOKEN_XOR: stack[sp-2].value = stack[sp-2].value ^ stack[sp].value; sp -= 2; break; case SWIG_TOKEN_LESSTHAN: stack[sp-2].value = stack[sp-2].value < stack[sp].value; sp -= 2; break; case SWIG_TOKEN_GREATERTHAN: stack[sp-2].value = stack[sp-2].value > stack[sp].value; sp -= 2; break; case SWIG_TOKEN_LTEQUAL: stack[sp-2].value = stack[sp-2].value <= stack[sp].value; sp -= 2; break; case SWIG_TOKEN_GTEQUAL: stack[sp-2].value = stack[sp-2].value >= stack[sp].value; sp -= 2; break; case SWIG_TOKEN_NOT: stack[sp-1].value = ~stack[sp].value; sp--; break; case SWIG_TOKEN_LNOT: stack[sp-1].value = !stack[sp].value; sp--; break; case EXPR_UMINUS: stack[sp-1].value = -stack[sp].value; sp--; break; case SWIG_TOKEN_SLASH: stack[sp-2].value = stack[sp-2].value / stack[sp].value; sp -= 2; break; case SWIG_TOKEN_PERCENT: stack[sp-2].value = stack[sp-2].value % stack[sp].value; sp -= 2; break; case SWIG_TOKEN_LSHIFT: stack[sp-2].value = stack[sp-2].value << stack[sp].value; sp -= 2; break; case SWIG_TOKEN_RSHIFT: stack[sp-2].value = stack[sp-2].value >> stack[sp].value; sp -= 2; break; default: errmsg = "Syntax error"; sp = 0; break; } } stack[sp].op = EXPR_VALUE; } /* ----------------------------------------------------------------------------- * Preprocessor_expr_init() * * Initialize the expression evaluator * ----------------------------------------------------------------------------- */ void Preprocessor_expr_init (void) { if (!expr_init) init_precedence(); if (!scan) scan = NewSwigScanner(); } /* ----------------------------------------------------------------------------- * Tokenizer * ----------------------------------------------------------------------------- */ static int expr_token(SwigScanner *s) { int t; while(1) { t = SwigScanner_token(s); if (!((t == SWIG_TOKEN_BACKSLASH) || (t == SWIG_TOKEN_ENDLINE))) break; } return t; } /* ----------------------------------------------------------------------------- * Preprocessor_expr() * * Evaluates an arithmetic expression. Returns the result and sets an error code. * ----------------------------------------------------------------------------- */ int Preprocessor_expr(DOH *s, int *error) { int token = 0; int op = 0; sp = 0; assert(s); assert(scan); Seek(s,0,SEEK_SET); /* Printf(stdout,"evaluating : '%s'\n", s); */ *error = 0; SwigScanner_clear(scan); SwigScanner_push(scan,s); /* Put initial state onto the stack */ stack[sp].op = EXPR_TOP; stack[sp].value = 0; while (1) { /* Look at the top of the stack */ switch(stack[sp].op) { case EXPR_TOP: /* An expression. Can be a number or another expression enclosed in parens */ token = expr_token(scan); if (!token) { errmsg = "Expected an expression"; *error = 1; return 0; } if ((token == SWIG_TOKEN_INT) || (token == SWIG_TOKEN_UINT) || (token == SWIG_TOKEN_LONG) || (token == SWIG_TOKEN_ULONG)) { /* A number. Reduce EXPR_TOP to an EXPR_VALUE */ char *c = Char(SwigScanner_text(scan)); stack[sp].value = (long) strtol(c,0,0); stack[sp].svalue = 0; /* stack[sp].value = (long) atol(Char(SwigScanner_text(scan))); */ stack[sp].op = EXPR_VALUE; } else if (token == SWIG_TOKEN_PLUS) { } else if ((token == SWIG_TOKEN_MINUS) || (token == SWIG_TOKEN_LNOT) || (token==SWIG_TOKEN_NOT)) { if (token == SWIG_TOKEN_MINUS) token = EXPR_UMINUS; stack[sp].value = token; stack[sp++].op = EXPR_OP; stack[sp].op = EXPR_TOP; stack[sp].svalue = 0; } else if ((token == SWIG_TOKEN_LPAREN)) { stack[sp++].op = EXPR_GROUP; stack[sp].op = EXPR_TOP; stack[sp].value = 0; stack[sp].svalue = 0; } else if (token == SWIG_TOKEN_ENDLINE) { } else if ((token == SWIG_TOKEN_STRING)) { stack[sp].svalue = NewString(SwigScanner_text(scan)); stack[sp].op = EXPR_VALUE; } else if ((token == SWIG_TOKEN_ID)) { stack[sp].value = 0; stack[sp].svalue = 0; stack[sp].op = EXPR_VALUE; } else goto syntax_error; break; case EXPR_VALUE: /* A value is on the stack. We may reduce or evaluate depending on what the next token is */ token = expr_token(scan); if (!token) { /* End of input. Might have to reduce if an operator is on stack */ while (sp > 0) { if (stack[sp-1].op == EXPR_OP) { reduce_op(); } else if (stack[sp-1].op == EXPR_GROUP) { errmsg = "Missing \')\'"; *error = 1; return 0; } else goto syntax_error; } return stack[sp].value; } /* Token must be an operator */ switch(token) { case SWIG_TOKEN_STAR: case SWIG_TOKEN_EQUALTO: case SWIG_TOKEN_NOTEQUAL: case SWIG_TOKEN_PLUS: case SWIG_TOKEN_MINUS: case SWIG_TOKEN_AND: case SWIG_TOKEN_LAND: case SWIG_TOKEN_OR: case SWIG_TOKEN_LOR: case SWIG_TOKEN_XOR: case SWIG_TOKEN_LESSTHAN: case SWIG_TOKEN_GREATERTHAN: case SWIG_TOKEN_LTEQUAL: case SWIG_TOKEN_GTEQUAL: case SWIG_TOKEN_SLASH: case SWIG_TOKEN_PERCENT: case SWIG_TOKEN_LSHIFT: case SWIG_TOKEN_RSHIFT: if ((sp == 0) || (stack[sp-1].op == EXPR_GROUP)) { /* No possibility of reduce. Push operator and expression */ sp++; stack[sp].op = EXPR_OP; stack[sp].value = token; sp++; stack[sp].op = EXPR_TOP; stack[sp].value = 0; } else { if (stack[sp-1].op != EXPR_OP) goto syntax_error; op = stack[sp-1].value; /* Previous operator */ /* Now, depending on the precedence relationship between the last operator and the current we will reduce or push */ if (prec[op] <= prec[token]) { /* Reduce the previous operator */ reduce_op(); if (stack[sp].op != EXPR_VALUE) goto syntax_error; } sp++; stack[sp].op = EXPR_OP; stack[sp].value = token; sp++; stack[sp].op = EXPR_TOP; stack[sp].value = 0; } break; case SWIG_TOKEN_RPAREN: if (sp == 0) goto extra_rparen; /* Might have to reduce operators first */ while ((sp > 0) && (stack[sp-1].op == EXPR_OP)) reduce_op(); if ((sp == 0) || (stack[sp-1].op != EXPR_GROUP)) goto extra_rparen; stack[sp-1].op = EXPR_VALUE; stack[sp-1].value = stack[sp].value; sp--; break; default: goto syntax_error; break; } break; default: fprintf(stderr,"Internal error in expression evaluator.\n"); abort(); } } syntax_error: errmsg = "Syntax error"; *error = 1; return 0; extra_rparen: errmsg = "Extra \')\'"; *error = 1; return 0; } /* ----------------------------------------------------------------------------- * Preprocessor_expr_error() * * Return error message set by the evaluator (if any) * ----------------------------------------------------------------------------- */ char * Preprocessor_expr_error() { return errmsg; } cableswig-0.1.0+git20150808.orig/SWIG/Source/Preprocessor/cpp.c0000644000175000000620000011477412561312227022470 0ustar stevestaff/* ----------------------------------------------------------------------------- * cpp.c * * An implementation of a C preprocessor plus some support for additional * SWIG directives. * * - SWIG directives such as %include, %extern, and %import are handled * - A new macro %define ... %enddef can be used for multiline macros * - No preprocessing is performed in %{ ... %} blocks * - Lines beginning with %# are stripped down to #... and passed through. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_cpp_c[] = "/cvsroot/SWIG/Source/Preprocessor/cpp.c,v 1.52 2004/01/15 22:46:06 cheetah Exp"; #include "swig.h" #include "preprocessor.h" #include static Hash *cpp = 0; /* C preprocessor data */ static int include_all = 0; /* Follow all includes */ static int ignore_missing = 0; static int import_all = 0; /* Follow all includes, but as %import statements */ static int single_include = 1; /* Only include each file once */ static Hash *included_files = 0; static List *dependencies = 0; /* Test a character to see if it starts an identifier */ static int isidentifier(int c) { if ((isalpha(c)) || (c == '_') || (c == '$')) return 1; else return 0; } /* Test a character to see if it valid in an identifier (after the first letter) */ static int isidchar(int c) { if ((isalnum(c)) || (c == '_') || (c == '$')) return 1; else return 0; } /* Skip whitespace */ static void skip_whitespace(File *s, File *out) { int c; while ((c = Getc(s)) != EOF) { if (!isspace(c)) { Ungetc(c,s); break; } else if (out) Putc(c,out); } } /* Skip to a specified character taking line breaks into account */ static int skip_tochar(File *s, int ch, File *out) { int c; while ((c = Getc(s)) != EOF) { if (out) Putc(c,out); if (c == ch) break; if (c == '\\') { c = Getc(s); if ((c != EOF) && (out)) Putc(c,out); } } if (c == EOF) return -1; return 0; } static void copy_location(DOH *s1, DOH *s2) { Setfile(s2,Getfile(s1)); Setline(s2,Getline(s1)); } static String *cpp_include(String_or_char *fn) { String *s; s = Swig_include(fn); if (s && single_include) { String *file = Getfile(s); if (Getattr(included_files,file)) { Delete(s); return 0; } Setattr(included_files,file,file); } if (!s) { Seek(fn,0,SEEK_SET); if (ignore_missing) { Swig_warning(WARN_PP_MISSING_FILE,Getfile(fn),Getline(fn),"Unable to find '%s'\n", fn); } else { Swig_error(Getfile(fn),Getline(fn),"Unable to find '%s'\n", fn); } } else { Seek(s,0,SEEK_SET); if (!dependencies) { dependencies = NewList(); } Append(dependencies, Copy(Swig_last_file())); } return s; } List *Preprocessor_depend(void) { return dependencies; } /* ----------------------------------------------------------------------------- * void Preprocessor_cpp_init() - Initialize the preprocessor * ----------------------------------------------------------------------------- */ void Preprocessor_init(void) { Hash *s; cpp = NewHash(); s = NewHash(); Setattr(cpp,"symbols",s); Preprocessor_expr_init(); /* Initialize the expression evaluator */ included_files = NewHash(); } /* ----------------------------------------------------------------------------- * void Preprocessor_include_all() - Instruct preprocessor to include all files * ----------------------------------------------------------------------------- */ void Preprocessor_include_all(int a) { include_all = a; } void Preprocessor_import_all(int a) { import_all = a; } void Preprocessor_ignore_missing(int a) { ignore_missing = a; } /* ----------------------------------------------------------------------------- * Preprocessor_define() * * Defines a new C preprocessor symbol. swigmacro specifies whether or not the macro has * SWIG macro semantics. * ----------------------------------------------------------------------------- */ String_or_char *Macro_vararg_name(String_or_char *str, String_or_char *line) { String_or_char *argname, *varargname; char *s, *dots; argname = Copy(str); s = Char(argname); dots = strchr(s, '.'); if (!dots) return NULL; if (strcmp(dots, "...") != 0) { Swig_error(Getfile(line), Getline(line), "Illegal macro argument name '%s'\n", str); return NULL; } if (dots == s) { varargname = NewString("__VA_ARGS__"); } else { *dots = '\0'; varargname = NewStringf(argname); } Delete(argname); return varargname; } Hash *Preprocessor_define(const String_or_char *_str, int swigmacro) { String *macroname = 0, *argstr = 0, *macrovalue = 0, *file = 0, *s = 0; Hash *macro = 0, *symbols = 0, *m1; List *arglist = 0; int c, line; int varargs = 0; String_or_char *str = (String_or_char *) _str; assert(cpp); assert(str); /* First make sure that string is actually a string */ if (DohCheck(str)) { s = NewString(str); copy_location(str,s); str = s; } else { str = NewString((char *) str); } Seek(str,0,SEEK_SET); line = Getline(str); file = Getfile(str); /* Skip over any leading whitespace */ skip_whitespace(str,0); /* Now look for a macro name */ macroname = NewString(""); while ((c = Getc(str)) != EOF) { if (c == '(') { argstr = NewString(""); copy_location(str,argstr); /* It is a macro. Go extract it's argument string */ while ((c = Getc(str)) != EOF) { if (c == ')') break; else Putc(c,argstr); } if (c != ')') { Swig_error(Getfile(str),Getline(str), "Missing \')\' in macro parameters\n"); goto macro_error; } break; } else if (isidchar(c) || (c == '%')) { Putc(c,macroname); } else if (isspace(c)) { break; } else if (c == '\\') { c = Getc(str); if (c != '\n') { Ungetc(c,str); Ungetc('\\',str); break; } } else { /*Swig_error(Getfile(str),Getline(str),"Illegal character in macro name\n"); goto macro_error; */ Ungetc(c,str); break; } } if (!swigmacro) skip_whitespace(str,0); macrovalue = NewString(""); while ((c = Getc(str)) != EOF) { Putc(c,macrovalue); } /* If there are any macro arguments, convert into a list */ if (argstr) { String *argname, *varargname; arglist = NewList(); Seek(argstr,0,SEEK_SET); argname = NewString(""); while ((c = Getc(argstr)) != EOF) { if (c == ',') { varargname = Macro_vararg_name(argname, str); if (varargname) { Swig_error(Getfile(str),Getline(str),"Variable-length macro argument must be last parameter\n"); } else { Append(arglist,argname); } Delete(argname); argname = NewString(""); } else if (isidchar(c) || (c == '.')) { Putc(c,argname); } else if (!(isspace(c) || (c == '\\'))) { Swig_error(Getfile(str),Getline(str),"Illegal character in macro argument name\n"); goto macro_error; } } if (Len(argname)) { /* Check for varargs */ varargname = Macro_vararg_name(argname, str); if (varargname) { Append(arglist,varargname); Delete(varargname); varargs = 1; } else { Append(arglist,argname); } Delete(argname); } } if (!swigmacro) { Replace(macrovalue,"\\\n"," ", DOH_REPLACE_NOQUOTE); } /* Look for special # substitutions. We only consider # that appears outside of quotes and comments */ { int state = 0; char *cc = Char(macrovalue); while (*cc) { switch(state) { case 0: if (*cc == '#') *cc = '\001'; else if (*cc == '/') state = 10; else if (*cc == '\'') state = 20; else if (*cc == '\"') state = 30; break; case 10: if (*cc == '*') state = 11; else if (*cc == '/') state = 15; else { state = 0; cc--; } break; case 11: if (*cc == '*') state = 12; break; case 12: if (*cc == '/') state = 0; else if (*cc != '*') state = 11; break; case 15: if (*cc == '\n') state = 0; break; case 20: if (*cc == '\'') state = 0; if (*cc == '\\') state = 21; break; case 21: state = 20; break; case 30: if (*cc == '\"') state = 0; if (*cc == '\\') state = 31; break; case 31: state = 30; break; default: break; } cc++; } } /* Get rid of whitespace surrounding # */ /* Replace(macrovalue,"#","\001",DOH_REPLACE_NOQUOTE); */ while(strstr(Char(macrovalue),"\001 ")) { Replace(macrovalue,"\001 ","\001", DOH_REPLACE_ANY); } while(strstr(Char(macrovalue)," \001")) { Replace(macrovalue," \001","\001", DOH_REPLACE_ANY); } /* Replace '##' with a special token */ Replace(macrovalue,"\001\001","\002", DOH_REPLACE_ANY); /* Go create the macro */ macro = NewHash(); Setattr(macro,"name", macroname); if (arglist) { Setattr(macro,"args",arglist); Delete(arglist); if (varargs) { Setattr(macro,"varargs","1"); } } Setattr(macro,"value",macrovalue); Delete(macrovalue); Setline(macro,line); Setfile(macro,file); if (swigmacro) { Setattr(macro,"swigmacro","1"); } symbols = Getattr(cpp,"symbols"); if ((m1 = Getattr(symbols,macroname))) { if (Cmp(Getattr(m1,"value"),macrovalue)) { Swig_error(Getfile(str),Getline(str),"Macro '%s' redefined,\n",macroname); Swig_error(Getfile(m1),Getline(m1),"previous definition of '%s'.\n",macroname); goto macro_error; } } Setattr(symbols,macroname,macro); Delete(str); Delete(argstr); Delete(macroname); return macro; macro_error: Delete(str); Delete(argstr); Delete(macroname); return 0; } /* ----------------------------------------------------------------------------- * Preprocessor_undef() * * Undefines a macro. * ----------------------------------------------------------------------------- */ void Preprocessor_undef(const String_or_char *str) { Hash *symbols; assert(cpp); symbols = Getattr(cpp,"symbols"); Delattr(symbols,str); } /* ----------------------------------------------------------------------------- * find_args() * * Isolates macro arguments and returns them in a list. For each argument, * leading and trailing whitespace is stripped (ala K&R, pg. 230). * ----------------------------------------------------------------------------- */ static List * find_args(String *s) { List *args; String *str; int c, level; long pos; /* Create a new list */ args = NewList(); copy_location(s,args); /* First look for a '(' */ pos = Tell(s); skip_whitespace(s,0); /* Now see if the next character is a '(' */ c = Getc(s); if (c != '(') { /* Not a macro, bail out now! */ Seek(s,pos, SEEK_SET); Delete(args); return 0; } c = Getc(s); /* Okay. This appears to be a macro so we will start isolating arguments */ while (c != EOF) { if (isspace(c)) { skip_whitespace(s,0); /* Skip leading whitespace */ c = Getc(s); } str = NewString(""); copy_location(s,str); level = 0; while (c != EOF) { if (c == '\"') { Putc(c,str); skip_tochar(s,'\"',str); c = Getc(s); continue; } else if (c == '\'') { Putc(c,str); skip_tochar(s,'\'',str); c = Getc(s); continue; } if ((c == ',') && (level == 0)) break; if ((c == ')') && (level == 0)) break; Putc(c,str); if (c == '(') level++; if (c == ')') level--; c = Getc(s); } if (level > 0) { goto unterm; } Chop(str); if (Len(args) || Len(str)) Append(args,str); Delete(str); /* if (Len(str) && (c != ')')) Append(args,str); */ if (c == ')') return args; c = Getc(s); } unterm: Swig_error(Getfile(args),Getline(args),"Unterminated macro call.\n"); return args; } /* ----------------------------------------------------------------------------- * DOH *get_filename(DOH *str) * * Read a filename from str. A filename can be enclose in quotes, angle brackets, * or bare. * ----------------------------------------------------------------------------- */ static String * get_filename(String *str) { String *fn; int c; skip_whitespace(str,0); fn = NewString(""); copy_location(str,fn); c = Getc(str); if (c == '\"') { while (((c = Getc(str)) != EOF) && (c != '\"')) Putc(c,fn); } else if (c == '<') { while (((c = Getc(str)) != EOF) && (c != '>')) Putc(c,fn); } else { Putc(c,fn); while (((c = Getc(str)) != EOF) && (!isspace(c))) Putc(c,fn); if (isspace(c)) Ungetc(c,str); } #if defined(_WIN32) || defined(MACSWIG) /* accept Unix path separator on non-Unix systems */ Replaceall(fn, "/", SWIG_FILE_DELIMETER); #endif #if defined(__CYGWIN__) /* accept Windows path separator in addition to Unix path separator */ Replaceall(fn, "\\", SWIG_FILE_DELIMETER); #endif Seek(fn,0,SEEK_SET); return fn; } static String * get_options(String *str) { int c; skip_whitespace(str,0); c = Getc(str); if (c == '(') { String *opt; int level = 1; opt = NewString("("); while (((c = Getc(str)) != EOF)) { Putc(c,opt); if (c == ')') { level--; if (!level) return opt; } if (c == '(') level++; } Delete(opt); return 0; } else { Ungetc(c,str); return 0; } } /* ----------------------------------------------------------------------------- * expand_macro() * * Perform macro expansion and return a new string. Returns NULL if some sort * of error occurred. * ----------------------------------------------------------------------------- */ static String * expand_macro(String_or_char *name, List *args) { DOH *symbols, *ns, *macro, *margs, *mvalue, *temp, *tempa, *e; DOH *Preprocessor_replace(DOH *); int i, l; int isvarargs = 0; symbols = Getattr(cpp,"symbols"); if (!symbols) return 0; /* See if the name is actually defined */ macro = Getattr(symbols,name); if (!macro) return 0; if (Getattr(macro,"*expanded*")) { ns = NewString(""); Printf(ns,"%s",name); if (args) { if (Len(args)) Putc('(',ns); for (i = 0; i < Len(args); i++) { Printf(ns,"%s",Getitem(args,i)); if (i < (Len(args) -1)) Putc(',',ns); } if (i) Putc(')',ns); } return ns; } /* Get macro arguments and value */ mvalue = Getattr(macro,"value"); assert(mvalue); margs = Getattr(macro,"args"); if (args && Getattr(macro,"varargs")) { isvarargs = 1; /* Variable length argument macro. We need to collect all of the extra arguments into a single argument */ if (Len(args) >= (Len(margs)-1)) { int i; int vi, na; String *vararg = NewString(""); vi = Len(margs)-1; na = Len(args); for (i = vi; i < na; i++) { Append(vararg,Getitem(args,i)); if ((i+1) < na) { Append(vararg,","); } } /* Remove arguments */ for (i = vi; i < na; i++) { Delitem(args,vi); } Append(args,vararg); Delete(vararg); } } /* If there are arguments, see if they match what we were given */ if (args && (margs) && (Len(margs) != Len(args))) { if (Len(margs) > (1+isvarargs)) Swig_error(Getfile(args),Getline(args),"Macro '%s' expects %d arguments\n", name, Len(margs)-isvarargs); else if (Len(margs) == (1+isvarargs)) Swig_error(Getfile(args),Getline(args),"Macro '%s' expects 1 argument\n", name); else Swig_error(Getfile(args),Getline(args),"Macro '%s' expects no arguments\n", name); return 0; } /* If the macro expects arguments, but none were supplied, we leave it in place */ if (!args && (margs)) { return NewString(name); } /* Copy the macro value */ ns = Copy(mvalue); copy_location(mvalue,ns); /* Tag the macro as being expanded. This is to avoid recursion in macro expansion */ temp = NewString(""); tempa = NewString(""); if (args && margs) { l = Len(margs); for (i = 0; i < l; i++) { DOH *arg, *aname; String *reparg; arg = Getitem(args,i); /* Get an argument value */ reparg = Preprocessor_replace(arg); aname = Getitem(margs,i); /* Get macro argument name */ if (strstr(Char(ns),"\001")) { /* Try to replace a quoted version of the argument */ Clear(temp); Clear(tempa); Printf(temp,"\001%s", aname); Printf(tempa,"\"%s\"",arg); Replace(ns, temp, tempa, DOH_REPLACE_ID_END); } if (strstr(Char(ns),"\002")) { /* Look for concatenation tokens */ Clear(temp); Clear(tempa); Printf(temp,"\002%s",aname); Append(tempa,"\002\003"); Replace(ns, temp, tempa, DOH_REPLACE_ID_END); Clear(temp); Clear(tempa); Printf(temp,"%s\002",aname); Append(tempa,"\003\002"); Replace(ns,temp,tempa, DOH_REPLACE_ID_BEGIN); } /* Non-standard macro expansion. The value `x` is replaced by a quoted version of the argument except that if the argument is already quoted nothing happens */ if (strstr(Char(ns),"`")) { String *rep; char *c; Clear(temp); Printf(temp,"`%s`",aname); c = Char(arg); if (*c == '\"') { rep = arg; } else { Clear(tempa); Printf(tempa,"\"%s\"",arg); rep = tempa; } Replace(ns,temp,rep, DOH_REPLACE_ANY); } if (isvarargs && i == l-1 && Len(arg) == 0) { /* Zero length varargs macro argument. We search for commas that might appear before and nuke them */ char *a, *s, *t, *name; int namelen; s = Char(ns); name = Char(aname); namelen = Len(aname); a = strstr(s,name); while (a) { if (!isidchar(a[namelen+1])) { /* Matched the entire vararg name, not just a prefix */ t = a-1; if (*t == '\002') { t--; while (t >= s) { if (isspace((int) *t)) t--; else if (*t == ',') { *t = ' '; } else break; } } } a = strstr(a+namelen,name); } } /* Replace(ns, aname, arg, DOH_REPLACE_ID); */ Replace(ns, aname, reparg, DOH_REPLACE_ID); /* Replace expanded args */ Replace(ns, "\003", arg, DOH_REPLACE_ANY); /* Replace unexpanded arg */ Delete(reparg); } } Replace(ns,"\002","",DOH_REPLACE_ANY); /* Get rid of concatenation tokens */ Replace(ns,"\001","#",DOH_REPLACE_ANY); /* Put # back (non-standard C) */ /* Expand this macro even further */ Setattr(macro,"*expanded*","1"); e = Preprocessor_replace(ns); Delattr(macro,"*expanded*"); Delete(ns); if (Getattr(macro,"swigmacro")) { String *g; String *f = NewString(""); Seek(e,0,SEEK_SET); copy_location(macro,e); g = Preprocessor_parse(e); /* Drop the macro in place, but with a marker around it */ Printf(f,"/*@%s,%d,%s@*/%s/*@@*/", Getfile(macro), Getline(macro), name, g); /* Printf(f," }\n"); */ Delete(g); Delete(e); e = f; } Delete(temp); Delete(tempa); return e; } /* ----------------------------------------------------------------------------- * evaluate_args() * * Evaluate the arguments of a macro * ----------------------------------------------------------------------------- */ List *evaluate_args(List *x) { Iterator i; String *Preprocessor_replace(String *); List *nl = NewList(); for (i = First(x); i.item; i = Next(i)) { Append(nl,Preprocessor_replace(i.item)); } return nl; } /* ----------------------------------------------------------------------------- * DOH *Preprocessor_replace(DOH *s) * * Performs a macro substitution on a string s. Returns a new string with * substitutions applied. This function works by walking down s and looking * for identifiers. When found, a check is made to see if they are macros * which are then expanded. * ----------------------------------------------------------------------------- */ DOH * Preprocessor_replace(DOH *s) { DOH *ns, *id, *symbols, *m; int c, i, state = 0; assert(cpp); symbols = Getattr(cpp,"symbols"); ns = NewString(""); copy_location(s,ns); Seek(s,0,SEEK_SET); id = NewString(""); /* Try to locate identifiers in s and replace them with macro replacements */ while ((c = Getc(s)) != EOF) { switch (state) { case 0: if (isidentifier(c) || (c == '%')) { Clear(id); copy_location(s,id); Putc(c,id); state = 1; } else if (c == '\"') { Putc(c,ns); skip_tochar(s,'\"',ns); } else if (c == '\'') { Putc(c,ns); skip_tochar(s,'\'',ns); } else if (c == '/') { Putc(c,ns); state = 10; } else { Putc(c,ns); } break; case 1: /* An identifier */ if (isidchar(c)) { Putc(c,id); state = 1; } else { /* We found the end of a valid identifier */ Ungetc(c,s); /* See if this is the special "defined" macro */ if (Cmp(id,"defined") == 0) { DOH *args; /* See whether or not a paranthesis has been used */ skip_whitespace(s,0); c = Getc(s); if (c == '(') { Seek(s,-1,SEEK_CUR); args = find_args(s); } else { DOH *arg = 0; args = NewList(); arg = NewString(""); if (isidchar(c)) Putc(c,arg); while ((c = Getc(s)) != EOF) { if (!isidchar(c)) { Seek(s,-1,SEEK_CUR); break; } Putc(c,arg); } Append(args,arg); Delete(arg); } if ((!args) || (!Len(args))) { Swig_error(Getfile(id),Getline(id),"No arguments given to defined()\n"); state = 0; break; } for (i = 0; i < Len(args); i++) { DOH *o = Getitem(args,i); if (!Getattr(symbols,o)) { break; } } if (i < Len(args)) Putc('0',ns); else Putc('1',ns); Delete(args); state = 0; break; } if (Cmp(id,"__LINE__") == 0) { Printf(ns,"%d",Getline(s)); state = 0; break; } if (Cmp(id,"__FILE__") == 0) { String *fn = Copy(Getfile(s)); Replaceall(fn,"\\","\\\\"); Printf(ns,"\"%s\"",fn); Delete(fn); state = 0; break; } /* See if the macro is defined in the preprocessor symbol table */ if ((m = Getattr(symbols,id))) { DOH *args = 0; DOH *e; /* See if the macro expects arguments */ if (Getattr(m,"args")) { /* Yep. We need to go find the arguments and do a substitution */ args = find_args(s); if (!Len(args)) { Delete(args); args = 0; } } else { args = 0; } e = expand_macro(id,args); if (e) { Printf(ns,"%s",e); } Delete(e); Delete(args); } else { Printf(ns,"%s",id); } state = 0; } break; case 10: if (c == '/') state = 11; else if (c == '*') state = 12; else { Ungetc(c,s); state = 0; break; } Putc(c,ns); break; case 11: Putc(c,ns); if (c == '\n') state = 0; break; case 12: Putc(c,ns); if (c == '*') state = 13; break; case 13: Putc(c,ns); if (c == '/') state = 0; else if (c != '*') state = 12; break; default: state = 0; break; } } /* Identifier at the end */ if (state == 1) { /* See if this is the special "defined" macro */ if (Cmp(id,"defined") == 0) { Swig_error(Getfile(id),Getline(id),"No arguments given to defined()\n"); } else if ((m = Getattr(symbols,id))) { DOH *e; /* Yes. There is a macro here */ /* See if the macro expects arguments */ /* if (Getattr(m,"args")) { Swig_error(Getfile(id),Getline(id),"Macro arguments expected.\n"); } */ e = expand_macro(id,0); Printf(ns,"%s",e); Delete(e); } else { Printf(ns,"%s",id); } } Delete(id); return ns; } /* ----------------------------------------------------------------------------- * int check_id(DOH *s) * * Checks the string s to see if it contains any unresolved identifiers. This * function contains the heuristic that determines whether or not a macro * definition passes through the preprocessor as a constant declaration. * ----------------------------------------------------------------------------- */ static int check_id(DOH *s) { static SwigScanner *scan = 0; int c; int hastok = 0; Seek(s,0,SEEK_SET); if (!scan) { scan = NewSwigScanner(); } SwigScanner_clear(scan); s = Copy(s); Seek(s,SEEK_SET,0); SwigScanner_push(scan,s); while ((c = SwigScanner_token(scan))) { hastok = 1; if ((c == SWIG_TOKEN_ID) || (c == SWIG_TOKEN_LBRACE) || (c == SWIG_TOKEN_RBRACE)) return 1; } if (!hastok) return 1; return 0; } /* addline(). Utility function for adding lines to a chunk */ static void addline(DOH *s1, DOH *s2, int allow) { if (allow) { Append(s1,s2); } else { char *c = Char(s2); while (*c) { if (*c == '\n') Putc('\n',s1); c++; } } } static void add_chunk(DOH *ns, DOH *chunk, int allow) { DOH *echunk; Seek(chunk,0,SEEK_SET); if (allow) { echunk = Preprocessor_replace(chunk); addline(ns,echunk,allow); Delete(echunk); } else { addline(ns,chunk,0); } Clear(chunk); } /* ----------------------------------------------------------------------------- * Preprocessor_parse() * * Parses the string s. Returns a new string containing the preprocessed version. * * Parsing rules : * 1. Lines starting with # are C preprocessor directives * 2. Macro expansion inside strings is not allowed * 3. All code inside false conditionals is changed to blank lines * 4. Code in %{, %} is not parsed because it may need to be * included inline (with all preprocessor directives included). * ----------------------------------------------------------------------------- */ String * Preprocessor_parse(String *s) { String *ns; /* New string containing the preprocessed text */ String *chunk, *sval, *decl; Hash *symbols; String *id = 0, *value = 0, *comment = 0; int i, state, val, e, c; int start_line = 0; int allow = 1; int level = 0; int mask = 0; int start_level = 0; int cpp_lines = 0; int cond_lines[256]; /* Blow away all carriage returns */ Replace(s,"\015","",DOH_REPLACE_ANY); ns = NewString(""); /* Return result */ decl = NewString(""); id = NewString(""); value = NewString(""); comment = NewString(""); chunk = NewString(""); copy_location(s,chunk); copy_location(s,ns); symbols = Getattr(cpp,"symbols"); state = 0; while ((c = Getc(s)) != EOF) { switch(state) { case 0: /* Initial state - in first column */ /* Look for C preprocessor directives. Otherwise, go directly to state 1 */ if (c == '#') { add_chunk(ns,chunk,allow); copy_location(s,chunk); cpp_lines = 1; state = 40; } else if (isspace(c)) { Putc(c,chunk); skip_whitespace(s,chunk); } else { state = 1; Ungetc(c,s); } break; case 1: /* Non-preprocessor directive */ /* Look for SWIG directives */ if (c == '%') { state = 100; break; } Putc(c,chunk); if (c == '\n') state = 0; else if (c == '\"') { start_line = Getline(s); if (skip_tochar(s,'\"',chunk) < 0) { Swig_error(Getfile(s),-1,"Unterminated string constant starting at line %d\n",start_line); } } else if (c == '\'') { start_line = Getline(s); if (skip_tochar(s,'\'',chunk) < 0) { Swig_error(Getfile(s),-1,"Unterminated character constant starting at line %d\n",start_line); } } else if (c == '/') state = 30; /* Comment */ break; case 30: /* Possibly a comment string of some sort */ start_line = Getline(s); Putc(c,chunk); if (c == '/') state = 31; else if (c == '*') state = 32; else state = 1; break; case 31: Putc(c,chunk); if (c == '\n') state = 0; break; case 32: Putc(c,chunk); if (c == '*') state = 33; break; case 33: Putc(c,chunk); if (c == '/') state = 1; else if (c != '*') state = 32; break; case 40: /* Start of a C preprocessor directive */ if (c == '\n') { Putc('\n',chunk); state = 0; } else if (isspace(c)) { state = 40; } else { /* Got the start of a preprocessor directive */ Ungetc(c,s); Clear(id); copy_location(s,id); state = 41; } break; case 41: /* Build up the name of the preprocessor directive */ if ((isspace(c) || (!isalpha(c)))) { Clear(value); Clear(comment); if (c == '\n') { Ungetc(c,s); state = 50; } else { state = 42; if (!isspace(c)) { Ungetc(c,s); } } copy_location(s,value); break; } Putc(c,id); break; case 42: /* Strip any leading space before preprocessor value */ if (isspace(c)) { if (c == '\n') { Ungetc(c,s); state = 50; } break; } state = 43; /* no break intended here */ case 43: /* Get preprocessor value */ if (c == '\n') { Ungetc(c,s); state = 50; } else if (c == '/') { state = 45; } else if (c == '\"') { Putc(c,value); skip_tochar(s,'\"',value); } else if (c == '\'') { Putc(c,value); skip_tochar(s,'\'',value); } else { Putc(c,value); if (c == '\\') state = 44; } break; case 44: if (c == '\n') { Putc(c,value); cpp_lines++; } else { Ungetc(c,s); } state = 43; break; /* States 45-48 are used to remove, but retain comments from macro values. The comments will be placed in the output in an alternative form */ case 45: if (c == '/') state = 46; else if (c == '*') state = 47; else if (c == '\n') { Putc('/',value); Ungetc(c,s); cpp_lines++; state = 50; } else { Putc('/',value); Putc(c,value); state = 43; } break; case 46: if (c == '\n') { Ungetc(c,s); cpp_lines++; state = 50; } else Putc(c,comment); break; case 47: if (c == '*') state = 48; else Putc(c,comment); break; case 48: if (c == '/') state = 43; else if (c == '*') Putc(c,comment); else { Putc('*',comment); Putc(c,comment); state = 47; } break; case 50: /* Check for various preprocessor directives */ Chop(value); if (Cmp(id,"define") == 0) { if (allow) { DOH *m, *v, *v1; Seek(value,0,SEEK_SET); m = Preprocessor_define(value,0); if ((m) && !(Getattr(m,"args"))) { v = Copy(Getattr(m,"value")); if (Len(v)) { Swig_error_silent(1); v1 = Preprocessor_replace(v); Swig_error_silent(0); /* Printf(stdout,"checking '%s'\n", v1); */ if (!check_id(v1)) { if (Len(comment) == 0) Printf(ns,"%%constant %s = %s;\n", Getattr(m,"name"), v1); else Printf(ns,"%%constant %s = %s; /*%s*/\n", Getattr(m,"name"),v1,comment); cpp_lines--; } Delete(v1); } Delete(v); } Delete(m); } } else if (Cmp(id,"undef") == 0) { if (allow) Preprocessor_undef(value); } else if (Cmp(id,"ifdef") == 0) { cond_lines[level] = Getline(id); level++; if (allow) { start_level = level; /* See if the identifier is in the hash table */ if (!Getattr(symbols,value)) allow = 0; mask = 1; } } else if (Cmp(id,"ifndef") == 0) { cond_lines[level] = Getline(id); level++; if (allow) { start_level = level; /* See if the identifier is in the hash table */ if (Getattr(symbols,value)) allow = 0; mask = 1; } } else if (Cmp(id,"else") == 0) { if (level <= 0) { Swig_error(Getfile(s),Getline(id),"Misplaced #else.\n"); } else { cond_lines[level-1] = Getline(id); if (allow) { allow = 0; mask = 0; } else if (level == start_level) { allow = 1*mask; } } } else if (Cmp(id,"endif") == 0) { level--; if (level < 0) { Swig_error(Getfile(id),Getline(id),"Extraneous #endif.\n"); level = 0; } else { if (level < start_level) { allow = 1; start_level--; } } } else if (Cmp(id,"if") == 0) { cond_lines[level] = Getline(id); level++; if (allow) { start_level = level; sval = Preprocessor_replace(value); Seek(sval,0,SEEK_SET); /* Printf(stdout,"Evaluating '%s'\n", sval); */ val = Preprocessor_expr(sval,&e); if (e) { Seek(value,0,SEEK_SET); Swig_warning(WARN_PP_EVALUATION,Getfile(value),Getline(value),"Could not evaluate '%s'\n", value); allow = 0; } else { if (val == 0) allow = 0; } mask = 1; } } else if (Cmp(id,"elif") == 0) { if (level == 0) { Swig_error(Getfile(s),Getline(id),"Misplaced #elif.\n"); } else { cond_lines[level-1] = Getline(id); if (allow) { allow = 0; mask = 0; } else if (level == start_level) { sval = Preprocessor_replace(value); Seek(sval,0,SEEK_SET); val = Preprocessor_expr(sval,&e); if (e) { Seek(value,0,SEEK_SET); Swig_warning(WARN_PP_EVALUATION,Getfile(value),Getline(value),"Could not evaluate '%s'\n", value); allow = 0; } else { if (val) allow = 1*mask; else allow = 0; } } } } else if (Cmp(id,"line") == 0) { } else if (Cmp(id,"include") == 0) { if (((include_all) || (import_all)) && (allow)) { String *s1, *s2, *fn; char *dirname; Seek(value,0,SEEK_SET); fn = get_filename(value); s1 = cpp_include(fn); if (s1) { if (include_all) Printf(ns,"%%includefile \"%s\" [\n", Swig_last_file()); else if (import_all) Printf(ns,"%%importfile \"%s\" [\n", Swig_last_file()); /* See if the filename has a directory component */ dirname = Swig_file_dirname(Swig_last_file()); if (!strlen(dirname)) dirname = 0; if (dirname) { dirname[strlen(dirname)-1] = 0; /* Kill trailing directory delimeter */ Swig_push_directory(dirname); } s2 = Preprocessor_parse(s1); addline(ns,s2,allow); Printf(ns,"\n]"); if (dirname) { Swig_pop_directory(); } Delete(s2); } Delete(s1); Delete(fn); } } else if (Cmp(id,"pragma") == 0) { if (Strncmp(value,"SWIG ",5) == 0) { char *c = Char(value)+5; while (*c && (isspace((int)*c))) c++; if (*c) { if (Strncmp(c,"nowarn=",7) == 0) { Swig_warnfilter(c+7,1); } } } } else if (Cmp(id,"level") == 0) { Swig_error(Getfile(s),Getline(id),"cpp debug: level = %d, startlevel = %d\n", level, start_level); } for (i = 0; i < cpp_lines; i++) Putc('\n',ns); state = 0; break; /* Swig directives */ case 100: /* %{,%} block */ if (c == '{') { start_line = Getline(s); add_chunk(ns,chunk,allow); copy_location(s,chunk); Putc('%',chunk); Putc(c,chunk); state = 105; } /* %#cpp - an embedded C preprocessor directive (we strip off the %) */ else if (c == '#') { add_chunk(ns,chunk,allow); Putc(c,chunk); state = 107; } else if (isidentifier(c)) { Clear(decl); Putc('%',decl); Putc(c,decl); state = 110; } else { Putc('%',chunk); Putc(c,chunk); state = 1; } break; case 105: Putc(c,chunk); if (c == '%') state = 106; break; case 106: Putc(c,chunk); if (c == '}') { state = 1; addline(ns,chunk,allow); Clear(chunk); copy_location(s,chunk); } else { state = 105; } break; case 107: Putc(c,chunk); if (c == '\n') { addline(ns,chunk,allow); Clear(chunk); state = 0; } else if (c == '\\') { state = 108; } break; case 108: Putc(c,chunk); state = 107; break; case 110: if (!isidchar(c)) { Ungetc(c,s); /* Look for common Swig directives */ if ((Cmp(decl,"%include") == 0) || (Cmp(decl,"%import") == 0) || (Cmp(decl,"%extern") == 0)) { /* Got some kind of file inclusion directive */ if (allow) { DOH *s1, *s2, *fn, *opt; if (Cmp(decl,"%extern") == 0) { Swig_warning(WARN_DEPRECATED_EXTERN, Getfile(s),Getline(s),"%%extern is deprecated. Use %%import instead.\n"); Clear(decl); Printf(decl,"%%import"); } opt = get_options(s); fn = get_filename(s); s1 = cpp_include(fn); if (s1) { char *dirname; add_chunk(ns,chunk,allow); copy_location(s,chunk); Printf(ns,"%sfile%s \"%s\" [\n", decl, opt, Swig_last_file()); if ((Cmp(decl,"%import") == 0) || (Cmp(decl,"%extern") == 0)) { Preprocessor_define("WRAPEXTERN 1", 0); Preprocessor_define("SWIGIMPORT 1", 0); } dirname = Swig_file_dirname(Swig_last_file()); if (!strlen(dirname)) dirname = 0; if (dirname) { dirname[strlen(dirname)-1] = 0; /* Kill trailing directory delimeter */ Swig_push_directory(dirname); } s2 = Preprocessor_parse(s1); if (dirname) { Swig_pop_directory(); } if ((Cmp(decl,"%import") == 0) || (Cmp(decl,"%extern") == 0)) { Preprocessor_undef("SWIGIMPORT"); Preprocessor_undef("WRAPEXTERN"); } addline(ns,s2,allow); Printf(ns,"\n]"); Delete(s2); Delete(s1); } Delete(fn); } state = 1; } else if (Cmp(decl,"%line") == 0) { /* Got a line directive */ state = 1; } else if (Cmp(decl,"%define") == 0) { /* Got a define directive */ add_chunk(ns,chunk,allow); copy_location(s,chunk); Clear(value); copy_location(s,value); state = 150; } else { Printf(chunk,"%s", decl); state = 1; } } else { Putc(c,decl); } break; /* Searching for the end of a %define statement */ case 150: Putc(c,value); if (c == '%') { int i = 0; char *d = "enddef"; for (i = 0; i < 6; i++) { c = Getc(s); Putc(c,value); if (c != d[i]) break; } c = Getc(s); Ungetc(c,s); if ((i == 6) && (isspace(c))) { /* Got the macro */ for (i = 0; i < 7; i++) { Delitem(value,DOH_END); } if (allow) { Seek(value,0,SEEK_SET); Preprocessor_define(value,1); } Putc('\n',ns); addline(ns,value,0); state = 0; } } break; default : Printf(stderr,"cpp: Invalid parser state %d\n", state); abort(); break; } } while (level > 0) { Swig_error(Getfile(s),-1,"Missing #endif for conditional starting on line %d\n", cond_lines[level-1]); level--; } if (state == 150) { Seek(value,0,SEEK_SET); Swig_error(Getfile(s),-1,"Missing %%enddef for macro starting on line %d\n",Getline(value)); } if ((state >= 105) && (state < 107)) { Swig_error(Getfile(s),-1,"Unterminated %%{ ... %%} block starting on line %d\n", start_line); } if ((state >= 30) && (state < 40)) { Swig_error(Getfile(s),-1,"Unterminated comment starting on line %d\n", start_line); } add_chunk(ns,chunk,allow); copy_location(s,chunk); /* DelScope(scp); */ Delete(decl); Delete(id); Delete(value); Delete(comment); Delete(chunk); /* fprintf(stderr,"cpp: %d\n", Len(Getattr(cpp,"symbols"))); */ return ns; } cableswig-0.1.0+git20150808.orig/SWIG/Source/CMakeLists.txt0000644000175000000620000000474612561312227021611 0ustar stevestaffMAKE_DIRECTORY(${CMAKE_CURRENT_BINARY_DIR}/CParse) FIND_PROGRAM(BISON_YACC bison) IF(BISON_YACC) ADD_CUSTOM_COMMAND( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/CParse/parser.c DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/CParse/parser.y COMMAND ${BISON_YACC} ARGS -y -d -o ${CMAKE_CURRENT_BINARY_DIR}/CParse/parser.c ${CMAKE_CURRENT_SOURCE_DIR}/CParse/parser.y ) ADD_CUSTOM_COMMAND( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/CParse/parser.h DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/CParse/parser.y COMMAND ${BISON_YACC} ARGS -y -d -o ${CMAKE_CURRENT_BINARY_DIR}/CParse/parser.c ${CMAKE_CURRENT_SOURCE_DIR}/CParse/parser.y ) ELSE(BISON_YACC) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/CParse/parser.c.in ${CMAKE_CURRENT_BINARY_DIR}/CParse/parser.c IMMEDIATE COPYONLY) CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/CParse/parser.h.in ${CMAKE_CURRENT_BINARY_DIR}/CParse/parser.h IMMEDIATE COPYONLY) ENDIF(BISON_YACC) FILE(READ Makefile.am AUTOMAKE_FILE) STRING(REGEX MATCH "AM_CFLAGS[ \t\n\r]+=[ \t\n\r]+.*[^\\\\]\nAM_CXXFLAGS" CFLAGS ${AUTOMAKE_FILE}) STRING(REGEX REPLACE "-I\\$\\(BUILD_SOURCE_DIR\\)" "${CMAKE_CURRENT_BINARY_DIR}" CFLAGS ${CFLAGS}) STRING(REGEX REPLACE "-I\\$\\(SOURCE_DIR\\)" "${CMAKE_CURRENT_SOURCE_DIR}" CFLAGS ${CFLAGS}) STRING(REGEX REPLACE "^AM_CFLAGS.*=[ \t\n\r]+" "" CFLAGS ${CFLAGS}) STRING(REGEX REPLACE "[ \t\n\r]+AM_CXXFLAGS$" "" CFLAGS ${CFLAGS}) STRING(REGEX REPLACE "[ \t\n\r]+\\\\[ \t\n\r]+" ";" CFLAGS ${CFLAGS}) INCLUDE_DIRECTORIES(BEFORE ${CFLAGS}) # find the eswig_SOURCES = ... .c stuff STRING(REGEX MATCH "eswig_SOURCES.*[\\]*.[\\.]c" OUT ${AUTOMAKE_FILE}) # remove the eswig_SOURCES = stuff STRING(REGEX REPLACE "eswig_SOURCES*.=" "" OUT ${OUT}) # get rid of spaces tabs and newlines STRING(REGEX REPLACE "[ \t\n\r]+" "" OUT ${OUT}) # replace the line continue markers with ; STRING(REGEX REPLACE "[\\\\]" ";" OUT ${OUT}) FOREACH(f ${OUT}) IF(${f} MATCHES ".*\\.y") SET(YACC_SRCS ${YACC_SRCS} ${f}) ELSE(${f} MATCHES ".*\\.y") SET(SWIG_AM_SOURCES ${SWIG_AM_SOURCES} ${f}) ENDIF(${f} MATCHES ".*\\.y") ENDFOREACH(f) SET(swig_CParse_SRCS ${CMAKE_CURRENT_BINARY_DIR}/CParse/parser.c ) SET_SOURCE_FILES_PROPERTIES(CParse/parser.c PROPERTIES GENERATED 1) SET_SOURCE_FILES_PROPERTIES(${swig_CParse_SRCS} PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/CParse/parser.h) SET(swig_SRCS ${SWIG_AM_SOURCES} ${swig_CParse_SRCS}) ADD_LIBRARY(swigLib ${swig_SRCS}) ADD_EXECUTABLE(swig ${swig_SRCS}) cableswig-0.1.0+git20150808.orig/SWIG/Source/Swig/0002755000175000000620000000000012561312227017751 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Source/Swig/getopt.c0000644000175000000620000000654612561312227021430 0ustar stevestaff/* ----------------------------------------------------------------------------- * getopt.c * * Handles the parsing of command line options. This is particularly nasty * compared to other utilities given that command line options can potentially * be read by many different modules within SWIG. Thus, in order to make sure * there are no unrecognized options, each module is required to "mark" * the options that it uses. Afterwards, we can make a quick scan to make * sure there are no unmarked options. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * * To do: * - This module needs to be modified so that it doesn't call exit(). * Should have cleaner error handling in general. * ----------------------------------------------------------------------------- */ char cvsroot_getopt_c[] = "/cvsroot/SWIG/Source/Swig/getopt.c,v 1.9 2002/11/30 22:10:13 beazley Exp"; #include "swig.h" static char **args; static int numargs; static int *marked; /* ----------------------------------------------------------------------------- * Swig_init_args() * * Initialize the argument list handler. * ----------------------------------------------------------------------------- */ void Swig_init_args(int argc, char **argv) { int i; assert(argc > 0); assert(argv); numargs = argc; args = argv; marked = (int *) malloc(numargs * sizeof(int)); for (i = 0; i < argc; i++) { marked[i] = 0; } marked[0] = 1; } /* ----------------------------------------------------------------------------- * Swig_mark_arg() * * Marks an argument as being parsed. * ----------------------------------------------------------------------------- */ void Swig_mark_arg(int n) { assert(marked); assert((n >= 0) && (n < numargs)); marked[n] = 1; } /* ----------------------------------------------------------------------------- * Swig_check_marked() * * Checks to see if argument has been picked up. * ----------------------------------------------------------------------------- */ int Swig_check_marked(int n) { assert((n>=0) && (n < numargs)); return marked[n]; } /* ----------------------------------------------------------------------------- * Swig_check_options() * * Checkers for unprocessed command line options and errors. * ----------------------------------------------------------------------------- */ void Swig_check_options() { int error = 0; int i; assert(marked); for (i = 1; i < numargs-1; i++) { if (!marked[i]) { Printf(stderr,"swig error : Unrecognized option %s\n", args[i]); error=1; } } if (error) { Printf(stderr,"Use 'swig -help' for available options.\n"); exit(1); } if (marked[numargs-1]) { Printf(stderr,"Must specify an input file. Use -help for available options.\n"); exit(1); } } /* ----------------------------------------------------------------------------- * Swig_arg_error() * * Generates a generic error message and exits. * ----------------------------------------------------------------------------- */ void Swig_arg_error() { Printf(stderr,"SWIG : Unable to parse command line options.\n"); Printf(stderr,"Use 'swig -help' for available options.\n"); exit(1); } cableswig-0.1.0+git20150808.orig/SWIG/Source/Swig/stype.c0000644000175000000620000005701512561312227021267 0ustar stevestaff/* ----------------------------------------------------------------------------- * stype.c * * This file provides general support for datatypes that are encoded in * the form of simple strings. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_stype_c[] = "/cvsroot/SWIG/Source/Swig/stype.c,v 1.42 2003/11/28 19:06:35 beazley Exp"; #include "swig.h" #include /* ----------------------------------------------------------------------------- * Synopsis * * The purpose of this module is to provide a general purpose type representation * based on simple text strings. * * General idea: * * Types are represented by a base type (e.g., "int") and a collection of * type operators applied to the base (e.g., pointers, arrays, etc...). * * Encoding: * * Types are encoded as strings of type constructors such as follows: * * String Encoding C Example * --------------- --------- * p.p.int int ** * a(300).a(400).int int [300][400] * p.q(const).char char const * * * All type constructors are denoted by a trailing '.': * * 'p.' = Pointer (*) * 'r.' = Reference (&) * 'a(n).' = Array of size n [n] * 'f(..,..).' = Function with arguments (args) * 'q(str).' = Qualifier (such as const or volatile) (const, volatile) * 'm(qual).' = Pointer to member (qual::*) * * The encoding follows the order that you might describe a type in words. * For example "p.a(200).int" is "A pointer to array of int's" and * "p.q(const).char" is "a pointer to a const char". * * This representation of types is fairly convenient because ordinary string * operations can be used for type manipulation. For example, a type could be * formed by combining two strings such as the following: * * "p.p." + "a(400).int" = "p.p.a(400).int" * * Similarly, one could strip a 'const' declaration from a type doing something * like this: * * Replace(t,"q(const).","",DOH_REPLACE_ANY) * * For the most part, this module tries to minimize the use of special * characters (*, [, <, etc...) in its type encoding. One reason for this * is that SWIG might be extended to encode data in formats such as XML * where you might want to do this: * * * p.p.int * ... * * * Or alternatively, * * blah * * In either case, it's probably best to avoid characters such as '&', '*', or '<'. * * Why not use C syntax? Well, C syntax is fairly complicated to parse * and not particularly easy to manipulate---especially for adding, deleting and * composing type constructors. The string representation presented here makes * this pretty easy. * * Why not use a bunch of nested data structures? Are you kidding? How * would that be easier to use than a few simple string operations? * ----------------------------------------------------------------------------- */ SwigType *NewSwigType(int t) { switch(t) { case T_BOOL: return NewString("bool"); break; case T_INT: return NewString("int"); break; case T_UINT: return NewString("unsigned int"); break; case T_SHORT: return NewString("short"); break; case T_USHORT: return NewString("unsigned short"); break; case T_LONG: return NewString("long"); break; case T_ULONG: return NewString("unsigned long"); break; case T_FLOAT: return NewString("float"); break; case T_DOUBLE: return NewString("double"); break; case T_CHAR: return NewString("char"); break; case T_SCHAR: return NewString("signed char"); break; case T_UCHAR: return NewString("unsigned char"); break; case T_STRING: { SwigType *t = NewString("char"); SwigType_add_pointer(t); return t; break; } case T_LONGLONG: return NewString("long long"); break; case T_ULONGLONG: return NewString("unsigned long long"); break; case T_VOID: return NewString("void"); break; default : return NewString(""); break; } } /* ----------------------------------------------------------------------------- * SwigType_push() * * Push a type constructor onto the type * ----------------------------------------------------------------------------- */ void SwigType_push(SwigType *t, String *cons) { if (!cons) return; if (!Len(cons)) return; if (Len(t)) { char *c = Char(cons); if (c[strlen(c)-1] != '.') Insert(t,0,"."); } Insert(t,0,cons); } /* ----------------------------------------------------------------------------- * SwigType_ispointer() * SwigType_ispointer_return() * SwigType_isarray() * SwigType_isreference() * SwigType_isfunction() * SwigType_isqualifier() * * Testing functions for querying a raw datatype * ----------------------------------------------------------------------------- */ int SwigType_ispointer_return(SwigType *t) { char* c; int idx; if (!t) return 0; c = Char(t); idx = strlen(c)-4; if (idx >= 0) { return (strcmp(c+idx, ").p.") == 0); } return 0; } int SwigType_isreference_return(SwigType *t) { char* c; int idx; if (!t) return 0; c = Char(t); idx = strlen(c)-4; if (idx >= 0) { return (strcmp(c+idx, ").r.") == 0); } return 0; } int SwigType_isconst(SwigType *t) { char *c; if (!t) return 0; c = Char(t); if (strncmp(c,"q(",2) == 0) { String *q = SwigType_parm(t); if (strstr(Char(q),"const")) { Delete(q); return 1; } Delete(q); } /* Hmmm. Might be const through a typedef */ if (SwigType_issimple(t)) { int ret; SwigType *td = SwigType_typedef_resolve(t); if (td) { ret = SwigType_isconst(td); Delete(td); return ret; } } return 0; } int SwigType_ismutable(SwigType *t) { int r; SwigType *qt = SwigType_typedef_resolve_all(t); if (SwigType_isreference(qt)) { Delete(SwigType_pop(qt)); } r = SwigType_isconst(qt); Delete(qt); return r ? 0 : 1; } int SwigType_isenum(SwigType *t) { char *c = Char(t); if (!t) return 0; if (strncmp(c,"enum ",5) == 0) { return 1; } return 0; } int SwigType_issimple(SwigType *t) { char *c = Char(t); if (!t) return 0; while (*c) { if (*c == '<') { int nest = 1; c++; while (*c && nest) { if (*c == '<') nest++; if (*c == '>') nest--; c++; } c--; } if (*c == '.') return 0; c++; } return 1; } /* ----------------------------------------------------------------------------- * SwigType_default() * * Create 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. * * Rules: * Pointers: p.SWIGTYPE * References: r.SWIGTYPE * Arrays: a().SWIGTYPE * Types: SWIGTYPE * MemberPointer: m(CLASS).SWIGTYPE * Enums: enum SWIGENUM * * Note: if this function is applied to a primitive type, it returns NULL. This * allows recursive application for special types like arrays. * ----------------------------------------------------------------------------- */ static Hash *default_cache = 0; SwigType *SwigType_default(SwigType *t) { String *r1, *def; String *r = 0; if (!default_cache) default_cache = NewHash(); r = Getattr(default_cache,t); if (r) { if (Strcmp(r,t) == 0) return 0; return Copy(r); } 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)) { if (r == t) r = Copy(t); do { Delete(SwigType_pop(r)); } while (SwigType_isqualifier(r)); } if (SwigType_ispointer(r)) { def = NewString("p.SWIGTYPE"); } else if (SwigType_isreference(r)) { def = NewString("r.SWIGTYPE"); } else if (SwigType_isarray(r)) { if (Strcmp(r,"a(ANY).SWIGTYPE") == 0) { def = NewString("a().SWIGTYPE"); } else { int i, empty = 0; int ndim = SwigType_array_ndim(r); for (i = 0; i < ndim; i++) { String *dim = SwigType_array_getdim(r,i); if (!Len(dim)) { empty = 1; } Delete(dim); } if (empty) { def = NewString("a().SWIGTYPE"); } else { def = NewString("a(ANY).SWIGTYPE"); } } } else if (SwigType_ismemberpointer(r)) { def = NewString("m(CLASS).SWIGTYPE"); } else if (SwigType_isenum(r)) { def = NewString("enum SWIGTYPE"); } else { def = NewString("SWIGTYPE"); } if (r != t) Delete(r); Setattr(default_cache,t,Copy(def)); if (Strcmp(def,t) == 0) { Delete(def); def = 0; } return def; } /* ----------------------------------------------------------------------------- * SwigType_namestr() * * Returns a string of the base type. Takes care of template expansions * ----------------------------------------------------------------------------- */ String * SwigType_namestr(const SwigType *t) { String *r; String *suffix; List *p; char tmp[256]; char *c, *d, *e; int i, sz; if (!SwigType_istemplate(t)) return NewString(t); c = Strstr(t,"<("); d = Char(t); e = tmp; while (d != c) { *(e++) = *(d++); } *e = 0; r = NewString(tmp); Putc('<',r); p = SwigType_parmlist(t); sz = Len(p); for (i = 0; i < sz; i++) { Append(r,SwigType_str(Getitem(p,i),0)); if ((i+1) < sz) Putc(',',r); } Putc(' ',r); Putc('>',r); suffix = SwigType_templatesuffix(t); Append(r,suffix); Delete(suffix); #if 0 if (SwigType_istemplate(r)) { SwigType *rr = SwigType_namestr(r); Delete(r); return rr; } #endif return r; } /* ----------------------------------------------------------------------------- * SwigType_str() * * Create a C string representation of a datatype. * ----------------------------------------------------------------------------- */ String * SwigType_str(SwigType *s, const String_or_char *id) { String *result; String *element = 0, *nextelement; List *elements; int nelements, i; if (id) { result = NewString(Char(id)); } else { result = NewString(""); } elements = SwigType_split(s); nelements = Len(elements); if (nelements > 0) { element = Getitem(elements,0); } /* Now, walk the type list and start emitting */ for (i = 0; i < nelements; i++) { if (i < (nelements - 1)) { nextelement = Getitem(elements,i+1); } else { nextelement = 0; } if (SwigType_isqualifier(element)) { DOH *q = 0; q = SwigType_parm(element); Insert(result,0," "); Insert(result,0,q); Delete(q); } else if (SwigType_ispointer(element)) { Insert(result,0,"*"); if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) { Insert(result,0,"("); Append(result,")"); } } else if (SwigType_ismemberpointer(element)) { String *q; q = SwigType_parm(element); Insert(result,0,"::*"); Insert(result,0,q); if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) { Insert(result,0,"("); Append(result,")"); } Delete(q); } else if (SwigType_isreference(element)) { Insert(result,0,"&"); if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) { Insert(result,0,"("); Append(result,")"); } } else if (SwigType_isarray(element)) { DOH *size; Append(result,"["); size = SwigType_parm(element); Append(result,size); Append(result,"]"); Delete(size); } else if (SwigType_isfunction(element)) { DOH *parms, *p; int j, plen; Append(result,"("); parms = SwigType_parmlist(element); plen = Len(parms); for (j = 0; j < plen; j++) { p = SwigType_str(Getitem(parms,j),0); Append(result,p); if (j < (plen-1)) Append(result,","); } Append(result,")"); Delete(parms); } else { if (Strcmp(element,"v(...)") == 0) { Insert(result,0,"..."); } else { String *bs = SwigType_namestr(element); Insert(result,0," "); Insert(result,0,bs); Delete(bs); } } element = nextelement; } Delete(elements); Chop(result); return result; } /* ----------------------------------------------------------------------------- * SwigType_ltype(SwigType *ty) * * Create a locally assignable type * ----------------------------------------------------------------------------- */ SwigType * SwigType_ltype(SwigType *s) { String *result; String *element; SwigType *td, *tc = 0; List *elements; int nelements, i; int firstarray = 1; result = NewString(""); tc = Copy(s); /* Nuke all leading qualifiers */ while (SwigType_isqualifier(tc)) { Delete(SwigType_pop(tc)); } if (SwigType_issimple(tc)) { /* Resolve any typedef definitions */ td = SwigType_typedef_resolve(tc); if (td && (SwigType_isconst(td) || SwigType_isarray(td) || SwigType_isenum(td) || SwigType_isreference(td))) { /* We need to use the typedef type */ Delete(tc); tc = td; } else if (td) { Delete(td); } } elements = SwigType_split(tc); nelements = Len(elements); /* Now, walk the type list and start emitting */ for (i = 0; i < nelements; i++) { element = Getitem(elements,i); if (SwigType_isqualifier(element)) { /* Do nothing. Ignore */ } else if (SwigType_ispointer(element)) { Append(result,element); firstarray = 0; } else if (SwigType_ismemberpointer(element)) { Append(result,element); firstarray = 0; } else if (SwigType_isreference(element)) { Append(result,"p."); firstarray = 0; } else if (SwigType_isarray(element) && firstarray) { Append(result,"p."); firstarray = 0; } else if (SwigType_isenum(element)) { Append(result,"int"); } else { Append(result,element); } } Delete(elements); Delete(tc); return result; } /* ----------------------------------------------------------------------------- * SwigType_lstr(DOH *s, DOH *id) * * Produces a type-string that is suitable as a lvalue in an expression. * That is, a type that can be freely assigned a value without violating * any C assignment rules. * * - Qualifiers such as 'const' and 'volatile' are stripped. * - Arrays are converted into a *single* pointer (i.e., * double [][] becomes double *). * - References are converted into a pointer. * - Typedef names that refer to read-only types will be replaced * with an equivalent assignable version. * -------------------------------------------------------------------- */ String * SwigType_lstr(SwigType *s, const String_or_char *id) { String *result; SwigType *tc; tc = SwigType_ltype(s); result = SwigType_str(tc,id); Delete(tc); return result; } /* ----------------------------------------------------------------------------- * SwigType_rcaststr() * * Produces a casting string that maps the type returned by lstr() to the real * datatype printed by str(). * ----------------------------------------------------------------------------- */ String *SwigType_rcaststr(SwigType *s, const String_or_char *name) { String *result, *cast; String *element = 0, *nextelement; SwigType *td, *rs, *tc = 0; List *elements; int nelements, i; int clear = 1; int firstarray = 1; int isreference = 0; int isarray = 0; result = NewString(""); if (SwigType_isconst(s)) { tc = Copy(s); Delete(SwigType_pop(tc)); rs = tc; } else { rs = s; } if (SwigType_issimple(rs)) { td = SwigType_typedef_resolve(rs); if ((td) && (SwigType_isconst(td) || SwigType_isarray(td) || SwigType_isreference(td))) { elements = SwigType_split(td); } else if (td && SwigType_isenum(td)) { elements = SwigType_split(rs); clear = 0; } else { elements = SwigType_split(rs); } if (td) Delete(td); } else { elements = SwigType_split(rs); } nelements = Len(elements); if (nelements > 0) { element = Getitem(elements,0); } /* Now, walk the type list and start emitting */ for (i = 0; i < nelements; i++) { if (i < (nelements - 1)) { nextelement = Getitem(elements,i+1); } else { nextelement = 0; } if (SwigType_isqualifier(element)) { DOH *q = 0; q = SwigType_parm(element); Insert(result,0," "); Insert(result,0,q); Delete(q); clear = 0; } else if (SwigType_ispointer(element)) { Insert(result,0,"*"); if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) { Insert(result,0,"("); Append(result,")"); } firstarray = 0; } else if (SwigType_ismemberpointer(element)) { String *q; Insert(result,0,"::*"); q = SwigType_parm(element); Insert(result,0,q); Delete(q); if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) { Insert(result,0,"("); Append(result,")"); } firstarray = 0; } else if (SwigType_isreference(element)) { Insert(result,0,"&"); if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) { Insert(result,0,"("); Append(result,")"); } isreference = 1; } else if (SwigType_isarray(element)) { DOH *size; if (firstarray && !isreference) { Append(result,"(*)"); firstarray = 0; } else { Append(result,"["); size = SwigType_parm(element); Append(result,size); Append(result,"]"); Delete(size); clear = 0; } isarray = 1; } else if (SwigType_isfunction(element)) { DOH *parms, *p; int j, plen; Append(result,"("); parms = SwigType_parmlist(element); plen = Len(parms); for (j = 0; j < plen; j++) { p = SwigType_str(Getitem(parms,j),0); Append(result,p); if (j < (plen-1)) Append(result,","); } Append(result,")"); Delete(parms); } else if (SwigType_isenum(element)) { String *bs = SwigType_namestr(element); Insert(result,0,bs); Delete(bs); clear = 0; } else { String *bs = SwigType_namestr(element); Insert(result,0," "); Insert(result,0,bs); Delete(bs); } element = nextelement; } Delete(elements); if (clear) { cast = NewString(""); } else { cast = NewStringf("(%s)",result); } if (name) { if (isreference) { if (isarray) Clear(cast); Append(cast,"*"); } Append(cast,name); } Delete(result); Delete(tc); return cast; } /* ----------------------------------------------------------------------------- * SwigType_lcaststr() * * Casts a variable from the real type to the local datatype. * ----------------------------------------------------------------------------- */ String *SwigType_lcaststr(SwigType *s, const String_or_char *name) { String *result; result = NewString(""); if (SwigType_isarray(s)) { Printf(result,"(%s)%s", SwigType_lstr(s,0),name); } else if (SwigType_isreference(s)) { Printf(result,"(%s)", SwigType_str(s,0)); if (name) Printv(result,name,NIL); } else if (SwigType_isqualifier(s)) { Printf(result,"(%s)%s", SwigType_lstr(s,0),name); } else { if (name) Append(result,name); } return result; } String *SwigType_manglestr_default(SwigType *s) { char *c; String *result,*base; SwigType *lt; SwigType *ss = 0; if (SwigType_istemplate(s)) { ss = SwigType_typedef_resolve_all(s); s = ss; } lt = SwigType_ltype(s); result = SwigType_prefix(lt); base = SwigType_base(lt); c = Char(result); while (*c) { if (!isalnum((int)*c)) *c = '_'; c++; } if (SwigType_istemplate(base)) { String *b = SwigType_namestr(base); Delete(base); base = b; } Replace(base,"struct ","", DOH_REPLACE_ANY); /* This might be problematic */ Replace(base,"class ","", DOH_REPLACE_ANY); Replace(base,"union ","", DOH_REPLACE_ANY); c = Char(base); while (*c) { if (*c == '<') *c = 'T'; else if (*c == '>') *c = 't'; else if (*c == '*') *c = 'p'; else if (*c == '[') *c = 'a'; else if (*c == ']') *c = 'A'; else if (*c == '&') *c = 'R'; else if (*c == '(') *c = 'f'; else if (*c == ')') *c = 'F'; else if (!isalnum((int)*c)) *c = '_'; c++; } Append(result,base); Insert(result,0,"_"); Delete(lt); Delete(base); if (ss) Delete(ss); return result; } String *SwigType_manglestr(SwigType *s) { return SwigType_manglestr_default(s); } /* ----------------------------------------------------------------------------- * SwigType_typename_replace() * * Replaces a typename in a type with something else. Needed for templates. * ----------------------------------------------------------------------------- */ void SwigType_typename_replace(SwigType *t, String *pat, String *rep) { String *nt; int i; List *elem; if (!Strstr(t,pat)) return; if (Strcmp(t,pat) == 0) { Replace(t,pat,rep,DOH_REPLACE_ANY); return; } nt = NewString(""); elem = SwigType_split(t); for (i = 0; i < Len(elem); i++) { String *e = Getitem(elem,i); if (SwigType_issimple(e)) { if (Strcmp(e,pat) == 0) { /* Replaces a type of the form 'pat' with 'rep' */ Replace(e,pat,rep,DOH_REPLACE_ANY); } else if (SwigType_istemplate(e)) { /* Replaces a type of the form 'pat' with 'rep' */ if (Strncmp(e,pat,Len(pat)) == 0) { String *repbase = SwigType_templateprefix(rep); Replace(e,pat,repbase,DOH_REPLACE_ID | DOH_REPLACE_FIRST); Delete(repbase); } { String *tsuffix; List *tparms = SwigType_parmlist(e); int j; String *nt = SwigType_templateprefix(e); Printv(nt,"<(",NIL); for (j = 0; j < Len(tparms); j++) { SwigType_typename_replace(Getitem(tparms,j), pat, rep); Printv(nt,Getitem(tparms,j),NIL); if (j < (Len(tparms)-1)) Putc(',',nt); } tsuffix = SwigType_templatesuffix(e); Printf(nt,")>%s", tsuffix); Delete(tsuffix); Clear(e); Append(e,nt); Delete(nt); Delete(tparms); } } else if (Swig_scopename_check(e)) { String *first, *rest; first = Swig_scopename_first(e); rest = Swig_scopename_suffix(e); SwigType_typename_replace(rest,pat,rep); SwigType_typename_replace(first,pat,rep); Clear(e); Printv(e,first,"::",rest,NIL); Delete(first); Delete(rest); } } else if (SwigType_isfunction(e)) { int j; List *fparms = SwigType_parmlist(e); Clear(e); Printv(e,"f(",NIL); for (j = 0; j < Len(fparms); j++) { SwigType_typename_replace(Getitem(fparms,j), pat, rep); Printv(e,Getitem(fparms,j),NIL); if (j < (Len(fparms)-1)) Putc(',',e); } Printv(e,").",NIL); Delete(fparms); } else if (SwigType_isarray(e)) { Replace(e,pat,rep, DOH_REPLACE_ID); } Append(nt,e); } Clear(t); Append(t,nt); } /* ----------------------------------------------------------------------------- * SwigType_check_decl() * * Checks type declarators for a match * ----------------------------------------------------------------------------- */ int SwigType_check_decl(SwigType *ty, const SwigType *decl) { SwigType *t,*t1,*t2; int r; t = SwigType_typedef_resolve_all(ty); t1 = SwigType_strip_qualifiers(t); t2 = SwigType_prefix(t1); r = Cmp(t2,decl); Delete(t); Delete(t1); Delete(t2); if (r == 0) return 1; return 0; } cableswig-0.1.0+git20150808.orig/SWIG/Source/Swig/swig.h0000644000175000000620000005365712561312227021111 0ustar stevestaff/* ----------------------------------------------------------------------------- * swig.h * * Header file for the SWIG core. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * Dustin Mitchell (djmitche@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * * /cvsroot/SWIG/Source/Swig/swig.h,v 1.82 2004/02/10 09:21:36 mmatus Exp * ----------------------------------------------------------------------------- */ #ifndef SWIGCORE_H_ #define SWIGCORE_H_ #include #include #include #include #ifdef __cplusplus extern "C" { #endif #ifndef MACSWIG #include "swigconfig.h" #endif #if defined(__cplusplus) && !defined(HAVE_BOOL) typedef int bool; #define true ((bool)1) #define false ((bool)0) #endif #include "doh.h" /* Status codes */ #define SWIG_OK 1 #define SWIG_ERROR 0 #define SWIG_NOWRAP 0 /* Short names for common data types */ typedef DOH String; typedef DOH Hash; typedef DOH List; typedef DOH String_or_char; typedef DOH File; typedef DOH Parm; typedef DOH ParmList; typedef DOH Node; typedef DOH Symtab; typedef DOH Typetab; typedef DOH SwigType; /* --- Legacy DataType interface. These type codes are provided solely for backwards compatibility with older modules --- */ /* --- The ordering of type values is used to determine type-promotion in the parser. Do not change */ /* Numeric types */ #define T_BOOL 1 #define T_SCHAR 2 #define T_UCHAR 3 #define T_SHORT 4 #define T_USHORT 5 #define T_ENUM 6 #define T_INT 7 #define T_UINT 8 #define T_LONG 9 #define T_ULONG 10 #define T_LONGLONG 11 #define T_ULONGLONG 12 #define T_FLOAT 20 #define T_DOUBLE 21 #define T_NUMERIC 22 /* non-numeric */ #define T_CHAR 30 #define T_USER 31 #define T_VOID 32 #define T_STRING 33 #define T_POINTER 34 #define T_REFERENCE 35 #define T_ARRAY 36 #define T_FUNCTION 37 #define T_MPOINTER 38 #define T_VARARGS 39 #define T_SYMBOL 98 #define T_ERROR 99 /* --- File interface --- */ extern void Swig_add_directory(const String_or_char *dirname); extern void Swig_push_directory(const String_or_char *dirname); extern void Swig_pop_directory(); extern String *Swig_last_file(); extern List *Swig_search_path(); extern FILE *Swig_open(const String_or_char *name); extern String *Swig_read_file(FILE *f); extern String *Swig_include(const String_or_char *name); extern int Swig_insert_file(const String_or_char *name, File *outfile); extern void Swig_set_config_file(const String_or_char *filename); extern String *Swig_get_config_file(void); extern void Swig_swiglib_set(const String_or_char *); extern String *Swig_swiglib_get(); extern void Swig_register_filebyname(const String_or_char *filename, File *outfile); extern File *Swig_filebyname(const String_or_char *filename); extern char *Swig_file_suffix(const String_or_char *filename); extern char *Swig_file_basename(const String_or_char *filename); extern char *Swig_file_filename(const String_or_char *filename); extern char *Swig_file_dirname(const String_or_char *filename); #if defined(MACSWIG) # define SWIG_FILE_DELIMETER ":" #elif defined(_WIN32) # define SWIG_FILE_DELIMETER "\\" #else # define SWIG_FILE_DELIMETER "/" #endif /* --- Command line parsing --- */ extern void Swig_init_args(int argc, char **argv); extern void Swig_mark_arg(int n); extern int Swig_check_marked(int n); extern void Swig_check_options(); extern void Swig_arg_error(); /* --- Scanner Interface --- */ typedef struct SwigScanner SwigScanner; extern SwigScanner *NewSwigScanner(); extern void DelSwigScanner(SwigScanner *); extern void SwigScanner_clear(SwigScanner *); extern void SwigScanner_push(SwigScanner *, String *); extern void SwigScanner_pushtoken(SwigScanner *, int); extern int SwigScanner_token(SwigScanner *); extern String *SwigScanner_text(SwigScanner *); extern void SwigScanner_skip_line(SwigScanner *); extern int SwigScanner_skip_balanced(SwigScanner *, int startchar, int endchar); extern void SwigScanner_set_location(SwigScanner *, String *file, int line); extern String *SwigScanner_get_file(SwigScanner *); extern int SwigScanner_get_line(SwigScanner *); extern void SwigScanner_idstart(SwigScanner *, char *idchar); #define SWIG_MAXTOKENS 512 #define SWIG_TOKEN_LPAREN 1 #define SWIG_TOKEN_RPAREN 2 #define SWIG_TOKEN_SEMI 3 #define SWIG_TOKEN_COMMA 4 #define SWIG_TOKEN_STAR 5 #define SWIG_TOKEN_LBRACE 6 #define SWIG_TOKEN_RBRACE 7 #define SWIG_TOKEN_EQUAL 8 #define SWIG_TOKEN_EQUALTO 9 #define SWIG_TOKEN_NOTEQUAL 10 #define SWIG_TOKEN_PLUS 11 #define SWIG_TOKEN_MINUS 12 #define SWIG_TOKEN_AND 13 #define SWIG_TOKEN_LAND 14 #define SWIG_TOKEN_OR 15 #define SWIG_TOKEN_LOR 16 #define SWIG_TOKEN_XOR 17 #define SWIG_TOKEN_LESSTHAN 18 #define SWIG_TOKEN_GREATERTHAN 19 #define SWIG_TOKEN_LTEQUAL 20 #define SWIG_TOKEN_GTEQUAL 21 #define SWIG_TOKEN_NOT 22 #define SWIG_TOKEN_LNOT 23 #define SWIG_TOKEN_LBRACKET 24 #define SWIG_TOKEN_RBRACKET 25 #define SWIG_TOKEN_SLASH 26 #define SWIG_TOKEN_BACKSLASH 27 #define SWIG_TOKEN_ENDLINE 28 #define SWIG_TOKEN_STRING 29 #define SWIG_TOKEN_POUND 30 #define SWIG_TOKEN_PERCENT 31 #define SWIG_TOKEN_COLON 32 #define SWIG_TOKEN_DCOLON 33 #define SWIG_TOKEN_LSHIFT 34 #define SWIG_TOKEN_RSHIFT 35 #define SWIG_TOKEN_ID 36 #define SWIG_TOKEN_FLOAT 37 #define SWIG_TOKEN_DOUBLE 38 #define SWIG_TOKEN_INT 39 #define SWIG_TOKEN_UINT 40 #define SWIG_TOKEN_LONG 41 #define SWIG_TOKEN_ULONG 42 #define SWIG_TOKEN_CHAR 43 #define SWIG_TOKEN_PERIOD 44 #define SWIG_TOKEN_AT 45 #define SWIG_TOKEN_DOLLAR 46 #define SWIG_TOKEN_CODEBLOCK 47 #define SWIG_TOKEN_RSTRING 48 #define SWIG_TOKEN_LONGLONG 49 #define SWIG_TOKEN_ULONGLONG 50 #define SWIG_TOKEN_ILLEGAL 98 #define SWIG_TOKEN_LAST 99 /* --- Functions for manipulating the string-based type encoding --- */ extern SwigType *NewSwigType(int typecode); extern void SwigType_del_element(SwigType *t); extern void SwigType_add_pointer(SwigType *t); extern void SwigType_add_memberpointer(SwigType *t, String_or_char *qual); extern void SwigType_del_pointer(SwigType *t); extern void SwigType_add_array(SwigType *t, String_or_char *size); extern SwigType *SwigType_pop_arrays(SwigType *t); extern void SwigType_add_reference(SwigType *t); extern void SwigType_del_reference(SwigType *t); extern void SwigType_add_qualifier(SwigType *t, String_or_char *qual); extern void SwigType_del_qualifier(SwigType *t); extern void SwigType_add_function(SwigType *t, ParmList *parms); extern void SwigType_add_template(SwigType *t, ParmList *parms); extern SwigType *SwigType_pop_function(SwigType *t); extern ParmList *SwigType_function_parms(SwigType *t); extern List *SwigType_split(SwigType *t); extern String *SwigType_pop(SwigType *t); extern void SwigType_push(SwigType *t, SwigType *s); extern List *SwigType_parmlist(const SwigType *p); extern String *SwigType_parm(String *p); extern String *SwigType_str(SwigType *s, const String_or_char *id); extern String *SwigType_lstr(SwigType *s, const String_or_char *id); extern String *SwigType_rcaststr(SwigType *s, const String_or_char *id); extern String *SwigType_lcaststr(SwigType *s, const String_or_char *id); extern String *SwigType_manglestr(SwigType *t); extern SwigType *SwigType_ltype(SwigType *t); extern int SwigType_ispointer(SwigType *t); extern int SwigType_ispointer_return(SwigType *t); extern int SwigType_ismemberpointer(SwigType *t); extern int SwigType_isreference(SwigType *t); extern int SwigType_isreference_return(SwigType *t); extern int SwigType_isarray(SwigType *t); extern int SwigType_isfunction(SwigType *t); extern int SwigType_isqualifier(SwigType *t); extern int SwigType_isconst(SwigType *t); extern int SwigType_issimple(SwigType *t); extern int SwigType_ismutable(SwigType *t); extern int SwigType_isvarargs(const SwigType *t); extern int SwigType_istemplate(const SwigType *t); extern int SwigType_isenum(SwigType *t); extern int SwigType_check_decl(SwigType *t, const String_or_char *decl); extern SwigType *SwigType_strip_qualifiers(SwigType *t); extern String *SwigType_base(SwigType *t); extern String *SwigType_namestr(const SwigType *t); extern String *SwigType_templateprefix(SwigType *t); extern String *SwigType_templatesuffix(const SwigType *t); extern String *SwigType_templateargs(SwigType *t); extern String *SwigType_prefix(SwigType *t); extern int SwigType_array_ndim(SwigType *t); extern String *SwigType_array_getdim(SwigType *t, int n); extern void SwigType_array_setdim(SwigType *t, int n, const String_or_char *rep); extern SwigType *SwigType_array_type(SwigType *t); extern String *SwigType_default(SwigType *t); extern void SwigType_typename_replace(SwigType *t, String *pat, String *rep); /* --- Type-system managment --- */ extern void SwigType_typesystem_init(); extern int SwigType_typedef(SwigType *type, String_or_char *name); extern int SwigType_typedef_class(String_or_char *name); extern int SwigType_typedef_using(String_or_char *qname); extern void SwigType_inherit(String *subclass, String *baseclass, String *cast); extern int SwigType_issubtype(SwigType *subtype, SwigType *basetype); extern void SwigType_scope_alias(String *aliasname, Typetab *t); extern void SwigType_using_scope(Typetab *t); extern void SwigType_new_scope(const String_or_char *name); extern void SwigType_inherit_scope(Typetab *scope); extern Typetab *SwigType_pop_scope(); extern Typetab *SwigType_set_scope(Typetab *h); extern void SwigType_print_scope(Typetab *t); extern SwigType *SwigType_typedef_resolve(SwigType *t); extern SwigType *SwigType_typedef_resolve_all(SwigType *t); extern SwigType *SwigType_typedef_qualified(SwigType *t); extern int SwigType_istypedef(SwigType *t); extern int SwigType_isclass(SwigType *t); extern void SwigType_attach_symtab(Symtab *syms); extern void SwigType_remember(SwigType *t); extern void SwigType_remember_clientdata(SwigType *t, const String_or_char *clientdata); extern void (*SwigType_remember_trace(void (*tf)(SwigType *, String *, String *)))(SwigType *, String *, String *); extern void SwigType_emit_type_table(File *f_headers, File *f_table); extern int SwigType_type(SwigType *t); /* --- Symbol table module --- */ extern void Swig_symbol_init(); extern void Swig_symbol_setscopename(const String_or_char *name); extern String *Swig_symbol_getscopename(); extern String *Swig_symbol_qualifiedscopename(Symtab *symtab); extern Symtab *Swig_symbol_newscope(); extern Symtab *Swig_symbol_setscope(Symtab *); extern Symtab *Swig_symbol_getscope(const String_or_char *symname); extern Symtab *Swig_symbol_current(); extern Symtab *Swig_symbol_popscope(); extern Node *Swig_symbol_add(String_or_char *symname, Node *node); extern void Swig_symbol_cadd(String_or_char *symname, Node *node); extern Node *Swig_symbol_clookup(String_or_char *symname, Symtab *tab); extern Node *Swig_symbol_clookup_check(String_or_char *symname, Symtab *tab, int (*check)(Node *)); extern Symtab *Swig_symbol_cscope(String_or_char *symname, Symtab *tab); extern Node *Swig_symbol_clookup_local(String_or_char *symname, Symtab *tab); extern Node *Swig_symbol_clookup_local_check(String_or_char *symname, Symtab *tab, int (*check)(Node *)); extern String *Swig_symbol_qualified(Node *node); extern Node *Swig_symbol_isoverloaded(Node *node); extern void Swig_symbol_remove(Node *node); extern void Swig_symbol_alias(String_or_char *aliasname, Symtab *tab); extern void Swig_symbol_inherit(Symtab *tab); extern SwigType *Swig_symbol_type_qualify(SwigType *ty, Symtab *tab); extern String *Swig_symbol_string_qualify(String *s, Symtab *tab); extern SwigType *Swig_symbol_typedef_reduce(SwigType *ty, Symtab *tab); /* --- Parameters and Parameter Lists --- */ /* Parameters are really just hidden behind a DOH object. The following interface will probably be simplified even further. */ extern Parm *NewParm(SwigType *type, const String_or_char *n); extern Parm *CopyParm(Parm *p); extern ParmList *CopyParmList(ParmList *); extern int ParmList_len(ParmList *); extern int ParmList_numarg(ParmList *); extern int ParmList_numrequired(ParmList *); extern String *ParmList_str(ParmList *); extern String *ParmList_protostr(ParmList *); /* --- Parse tree support --- */ /* DOM-like node access */ #define nodeType(x) Getattr(x,"nodeType") #define parentNode(x) Getattr(x,"parentNode") #define previousSibling(x) Getattr(x,"previousSibling") #define nextSibling(x) Getattr(x,"nextSibling") #define firstChild(x) Getattr(x,"firstChild") #define lastChild(x) Getattr(x,"lastChild") extern int checkAttribute(Node *obj, const String_or_char *name, const String_or_char *value); /* Macros to set up the DOM tree (mostly used by the parser) */ #define set_nodeType(x,v) Setattr(x,"nodeType",v) #define set_parentNode(x,v) Setattr(x,"parentNode",v) #define set_previousSibling(x,v) Setattr(x,"previousSibling",v) #define set_nextSibling(x,v) Setattr(x,"nextSibling",v) #define set_firstChild(x,v) Setattr(x,"firstChild",v) #define set_lastChild(x,v) Setattr(x,"lastChild",v) extern void appendChild(Node *node, Node *child); extern void deleteNode(Node *node); extern Node *copyNode(Node *node); extern void Swig_tag_nodes(Node *node, const String_or_char *attrname, DOH *value); extern int Swig_require(const char *ns, Node *node, ...); extern int Swig_save(const char *ns, Node *node,...); extern void Swig_restore(Node *node); /* Debugging of parse trees */ extern void Swig_print_tags(File *obj, Node *root); extern void Swig_print_tree(Node *obj); extern void Swig_print_node(Node *obj); /* -- Wrapper function Object */ typedef struct { Hash *localh; String *def; String *locals; String *code; } Wrapper; extern Wrapper *NewWrapper(); extern void DelWrapper(Wrapper *w); extern void Wrapper_compact_print_mode_set(int flag); extern void Wrapper_pretty_print(String *str, File *f); extern void Wrapper_compact_print(String *str, File *f); extern void Wrapper_print(Wrapper *w, File *f); extern int Wrapper_add_local(Wrapper *w, const String_or_char *name, const String_or_char *decl); extern int Wrapper_add_localv(Wrapper *w, const String_or_char *name, ...); extern int Wrapper_check_local(Wrapper *w, const String_or_char *name); extern char *Wrapper_new_local(Wrapper *w, const String_or_char *name, const String_or_char *decl); extern char *Wrapper_new_localv(Wrapper *w, const String_or_char *name, ...); /* --- Naming functions --- */ extern void Swig_name_register(const String_or_char *method, const String_or_char *format); extern void Swig_name_unregister(const String_or_char *method); extern String *Swig_name_mangle(const String_or_char *s); extern String *Swig_name_wrapper(const String_or_char *fname); extern String *Swig_name_member(const String_or_char *classname, const String_or_char *mname); extern String *Swig_name_get(const String_or_char *vname); extern String *Swig_name_set(const String_or_char *vname); extern String *Swig_name_construct(const String_or_char *classname); extern String *Swig_name_copyconstructor(const String_or_char *classname); extern String *Swig_name_destroy(const String_or_char *classname); extern String *Swig_name_disown(const String_or_char *classname); /* --- parameterized rename functions --- */ extern void Swig_name_object_set(Hash *namehash, String_or_char *name, SwigType *decl, DOH *object); extern DOH *Swig_name_object_get(Hash *namehash, String_or_char *prefix, String_or_char *name, SwigType *decl); extern void Swig_name_object_inherit(Hash *namehash, String *base, String *derived); extern void Swig_features_get(Hash *features, String_or_char *prefix, String_or_char *name, SwigType *decl, Node *n); extern void Swig_feature_set(Hash *features, const String_or_char *name, SwigType *decl, const String_or_char *featurename, String *value); /* --- Misc --- */ extern char *Swig_copy_string(const char *c); extern void Swig_banner(File *f); extern String *Swig_string_escape(String *s); extern String *Swig_string_mangle(String *s); extern String *Swig_scopename_prefix(String *s); extern String *Swig_scopename_last(String *s); extern String *Swig_scopename_first(String *s); extern String *Swig_scopename_suffix(String *s); extern int Swig_scopename_check(String *s); extern void Swig_init(); extern void Swig_warn(const char *filename, int line, const char *msg); #define WARNING(msg) Swig_warn(__FILE__,__LINE__,msg) typedef enum { EMF_STANDARD, EMF_MICROSOFT } ErrorMessageFormat; extern void Swig_warning(int num, const String_or_char *filename, int line, const char *fmt, ...); extern void Swig_error(const String_or_char *filename, int line, const char *fmt, ...); extern int Swig_error_count(void); extern void Swig_error_silent(int s); extern void Swig_warnfilter(const String_or_char *wlist, int val); extern void Swig_warnall(void); extern int Swig_warn_count(void); extern void Swig_error_msg_format(ErrorMessageFormat format); /* --- C Wrappers --- */ extern String *Swig_cparm_name(Parm *p, int i); extern String *Swig_clocal(SwigType *t, String_or_char *name, String_or_char *value); extern String *Swig_wrapped_var_type(SwigType *t); extern int Swig_cargs(Wrapper *w, ParmList *l); extern String *Swig_cresult(SwigType *t, const String_or_char *name, const String_or_char *decl); extern String *Swig_cfunction_call(String_or_char *name, ParmList *parms); extern String *Swig_cmethod_call(String_or_char *name, ParmList *parms, String_or_char *self); extern String *Swig_cconstructor_call(String_or_char *name); extern String *Swig_cppconstructor_call(String_or_char *name, ParmList *parms); extern String *Swig_unref_call(Node *n); extern String *Swig_ref_call(Node *n, const String* lname); extern String *Swig_cdestructor_call(Node *n); extern String *Swig_cppdestructor_call(Node *n); extern String *Swig_cmemberset_call(String_or_char *name, SwigType *type, String_or_char *self); extern String *Swig_cmemberget_call(const String_or_char *name, SwigType *t, String_or_char *self); /* --- Transformations --- */ extern int Swig_MethodToFunction(Node *n, String *classname, int flags); 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_MembersetToFunction(Node *n, String *classname, int flags); extern int Swig_MembergetToFunction(Node *n, String *classname, int flags); extern int Swig_VargetToFunction(Node *n); extern int Swig_VarsetToFunction(Node *n); #define CWRAP_EXTEND 0x01 #define CWRAP_SMART_POINTER 0x02 /* --- Director Helpers --- */ extern Node *Swig_methodclass(Node *n); extern int Swig_directorbase(Node *n); extern int Swig_directorclass(Node *n); extern int Swig_directormethod(Node *n); extern Node *Swig_directormap(Node *n, String *type); /* --- Legacy Typemap API (somewhat simplified, ha!) --- */ extern void Swig_typemap_init(); extern void Swig_typemap_register(const String_or_char *op, ParmList *pattern, String_or_char *code, ParmList *locals, ParmList *kwargs); extern int Swig_typemap_copy(const String_or_char *op, ParmList *srcpattern, ParmList *pattern); extern void Swig_typemap_clear(const String_or_char *op, ParmList *pattern); extern int Swig_typemap_apply(ParmList *srcpat, ParmList *destpat); extern void Swig_typemap_clear_apply(ParmList *pattern); extern void Swig_typemap_debug(); extern Hash *Swig_typemap_search(const String_or_char *op, SwigType *type, String_or_char *pname, SwigType **matchtype); extern Hash *Swig_typemap_search_multi(const String_or_char *op, ParmList *parms, int *nmatch); extern String *Swig_typemap_lookup(const String_or_char *op, SwigType *type, String_or_char *pname, String_or_char *lname, String_or_char *source, String_or_char *target, Wrapper *f); extern String *Swig_typemap_lookup_new(const String_or_char *op, Node *n, const String_or_char *lname, Wrapper *f); extern void Swig_typemap_attach_kwargs(Hash *tm, const String_or_char *op, Parm *p); extern void Swig_typemap_new_scope(); extern Hash *Swig_typemap_pop_scope(); extern void Swig_typemap_attach_parms(const String_or_char *op, ParmList *parms, Wrapper *f); /* --- Code fragment support --- */ extern void Swig_fragment_register(Node* fragment); extern void Swig_fragment_emit(String *name); /* hacks defined in C++ ! */ extern int Swig_need_protected(); #ifdef __cplusplus } #endif #endif cableswig-0.1.0+git20150808.orig/SWIG/Source/Swig/typeobj.c0000644000175000000620000005715012561312227021577 0ustar stevestaff/* ----------------------------------------------------------------------------- * typeobj.c * * This file provides functions for constructing, manipulating, and testing * type objects. Type objects are merely the raw low-level representation * of C++ types. They do not incorporate high-level type system features * like typedef, namespaces, etc. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2003. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_typeobj_c[] = "/cvsroot/SWIG/Source/Swig/typeobj.c,v 1.5 2004/01/15 22:46:07 cheetah Exp"; #include "swig.h" #include /* ----------------------------------------------------------------------------- * Synopsis * * This file provides a collection of low-level functions for constructing and * manipulating C++ data types. In SWIG, C++ datatypes are encoded as simple * text strings. This representation is compact, easy to debug, and easy to read. * * General idea: * * Types are represented by a base type (e.g., "int") and a collection of * type operators applied to the base (e.g., pointers, arrays, etc...). * * Encoding: * * Types are encoded as strings of type constructors such as follows: * * String Encoding C Example * --------------- --------- * p.p.int int ** * a(300).a(400).int int [300][400] * p.q(const).char char const * * * All type constructors are denoted by a trailing '.': * * 'p.' = Pointer (*) * 'r.' = Reference (&) * 'a(n).' = Array of size n [n] * 'f(..,..).' = Function with arguments (args) * 'q(str).' = Qualifier (such as const or volatile) (const, volatile) * 'm(qual).' = Pointer to member (qual::*) * * The encoding follows the order that you might describe a type in words. * For example "p.a(200).int" is "A pointer to array of int's" and * "p.q(const).char" is "a pointer to a const char". * * This representation of types is fairly convenient because ordinary string * operations can be used for type manipulation. For example, a type could be * formed by combining two strings such as the following: * * "p.p." + "a(400).int" = "p.p.a(400).int" * * For C++, typenames may be parameterized using <(...)>. Here are some * examples: * * String Encoding C++ Example * --------------- ------------ * p.vector<(int)> vector * * r.foo<(int,p.double)> foo & * * Contents of this file: * * Most of this functions in this file pertain to the low-level manipulation * of type objects. There are constructor functions like this: * * SwigType_add_pointer() * SwigType_add_reference() * SwigType_add_array() * * These are used to build new types. There are also functions to undo these * operations. For example: * * SwigType_del_pointer() * SwigType_del_reference() * SwigType_del_array() * * In addition, there are query functions * * SwigType_is_pointer() * SwigType_is_reference() * SwigType_is_array() * * Finally, there are some data extraction functions that can be used to * extract array dimensions, template arguments, and so forth. * * It is very important for developers to realize that the functions in this * module do *NOT* incorporate higher-level type system features like typedef. * For example, you could have C code like this: * * typedef int *intptr; * * In this case, a SwigType of type 'intptr' will be treated as a simple type and * functions like SwigType_is_pointer() will evaluate as false. It is strongly * advised that developers use the TypeSys_* interface to check types in a more * reliable manner. * ----------------------------------------------------------------------------- */ /* ----------------------------------------------------------------------------- * NewSwigType() * * Constructs a new type object. Eventually, it would be nice for this function * to accept an initial value in the form a C/C++ abstract type (currently unimplemented). * ----------------------------------------------------------------------------- */ #ifdef NEW SwigType * NewSwigType(const String_or_char *initial) { return NewString(initial); } #endif /* The next few functions are utility functions used in the construction and management of types */ /* ----------------------------------------------------------------------------- * static element_size() * * This utility function finds the size of a single type element in a type string. * Type elements are always delimeted by periods, but may be nested with * parentheses. A nested element is always handled as a single item. * * Returns the integer size of the element (which can be used to extract a * substring, to chop the element off, or for other purposes). * ----------------------------------------------------------------------------- */ static int element_size(char *c) { int nparen; char *s = c; while (*c) { if (*c == '.') { c++; return (int) (c - s); } else if (*c == '(') { nparen = 1; c++; while (*c) { if (*c == '(') nparen++; if (*c == ')') { nparen--; if (nparen == 0) break; } c++; } } if (*c) c++; } return (int) (c - s); } /* ----------------------------------------------------------------------------- * SwigType_del_element() * * Deletes one type element from the type. * ----------------------------------------------------------------------------- */ void SwigType_del_element(SwigType *t) { int sz = element_size(Char(t)); Delslice(t,0,sz); } /* ----------------------------------------------------------------------------- * SwigType_pop() * * Pop one type element off the type. * ----------------------------------------------------------------------------- */ SwigType * SwigType_pop(SwigType *t) { SwigType *result; char *c; int sz; c = Char(t); if (!*c) return 0; sz = element_size(c); result = NewStringWithSize(c,sz); Delslice(t,0,sz); c = Char(t); if (*c == '.') { Delitem(t,0); } return result; } /* ----------------------------------------------------------------------------- * SwigType_parm() * * Returns the parameter of an operator as a string * ----------------------------------------------------------------------------- */ String * SwigType_parm(SwigType *t) { char *start, *c; int nparens = 0; c = Char(t); while (*c && (*c != '(') && (*c != '.')) c++; if (!*c || (*c == '.')) return 0; c++; start = c; while (*c) { if (*c == ')') { if (nparens == 0) break; nparens--; } else if (*c == '(') { nparens++; } c++; } return NewStringWithSize(start, (int) (c-start)); } /* ----------------------------------------------------------------------------- * SwigType_split() * * Splits a type into it's component parts and returns a list of string. * ----------------------------------------------------------------------------- */ List *SwigType_split(SwigType *t) { DOH *item; List *list; char *c; int len; c = Char(t); list = NewList(); while (*c) { len = element_size(c); item = NewStringWithSize(c,len); Append(list,item); Delete(item); c = c + len; if (*c == '.') c++; } return list; } /* ----------------------------------------------------------------------------- * SwigType_parmlist() * * Splits a comma separated list of type components into strings. * ----------------------------------------------------------------------------- */ List *SwigType_parmlist(const String *p) { DOH *item; List *list; char *c, *itemstart; c = Char(p); while (*c && (*c != '(') && (*c != '.')) c++; if (!*c || (*c == '.')) return 0; c++; list = NewList(); itemstart = c; while (*c) { if (*c == ',') { item = NewStringWithSize(itemstart, (int) (c - itemstart)); Append(list,item); Delete(item); itemstart = c+1; } else if (*c == '(') { int nparens = 1; c++; while (*c) { if (*c == '(') nparens++; if (*c == ')') { nparens--; if (nparens == 0) break; } c++; } } else if (*c == ')') { break; } if (*c) c++; } item = NewStringWithSize(itemstart,(int) (c - itemstart)); Append(list,item); Delete(item); return list; } /* ----------------------------------------------------------------------------- * Pointers * * SwigType_add_pointer() * SwigType_del_pointer() * SwigType_ispointer() * * Add, remove, and test if a type is a pointer. The deletion and query * functions take into account qualifiers (if any). * ----------------------------------------------------------------------------- */ void SwigType_add_pointer(SwigType *t) { Insert(t,0,"p."); } void SwigType_del_pointer(SwigType *t) { char *c, *s; c = Char(t); s = c; /* Skip qualifiers, if any */ if (strncmp(c,"q(",2) == 0) { c = strchr(c,'.'); assert(c); c++; } if (strncmp(c,"p.",2)) { printf("Fatal error. SwigType_del_pointer applied to non-pointer.\n"); abort(); } Delslice(t,0,(c-s)+2); } int SwigType_ispointer(SwigType *t) { char *c; if (!t) return 0; c = Char(t); /* Skip qualifiers, if any */ if (strncmp(c,"q(",2) == 0) { c = strchr(c,'.'); if (!c) return 0; c++; } if (strncmp(c,"p.",2) == 0) { return 1; } return 0; } /* ----------------------------------------------------------------------------- * References * * SwigType_add_reference() * SwigType_del_reference() * SwigType_isreference() * * Add, remove, and test if a type is a pointer. The deletion and query * functions take into account qualifiers (if any). * ----------------------------------------------------------------------------- */ void SwigType_add_reference(SwigType *t) { Insert(t,0,"r."); } void SwigType_del_reference(SwigType *t) { char *c = Char(t); assert(strncmp(c,"r.",2) == 0); Delslice(t,0,2); } int SwigType_isreference(SwigType *t) { char *c; if (!t) return 0; c = Char(t); if (strncmp(c,"r.",2) == 0) { return 1; } return 0; } /* ----------------------------------------------------------------------------- * Qualifiers * * SwigType_add_qualifier() * SwigType_del_qualifier() * SwigType_is_qualifier() * * Adds type qualifiers like "const" and "volatile". When multiple qualifiers * are added to a type, they are combined together into a single qualifier. * Repeated qualifications have no effect. Moreover, the order of qualifications * is alphabetical---meaning that "const volatile" and "volatile const" are * stored in exactly the same way as "q(const volatile)". * ----------------------------------------------------------------------------- */ void SwigType_add_qualifier(SwigType *t, String *qual) { char temp[256], newq[256]; int sz, added = 0; char *q, *cqual; char *c = Char(t); cqual = Char(qual); if (!(strncmp(c,"q(",2) == 0)) { sprintf(temp,"q(%s).",cqual); Insert(t,0,temp); return; } /* The type already has a qualifier on it. In this case, we first check to see if the qualifier is already specified. In that case do nothing. If it is a new qualifier, we add it to the qualifier list in alphabetical order */ sz = element_size(c); strncpy(temp,c, (sz < 256) ? sz : 256); if (strstr(temp,cqual)) { /* Qualifier already added */ return; } /* Add the qualifier to the existing list. */ strcpy(newq,"q("); q = temp+2; q = strtok(q," )."); while (q) { if (strcmp(cqual,q) < 0) { /* New qualifier is less that current qualifier. We need to insert it */ strcat(newq,cqual); strcat(newq," "); strcat(newq,q); added = 1; } else { strcat(newq,q); } q = strtok(NULL," )."); if (q) { strcat(newq," "); } } if (!added) { strcat(newq," "); strcat(newq,cqual); } strcat(newq,")."); Delslice(t,0,sz); Insert(t,0,newq); } void SwigType_del_qualifier(SwigType *t) { char *c = Char(t); assert(strncmp(c,"q(",2) == 0); Delslice(t,0,element_size(Char(t))); } int SwigType_isqualifier(SwigType *t) { char *c; if (!t) return 0; c = Char(t); if (strncmp(c,"q(",2) == 0) { return 1; } return 0; } /* ----------------------------------------------------------------------------- * Member Pointers * * SwigType_add_memberpointer() * SwigType_del_memberpointer() * SwigType_ismemberpointer() * * Add, remove, and test for C++ pointer to members. * ----------------------------------------------------------------------------- */ void SwigType_add_memberpointer(SwigType *t, String_or_char *name) { String *temp = NewStringf("m(%s).", name); Insert(t,0,temp); Delete(temp); } void SwigType_del_memberpointer(SwigType *t) { char *c = Char(t); assert(strncmp(c,"m(",2) == 0); Delslice(t,0,element_size(c)); } int SwigType_ismemberpointer(SwigType *t) { char *c; if (!t) return 0; c = Char(t); if (strncmp(c,"m(",2) == 0) { return 1; } return 0; } /* ----------------------------------------------------------------------------- * Arrays * * SwigType_add_array() * SwigType_del_array() * SwigType_isarray() * * Utility functions: * * SwigType_array_ndim() - Calculate number of array dimensions. * SwigType_array_getdim() - Get array dimension * SwigType_array_setdim() - Set array dimension * SwigType_array_type() - Return array type * SwigType_pop_arrays() - Remove all arrays * ----------------------------------------------------------------------------- */ void SwigType_add_array(SwigType *t, String *size) { char temp[512]; strcpy(temp,"a("); strcat(temp,Char(size)); strcat(temp,")."); Insert(t,0,temp); } void SwigType_del_array(SwigType *t) { char *c = Char(t); assert(strncmp(c,"a(",2) == 0); Delslice(t,0,element_size(c)); } int SwigType_isarray(SwigType *t) { char *c; if (!t) return 0; c = Char(t); if (strncmp(c,"a(",2) == 0) { return 1; } return 0; } /* Remove all arrays */ SwigType * SwigType_pop_arrays(SwigType *t) { String *ta; assert(SwigType_isarray(t)); ta = NewString(""); while (SwigType_isarray(t)) { SwigType *td = SwigType_pop(t); Append(ta,td); Delete(td); } return ta; } /* Return number of array dimensions */ int SwigType_array_ndim(SwigType *t) { int ndim = 0; char *c = Char(t); while (c && (strncmp(c,"a(",2) == 0)) { c = strchr(c,'.'); c++; ndim++; } return ndim; } /* Get nth array dimension */ String * SwigType_array_getdim(SwigType *t, int n) { char *c = Char(t); while (c && (strncmp(c,"a(",2) == 0) && (n > 0)) { c = strchr(c,'.'); c++; n--; } if (n == 0) return SwigType_parm(c); return 0; } /* Replace nth array dimension */ void SwigType_array_setdim(SwigType *t, int n, const String_or_char *rep) { String *result = 0; char temp; char *start; char *c = Char(t); start = c; if (strncmp(c,"a(",2)) abort(); while (c && (strncmp(c,"a(",2) == 0) && (n > 0)) { c = strchr(c,'.'); c++; n--; } if (n == 0) { temp = *c; *c = 0; result = NewString(start); Printf(result,"a(%s)",rep); *c = temp; c = strchr(c,'.'); Append(result,c); } Clear(t); Append(t,result); Delete(result); } /* Return base type of an array */ SwigType * SwigType_array_type(SwigType *ty) { SwigType *t; t = Copy(ty); while (SwigType_isarray(t)) { Delete(SwigType_pop(t)); } return t; } /* ----------------------------------------------------------------------------- * Functions * * SwigType_add_function() * SwigType_del_function() * SwigType_isfunction() * SwigType_pop_function() * * Add, remove, and test for function types. * ----------------------------------------------------------------------------- */ void SwigType_add_function(SwigType *t, ParmList *parms) { String *pstr; Parm *p; Insert(t,0,")."); pstr = NewString("f("); p = parms; for (p = parms; p; p = nextSibling(p)) { if (p != parms) Putc(',',pstr); Printv(pstr, Getattr(p,"type"), NIL); } Insert(t,0,pstr); Delete(pstr); } SwigType * SwigType_pop_function(SwigType *t) { SwigType *f = 0; SwigType *g = 0; char *c = Char(t); if (strncmp(c,"q(",2) == 0) { f = SwigType_pop(t); c = Char(t); } if (strncmp(c,"f(",2)) { printf("Fatal error. SwigType_pop_function applied to non-function.\n"); abort(); } g = SwigType_pop(t); if (f) SwigType_push(g,f); Delete(f); return g; } int SwigType_isfunction(SwigType *t) { char *c; if (!t) { return 0; } c = Char(t); if (strncmp(c,"q(",2) == 0) { /* Might be a 'const' function. Try to skip over the 'const' */ c = strchr(c,'.'); if (c) c++; else return 0; } if (strncmp(c,"f(",2) == 0) { return 1; } return 0; } ParmList * SwigType_function_parms(SwigType *t) { List *l = SwigType_parmlist(t); Hash *p, *pp = 0, *firstp = 0; Iterator o; for (o = First(l); o.item; o = Next(o)) { p = NewParm(o.item,0); if (!firstp) firstp = p; if (pp) { set_nextSibling(pp,p); } pp = p; } Delete(l); return firstp; } int SwigType_isvarargs(const SwigType *t) { if (Strcmp(t,"v(...)") == 0) return 1; return 0; } /* ----------------------------------------------------------------------------- * Templates * * SwigType_add_template() * * Template handling. * ----------------------------------------------------------------------------- */ /* ----------------------------------------------------------------------------- * SwigType_add_template() * * Adds a template to a type. This template is encoded in the SWIG type * mechanism and produces a string like this: * * vector ----> "vector<(p.int)>" * ----------------------------------------------------------------------------- */ void SwigType_add_template(SwigType *t, ParmList *parms) { Parm *p; Append(t,"<("); p = parms; for (p = parms; p; p = nextSibling(p)) { String *v; if (Getattr(p,"default")) continue; if (p != parms) Append(t,","); v = Getattr(p,"value"); if (v) { Append(t,v); } else { Append(t,Getattr(p,"type")); } } Append(t,")>"); } /* ----------------------------------------------------------------------------- * SwigType_templateprefix() * * Returns the prefix before the first template definition. * For example: * * Foo<(p.int)>::bar * * Results in "Foo" * ----------------------------------------------------------------------------- */ String * SwigType_templateprefix(SwigType *t) { char *c,*s; s = Char(t); c = s; while (*c) { if (*c == '<') { return NewStringWithSize(s,c-s); } c++; } return NewString(s); } /* ----------------------------------------------------------------------------- * SwigType_templatesuffix() * * Returns text after a template substitution. Used to handle scope names * for example: * * Foo<(p.int)>::bar * * returns "::bar" * ----------------------------------------------------------------------------- */ String * SwigType_templatesuffix(const SwigType *t) { char *c; c = Char(t); while (*c) { if ((*c == '<') && (*(c+1) == '(')) { int nest = 1; c++; while (*c && nest) { if (*c == '<') nest++; if (*c == '>') nest--; c++; } return NewString(c); } c++; } return NewString(""); } /* ----------------------------------------------------------------------------- * SwigType_templateargs() * * Returns the template part * ----------------------------------------------------------------------------- */ String * SwigType_templateargs(SwigType *t) { char *c; char *start; c = Char(t); while (*c) { if ((*c == '<') && (*(c+1) == '(')) { int nest = 1; start = c; c++; while (*c && nest) { if (*c == '<') nest++; if (*c == '>') nest--; c++; } return NewStringWithSize(start,c-start); } c++; } return 0; } /* ----------------------------------------------------------------------------- * SwigType_istemplate() * * Tests a type to see if it includes template parameters * ----------------------------------------------------------------------------- */ int SwigType_istemplate(const SwigType *t) { if (Strstr(t,"<(")) return 1; return 0; } /* ----------------------------------------------------------------------------- * SwigType_base() * * This function returns the base of a type. For example, if you have a * type "p.p.int", the function would return "int". * ----------------------------------------------------------------------------- */ SwigType * SwigType_base(SwigType *t) { char *c; char *lastop = 0; c = Char(t); lastop = c; /* Search for the last type constructor separator '.' */ while (*c) { if (*c == '.') { if (*(c+1)) { lastop = c+1; } c++; continue; } if (*c == '<') { /* Skip over template---it's part of the base name */ int ntemp = 1; c++; while ((*c) && (ntemp > 0)) { if (*c == '>') ntemp--; else if (*c == '<') ntemp++; c++; } if (ntemp) break; continue; } if (*c == '(') { /* Skip over params */ int nparen = 1; c++; while ((*c) && (nparen > 0)) { if (*c == '(') nparen++; else if (*c == ')') nparen--; c++; } if (nparen) break; continue; } c++; } return NewString(lastop); } /* ----------------------------------------------------------------------------- * SwigType_prefix() * * Returns the prefix of a datatype. For example, the prefix of the * type "p.p.int" is "p.p.". * ----------------------------------------------------------------------------- */ String * SwigType_prefix(SwigType *t) { char *c, *d; String *r = 0; c = Char(t); d = c + strlen(c); /* Check for a type constructor */ if ((d > c) && (*(d-1) == '.')) d--; while (d > c) { d--; if (*d == '>') { int nest = 1; d--; while ((d > c) && (nest)) { if (*d == '>') nest++; if (*d == '<') nest--; d--; } } if (*d == ')') { /* Skip over params */ int nparen = 1; d--; while ((d > c) && (nparen)) { if (*d == ')') nparen++; if (*d == '(') nparen--; d--; } } if (*d == '.') { char t = *(d+1); *(d+1) = 0; r = NewString(c); *(d+1) = t; return r; } } return NewString(""); } /* ----------------------------------------------------------------------------- * SwigType_strip_qualifiers() * * Strip all qualifiers from a type and return a new type * ----------------------------------------------------------------------------- */ SwigType * SwigType_strip_qualifiers(SwigType *t) { static Hash *memoize_stripped = 0; SwigType *r; List *l; Iterator ei; if (!memoize_stripped) memoize_stripped = NewHash(); r = Getattr(memoize_stripped,t); if (r) return Copy(r); l = SwigType_split(t); r = NewString(""); for (ei = First(l);ei.item; ei = Next(ei)) { if (SwigType_isqualifier(ei.item)) continue; Append(r,ei.item); } Delete(l); { String *key, *value; key = Copy(t); value = Copy(r); Setattr(memoize_stripped,key,value); Delete(key); Delete(value); } return r; } cableswig-0.1.0+git20150808.orig/SWIG/Source/Swig/cwrap.c0000644000175000000620000007313412561312227021237 0ustar stevestaff/* ----------------------------------------------------------------------------- * cwrap.c * * This file defines a variety of wrapping rules for C/C++ handling including * the naming of local variables, calling conventions, and so forth. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1998-2000. The University of Chicago * Copyright (C) 1995-1998. The University of Utah and The Regents of the * University of California. * * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_cwrap_c[] = "/cvsroot/SWIG/Source/Swig/cwrap.c,v 1.32 2004/02/10 09:21:36 mmatus Exp"; #include "swig.h" static Parm *nonvoid_parms(Parm *p) { if (p) { SwigType *t = Getattr(p,"type"); if (SwigType_type(t) == T_VOID) return 0; } return p; } /* ----------------------------------------------------------------------------- * Swig_parm_name() * * Generates a name for the ith argument in an argument list * ----------------------------------------------------------------------------- */ String * Swig_cparm_name(Parm *p, int i) { String *name = NewStringf("arg%d",i+1); if (p) { Setattr(p,"lname",name); } return name; } /* ----------------------------------------------------------------------------- * Swig_clocal() * * Creates a string that declares a C local variable type. Converts references * and user defined types to pointers. * ----------------------------------------------------------------------------- */ String * Swig_clocal(SwigType *t, String_or_char *name, String_or_char *value) { String *decl; decl = NewString(""); switch(SwigType_type(t)) { case T_REFERENCE: if (value) { Printf(decl,"%s = (%s) &%s_defvalue", SwigType_lstr(t,name), SwigType_lstr(t,0), name); } else { Printf(decl,"%s = 0", SwigType_lstr(t,name)); } break; case T_VOID: break; case T_VARARGS: Printf(decl,"void *%s = 0", name); break; default: if (value) { Printf(decl,"%s = (%s) %s", SwigType_lstr(t,name), SwigType_lstr(t,0), SwigType_lcaststr(t,value)); } else { Printf(decl,"%s", SwigType_lstr(t,name)); } } return decl; } /* ----------------------------------------------------------------------------- * Swig_wrapped_var_convert() * * Converts a member variable for use in the get and set wrapper methods. * This function only converts user defined types to pointers. * ----------------------------------------------------------------------------- */ String * Swig_wrapped_var_type(SwigType *t) { SwigType *ty; ty = Copy(t); if (SwigType_isclass(t)) { SwigType_add_pointer(ty); } return ty; } static String * Swig_wrapped_var_deref(SwigType *t, String_or_char *name) { if (SwigType_isclass(t)) { return NewStringf("*%s",name); } else { return SwigType_rcaststr(t,name); } } static String * Swig_wrapped_var_assign(SwigType *t, const String_or_char *name) { if (SwigType_isclass(t)) { return NewStringf("&%s",name); } else { return SwigType_lcaststr(t,name); } } /* ----------------------------------------------------------------------------- * Swig_cargs() * * Emit all of the local variables for a list of parameters. Returns the * number of parameters. * ----------------------------------------------------------------------------- */ int Swig_cargs(Wrapper *w, ParmList *p) { int i; SwigType *pt; String *pvalue; String *pname; String *local; String *lname; SwigType *altty; String *type; int tycode; i = 0; while (p != 0) { lname = Swig_cparm_name(p,i); pt = Getattr(p,"type"); if ((SwigType_type(pt) != T_VOID)) { pname = Getattr(p,"name"); pvalue = Getattr(p,"value"); altty = Getattr(p,"alttype"); type = Getattr(p,"type"); tycode = SwigType_type(type); if (tycode == T_REFERENCE) { if (pvalue) { String *defname, *defvalue; defname = NewStringf("%s_defvalue", lname); defvalue = NewStringf("%s = %s", SwigType_str(type,defname), pvalue); Wrapper_add_localv(w,defname, defvalue, NIL); Delete(defname); Delete(defvalue); } } else if (!pvalue && (tycode == T_POINTER)) { pvalue = (String *) "0"; } if (!altty) { local = Swig_clocal(pt,lname,pvalue); } else { local = Swig_clocal(altty,lname, pvalue); } Wrapper_add_localv(w,lname,local,NIL); i++; } p = nextSibling(p); } return(i); } /* ----------------------------------------------------------------------------- * Swig_cresult() * * This function generates the C code needed to set the result of a C * function call. * ----------------------------------------------------------------------------- */ String *Swig_cresult(SwigType *t, const String_or_char *name, const String_or_char *decl) { String *fcall; fcall = NewString(""); switch(SwigType_type(t)) { case T_VOID: break; case T_REFERENCE: Printf(fcall,"{\n"); Printf(fcall,"%s = ", SwigType_str(t,"_result_ref")); break; case T_USER: Printf(fcall,"%s = ", name); break; default: /* Normal return value */ Printf(fcall,"%s = (%s)", name, SwigType_lstr(t,0)); break; } /* Now print out function call */ Printv(fcall,decl,NIL); /* A sick hack */ { char *c = Char(decl) + Len(decl) - 1; if (!((*c == ';') || (*c == '}'))) Printf(fcall, ";"); } Printf(fcall,"\n"); if (SwigType_type(t) == T_REFERENCE) { Printf(fcall,"%s = (%s) &_result_ref;\n", name, SwigType_lstr(t,0)); Printf(fcall,"}\n"); } return fcall; } /* ----------------------------------------------------------------------------- * Swig_cfunction_call() * * Creates a string that calls a C function using the local variable rules * defined above. * * name(arg0, arg1, arg2, ... argn) * * ----------------------------------------------------------------------------- */ String * Swig_cfunction_call(String_or_char *name, ParmList *parms) { String *func; int i = 0; int comma = 0; Parm *p = parms; SwigType *pt; String *nname; func = NewString(""); nname = SwigType_namestr(name); Printf(func,"%s(", nname); while (p) { String *pname; pt = Getattr(p,"type"); if ((SwigType_type(pt) != T_VOID)) { if (comma) Printf(func,","); pname = Swig_cparm_name(p,i); Printf(func,"%s", SwigType_rcaststr(pt, pname)); comma = 1; i++; } p = nextSibling(p); } Printf(func,")"); return func; } /* ----------------------------------------------------------------------------- * Swig_cmethod_call() * * Generates a string that calls a C++ method from a list of parameters. * * arg0->name(arg1, arg2, arg3, ..., argn) * * self is an argument that defines how to handle the first argument. Normally, * it should be set to "this->". With C++ proxy classes enabled, it could be * set to "(*this)->" or some similar sequence. * ----------------------------------------------------------------------------- */ String * Swig_cmethod_call(String_or_char *name, ParmList *parms, String_or_char *self) { String *func, *nname; int i = 0; Parm *p = parms; SwigType *pt; int comma = 0; if (!self) self = (char *) "(this)->"; func = NewString(""); nname = SwigType_namestr(name); if (!p) return func; Append(func,self); pt = Getattr(p,"type"); /* If the method is invoked through a dereferenced pointer, we don't add any casts (needed for smart pointers). Otherwise, we cast to the appropriate type */ if (Strstr(func,"*this")) { Replaceall(func,"this", Swig_cparm_name(p,0)); } else { Replaceall(func,"this", SwigType_rcaststr(pt, Swig_cparm_name(p,0))); } if (SwigType_istemplate(name)) { Printf(func,"template %s(", nname); } else { Printf(func,"%s(", nname); } i++; p = nextSibling(p); while (p) { String *pname; pt = Getattr(p,"type"); if ((SwigType_type(pt) != T_VOID)) { if (comma) Printf(func,","); pname = Swig_cparm_name(p,i); Printf(func,"%s", SwigType_rcaststr(pt, pname)); comma = 1; i++; } p = nextSibling(p); } Printf(func,")"); Delete(nname); return func; } /* ----------------------------------------------------------------------------- * Swig_cconstructor_call() * * Creates a string that calls a C constructor function. * * (name *) calloc(1,sizeof(name)); * ----------------------------------------------------------------------------- */ String * Swig_cconstructor_call(String_or_char *name) { DOH *func; func = NewString(""); Printf(func,"(%s *) calloc(1, sizeof(%s))", name, name); return func; } /* ----------------------------------------------------------------------------- * Swig_cppconstructor_call() * * Creates a string that calls a C function using the local variable rules * defined above. * * name(arg0, arg1, arg2, ... argn) * * ----------------------------------------------------------------------------- */ String * Swig_cppconstructor_base_call(String_or_char *name, ParmList *parms, int skip_self) { String *func; String *nname; int i = 0; int comma = 0; Parm *p = parms; SwigType *pt; if (skip_self) { if (p) p = nextSibling(p); i++; } nname = SwigType_namestr(name); func = NewString(""); Printf(func,"new %s(", nname); while (p) { String *pname; pt = Getattr(p,"type"); if ((SwigType_type(pt) != T_VOID)) { if (comma) Printf(func,","); if (!Getattr(p, "arg:byname")) { pname = Swig_cparm_name(p,i); i++; } else { if ((pname = Getattr(p, "value"))) pname = Copy(pname); else pname = Copy(Getattr(p, "name")); } Printf(func,"%s", SwigType_rcaststr(pt, pname)); comma = 1; } p = nextSibling(p); } Printf(func,")"); Delete(nname); return func; } String * Swig_cppconstructor_call(String_or_char *name, ParmList *parms) { return Swig_cppconstructor_base_call(name, parms, 0); } String * Swig_cppconstructor_nodirector_call(String_or_char *name, ParmList *parms) { return Swig_cppconstructor_base_call(name, parms, 1); } String * Swig_cppconstructor_director_call(String_or_char *name, ParmList *parms) { return Swig_cppconstructor_base_call(name, parms, 0); } /* ----------------------------------------------------------------------------- * Swig_cattr_search() * * This function search for the class attribute 'attr' in the class * 'n' or recursively in its bases. * * if you define SWIG_FAST_REC_SEARCH, the method will set the found * 'attr' in io the target class 'n'. If not, the method will set the * 'noattr' one. This prevents of having to navigate the entire * hierarchy tree everytime, so, it is an O(1) method... or something * like that. However, it populates all the parsed classes with the * 'attr' and/or 'noattr' attributes. * * If you undefine the SWIG_FAST_REC_SEARCH no attribute will be set * while searching. This could be slower for large projects with very * large hierarchy trees... or maybe not. But it will be cleaner. * * Maybe latter a swig option can be added to switch at runtime. * * ----------------------------------------------------------------------------- */ /* #define SWIG_FAST_REC_SEARCH 1 */ String * Swig_cattr_search(Node *n, const String *attr, const String *noattr) { String *f = 0; n = Swig_methodclass(n); if (Getattr(n, noattr)) { /* Printf(stdout,"noattr in %s\n", Getattr(n,"name")); */ return 0; } f = Getattr(n, attr); if (f) { /* Printf(stdout,"attr in %s\n", Getattr(n,"name")); */ return f; } else { List* bl = Getattr(n, "bases"); if (bl) { Iterator bi; for (bi = First(bl); bi.item; bi = Next(bi)) { f = Swig_cattr_search(bi.item, attr, noattr); if (f) { #ifdef SWIG_FAST_REC_SEARCH Setattr(n, attr, f); #endif return f; } } } } #ifdef SWIG_FAST_REC_SEARCH Setattr(n, noattr, "1"); #endif return 0; } /* ----------------------------------------------------------------------------- * Swig_unref_call() * * find the unref call, if any. * ----------------------------------------------------------------------------- */ String * Swig_unref_call(Node *n) { String* unref = 0; n = Swig_methodclass(n); if (!Getattr(n,"feature:nounref")) { unref = Getattr(n,"feature:unref"); unref = unref ? unref : Swig_cattr_search(n,"feature:unref","feature:nounref"); if (unref) { unref = NewStringf("%s",unref); Replaceall(unref,"$this",Swig_cparm_name(0,0)); } } return unref; } /* ----------------------------------------------------------------------------- * Swig_ref_call() * * find the ref call, if any. * ----------------------------------------------------------------------------- */ String * Swig_ref_call(Node *n, const String* lname) { String* ref = 0; n = Swig_methodclass(n); if (!Getattr(n,"feature:noref")) { ref = Getattr(n,"feature:ref"); ref = ref ? ref : Swig_cattr_search(n,"feature:ref","feature:noref"); if (ref) { ref = NewStringf("%s",ref); Replaceall(ref,"$this",lname); } } return ref; } /* ----------------------------------------------------------------------------- * Swig_cdestructor_call() * * Creates a string that calls a C constructor function. * * free((char *) arg0); * ----------------------------------------------------------------------------- */ String * Swig_cdestructor_call(Node *n) { String* unref = Swig_unref_call(n); if (unref) return unref; return NewStringf("free((char *) %s);",Swig_cparm_name(0,0)); } /* ----------------------------------------------------------------------------- * Swig_cppdestructor_call() * * Creates a string that calls a C constructor function. * * delete arg0; * ----------------------------------------------------------------------------- */ String * Swig_cppdestructor_call(Node *n) { String* unref = Swig_unref_call(n); if (unref) return unref; return NewStringf("delete %s;",Swig_cparm_name(0,0)); } /* ----------------------------------------------------------------------------- * Swig_cmemberset_call() * * Generates a string that sets the name of a member in a C++ class or C struct. * * arg0->name = arg1 * * ----------------------------------------------------------------------------- */ String * Swig_cmemberset_call(String_or_char *name, SwigType *type, String_or_char *self) { String *func; func = NewString(""); if (!self) self = NewString("(this)->"); else self = NewString(self); Replaceall(self,"this",Swig_cparm_name(0,0)); if (SwigType_type(type) != T_ARRAY) { Printf(func,"if (%s) %s%s = %s",Swig_cparm_name(0,0), self,name, Swig_wrapped_var_deref(type, Swig_cparm_name(0,1))); } Delete(self); return(func); } /* ----------------------------------------------------------------------------- * Swig_cmemberget_call() * * Generates a string that sets the name of a member in a C++ class or C struct. * * arg0->name * * ----------------------------------------------------------------------------- */ String * Swig_cmemberget_call(const String_or_char *name, SwigType *t, String_or_char *self) { String *func; if (!self) self = NewString("(this)->"); else self = NewString(self); Replaceall(self,"this",Swig_cparm_name(0,0)); func = NewString(""); Printf(func,"%s (%s%s)", Swig_wrapped_var_assign(t,""),self, name); Delete(self); return func; } /* ----------------------------------------------------------------------------- * Swig_MethodToFunction(Node *n) * * Converts a C++ method node to a function accessor function. * ----------------------------------------------------------------------------- */ int Swig_MethodToFunction(Node *n, String *classname, int flags) { String *name, *qualifier; ParmList *parms; SwigType *type; Parm *p; String *self = 0; /* If smart pointer, change self derefencing */ if (flags & CWRAP_SMART_POINTER) { self = NewString("(*this)->"); } /* If node is a member template expansion, we don't allow added code */ if (Getattr(n,"templatetype")) flags &= ~(CWRAP_EXTEND); name = Getattr(n,"name"); qualifier = Getattr(n,"qualifier"); parms = CopyParmList(nonvoid_parms(Getattr(n,"parms"))); type = NewString(classname); if (qualifier) { SwigType_push(type,qualifier); } SwigType_add_pointer(type); p = NewParm(type,"self"); Setattr(p,"hidden","1"); set_nextSibling(p,parms); Delete(type); /* Generate action code for the access */ if (!(flags & CWRAP_EXTEND)) { Setattr(n,"wrap:action", Swig_cresult(Getattr(n,"type"),"result", Swig_cmethod_call(name,p,self))); } else { String *code; String *mangled; String *membername = Swig_name_member(classname, name); mangled = Swig_name_mangle(membername); code = Getattr(n,"code"); type = Getattr(n,"type"); /* Check if the method is overloaded. If so, and it has code attached, we append an extra suffix to avoid a name-clash in the generated wrappers. This allows overloaded methods to be defined in C. */ if (Getattr(n,"sym:overloaded") && code) { Append(mangled,Getattr(n,"sym:overname")); } Setattr(n,"wrap:action", Swig_cresult(Getattr(n,"type"),"result", Swig_cfunction_call(mangled,p))); /* See if there is any code that we need to emit */ if (code) { String *body; String *tmp = NewStringf("%s(%s)", mangled, ParmList_str(p)); body = SwigType_str(type,tmp); Delete(tmp); Printv(body,code,"\n",NIL); Setattr(n,"wrap:code",body); } Delete(membername); Delete(mangled); } Setattr(n,"parms",p); Delete(p); Delete(self); return SWIG_OK; } /* ----------------------------------------------------------------------------- * Swig_methodclass() * * This function returns the class node for a given method or class. * ----------------------------------------------------------------------------- */ Node* Swig_methodclass(Node *n) { Node* type = Getattr(n, "nodeType"); if (!Cmp(type, "class")) return n; return Getattr(n, "parentNode"); } int Swig_directorbase(Node *n) { Node *classNode = Swig_methodclass(n); return (classNode && (Getattr(classNode, "directorBase") != 0)); } int Swig_directorclass(Node *n) { Node *classNode = Swig_methodclass(n); assert(classNode != 0); return (Getattr(classNode, "vtable") != 0); } int Swig_directormethod(Node *n) { Node *classNode = Swig_methodclass(n); if (classNode) { Node *vtable = Getattr(classNode, "vtable"); if (vtable) { String *name = Getattr(n, "name"); String *decl = Getattr(n, "decl"); String *local_decl = SwigType_typedef_resolve_all(decl); String *method_id = NewStringf("%s|%s", name, local_decl); Hash *item = Getattr(vtable, method_id); Delete(method_id); Delete(local_decl); if (item) { return (Getattr(item, "director") != 0); } } } return 0; } Node * Swig_directormap(Node *module, String *type) { int is_void = !Cmp(type, "void"); if (!is_void && module) { /* ?? follow the inheritance hierarchy? */ String* base = SwigType_base(type); Node *directormap = Getattr(module, "wrap:directormap"); if (directormap) return Getattr(directormap, base); } return 0; } /* ----------------------------------------------------------------------------- * Swig_ConstructorToFunction() * * This function creates a C wrapper for a C constructor function. * ----------------------------------------------------------------------------- */ int Swig_ConstructorToFunction(Node *n, String *classname, String *none_comparison, String *director_ctor, int cplus, int flags) { ParmList *parms; Parm *prefix_args; Parm *postfix_args; Parm *p; ParmList *directorparms; SwigType *type; String *membername; String *mangled; Node *classNode; int use_director; classNode = Swig_methodclass(n); use_director = Swig_directorclass(n); membername = Swig_name_construct(classname); mangled = Swig_name_mangle(membername); parms = CopyParmList(nonvoid_parms(Getattr(n,"parms"))); /* Prepend the list of prefix_args (if any) */ prefix_args = Getattr(n,"director:prefix_args"); if (prefix_args != NIL) { Parm *p2, *p3; directorparms = CopyParmList(prefix_args); for (p = directorparms; nextSibling(p); p = nextSibling(p)); for (p2 = parms; p2; p2 = nextSibling(p2)) { p3 = CopyParm(p2); set_nextSibling(p, p3); p = p3; } } else directorparms = parms; postfix_args = Getattr(n,"director:postfix_args"); if (postfix_args != NIL) { Parm *p2, *p3, *p4; if (prefix_args == NIL) /* no prefix args from above. */ directorparms = CopyParmList(parms); if (directorparms != NIL) { p2 = directorparms; for ( ; nextSibling(p2); p2 = nextSibling(p2)); for (p3 = postfix_args; p3; p3 = nextSibling(p3)) { p4 = CopyParm(p3); set_nextSibling(p2, p4); p2 = p4; } } else directorparms = CopyParmList(postfix_args); } type = NewString(classname); SwigType_add_pointer(type); if (flags & CWRAP_EXTEND) { String *code = Getattr(n,"code"); if (code) { String *wrap, *s; if (Getattr(n,"sym:overloaded") && code) { Append(mangled,Getattr(n,"sym:overname")); } s = NewStringf("%s(%s)", mangled, ParmList_str(parms)); wrap = SwigType_str(type,s); Delete(s); Printv(wrap,code,"\n",NIL); Setattr(n,"wrap:code",wrap); Delete(wrap); } Setattr(n,"wrap:action", Swig_cresult(type,"result", Swig_cfunction_call(mangled,parms))); } else { if (cplus) { /* if a C++ director class exists, create it rather than the original class */ if (use_director) { int abstract = Getattr(n, "abstract") != 0; Node *parent = Swig_methodclass(n); String *name = Getattr(parent, "sym:name"); String* directorname = NewStringf("SwigDirector_%s", name); String* action = NewString(""); String* tmp_none_comparison = Copy(none_comparison); String* director_call; String* nodirector_call; Replaceall( tmp_none_comparison, "$arg", "arg1" ); director_call = Swig_cppconstructor_director_call(directorname, directorparms); nodirector_call = Swig_cppconstructor_nodirector_call(classname, parms); if (abstract) { /* whether or not the abstract class has been subclassed in python, * create a director instance (there's no way to create a normal * instance). if any of the pure virtual methods haven't been * implemented in the target language, calls to those methods will * generate Swig::DirectorPureVirtualException exceptions. */ Printv(action, Swig_cresult(type, "result", director_call), NIL); } else { /* (scottm): The code for creating a new director is now a string template that gets passed in via the director_ctor argument. $comparison : an 'if' comparison from none_comparison $director_new: Call new for director class $nondirector_new: Call new for non-director class */ Printv(action, director_ctor, NIL); Replaceall( action, "$comparison", tmp_none_comparison); Replaceall( action, "$director_new", Swig_cresult(type, "result", director_call) ); Replaceall( action, "$nondirector_new", Swig_cresult(type, "result", nodirector_call) ); } Setattr(n, "wrap:action", action); Delete(tmp_none_comparison); Delete(action); Delete(directorname); } else { Setattr(n,"wrap:action", Swig_cresult(type,"result", Swig_cppconstructor_call(classname,parms))); } } else { Setattr(n,"wrap:action", Swig_cresult(type,"result", Swig_cconstructor_call(classname))); } } Setattr(n,"type",type); Setattr(n,"parms", parms); Delete(type); if (directorparms != parms) Delete(directorparms); Delete(parms); Delete(mangled); Delete(membername); return SWIG_OK; } /* ----------------------------------------------------------------------------- * Swig_DestructorToFunction() * * This function creates a C wrapper for a destructor function. * ----------------------------------------------------------------------------- */ int Swig_DestructorToFunction(Node *n, String *classname, int cplus, int flags) { SwigType *type; Parm *p; type = NewString(classname); SwigType_add_pointer(type); p = NewParm(type,"self"); Delete(type); type = NewString("void"); if (flags & CWRAP_EXTEND) { String *membername, *mangled, *code; membername = Swig_name_destroy(classname); mangled = Swig_name_mangle(membername); code = Getattr(n,"code"); if (code) { String *s = NewStringf("void %s(%s)", mangled, ParmList_str(p)); Printv(s,code,"\n",NIL); Setattr(n,"wrap:code",s); Delete(s); } Setattr(n,"wrap:action", NewStringf("%s;\n", Swig_cfunction_call(mangled,p))); Delete(membername); Delete(mangled); } else { if (cplus) { Setattr(n,"wrap:action", NewStringf("%s\n",Swig_cppdestructor_call(n))); } else { Setattr(n,"wrap:action", NewStringf("%s\n", Swig_cdestructor_call(n))); } } Setattr(n,"type",type); Setattr(n,"parms", p); Delete(type); Delete(p); return SWIG_OK; } /* ----------------------------------------------------------------------------- * Swig_MembersetToFunction() * * This function creates a C wrapper for setting a structure member. * ----------------------------------------------------------------------------- */ int Swig_MembersetToFunction(Node *n, String *classname, int flags) { String *name; ParmList *parms; Parm *p; SwigType *t; SwigType *ty; SwigType *type; String *membername; String *mangled; String *self= 0; if (flags & CWRAP_SMART_POINTER) { self = NewString("(*this)->"); } name = Getattr(n,"name"); type = Getattr(n,"type"); membername = Swig_name_member(classname, Swig_name_set(name)); mangled = Swig_name_mangle(membername); t = NewString(classname); SwigType_add_pointer(t); parms = NewParm(t,"self"); Delete(t); ty = Swig_wrapped_var_type(type); p = NewParm(ty,name); set_nextSibling(parms,p); /* If the type is a pointer or reference. We mark it with a special wrap:disown attribute */ if (SwigType_check_decl(type,"p.")) { Setattr(p,"wrap:disown","1"); } Delete(p); if (flags & CWRAP_EXTEND) { String *code = Getattr(n,"code"); if (code) { String *s = NewStringf("void %s(%s)", mangled, ParmList_str(parms)); Printv(s,code,"\n",NIL); Setattr(n,"wrap:code",s); Delete(s); } Setattr(n,"wrap:action", NewStringf("%s;\n", Swig_cfunction_call(mangled,parms))); } else { Setattr(n,"wrap:action", NewStringf("%s;\n", Swig_cmemberset_call(name,type,self))); } Setattr(n,"type","void"); Setattr(n,"parms", parms); Delete(parms); Delete(ty); Delete(membername); Delete(mangled); Delete(self); return SWIG_OK; } /* ----------------------------------------------------------------------------- * Swig_MembergetToFunction() * * This function creates a C wrapper for setting a structure member. * ----------------------------------------------------------------------------- */ int Swig_MembergetToFunction(Node *n, String *classname, int flags) { String *name; ParmList *parms; SwigType *t; SwigType *ty; SwigType *type; String *membername; String *mangled; String *self = 0; if (flags & CWRAP_SMART_POINTER) { self = NewString("(*this)->"); } name = Getattr(n,"name"); type = Getattr(n,"type"); membername = Swig_name_member(classname, Swig_name_get(name)); mangled = Swig_name_mangle(membername); t = NewString(classname); SwigType_add_pointer(t); parms = NewParm(t,"self"); Delete(t); ty = Swig_wrapped_var_type(type); if (flags & CWRAP_EXTEND) { String *code = Getattr(n,"code"); if (code) { String *tmp = NewStringf("%s(%s)", mangled, ParmList_str(parms)); String *s = SwigType_str(ty,tmp); Delete(tmp); Printv(s,code,"\n",NIL); Setattr(n,"wrap:code",s); Delete(s); } Setattr(n,"wrap:action", Swig_cresult(ty,"result",Swig_cfunction_call(mangled,parms))); } else { Setattr(n,"wrap:action", Swig_cresult(ty,"result",Swig_cmemberget_call(name,type,self))); } Setattr(n,"type",ty); Setattr(n,"parms", parms); Delete(parms); Delete(ty); Delete(membername); Delete(mangled); return SWIG_OK; } /* ----------------------------------------------------------------------------- * Swig_VarsetToFunction() * * This function creates a C wrapper for setting a global variable. * ----------------------------------------------------------------------------- */ int Swig_VarsetToFunction(Node *n) { String *name,*nname; ParmList *parms; SwigType *type, *ty; name = Getattr(n,"name"); type = Getattr(n,"type"); nname = SwigType_namestr(name); ty = Swig_wrapped_var_type(type); parms = NewParm(ty,"value"); Delete(ty); Setattr(n,"wrap:action", NewStringf("%s = %s;\n", nname, Swig_wrapped_var_deref(type,Swig_cparm_name(0,0)))); Setattr(n,"type","void"); Setattr(n,"parms",parms); Delete(parms); Delete(nname); return SWIG_OK; } /* ----------------------------------------------------------------------------- * Swig_VargetToFunction() * * This function creates a C wrapper for getting a global variable. * ----------------------------------------------------------------------------- */ int Swig_VargetToFunction(Node *n) { String *name, *nname; SwigType *type, *ty; name = Getattr(n,"name"); type = Getattr(n,"type"); nname = SwigType_namestr(name); ty = Swig_wrapped_var_type(type); Setattr(n,"wrap:action", Swig_cresult(ty,"result",Swig_wrapped_var_assign(type,nname))); Setattr(n,"type",ty); Delattr(n,"parms"); Delete(nname); Delete(ty); return SWIG_OK; } cableswig-0.1.0+git20150808.orig/SWIG/Source/Swig/warn.c0000644000175000000620000000222212561312227021060 0ustar stevestaff/* ----------------------------------------------------------------------------- * warn.c * * SWIG warning framework. This was added to warn developers about * deprecated APIs and other features. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2001. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_warn_c[] = "/cvsroot/SWIG/Source/Swig/warn.c,v 1.3 2002/11/30 22:10:17 beazley Exp"; #include "swig.h" static Hash *warnings = 0; /* ----------------------------------------------------------------------------- * Swig_warn() * * Issue a warning * ----------------------------------------------------------------------------- */ void Swig_warn(const char *filename, int line, const char *msg) { String *key; if (!warnings) { warnings = NewHash(); } key = NewStringf("%s:%d", filename,line); if (!Getattr(warnings,key)) { Printf(stderr,"swig-dev warning:%s:%d:%s\n", filename, line, msg); Setattr(warnings,key,key); } Delete(key); } cableswig-0.1.0+git20150808.orig/SWIG/Source/Swig/typemap.c0000644000175000000620000012167212561312227021603 0ustar stevestaff/* ----------------------------------------------------------------------------- * typemap.c * * A somewhat generalized implementation of SWIG1.1 typemaps. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_typemap_c[] = "/cvsroot/SWIG/Source/Swig/typemap.c,v 1.29 2004/02/10 09:21:36 mmatus Exp"; #include "swig.h" #include "cparse.h" #include static void replace_embedded_typemap(String *s); /* ----------------------------------------------------------------------------- * Typemaps are stored in a collection of nested hash tables. Something like * this: * * [ type ] * +-------- [ name ] * +-------- [ name ] * * Each hash table [ type ] or [ name ] then contains references to the * different typemap methods. These are referenced by names such as * "tmap:in", "tmap:out", "tmap:argout", and so forth. * * The object corresponding to a specific method has the following * attributes: * * "type" - Typemap type * "pname" - Parameter name * "code" - Typemap code * "typemap" - Descriptive text describing the actual map * "locals" - Local variables (if any) * * ----------------------------------------------------------------------------- */ #define MAX_SCOPE 32 static Hash *typemaps[MAX_SCOPE]; static int tm_scope = 0; /* ----------------------------------------------------------------------------- * Swig_typemap_init() * * Initialize the typemap system * ----------------------------------------------------------------------------- */ void Swig_typemap_init() { int i; for (i = 0; i < MAX_SCOPE; i++) { typemaps[i] = 0; } typemaps[0] = NewHash(); tm_scope = 0; } static String *tmop_name(const String_or_char *op) { static Hash *names = 0; String *s; /* Due to "interesting" object-identity semantics of DOH, we have to make sure that we only intern strings without object identity into the hash table. (Swig_typemap_attach_kwargs calls tmop_name several times with the "same" String *op (i.e., same object identity) but differing string values.) Most other callers work around this by using char* rather than String *. -- mkoeppe, Jun 17, 2003 */ const char *op_without_object_identity = Char(op); if (!names) names = NewHash(); s = Getattr(names, op_without_object_identity); if (s) return s; s = NewStringf("tmap:%s",op); Setattr(names,op_without_object_identity,s); return s; } /* ----------------------------------------------------------------------------- * Swig_typemap_new_scope() * * Create a new typemap scope * ----------------------------------------------------------------------------- */ void Swig_typemap_new_scope() { tm_scope++; typemaps[tm_scope] = NewHash(); } /* ----------------------------------------------------------------------------- * Swig_typemap_pop_scope() * * Pop the last typemap scope off * ----------------------------------------------------------------------------- */ Hash * Swig_typemap_pop_scope() { if (tm_scope > 0) { return typemaps[tm_scope--]; } return 0; } /* ----------------------------------------------------------------------------- * Swig_typemap_register() * * Add a new multi-valued typemap * ----------------------------------------------------------------------------- */ void Swig_typemap_register(const String_or_char *op, ParmList *parms, String_or_char *code, ParmList *locals, ParmList *kwargs) { Hash *tm; Hash *tm1; Hash *tm2; Parm *np; String *tmop; SwigType *type; String *pname; if (!parms) return; tmop = tmop_name(op); /* Register the first type in the parameter list */ type = Getattr(parms,"type"); pname = Getattr(parms,"name"); /* See if this type has been seen before */ tm = Getattr(typemaps[tm_scope],type); if (!tm) { tm = NewHash(); Setattr(typemaps[tm_scope],Copy(type),tm); Delete(tm); } if (pname) { /* See if parameter has been seen before */ tm1 = Getattr(tm,pname); if (!tm1) { tm1 = NewHash(); Setattr(tm,NewString(pname),tm1); Delete(tm1); } tm = tm1; } /* Now see if this typemap op has been seen before */ tm2 = Getattr(tm,tmop); if (!tm2) { tm2 = NewHash(); Setattr(tm,tmop,tm2); Delete(tm2); } /* For a multi-valued typemap, the typemap code and information is really only stored in the last argument. However, to make this work, we perform a really neat trick using the typemap operator name. For example, consider this typemap %typemap(in) (int foo, int *bar, char *blah[]) { ... } To store it, we look at typemaps for the following: operator type-name ---------------------------------------------- "in" int foo "in-int+foo:" int *bar "in-int+foo:-p.int+bar: char *blah[] Notice how the operator expands to encode information about previous arguments. */ np = nextSibling(parms); if (np) { /* Make an entirely new operator key */ String *newop = NewStringf("%s-%s+%s:",op,type,pname); /* Now reregister on the remaining arguments */ Swig_typemap_register(newop,np,code,locals,kwargs); /* Setattr(tm2,newop,newop); */ Delete(newop); } else { Setattr(tm2,"code",NewString(code)); Setattr(tm2,"type",Copy(type)); Setattr(tm2,"typemap",NewStringf("typemap(%s) %s", op, SwigType_str(type,pname))); if (pname) { Setattr(tm2,"pname", NewString(pname)); } Setattr(tm2,"locals", CopyParmList(locals)); Setattr(tm2,"kwargs", CopyParmList(kwargs)); } } /* ----------------------------------------------------------------------------- * Swig_typemap_get() * * Retrieve typemap information from current scope. * ----------------------------------------------------------------------------- */ static Hash * Swig_typemap_get(SwigType *type, String_or_char *name, int scope) { Hash *tm, *tm1; /* See if this type has been seen before */ if ((scope < 0) || (scope > tm_scope)) return 0; tm = Getattr(typemaps[scope],type); if (!tm) { return 0; } if ((name) && Len(name)) { tm1 = Getattr(tm, name); return tm1; } return tm; } /* ----------------------------------------------------------------------------- * Swig_typemap_copy() * * Copy a typemap * ----------------------------------------------------------------------------- */ int Swig_typemap_copy(const String_or_char *op, ParmList *srcparms, ParmList *parms) { Hash *tm = 0; String *tmop; Parm *p; String *pname; SwigType *ptype; int ts = tm_scope; String *tmops, *newop; if (ParmList_len(parms) != ParmList_len(srcparms)) return -1; tmop = tmop_name(op); while (ts >= 0) { p = srcparms; tmops = NewString(tmop); while (p) { ptype = Getattr(p,"type"); pname = Getattr(p,"name"); /* Lookup the type */ tm = Swig_typemap_get(ptype,pname,ts); if (!tm) break; tm = Getattr(tm,tmops); if (!tm) break; /* Got a match. Look for next typemap */ newop = NewStringf("%s-%s+%s:",tmops,ptype,pname); Delete(tmops); tmops = newop; p = nextSibling(p); } Delete(tmops); if (!p && tm) { /* Got some kind of match */ Swig_typemap_register(op,parms, Getattr(tm,"code"), Getattr(tm,"locals"),Getattr(tm,"kwargs")); return 0; } ts--; } /* Not found */ return -1; } /* ----------------------------------------------------------------------------- * Swig_typemap_clear() * * Delete a multi-valued typemap * ----------------------------------------------------------------------------- */ void Swig_typemap_clear(const String_or_char *op, ParmList *parms) { SwigType *type; String *name; Parm *p; String *newop; Hash *tm = 0; /* This might not work */ newop = NewString(op); p = parms; while (p) { type = Getattr(p,"type"); name = Getattr(p,"name"); tm = Swig_typemap_get(type,name,tm_scope); if (!tm) return; p = nextSibling(p); if (p) Printf(newop,"-%s+%s:", type,name); } if (tm) { tm = Getattr(tm, tmop_name(newop)); if (tm) { Delattr(tm,"code"); Delattr(tm,"locals"); Delattr(tm,"kwargs"); } } Delete(newop); } /* ----------------------------------------------------------------------------- * Swig_typemap_apply() * * Multi-argument %apply directive. This is pretty horrible so I sure hope * it works. * ----------------------------------------------------------------------------- */ static int count_args(String *s) { /* Count up number of arguments */ int na = 0; char *c = Char(s); while (*c) { if (*c == '+') na++; c++; } return na; } int Swig_typemap_apply(ParmList *src, ParmList *dest) { String *ssig, *dsig; Parm *p, *np, *lastp, *dp, *lastdp = 0; int narg = 0; int ts = tm_scope; SwigType *type = 0, *name; Hash *tm, *sm; int match = 0; /* Printf(stdout,"apply : %s --> %s\n", ParmList_str(src), ParmList_str(dest)); */ /* Create type signature of source */ ssig = NewString(""); dsig = NewString(""); p = src; dp = dest; lastp = 0; while (p) { lastp = p; lastdp = dp; np = nextSibling(p); if (np) { Printf(ssig,"-%s+%s:", Getattr(p,"type"), Getattr(p,"name")); Printf(dsig,"-%s+%s:", Getattr(dp,"type"), Getattr(dp,"name")); narg++; } p = np; dp = nextSibling(dp); } /* make sure a typemap node exists for the last destination node */ tm = Getattr(typemaps[tm_scope],Getattr(lastdp,"type")); if (!tm) { tm = NewHash(); Setattr(typemaps[tm_scope],Getattr(lastdp,"type"),tm); Delete(tm); } name = Getattr(lastdp,"name"); if (name) { Hash *tm1 = Getattr(tm,name); if (!tm1) { tm1 = NewHash(); Setattr(tm,NewString(name),tm1); Delete(tm1); } tm = tm1; } /* This is a little nasty. We need to go searching for all possible typemaps in the source and apply them to the target */ type = Getattr(lastp,"type"); name = Getattr(lastp,"name"); while (ts >= 0) { /* See if there is a matching typemap in this scope */ sm = Swig_typemap_get(type,name,ts); if (sm) { /* Got a typemap. Need to only merge attributes for methods that match our signature */ Iterator ki; match = 1; for (ki = First(sm); ki.key; ki = Next(ki)) { /* Check for a signature match with the source signature */ if ((count_args(ki.key) == narg) && (Strstr(ki.key,ssig))) { String *oldm; /* A typemap we have to copy */ String *nkey = Copy(ki.key); Replace(nkey,ssig,dsig,DOH_REPLACE_ANY); /* Make sure the typemap doesn't already exist in the target map */ oldm = Getattr(tm,nkey); if (!oldm || (!Getattr(tm,"code"))) { String *code; ParmList *locals; ParmList *kwargs; Hash *sm1 = ki.item; code = Getattr(sm1,"code"); locals = Getattr(sm1,"locals"); kwargs = Getattr(sm1,"kwargs"); if (code) { Replace(nkey,dsig,"", DOH_REPLACE_ANY); Replace(nkey,"tmap:","", DOH_REPLACE_ANY); Swig_typemap_register(nkey,dest,code,locals,kwargs); } } Delete(nkey); } } } ts--; } return match; } /* ----------------------------------------------------------------------------- * Swig_typemap_clear_apply() * * %clear directive. Clears all typemaps for a type (in the current scope only). * ----------------------------------------------------------------------------- */ /* Multi-argument %clear directive */ void Swig_typemap_clear_apply(Parm *parms) { String *tsig; Parm *p, *np, *lastp; int narg = 0; Hash *tm; String *name; /* Create a type signature of the parameters */ tsig = NewString(""); p = parms; lastp = 0; while (p) { lastp = p; np = nextSibling(p); if (np) { Printf(tsig,"-%s+%s:", Getattr(p,"type"), Getattr(p,"name")); narg++; } p = np; } tm = Getattr(typemaps[tm_scope],Getattr(lastp,"type")); if (!tm) { Delete(tsig); return; } name = Getattr(lastp,"name"); if (name) { tm = Getattr(tm,name); } if (tm) { /* Clear typemaps that match our signature */ Iterator ki, ki2; for (ki = First(tm); ki.key; ki = Next(ki)) { if (Strncmp(ki.key,"tmap:",5) == 0) { int na = count_args(ki.key); if ((na == narg) && Strstr(ki.key,tsig)) { Hash *h = ki.item; for (ki2 = First(h); ki2.key; ki2 = Next(ki2)) { Delattr(h,ki2.key); } } } } } Delete(tsig); } /* Internal function to strip array dimensions. */ static SwigType *strip_arrays(SwigType *type) { SwigType *t; int ndim; int i; t = Copy(type); ndim = SwigType_array_ndim(t); for (i = 0; i < ndim; i++) { SwigType_array_setdim(t,i,"ANY"); } return t; } /* ----------------------------------------------------------------------------- * Swig_typemap_search() * * Search for a typemap match. Tries to find the most specific typemap * that includes a 'code' attribute. * ----------------------------------------------------------------------------- */ Hash * Swig_typemap_search(const String_or_char *op, SwigType *type, String_or_char *name, SwigType **matchtype) { Hash *result = 0, *tm, *tm1, *tma; Hash *backup = 0; SwigType *noarrays = 0; SwigType *primitive = 0; SwigType *ctype = 0; int ts; int isarray; String *cname = 0; SwigType *unstripped = 0; String *tmop = tmop_name(op); if ((name) && Len(name)) cname = name; ts = tm_scope; while (ts >= 0) { ctype = type; while (ctype) { /* Try to get an exact type-match */ tm = Getattr(typemaps[ts],ctype); if (tm && cname) { tm1 = Getattr(tm,cname); if (tm1) { result = Getattr(tm1,tmop); /* See if there is a type-name match */ if (result && Getattr(result,"code")) goto ret_result; if (result) backup = result; } } if (tm) { result = Getattr(tm,tmop); /* See if there is simply a type match */ if (result && Getattr(result,"code")) goto ret_result; if (result) backup = result; } isarray = SwigType_isarray(ctype); if (isarray) { /* If working with arrays, strip away all of the dimensions and replace with "ANY". See if that generates a match */ if (!noarrays) { noarrays = strip_arrays(ctype); } tma = Getattr(typemaps[ts],noarrays); if (tma && cname) { tm1 = Getattr(tma,cname); if (tm1) { result = Getattr(tm1,tmop); /* type-name match */ if (result && Getattr(result,"code")) goto ret_result; if (result) backup = result; } } if (tma) { result = Getattr(tma,tmop); /* type match */ if (result && Getattr(result,"code")) goto ret_result; if (result) backup = result; } Delete(noarrays); noarrays = 0; } /* 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 (Strcmp(ctype,unstripped) != 0) continue; /* Types are different */ Delete(ctype); ctype = unstripped; unstripped = 0; } { String *octype; if (unstripped) { Delete(ctype); ctype = unstripped; unstripped = 0; } octype = ctype; ctype = SwigType_typedef_resolve(ctype); if (octype != type) Delete(octype); } } /* Hmmm. Well, no match seems to be found at all. See if there is some kind of default mapping */ primitive = SwigType_default(type); while (primitive) { tm = Getattr(typemaps[ts],primitive); if (tm && cname) { tm1 = Getattr(tm,cname); if (tm1) { result = Getattr(tm1,tmop); /* See if there is a type-name match */ if (result) goto ret_result; } } if (tm) { /* See if there is simply a type match */ result = Getattr(tm,tmop); if (result) goto ret_result; } { SwigType *nprim = SwigType_default(primitive); Delete(primitive); primitive = nprim; } } if (ctype != type) { Delete(ctype); ctype = 0; } ts--; /* Hmmm. Nothing found in this scope. Guess we'll go try another scope */ } result = backup; ret_result: if (noarrays) Delete(noarrays); if (primitive) Delete(primitive); if ((unstripped) && (unstripped != type)) Delete(unstripped); if (matchtype) { *matchtype = Copy(ctype); } if (type != ctype) Delete(ctype); return result; } /* ----------------------------------------------------------------------------- * Swig_typemap_search_multi() * * Search for a multi-valued typemap. * ----------------------------------------------------------------------------- */ Hash * Swig_typemap_search_multi(const String_or_char *op, ParmList *parms, int *nmatch) { SwigType *type; SwigType *mtype = 0; String *name; String *newop; Hash *tm, *tm1; if (!parms) { *nmatch = 0; return 0; } type = Getattr(parms,"type"); name = Getattr(parms,"name"); /* Try to find a match on the first type */ tm = Swig_typemap_search(op, type, name, &mtype); if (tm) { if (mtype && SwigType_isarray(mtype)) { Setattr(parms,"tmap:match", mtype); } Delete(mtype); newop = NewStringf("%s-%s+%s:", op, type,name); tm1 = Swig_typemap_search_multi(newop, nextSibling(parms), nmatch); if (tm1) tm = tm1; if (Getattr(tm,"code")) { *(nmatch) = *nmatch + 1; } else { tm = 0; } Delete(newop); } return tm; } /* ----------------------------------------------------------------------------- * typemap_replace_vars() * * Replaces typemap variables on a string. index is the $n variable. * type and pname are the type and parameter name. * ----------------------------------------------------------------------------- */ static void replace_local_types(ParmList *p, const String *name, const String *rep) { SwigType *t; while (p) { t = Getattr(p,"type"); Replace(t,name,rep,DOH_REPLACE_ANY); p = nextSibling(p); } } static int check_locals(ParmList *p, const char *s) { while (p) { char *c = GetChar(p,"type"); if (strstr(c,s)) return 1; p = nextSibling(p); } return 0; } static void typemap_replace_vars(String *s, ParmList *locals, SwigType *type, String *pname, String *lname, int index) { char var[512]; char *varname; SwigType *ftype; Replaceall(s,"$typemap","$TYPEMAP"); ftype = SwigType_typedef_resolve_all(type); if (!pname) pname = lname; { Parm *p; int rep = 0; p = locals; while (p) { if (Strchr(Getattr(p,"type"),'$')) rep = 1; p = nextSibling(p); } if (!rep) locals = 0; } sprintf(var,"$%d_",index); varname = &var[strlen(var)]; /* If the original datatype was an array. We're going to go through and substitute its array dimensions */ if (SwigType_isarray(type)) { String *size; int ndim = SwigType_array_ndim(type); int i; size = NewString(""); for (i = 0; i < ndim; i++) { String *dim = SwigType_array_getdim(type,i); if (index == 1) { char t[32]; sprintf(t,"$dim%d",i); Replace(s,t,dim,DOH_REPLACE_ANY); replace_local_types(locals,t,dim); } sprintf(varname,"dim%d",i); Replace(s,var,dim,DOH_REPLACE_ANY); replace_local_types(locals,var,dim); if (Len(size)) Putc('*',size); Append(size,dim); Delete(dim); } sprintf(varname,"size"); Replace(s,var,size,DOH_REPLACE_ANY); replace_local_types(locals,var,size); Delete(size); } /* Parameter name substitution */ if (index == 1) { Replace(s,"$parmname",pname, DOH_REPLACE_ANY); } strcpy(varname,"name"); Replace(s,var,pname,DOH_REPLACE_ANY); /* Type-related stuff */ { SwigType *star_type, *amp_type, *base_type; SwigType *ltype, *star_ltype, *amp_ltype; String *mangle, *star_mangle, *amp_mangle, *base_mangle, *base_name; String *descriptor, *star_descriptor, *amp_descriptor; String *ts; char *sc; sc = Char(s); if (strstr(sc,"type") || check_locals(locals,"type")) { /* Given type : $type */ ts = SwigType_str(type,0); if (index == 1) { Replace(s, "$type", ts, DOH_REPLACE_ANY); replace_local_types(locals,"$type",type); } strcpy(varname,"type"); Replace(s,var,ts,DOH_REPLACE_ANY); replace_local_types(locals,var,type); Delete(ts); sc = Char(s); } if (strstr(sc,"ltype") || check_locals(locals,"ltype")) { /* Local type: $ltype */ ltype = SwigType_ltype(type); ts = SwigType_str(ltype,0); if (index == 1) { Replace(s, "$ltype", ts, DOH_REPLACE_ANY); replace_local_types(locals,"$ltype",ltype); } strcpy(varname,"ltype"); Replace(s,var,ts,DOH_REPLACE_ANY); replace_local_types(locals,var,ltype); Delete(ts); Delete(ltype); sc = Char(s); } if (strstr(sc,"mangle") || strstr(sc,"descriptor")) { /* Mangled type */ mangle = SwigType_manglestr(type); if (index == 1) Replace(s, "$mangle", mangle, DOH_REPLACE_ANY); strcpy(varname,"mangle"); Replace(s,var,mangle,DOH_REPLACE_ANY); descriptor = NewStringf("SWIGTYPE%s", mangle); if (index == 1) if (Replace(s, "$descriptor", descriptor, DOH_REPLACE_ANY)) SwigType_remember(type); strcpy(varname,"descriptor"); if (Replace(s,var,descriptor,DOH_REPLACE_ANY)) SwigType_remember(type); Delete(descriptor); Delete(mangle); } /* One pointer level removed */ /* This creates variables of the form $*n_type $*n_ltype */ if (SwigType_ispointer(ftype) || (SwigType_isarray(ftype)) || (SwigType_isreference(ftype))) { if (!(SwigType_isarray(type) || SwigType_ispointer(type) || SwigType_isreference(type))) { star_type = Copy(ftype); } else { star_type = Copy(type); } if (!SwigType_isreference(star_type)) { if (SwigType_isarray(star_type)) { SwigType_del_element(star_type); } else { SwigType_del_pointer(star_type); } ts = SwigType_str(star_type,0); if (index == 1) { Replace(s, "$*type", ts, DOH_REPLACE_ANY); replace_local_types(locals,"$*type",star_type); } sprintf(varname,"$*%d_type",index); Replace(s,varname,ts,DOH_REPLACE_ANY); replace_local_types(locals,varname,star_type); Delete(ts); } else { SwigType_del_element(star_type); } star_ltype = SwigType_ltype(star_type); ts = SwigType_str(star_ltype,0); if (index == 1) { Replace(s, "$*ltype", ts, DOH_REPLACE_ANY); replace_local_types(locals,"$*ltype",star_ltype); } sprintf(varname,"$*%d_ltype",index); Replace(s,varname,ts,DOH_REPLACE_ANY); replace_local_types(locals,varname,star_ltype); Delete(ts); Delete(star_ltype); star_mangle = SwigType_manglestr(star_type); if (index == 1) Replace(s, "$*mangle", star_mangle, DOH_REPLACE_ANY); sprintf(varname,"$*%d_mangle",index); Replace(s,varname,star_mangle,DOH_REPLACE_ANY); star_descriptor = NewStringf("SWIGTYPE%s", star_mangle); if (index == 1) if (Replace(s, "$*descriptor", star_descriptor, DOH_REPLACE_ANY)) SwigType_remember(star_type); sprintf(varname,"$*%d_descriptor",index); if (Replace(s,varname,star_descriptor,DOH_REPLACE_ANY)) SwigType_remember(star_type); Delete(star_descriptor); Delete(star_mangle); Delete(star_type); } else { /* TODO: Signal error if one of the $* substitutions is requested */ } /* One pointer level added */ amp_type = Copy(type); SwigType_add_pointer(amp_type); ts = SwigType_str(amp_type,0); if (index == 1) { Replace(s, "$&type", ts, DOH_REPLACE_ANY); replace_local_types(locals,"$&type",amp_type); } sprintf(varname,"$&%d_type",index); Replace(s,varname,ts,DOH_REPLACE_ANY); replace_local_types(locals,varname,amp_type); Delete(ts); amp_ltype = SwigType_ltype(type); SwigType_add_pointer(amp_ltype); ts = SwigType_str(amp_ltype,0); if (index == 1) { Replace(s, "$<ype", ts, DOH_REPLACE_ANY); replace_local_types(locals, "$<ype", amp_ltype); } sprintf(varname,"$&%d_ltype",index); Replace(s,varname,ts,DOH_REPLACE_ANY); replace_local_types(locals,varname,amp_ltype); Delete(ts); Delete(amp_ltype); amp_mangle = SwigType_manglestr(amp_type); if (index == 1) Replace(s, "$&mangle", amp_mangle, DOH_REPLACE_ANY); sprintf(varname,"$&%d_mangle",index); Replace(s,varname,amp_mangle,DOH_REPLACE_ANY); amp_descriptor = NewStringf("SWIGTYPE%s", amp_mangle); if (index == 1) if (Replace(s, "$&descriptor", amp_descriptor, DOH_REPLACE_ANY)) SwigType_remember(amp_type); sprintf(varname,"$&%d_descriptor",index); if (Replace(s,varname,amp_descriptor,DOH_REPLACE_ANY)) SwigType_remember(amp_type); Delete(amp_descriptor); Delete(amp_mangle); Delete(amp_type); /* Base type */ if (SwigType_isarray(type)) { SwigType *bt = Copy(type); Delete(SwigType_pop_arrays(bt)); base_type = SwigType_str(bt,0); Delete(bt); } else { base_type = SwigType_base(type); } base_name = SwigType_namestr(base_type); if (index == 1) { Replace(s,"$basetype", base_name, DOH_REPLACE_ANY); replace_local_types(locals,"$basetype", base_name); } strcpy(varname,"basetype"); Replace(s,var,base_type,DOH_REPLACE_ANY); replace_local_types(locals,var,base_name); base_mangle = SwigType_manglestr(base_type); if (index == 1) Replace(s,"$basemangle", base_mangle, DOH_REPLACE_ANY); strcpy(varname,"basemangle"); Replace(s,var,base_mangle,DOH_REPLACE_ANY); Delete(base_mangle); Delete(base_type); Delete(base_name); } /* Replace any $n. with (&n)-> */ { char temp[64]; sprintf(var,"$%d.",index); sprintf(temp,"(&$%d)->", index); Replace(s,var,temp,DOH_REPLACE_ANY); } /* Replace the bare $n variable */ sprintf(var,"$%d",index); Replace(s,var,lname,DOH_REPLACE_ANY); Delete(ftype); } /* ------------------------------------------------------------------------ * static typemap_locals() * * Takes a string, a parameter list and a wrapper function argument and * creates the local variables. * ------------------------------------------------------------------------ */ static void typemap_locals(DOHString *s, ParmList *l, Wrapper *f, int argnum) { Parm *p; char *new_name; p = l; while (p) { SwigType *pt = Getattr(p,"type"); String *pn = Getattr(p,"name"); String *value = Getattr(p,"value"); if (pn) { if (Len(pn) > 0) { String *str; int isglobal = 0; str = NewString(""); if (Strncmp(pn,"_global_",8) == 0) { isglobal = 1; } /* If the user gave us $type as the name of the local variable, we'll use the passed datatype instead */ if ((argnum >= 0) && (!isglobal)) { Printf(str,"%s%d",pn,argnum); } else { Printf(str,"%s",pn); } if (isglobal && Wrapper_check_local(f,str)) { p = nextSibling(p); continue; } if (value) { new_name = Wrapper_new_localv(f,str, SwigType_str(pt,str), "=", value, NIL); } else { new_name = Wrapper_new_localv(f,str, SwigType_str(pt,str), NIL); } if (!isglobal) { /* Substitute */ Replace(s,pn,new_name,DOH_REPLACE_ID | DOH_REPLACE_NOQUOTE); } } } p = nextSibling(p); } } /* ----------------------------------------------------------------------------- * Swig_typemap_lookup() * * Perform a typemap lookup (ala SWIG1.1) * ----------------------------------------------------------------------------- */ String *Swig_typemap_lookup(const String_or_char *op, SwigType *type, String_or_char *pname, String_or_char *lname, String_or_char *source, String_or_char *target, Wrapper *f) { Hash *tm; String *s = 0; SwigType *mtype = 0; ParmList *locals; tm = Swig_typemap_search(op,type,pname,&mtype); if (!tm) return 0; s = Getattr(tm,"code"); if (!s) return 0; /* Blocked */ if (Cmp(s,"pass") == 0) return 0; s = Copy(s); /* Make a local copy of the typemap code */ locals = Getattr(tm,"locals"); if (locals) locals = CopyParmList(locals); /* This is wrong. It replaces locals in place. Need to fix this */ if (mtype && SwigType_isarray(mtype)) { typemap_replace_vars(s,locals,mtype,pname,lname,1); } else { typemap_replace_vars(s,locals,type,pname,lname,1); } if (locals && f) { typemap_locals(s,locals,f,-1); } replace_embedded_typemap(s); /* Now perform character replacements */ Replace(s,"$source",source,DOH_REPLACE_ANY); Replace(s,"$target",target,DOH_REPLACE_ANY); /* { String *tmname = Getattr(tm,"typemap"); if (tmname) Replace(s,"$typemap",tmname, DOH_REPLACE_ANY); } */ Replace(s,"$parmname",pname, DOH_REPLACE_ANY); /* Replace(s,"$name",pname,DOH_REPLACE_ANY); */ Delete(locals); Delete(mtype); return s; } /* ----------------------------------------------------------------------------- * Swig_typemap_lookup_new() * * Attach one or more typemaps to a node * ----------------------------------------------------------------------------- */ String *Swig_typemap_lookup_new(const String_or_char *op, Node *node, const String_or_char *lname, Wrapper *f) { SwigType *type; SwigType *mtype = 0; String *pname; Hash *tm; String *s = 0; String *sdef = 0; ParmList *locals; ParmList *kw; char temp[256]; String *symname; String *cname = 0; String *clname = 0; /* special case, we need to check for 'ref' call and set the defaul code 'sdef' */ if (Cmp(op,"newfree") == 0) { sdef = Swig_ref_call(node, lname); } type = Getattr(node,"type"); if (!type) return sdef; pname = Getattr(node,"name"); tm = Swig_typemap_search(op,type,pname,&mtype); if (!tm) return sdef; s = Getattr(tm,"code"); if (!s) return sdef; /* Empty typemap. No match */ if (Cmp(s,"pass") == 0) return sdef; s = Copy(s); /* Make a local copy of the typemap code */ locals = Getattr(tm,"locals"); if (locals) locals = CopyParmList(locals); if (pname) { if (SwigType_istemplate(pname)) { cname = SwigType_namestr(pname); pname = cname; } } if (SwigType_istemplate((char*)lname)) { clname = SwigType_namestr((char *)lname); lname = clname; } if (mtype && SwigType_isarray(mtype)) { typemap_replace_vars(s,locals,mtype,pname,(char *) lname,1); } else { typemap_replace_vars(s,locals,type,pname,(char *) lname,1); } if (locals && f) { typemap_locals(s,locals,f,-1); } replace_embedded_typemap(s); /* { String *tmname = Getattr(tm,"typemap"); if (tmname) Replace(s,"$typemap",tmname, DOH_REPLACE_ANY); }*/ Replace(s,"$name",pname,DOH_REPLACE_ANY); symname = Getattr(node,"sym:name"); if (symname) { Replace(s,"$symname",symname, DOH_REPLACE_ANY); } Setattr(node,tmop_name(op),s); if (locals) { sprintf(temp,"%s:locals", Char(op)); Setattr(node,tmop_name(temp), locals); Delete(locals); } if (checkAttribute(tm,"type","SWIGTYPE")) { sprintf(temp,"%s:SWIGTYPE", Char(op)); Setattr(node,tmop_name(temp),"1"); } /* Attach kwargs */ kw = Getattr(tm,"kwargs"); while (kw) { sprintf(temp,"%s:%s",Char(op),Char(Getattr(kw,"name"))); Setattr(node,tmop_name(temp), Copy(Getattr(kw,"value"))); kw = nextSibling(kw); } /* Look for warnings */ { String *w; sprintf(temp,"%s:warning", Char(op)); w = Getattr(node,tmop_name(temp)); if (w) { Swig_warning(0,Getfile(node),Getline(node),"%s\n", w); } } /* Look for code fragments */ { String *f; sprintf(temp,"%s:fragment", Char(op)); f = Getattr(node,tmop_name(temp)); if (f) { char *c, *tok; String *t = Copy(f); c = Char(t); tok = strtok(c,","); while (tok) { Swig_fragment_emit(tok); tok = strtok(NULL,","); } Delete(t); } } if (cname) Delete(cname); if (clname) Delete(clname); if (mtype) Delete(mtype); if (sdef) { /* put 'ref' and 'newfree' codes together */ String *p = NewStringf("%s\n%s", sdef, s); Delete(s); Delete(sdef); s = p; } return s; } /* ----------------------------------------------------------------------------- * Swig_typemap_attach_kwargs() * * If this hash (tm) contains a linked list of parameters under its "kwargs" * attribute, add keys for each of those named keyword arguments to this * parameter for later use. * For example, attach the typemap attributes to p: * %typemap(in, foo="xyz") ... * A new attribute called "tmap:in:foo" with value "xyz" is attached to p. * ----------------------------------------------------------------------------- */ void Swig_typemap_attach_kwargs(Hash *tm, const String_or_char *op, Parm *p) { String *temp = NewString(""); Parm *kw = Getattr(tm,"kwargs"); while (kw) { Clear(temp); Printf(temp,"%s:%s",op,Getattr(kw,"name")); Setattr(p,tmop_name(temp),Copy(Getattr(kw,"value"))); kw = nextSibling(kw); } Delete(temp); } /* ----------------------------------------------------------------------------- * Swig_typemap_warn() * * If any warning message is attached to this parameter's "tmap:op:warning" * attribute, print that warning message. * ----------------------------------------------------------------------------- */ static void Swig_typemap_warn(const String_or_char *op, Parm *p) { String *temp = NewStringf("%s:warning",op); String *w = Getattr(p,tmop_name(temp)); Delete(temp); if (w) { Swig_warning(0,Getfile(p),Getline(p),"%s\n",w); } } static void Swig_typemap_emit_code_fragments(const String_or_char *op, Parm *p) { String *temp = NewStringf("%s:fragment",op); String *f = Getattr(p,tmop_name(temp)); if (f) { char *c, *tok; String *t = Copy(f); c = Char(t); tok = strtok(c,","); while (tok) { Swig_fragment_emit(tok); tok = strtok(NULL,","); } Delete(t); } Delete(temp); } /* ----------------------------------------------------------------------------- * Swig_typemap_attach_parms() * * Given a parameter list, this function attaches all of the typemaps for a * given typemap type * ----------------------------------------------------------------------------- */ void Swig_typemap_attach_parms(const String_or_char *op, ParmList *parms, Wrapper *f) { Parm *p, *firstp; Hash *tm; int nmatch = 0; int i; String *s; ParmList *locals; int argnum = 0; char temp[256]; p = parms; while (p) { argnum++; nmatch = 0; tm = Swig_typemap_search_multi(op,p,&nmatch); if (!tm) { p = nextSibling(p); continue; } s = Getattr(tm,"code"); if (!s) { p = nextSibling(p); continue; } /* Empty typemap. No match */ if (Cmp(s,"pass") == 0) { p = nextSibling(p); continue; } s = Copy(s); locals = Getattr(tm,"locals"); if (locals) locals = CopyParmList(locals); firstp = p; for (i = 0; i < nmatch; i++) { SwigType *type; String *pname; String *lname; SwigType *mtype; type = Getattr(p,"type"); pname = Getattr(p,"name"); lname = Getattr(p,"lname"); mtype = Getattr(p,"tmap:match"); if (mtype) { typemap_replace_vars(s,locals, mtype,pname,lname,i+1); Delattr(p,"tmap:match"); } else { typemap_replace_vars(s,locals, type,pname,lname,i+1); } if (checkAttribute(tm,"type","SWIGTYPE")) { sprintf(temp,"%s:SWIGTYPE", Char(op)); Setattr(p,tmop_name(temp),"1"); } p = nextSibling(p); } if (locals && f) { typemap_locals(s,locals,f,argnum); } replace_embedded_typemap(s); /* Replace the argument number */ sprintf(temp,"%d",argnum); Replace(s,"$argnum",temp, DOH_REPLACE_ANY); /* Attach attributes to object */ Setattr(firstp,tmop_name(op),s); /* Code object */ if (locals) { sprintf(temp,"%s:locals", Char(op)); Setattr(firstp,tmop_name(temp), locals); Delete(locals); } /* Attach a link to the next parameter. Needed for multimaps */ sprintf(temp,"%s:next",Char(op)); Setattr(firstp,tmop_name(temp),p); /* Attach kwargs */ Swig_typemap_attach_kwargs(tm,op,firstp); /* Print warnings, if any */ Swig_typemap_warn(op,firstp); /* Look for code fragments */ Swig_typemap_emit_code_fragments(op,firstp); } } /* ----------------------------------------------------------------------------- * split_embedded() * * This function replaces the special variable $typemap(....) with typemap * code. The general form of $typemap is as follows: * * $TYPEMAP(method, $var1=value, $var2=value, $var3=value,...) * * For example: * * $TYPEMAP(in, $1=int x, $input=y, ...) * * ----------------------------------------------------------------------------- */ /* Splits the arguments of an embedded typemap */ static List *split_embedded(String *s) { List *args = 0; char *c,*start; int level=0; int leading = 1; args = NewList(); c = Strstr(s,"("); c++; start = c; while (*c) { if (*c == '\"') { c++; while (*c) { if (*c == '\\') { c++; } else { if (*c == '\"') break; } c++; } } if ((level == 0) && ((*c == ',') || (*c == ')'))) { String *tmp = NewStringWithSize(start,c-start); Append(args,tmp); Delete(tmp); start = c+1; leading = 1; if (*c == ')') break; c++; continue; } if (*c == '(') level++; if (*c == ')') level--; if (isspace((int)*c) && leading) start++; if (!isspace((int)*c)) leading = 0; c++; } return args; } static void split_var(String *s, String **name, String **value) { char *eq; char *c; eq = Strstr(s,"="); if (!eq) { *name = 0; *value = 0; return; } c = Char(s); *name = NewStringWithSize(c,eq-c); /* Look for $n variables */ if (isdigit((int)*(c))) { /* Parse the value as a type */ String *v; Parm *p; v = NewString(eq+1); p = Swig_cparse_parm(v); Delete(v); *value = p; } else { *value = NewString(eq+1); } } static void replace_embedded_typemap(String *s) { while (Strstr(s,"$TYPEMAP(")) { /* Gather the argument */ char *start, *end=0,*c; int level = 0; String *tmp; start = Strstr(s,"$TYPEMAP("); c = start; while (*c) { if (*c == '(') level++; if (*c == ')') { level--; if (level == 0) { end = c+1; break; } } c++; } if (end) { tmp = NewStringWithSize(start,(end-start)); } else { tmp = 0; } /* Got a substitution. Split it apart into pieces */ if (tmp) { List *l; Hash *vars; String *method; int i; l = split_embedded(tmp); vars = NewHash(); for (i = 1; i < Len(l); i++) { String *n, *v; split_var(Getitem(l,i),&n,&v); if (n && v) { Insert(n,0,"$"); Setattr(vars,n,v); } } method = Getitem(l,0); /* Generate the parameter list for matching typemaps */ { Parm *p = 0; Parm *first = 0; char temp[32]; int n = 1; while (1) { Hash *v; sprintf(temp,"$%d",n); v = Getattr(vars,temp); if (v) { if (p) { set_nextSibling(p,v); set_previousSibling(v,p); } p = v; Setattr(p,"lname",Getattr(p,"name")); if (Getattr(p,"value")) { Setattr(p,"name",Getattr(p,"value")); } if (!first) first = p; DohIncref(p); Delattr(vars,temp); } else { break; } n++; } /* Perform a typemap search */ if (first) { Swig_typemap_attach_parms(method,first,0); { String *tm; int match = 0; char attr[64]; sprintf(attr,"tmap:%s",Char(method)); /* Look for the typemap code */ tm = Getattr(first,attr); if (tm) { sprintf(attr,"tmap:%s:next",Char(method)); if (!Getattr(first,attr)) { /* Should be no more matches. Hack??? */ /* Replace all of the remaining variables */ Iterator ki; for (ki = First(vars); ki.key; ki = Next(ki)) { Replace(tm,ki.key,ki.item, DOH_REPLACE_ANY); } /* Do the replacement */ Replace(s,tmp,tm, DOH_REPLACE_ANY); Delete(tm); Delete(vars); match = 1; } } if (!match) { Swig_error(Getfile(s),Getline(s),"No typemap found for %s\n", tmp); } } } } Replace(s,tmp,"", DOH_REPLACE_ANY); } } } /* ----------------------------------------------------------------------------- * Swig_typemap_debug() * ----------------------------------------------------------------------------- */ void Swig_typemap_debug() { int ts; Printf(stdout,"---[ typemaps ]--------------------------------------------------------------\n"); ts = tm_scope; while (ts >= 0) { Printf(stdout,"::: scope %d\n\n",ts); Printf(stdout,"%s\n", typemaps[ts]); ts--; } Printf(stdout,"-----------------------------------------------------------------------------\n"); } cableswig-0.1.0+git20150808.orig/SWIG/Source/Swig/.cvsignore0000644000175000000620000000005112561312227021743 0ustar stevestaff*.flc supertest *_wrap.* .deps .dirstamp cableswig-0.1.0+git20150808.orig/SWIG/Source/Swig/include.c0000644000175000000620000002327012561312227021542 0ustar stevestaff/* ----------------------------------------------------------------------------- * include.c * * The functions in this file are used to manage files in the SWIG library. * General purpose functions for opening, including, and retrieving pathnames * are provided. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_include_c[] = "/cvsroot/SWIG/Source/Swig/include.c,v 1.19 2003/12/28 21:38:58 cheetah Exp"; #include "swig.h" /* Delimeter used in accessing files and directories */ static List *directories = 0; /* List of include directories */ static String *lastpath = 0; /* Last file that was included */ static String *swiglib = 0; /* Location of SWIG library */ static String *lang_config = 0; /* Language configuration file */ /* This function sets the name of the configuration file */ void Swig_set_config_file(const String_or_char *filename) { lang_config = NewString(filename); } String *Swig_get_config_file() { return lang_config; } /* ----------------------------------------------------------------------------- * Swig_swiglib_set() * Swig_swiglib_get() * * Set the location of the SWIG library. This isn't really used, by the * include mechanism, but rather as a query interface for language modules. * ----------------------------------------------------------------------------- */ void Swig_swiglib_set(const String_or_char *sl) { swiglib = NewString(sl); } String * Swig_swiglib_get() { return swiglib; } /* ----------------------------------------------------------------------------- * Swig_add_directory() * * Adds a directory to the SWIG search path. * ----------------------------------------------------------------------------- */ void Swig_add_directory(const String_or_char *dirname) { if (!directories) directories = NewList(); assert(directories); if (!DohIsString(dirname)) { dirname = NewString((char *) dirname); assert(dirname); } Append(directories, dirname); } /* ----------------------------------------------------------------------------- * Swig_push_directory() * * Inserts a directory at the front of the SWIG search path. This is used by * the preprocessor to grab files in the same directory as other included files. * ----------------------------------------------------------------------------- */ void Swig_push_directory(const String_or_char *dirname) { if (!directories) directories = NewList(); assert(directories); if (!DohIsString(dirname)) { dirname = NewString((char *) dirname); assert(dirname); } Insert(directories, 0, dirname); } /* ----------------------------------------------------------------------------- * Swig_pop_directory() * * Pops a directory off the front of the SWIG search path. This is used by * the preprocessor. * ----------------------------------------------------------------------------- */ void Swig_pop_directory() { if (!directories) return; Delitem(directories,0); } /* ----------------------------------------------------------------------------- * Swig_last_file() * * Returns the full pathname of the last file opened. * ----------------------------------------------------------------------------- */ String * Swig_last_file() { assert(lastpath); return lastpath; } /* ----------------------------------------------------------------------------- * Swig_search_path() * * Returns a list of the current search paths. * ----------------------------------------------------------------------------- */ List * Swig_search_path() { String *filename; String *dirname; List *slist; int i; slist = NewList(); assert(slist); filename = NewString(""); assert(filename); #ifdef MACSWIG Printf(filename,"%s",SWIG_FILE_DELIMETER); #else Printf(filename,".%s", SWIG_FILE_DELIMETER); #endif Append(slist,filename); for (i = 0; i < Len(directories); i++) { dirname = Getitem(directories,i); filename = NewString(""); assert(filename); Printf(filename, "%s%s", dirname, SWIG_FILE_DELIMETER); Append(slist,filename); } return slist; } /* ----------------------------------------------------------------------------- * Swig_open() * * Looks for a file and open it. Returns an open FILE * on success. * ----------------------------------------------------------------------------- */ FILE * Swig_open(const String_or_char *name) { FILE *f; String *filename; List *spath = 0; char *cname; int i; if (!directories) directories = NewList(); assert(directories); cname = Char(name); filename = NewString(cname); assert(filename); f = fopen(Char(filename),"r"); if (!f) { spath = Swig_search_path(); for (i = 0; i < Len(spath); i++) { Clear(filename); Printf(filename,"%s%s", Getitem(spath,i), cname); f = fopen(Char(filename),"r"); if (f) break; } Delete(spath); } if (f) { #if defined(_WIN32) /* Note not on Cygwin else filename is displayed with double '/' */ Replaceall(filename,"\\\\","\\"); /* remove double '\' in case any already present */ Replaceall(filename,"\\","\\\\"); #endif Delete(lastpath); lastpath = Copy(filename); } Delete(filename); return f; } /* ----------------------------------------------------------------------------- * Swig_read_file() * * Reads data from an open FILE * and returns it as a string. * ----------------------------------------------------------------------------- */ String * Swig_read_file(FILE *f) { char buffer[4096]; String *str = NewString(""); assert(str); while (fgets(buffer,4095,f)) { Append(str,buffer); } Append(str,"\n"); return str; } /* ----------------------------------------------------------------------------- * Swig_include() * * Opens a file and returns it as a string. * ----------------------------------------------------------------------------- */ String * Swig_include(const String_or_char *name) { FILE *f; String *str; f = Swig_open(name); if (!f) return 0; str = Swig_read_file(f); fclose(f); Seek(str,0,SEEK_SET); Setfile(str,lastpath); Setline(str,1); return str; } /* ----------------------------------------------------------------------------- * Swig_insert_file() * * Copies the contents of a file into another file * ----------------------------------------------------------------------------- */ int Swig_insert_file(const String_or_char *filename, File *outfile) { char buffer[4096]; int nbytes; FILE *f = Swig_open(filename); if (!f) return -1; while ((nbytes = Read(f,buffer,4096)) > 0) { Write(outfile,buffer,nbytes); } return 0; } /* ----------------------------------------------------------------------------- * Swig_register_filebyname() * * Register a "named" file with the core. Named files can become targets * for %insert directives and other SWIG operations. This function takes * the place of the f_header, f_wrapper, f_init, and other global variables * in SWIG1.1 * ----------------------------------------------------------------------------- */ static Hash *named_files = 0; void Swig_register_filebyname(const String_or_char *filename, File *outfile) { if (!named_files) named_files = NewHash(); Setattr(named_files, filename, outfile); } /* ----------------------------------------------------------------------------- * Swig_filebyname() * * Get a named file * ----------------------------------------------------------------------------- */ File * Swig_filebyname(const String_or_char *filename) { if (!named_files) return 0; return Getattr(named_files,filename); } /* ----------------------------------------------------------------------------- * Swig_file_suffix() * * Returns the suffix of a file * ----------------------------------------------------------------------------- */ char * Swig_file_suffix(const String_or_char *filename) { char *d; char *c = Char(filename); if (strlen(c)) { d = c + Len(filename) - 1; while (d != c) { if (*d == '.') return d; d--; } return c+Len(filename); } return c; } /* ----------------------------------------------------------------------------- * Swig_file_basename() * * Returns the filename with no suffix attached. * ----------------------------------------------------------------------------- */ char * Swig_file_basename(const String_or_char *filename) { static char tmp[1024]; char *c; strcpy(tmp,Char(filename)); c = Swig_file_suffix(tmp); *c = 0; return tmp; } /* ----------------------------------------------------------------------------- * Swig_file_filename() * * Return the file with any leading path stripped off * ----------------------------------------------------------------------------- */ char * Swig_file_filename(const String_or_char *filename) { static char tmp[1024]; const char *delim = SWIG_FILE_DELIMETER; char *c; strcpy(tmp,Char(filename)); if ((c=strrchr(tmp,*delim))) return c+1; else return tmp; } /* ----------------------------------------------------------------------------- * Swig_file_dirname() * * Return the name of the directory associated with a file * ----------------------------------------------------------------------------- */ char * Swig_file_dirname(const String_or_char *filename) { static char tmp[1024]; const char *delim = SWIG_FILE_DELIMETER; char *c; strcpy(tmp,Char(filename)); if (!strstr(tmp,delim)) { return ""; } c = tmp + strlen(tmp) -1; while (*c != *delim) c--; *(++c) = 0; return tmp; } cableswig-0.1.0+git20150808.orig/SWIG/Source/Swig/misc.c0000644000175000000620000002323512561312227021053 0ustar stevestaff/* ----------------------------------------------------------------------------- * misc.c * * Miscellaneous functions that don't really fit anywhere else. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_misc_c[] = "/cvsroot/SWIG/Source/Swig/misc.c,v 1.21 2004/01/22 22:42:18 cheetah Exp"; #include "swig.h" #include /* ----------------------------------------------------------------------------- * Swig_copy_string() * * Duplicate a NULL-terminate string given as a char *. * ----------------------------------------------------------------------------- */ char * Swig_copy_string(const char *s) { char *c = 0; if (s) { c = (char *) malloc(strlen(s)+1); strcpy(c,s); } return c; } /* ----------------------------------------------------------------------------- * Swig_banner() * * Emits the SWIG identifying banner. * ----------------------------------------------------------------------------- */ void Swig_banner(File *f) { Printf(f, "/* ----------------------------------------------------------------------------\n\ * This file was automatically generated by SWIG (http://www.swig.org).\n\ * Version %s\n\ * \n\ * This file is not intended to be easily readable and contains a number of \n\ * coding conventions designed to improve portability and efficiency. Do not make\n\ * changes to this file unless you know what you are doing--modify the SWIG \n\ * interface file instead. \n", PACKAGE_VERSION); /* String too long for ISO compliance */ Printf(f, " * ----------------------------------------------------------------------------- */\n\n"); } /* ----------------------------------------------------------------------------- * Swig_string_escape() * * Takes a string object and produces a string with escape codes added to it. * ----------------------------------------------------------------------------- */ String *Swig_string_escape(String *s) { String *ns; int c; ns = NewString(""); while ((c = Getc(s)) != EOF) { if (c == '\n') { Printf(ns,"\\n"); } else if (c == '\r') { Printf(ns,"\\r"); } else if (c == '\t') { Printf(ns,"\\t"); } else if (c == '\\') { Printf(ns,"\\\\"); } else if (c == '\'') { Printf(ns,"\\'"); } else if (c == '\"') { Printf(ns,"\\\""); } else if (c == ' ') { Putc(c,ns); } else if (!isgraph(c)) { Printf(ns,"\\%o", c); } else { Putc(c,ns); } } return ns; } /* ----------------------------------------------------------------------------- * Swig_string_upper() * * Takes a string object and convets it to all caps. * ----------------------------------------------------------------------------- */ String *Swig_string_upper(String *s) { String *ns; int c; ns = NewString(""); while ((c = Getc(s)) != EOF) { Putc(toupper(c),ns); } return ns; } /* ----------------------------------------------------------------------------- * Swig_string_lower() * * Takes a string object and convets it to all lower. * ----------------------------------------------------------------------------- */ String *Swig_string_lower(String *s) { String *ns; int c; ns = NewString(""); while ((c = Getc(s)) != EOF) { Putc(tolower(c),ns); } return ns; } /* ----------------------------------------------------------------------------- * Swig_string_title() * * Takes a string object and convets it to all lower. * ----------------------------------------------------------------------------- */ String *Swig_string_title(String *s) { String *ns; int first = 1; int c; ns = NewString(""); while ((c = Getc(s)) != EOF) { Putc(first ? toupper(c) : tolower(c),ns); first = 0; } return ns; } /* ----------------------------------------------------------------------------- * Swig_string_typecode() * * Takes a string with possible type-escapes in it and replaces them with * real C datatypes. * ----------------------------------------------------------------------------- */ String *Swig_string_typecode(String *s) { String *ns; int c; String *tc; ns = NewString(""); while ((c = Getc(s)) != EOF) { if (c == '`') { tc = NewString(""); while ((c = Getc(s)) != EOF) { if (c == '`') break; Putc(c,tc); } Printf(ns,"%s",SwigType_str(tc,0)); } else { Putc(c,ns); if (c == '\'') { while ((c = Getc(s)) != EOF) { Putc(c,ns); if (c == '\'') break; if (c == '\\') { c = Getc(s); Putc(c,ns); } } } else if (c == '\"') { while ((c = Getc(s)) != EOF) { Putc(c,ns); if (c == '\"') break; if (c == '\\') { c = Getc(s); Putc(c,ns); } } } } } return ns; } /* ----------------------------------------------------------------------------- * Swig_string_mangle() * * Take a string and mangle it by stripping all non-valid C identifier characters * ----------------------------------------------------------------------------- */ String *Swig_string_mangle(String *s) { String *t = Copy(s); char *c = Char(t); while (*c) { if (!isalnum(*c)) *c = '_'; c++; } return t; } /* ----------------------------------------------------------------------------- * Swig_scopename_prefix() * * Take a qualified name like "A::B::C" and return the scope name. * In this case, "A::B". Returns NULL if there is no base. * ----------------------------------------------------------------------------- */ String * Swig_scopename_prefix(String *s) { char tmp[1024]; char *c, *cc; if (!Strstr(s,"::")) return 0; strcpy(tmp,Char(s)); c = tmp; cc = c; while (*c) { if (strncmp(c,"::",2) == 0) { cc = c; c += 2; } else { if (*c == '<') { int level = 1; c++; while (*c && level) { if (*c == '<') level++; if (*c == '>') level--; c++; } } else { c++; } } } *cc = 0; if (cc != tmp) { return NewString(tmp); } else { return 0; } } /* ----------------------------------------------------------------------------- * Swig_scopename_last() * * Take a qualified name like "A::B::C" and returns the last. In this * case, "C". * ----------------------------------------------------------------------------- */ String * Swig_scopename_last(String *s) { char tmp[1024]; char *c, *cc; if (!Strstr(s,"::")) return NewString(s); strcpy(tmp,Char(s)); c = tmp; cc = c; while (*c) { if (strncmp(c,"::",2) == 0) { cc = c; c += 2; } else { if (*c == '<') { int level = 1; c++; while (*c && level) { if (*c == '<') level++; if (*c == '>') level--; c++; } } else { c++; } } } return NewString(cc+2); } /* ----------------------------------------------------------------------------- * Swig_scopename_first() * * Take a qualified name like "A::B::C" and returns the first scope name. * In this case, "A". Returns NULL if there is no base. * ----------------------------------------------------------------------------- */ String * Swig_scopename_first(String *s) { char tmp[1024]; char *c; if (!Strstr(s,"::")) return 0; strcpy(tmp,Char(s)); c = tmp; while (*c) { if (strncmp(c,"::",2) == 0) { break; } else { if (*c == '<') { int level = 1; c++; while (*c && level) { if (*c == '<') level++; if (*c == '>') level--; c++; } } else { c++; } } } if (*c && (c != tmp)) { *c = 0; return NewString(tmp); } else { return 0; } } /* ----------------------------------------------------------------------------- * Swig_scopename_suffix() * * Take a qualified name like "A::B::C" and returns the suffix. * In this case, "B::C". Returns NULL if there is no suffix. * ----------------------------------------------------------------------------- */ String * Swig_scopename_suffix(String *s) { char tmp[1024]; char *c; if (!Strstr(s,"::")) return 0; strcpy(tmp,Char(s)); c = tmp; while (*c) { if (strncmp(c,"::",2) == 0) { break; } else { if (*c == '<') { int level = 1; c++; while (*c && level) { if (*c == '<') level++; if (*c == '>') level--; c++; } } else { c++; } } } if (*c && (c != tmp)) { return NewString(c+2); } else { return 0; } } /* ----------------------------------------------------------------------------- * Swig_scopename_check() * * Checks to see if a name is qualified with a scope name * ----------------------------------------------------------------------------- */ int Swig_scopename_check(String *s) { char *c = Char(s); if (!Strstr(s,"::")) return 0; while (*c) { if (strncmp(c,"::",2) == 0) { return 1; } else { if (*c == '<') { int level = 1; c++; while (*c && level) { if (*c == '<') level++; if (*c == '>') level--; c++; } } else { c++; } } } return 0; } /* ----------------------------------------------------------------------------- * Swig_init() * * Initialize the SWIG core * ----------------------------------------------------------------------------- */ void Swig_init() { /* Set some useful string encoding methods */ DohEncoding("escape", Swig_string_escape); DohEncoding("upper", Swig_string_upper); DohEncoding("lower", Swig_string_lower); DohEncoding("title", Swig_string_title); DohEncoding("typecode",Swig_string_typecode); /* Initialize typemaps */ Swig_typemap_init(); /* Initialize symbol table */ Swig_symbol_init(); /* Initialize type system */ SwigType_typesystem_init(); } cableswig-0.1.0+git20150808.orig/SWIG/Source/Swig/naming.c0000644000175000000620000003726312561312227021377 0ustar stevestaff/* ----------------------------------------------------------------------------- * naming.c * * Functions for generating various kinds of names during code generation * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_naming_c[] = "/cvsroot/SWIG/Source/Swig/naming.c,v 1.9 2004/01/15 22:46:06 cheetah Exp"; #include "swig.h" #include /* Hash table containing naming data */ static Hash *naming_hash = 0; /* ----------------------------------------------------------------------------- * Swig_name_register() * * Register a new naming format. * ----------------------------------------------------------------------------- */ void Swig_name_register(const String_or_char *method, const String_or_char *format) { if (!naming_hash) naming_hash = NewHash(); Setattr(naming_hash,method,format); } void Swig_name_unregister(const String_or_char *method) { if (naming_hash) { Delattr(naming_hash,method); } } static int name_mangle(String *r) { char *c; int special; special = 0; Replaceall(r,"::","_"); c = Char(r); while (*c) { if (!isalnum((int) *c) && (*c != '_')) { special = 1; switch(*c) { case '+': *c = 'a'; break; case '-': *c = 's'; break; case '*': *c = 'm'; break; case '/': *c = 'd'; break; case '<': *c = 'l'; break; case '>': *c = 'g'; break; case '=': *c = 'e'; break; case ',': *c = 'c'; break; case '(': *c = 'p'; break; case ')': *c = 'P'; break; case '[': *c = 'b'; break; case ']': *c = 'B'; break; case '^': *c = 'x'; break; case '&': *c = 'A'; break; case '|': *c = 'o'; break; case '~': *c = 'n'; break; case '!': *c = 'N'; break; case '%': *c = 'M'; break; case '.': *c = 'f'; break; case '?': *c = 'q'; break; default: *c = '_'; break; } } c++; } if (special) Append(r,"___"); return special; } /* ----------------------------------------------------------------------------- * Swig_name_mangle() * * Converts all of the non-identifier characters of a string to underscores. * ----------------------------------------------------------------------------- */ String * Swig_name_mangle(const String_or_char *s) { String *r = NewString(s); name_mangle(r); return r; } /* ----------------------------------------------------------------------------- * Swig_name_wrapper() * * Returns the name of a wrapper function. * ----------------------------------------------------------------------------- */ String * Swig_name_wrapper(const String_or_char *fname) { String *r; String *f; r = NewString(""); if (!naming_hash) naming_hash = NewHash(); f = Getattr(naming_hash,"wrapper"); if (!f) { Append(r,"_wrap_%f"); } else { Append(r,f); } Replace(r,"%f",fname, DOH_REPLACE_ANY); name_mangle(r); return r; } /* ----------------------------------------------------------------------------- * Swig_name_member() * * Returns the name of a class method. * ----------------------------------------------------------------------------- */ String * Swig_name_member(const String_or_char *classname, const String_or_char *mname) { String *r; String *f; String *rclassname; char *cname; rclassname = SwigType_namestr(classname); r = NewString(""); if (!naming_hash) naming_hash = NewHash(); f = Getattr(naming_hash,"member"); if (!f) { Append(r,"%c_%m"); } else { Append(r,f); } cname = Char(rclassname); if ((strncmp(cname,"struct ", 7) == 0) || ((strncmp(cname,"class ", 6) == 0)) || ((strncmp(cname,"union ", 6) == 0))) { cname = strchr(cname, ' ')+1; } Replace(r,"%c",cname, DOH_REPLACE_ANY); Replace(r,"%m",mname, DOH_REPLACE_ANY); /* name_mangle(r);*/ Delete(rclassname); return r; } /* ----------------------------------------------------------------------------- * Swig_name_get() * * Returns the name of the accessor function used to get a variable. * ----------------------------------------------------------------------------- */ String * Swig_name_get(const String_or_char *vname) { String *r; String *f; r = NewString(""); if (!naming_hash) naming_hash = NewHash(); f = Getattr(naming_hash,"get"); if (!f) { Append(r,"%v_get"); } else { Append(r,f); } Replace(r,"%v",vname, DOH_REPLACE_ANY); Replace(r,"::","_", DOH_REPLACE_ANY); return r; } /* ----------------------------------------------------------------------------- * Swig_name_set() * * Returns the name of the accessor function used to set a variable. * ----------------------------------------------------------------------------- */ String * Swig_name_set(const String_or_char *vname) { String *r; String *f; r = NewString(""); if (!naming_hash) naming_hash = NewHash(); f = Getattr(naming_hash,"set"); if (!f) { Append(r,"%v_set"); } else { Append(r,f); } Replace(r,"%v",vname, DOH_REPLACE_ANY); Replace(r,"::","_", DOH_REPLACE_ANY); return r; } /* ----------------------------------------------------------------------------- * Swig_name_construct() * * Returns the name of the accessor function used to create an object. * ----------------------------------------------------------------------------- */ String * Swig_name_construct(const String_or_char *classname) { String *r; String *f; String *rclassname; char *cname; rclassname = SwigType_namestr(classname); r = NewString(""); if (!naming_hash) naming_hash = NewHash(); f = Getattr(naming_hash,"construct"); if (!f) { Append(r,"new_%c"); } else { Append(r,f); } cname = Char(rclassname); if ((strncmp(cname,"struct ", 7) == 0) || ((strncmp(cname,"class ", 6) == 0)) || ((strncmp(cname,"union ", 6) == 0))) { cname = strchr(cname, ' ')+1; } Replace(r,"%c",cname, DOH_REPLACE_ANY); Delete(rclassname); return r; } /* ----------------------------------------------------------------------------- * Swig_name_copyconstructor() * * Returns the name of the accessor function used to copy an object. * ----------------------------------------------------------------------------- */ String * Swig_name_copyconstructor(const String_or_char *classname) { String *r; String *f; String *rclassname; char *cname; rclassname = SwigType_namestr(classname); r = NewString(""); if (!naming_hash) naming_hash = NewHash(); f = Getattr(naming_hash,"construct"); if (!f) { Append(r,"copy_%c"); } else { Append(r,f); } cname = Char(rclassname); if ((strncmp(cname,"struct ", 7) == 0) || ((strncmp(cname,"class ", 6) == 0)) || ((strncmp(cname,"union ", 6) == 0))) { cname = strchr(cname, ' ')+1; } Replace(r,"%c",cname, DOH_REPLACE_ANY); Delete(rclassname); return r; } /* ----------------------------------------------------------------------------- * Swig_name_destroy() * * Returns the name of the accessor function used to destroy an object. * ----------------------------------------------------------------------------- */ String *Swig_name_destroy(const String_or_char *classname) { String *r; String *f; String *rclassname; char *cname; rclassname = SwigType_namestr(classname); r = NewString(""); if (!naming_hash) naming_hash = NewHash(); f = Getattr(naming_hash,"destroy"); if (!f) { Append(r,"delete_%c"); } else { Append(r,f); } cname = Char(rclassname); if ((strncmp(cname,"struct ", 7) == 0) || ((strncmp(cname,"class ", 6) == 0)) || ((strncmp(cname,"union ", 6) == 0))) { cname = strchr(cname, ' ')+1; } Replace(r,"%c",cname, DOH_REPLACE_ANY); Delete(rclassname); return r; } /* ----------------------------------------------------------------------------- * Swig_name_disown() * * Returns the name of the accessor function used to disown an object. * ----------------------------------------------------------------------------- */ String *Swig_name_disown(const String_or_char *classname) { String *r; String *f; String *rclassname; char *cname; rclassname = SwigType_namestr(classname); r = NewString(""); if (!naming_hash) naming_hash = NewHash(); f = Getattr(naming_hash,"disown"); if (!f) { Append(r,"disown_%c"); } else { Append(r,f); } cname = Char(rclassname); if ((strncmp(cname,"struct ", 7) == 0) || ((strncmp(cname,"class ", 6) == 0)) || ((strncmp(cname,"union ", 6) == 0))) { cname = strchr(cname, ' ')+1; } Replace(r,"%c",cname, DOH_REPLACE_ANY); Delete(rclassname); return r; } /* ----------------------------------------------------------------------------- * Swig_name_object_set() * * Sets an object associated with a name and optional declarators. * ----------------------------------------------------------------------------- */ void Swig_name_object_set(Hash *namehash, String *name, SwigType *decl, DOH *object) { DOH *n; /* Printf(stdout,"name: '%s', '%s'\n", name, decl);*/ n = Getattr(namehash,name); if (!n) { n = NewHash(); Setattr(namehash,name,n); } /* Add an object based on the declarator value */ if (!decl) { Setattr(n,NewString("*"),object); } else { Setattr(n,Copy(decl),object); } } /* ----------------------------------------------------------------------------- * Swig_name_object_get() * * Return an object associated with an optional class prefix, name, and * declarator. This function operates according to name matching rules * described for the %rename directive in the SWIG manual. * ----------------------------------------------------------------------------- */ static DOH *get_object(Hash *n, String *decl) { DOH *rn = 0; if (!n) return 0; if (decl) { rn = Getattr(n,decl); } else { rn = Getattr(n,"*"); } return rn; } DOH * Swig_name_object_get(Hash *namehash, String *prefix, String *name, SwigType *decl) { String *tname; DOH *rn = 0; Hash *n; char *ncdecl = 0; if (!namehash) return 0; /* DB: This removed to more tightly control feature/name matching */ /* if ((decl) && (SwigType_isqualifier(decl))) { ncdecl = strchr(Char(decl),'.'); ncdecl++; } */ /* Perform a class-based lookup (if class prefix supplied) */ if (prefix) { if (Len(prefix)) { tname = NewStringf("%s::%s",prefix,name); n = Getattr(namehash,tname); rn = get_object(n,decl); if ((!rn) && ncdecl) rn = get_object(n,ncdecl); if (!rn) rn = get_object(n,0); Delete(tname); } /* A wildcard-based class lookup */ if (!rn) { tname = NewStringf("*::%s",name); n = Getattr(namehash,tname); rn = get_object(n,decl); if ((!rn) && ncdecl) rn = get_object(n,ncdecl); if (!rn) rn = get_object(n,0); Delete(tname); } } else { /* Lookup in the global namespace only */ tname = NewStringf("::%s",name); n = Getattr(namehash,tname); rn = get_object(n,decl); if ((!rn) && ncdecl) rn = get_object(n,ncdecl); if (!rn) rn = get_object(n,0); Delete(tname); } /* Catch-all */ if (!rn) { n = Getattr(namehash,name); rn = get_object(n,decl); if ((!rn) && ncdecl) rn = get_object(n,ncdecl); if (!rn) rn = get_object(n,0); } return rn; } /* ----------------------------------------------------------------------------- * Swig_name_object_inherit() * * Implements name-based inheritance scheme. * ----------------------------------------------------------------------------- */ void Swig_name_object_inherit(Hash *namehash, String *base, String *derived) { Iterator ki; String *bprefix; String *dprefix; char *cbprefix; int plen; if (!namehash) return; bprefix = NewStringf("%s::",base); dprefix = NewStringf("%s::",derived); cbprefix = Char(bprefix); plen = strlen(cbprefix); for (ki = First(namehash); ki.key; ki = Next(ki)) { char *k = Char(ki.key); if (strncmp(k,cbprefix,plen) == 0) { Hash *n, *newh; String *nkey; Iterator oi; nkey = NewStringf("%s%s",dprefix,k+plen); n = ki.item; newh = Getattr(namehash,nkey); if (!newh) { newh = NewHash(); Setattr(namehash,nkey,newh); } for (oi = First(n); oi.key; oi = Next(oi)) { if (!Getattr(newh,oi.key)) { Setattr(newh,oi.key,Copy(oi.item)); } } } } } /* ----------------------------------------------------------------------------- * Swig_features_get() * * Given a node, this function merges features. * ----------------------------------------------------------------------------- */ static void merge_features(Hash *features, Node *n) { Iterator ki; if (!features) return; for (ki = First(features); ki.key; ki = Next(ki)) { if (Getattr(n,ki.key)) { continue; } Setattr(n,ki.key,Copy(ki.item)); } } void Swig_features_get(Hash *features, String *prefix, String *name, SwigType *decl, Node *node) { String *tname; DOH *rn = 0; Hash *n; char *ncdecl = 0; if (!features) return; if ((decl) && (SwigType_isqualifier(decl))) { ncdecl = strchr(Char(decl),'.'); ncdecl++; } if (name) { /* Perform a class-based lookup (if class prefix supplied) */ if (prefix) { if (Len(prefix)) { tname = NewStringf("%s::%s",prefix,name); n = Getattr(features,tname); rn = get_object(n,decl); merge_features(rn,node); if (ncdecl) { rn = get_object(n,ncdecl); merge_features(rn,node); } rn = get_object(n,0); merge_features(rn,node); Delete(tname); } /* A wildcard-based class lookup */ tname = NewStringf("*::%s",name); n = Getattr(features,tname); rn = get_object(n,decl); merge_features(rn,node); if (ncdecl) { rn = get_object(n,ncdecl); merge_features(rn,node); } rn = get_object(n,0); merge_features(rn,node); Delete(tname); /* A class-generic feature */ if (Len(prefix)) { tname = NewStringf("%s::",prefix); n = Getattr(features,tname); rn = get_object(n,0); merge_features(rn,node); Delete(tname); } } else { /* Lookup in the global namespace only */ tname = NewStringf("::%s",name); n = Getattr(features,tname); rn = get_object(n,decl); merge_features(rn,node); if (ncdecl) { rn = get_object(n,ncdecl); merge_features(rn,node); } rn = get_object(n,0); merge_features(rn,node); Delete(tname); } /* Catch-all */ n = Getattr(features,name); rn = get_object(n,decl); merge_features(rn,node); if (ncdecl) { rn = get_object(n,ncdecl); merge_features(rn,node); } rn = get_object(n,0); merge_features(rn,node); } /* Global features */ n = Getattr(features,""); rn = get_object(n,0); merge_features(rn,node); } /* ----------------------------------------------------------------------------- * Swig_feature_set() * * Sets a feature name and value. * ----------------------------------------------------------------------------- */ void Swig_feature_set(Hash *features, const String_or_char *name, SwigType *decl, const String_or_char *featurename, String *value) { Hash *n; Hash *fhash; /* Printf(stdout,"feature: %s %s %s %s\n", name, decl, featurename, value);*/ n = Getattr(features,name); if (!n) { n = NewHash(); Setattr(features,name,n); } if (!decl) { fhash = Getattr(n,"*"); if (!fhash) { fhash = NewHash(); Setattr(n,"*",fhash); } } else { fhash = Getattr(n,decl); if (!fhash) { fhash = NewHash(); Setattr(n,Copy(decl),fhash); } } if (value) { Setattr(fhash,featurename,value); } else { Delattr(fhash,featurename); } } cableswig-0.1.0+git20150808.orig/SWIG/Source/Swig/fragment.c0000644000175000000620000000466212561312227021726 0ustar stevestaff/* ----------------------------------------------------------------------------- * fragment.c * * This file manages named code fragments. Code fragments are typically * used to hold helper-code that may or may not be included in the wrapper * file (depending on what features are actually used in the interface). * * By using fragments, it's possible to greatly reduce the amount of * wrapper code and to generate cleaner wrapper files. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_fragment_c[] = "/cvsroot/SWIG/Source/Swig/fragment.c,v 1.4 2004/01/27 23:39:35 mmatus Exp"; #include "swig.h" static Hash *fragments = 0; /* ----------------------------------------------------------------------------- * Swig_fragment_register() * * Add a fragment. Use the original Node*, so, if something needs to be * changed, lang.cxx doesn't nedd to be touched again. * ----------------------------------------------------------------------------- */ void Swig_fragment_register(Node* fragment) { String *name = Getattr(fragment,"name"); String *section = Getattr(fragment,"section"); String *ccode = Copy(Getattr(fragment,"code")); Hash *kwargs = Getattr(fragment,"kwargs"); if (!fragments) { fragments = NewHash(); } Setmeta(ccode,"section",Copy(section)); if (kwargs) Setmeta(ccode,"kwargs",Copy(kwargs)); Setattr(fragments,Copy(name),ccode); } /* ----------------------------------------------------------------------------- * Swig_fragment_emit() * * Emit a fragment * ----------------------------------------------------------------------------- */ void Swig_fragment_emit(String *name) { String *code; if (!fragments) return; code = Getattr(fragments,name); if (code) { String *section = Getmeta(code,"section"); Hash *n = Getmeta(code,"kwargs"); while (n) { if (Cmp(Getattr(n,"name"),"fragment") == 0) { Swig_fragment_emit(Getattr(n,"value")); } n = nextSibling(n); } if (section) { File *f = Swig_filebyname(section); if (!f) { Swig_error(Getfile(code),Getline(code),"Bad section '%s' for code fragment '%s'\n", section,name); } else { Printf(f,"%s\n",code); } } Delattr(fragments,name); } } cableswig-0.1.0+git20150808.orig/SWIG/Source/Swig/tree.c0000644000175000000620000002022412561312227021052 0ustar stevestaff/* ----------------------------------------------------------------------------- * tree.c * * This file provides some general purpose functions for manipulating * parse trees. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ #include "swig.h" #include #include char cvsroot_tree_c[] = "/cvsroot/SWIG/Source/Swig/tree.c,v 1.13 2003/09/11 20:26:57 beazley Exp"; /* ----------------------------------------------------------------------------- * Swig_print_tags() * * Dump the tag structure of a parse tree to standard output * ----------------------------------------------------------------------------- */ void Swig_print_tags(DOH *obj, DOH *root) { DOH *croot, *newroot; DOH *cobj; if (!root) croot = NewString(""); else croot = root; while (obj) { Printf(stdout,"%s . %s (%s:%d)\n", croot, nodeType(obj), Getfile(obj), Getline(obj)); cobj = firstChild(obj); if (cobj) { newroot = NewStringf("%s . %s",croot,nodeType(obj)); Swig_print_tags(cobj,newroot); Delete(newroot); } obj = nextSibling(obj); } if (!root) Delete(croot); } /* ----------------------------------------------------------------------------- * Swig_print_tree() * * Dump the tree structure of a parse tree to standard output * ----------------------------------------------------------------------------- */ static int indent_level = 0; static void print_indent(int l) { int i; for (i = 0; i < indent_level; i++) { fputc(' ', stdout); } if (l) { fputc('|', stdout); fputc(' ', stdout); } } /* ----------------------------------------------------------------------------- * Swig_dump_node(Node *n) * ----------------------------------------------------------------------------- */ void Swig_print_node(Node *obj) { Iterator ki; Node *cobj; print_indent(0); Printf(stdout,"+++ %s ----------------------------------------\n", nodeType(obj)); ki = First(obj); while (ki.key) { String *k = ki.key; if ((Cmp(k,"nodeType") == 0) || (Cmp(k,"firstChild") == 0) || (Cmp(k,"lastChild") == 0) || (Cmp(k,"parentNode") == 0) || (Cmp(k,"nextSibling") == 0) || (Cmp(k,"previousSibling") == 0) || (*(Char(k)) == '$')) { /* Do nothing */ } else if (Cmp(k,"parms") == 0) { print_indent(2); Printf(stdout,"%-12s - %s\n", k, ParmList_protostr(Getattr(obj,k))); } else { DOH *o; char *trunc = ""; print_indent(2); if (DohIsString(Getattr(obj,k))) { o = Str(Getattr(obj,k)); if (Len(o) > 200) { trunc = "..."; } Printf(stdout,"%-12s - \"%(escape)-0.200s%s\"\n", k, o, trunc); Delete(o); } else { Printf(stdout,"%-12s - 0x%x\n", k, Getattr(obj,k)); } } ki = Next(ki); } cobj = firstChild(obj); if (cobj) { indent_level += 6; Printf(stdout,"\n"); Swig_print_tree(cobj); indent_level -= 6; } else { print_indent(1); Printf(stdout,"\n"); } } void Swig_print_tree(DOH *obj) { while (obj) { Swig_print_node(obj); obj = nextSibling(obj); } } /* ----------------------------------------------------------------------------- * appendChild() * * Appends a new child to a node * ----------------------------------------------------------------------------- */ void appendChild(Node *node, Node *chd) { Node *lc; if (!chd) return; lc = lastChild(node); if (!lc) { set_firstChild(node,chd); } else { set_nextSibling(lc,chd); set_previousSibling(chd,lc); } while (chd) { lc = chd; set_parentNode(chd,node); chd = nextSibling(chd); } set_lastChild(node,lc); } /* ----------------------------------------------------------------------------- * deleteNode() * * Deletes a node. * ----------------------------------------------------------------------------- */ void deleteNode(Node *n) { Node *parent; Node *prev; Node *next; parent = parentNode(n); prev = previousSibling(n); next = nextSibling(n); if (prev) { set_nextSibling(prev,next); } else { if (parent) { set_firstChild(parent,next); } } if (next) { set_previousSibling(next,prev); } else { if (parent) { set_lastChild(parent,prev); } } } /* ----------------------------------------------------------------------------- * copyNode() * * Copies a node, but only copies simple attributes (no lists, hashes). * ----------------------------------------------------------------------------- */ Node * copyNode(Node *n) { Iterator ki; Node *c = NewHash(); for (ki = First(n); ki.key; ki = Next(ki)) { if (DohIsString(ki.item)) { Setattr(c,ki.key,Copy(ki.item)); } } Setfile(c,Getfile(n)); Setline(c,Getline(n)); return c; } /* ----------------------------------------------------------------------------- * Swig_tag_nodes() * * Tags a collection of nodes with an attribute. Used by the parser to mark * subtypes with extra information. * ----------------------------------------------------------------------------- */ void Swig_tag_nodes(Node *n, const String_or_char *attrname, DOH *value) { while (n) { Setattr(n,attrname,value); Swig_tag_nodes(firstChild(n),attrname, value); n = nextSibling(n); } } int checkAttribute(Node *n, const String_or_char *name, const String_or_char *value) { String *v; v = Getattr(n,name); if (!v) return 0; if (Cmp(v,value) == 0) return 1; return 0; } /* ----------------------------------------------------------------------------- * Swig_require() * ----------------------------------------------------------------------------- */ int Swig_require(const char *ns, Node *n, ...) { va_list ap; char *name; DOH *obj; char temp[512]; va_start(ap, n); name = va_arg(ap, char *); while (name) { int newref = 0; int opt = 0; if (*name == '*') { newref = 1; name++; } else if (*name == '?') { newref = 1; opt = 1; name++; } obj = Getattr(n,name); if (!opt && !obj) { Printf(stderr,"%s:%d. Fatal error (Swig_require). Missing attribute '%s' in node '%s'.\n", Getfile(n), Getline(n), name, nodeType(n)); assert(obj); } if (!obj) obj = DohNone; if (newref) { /* Save a copy of the attribute */ strcpy(temp,ns); strcat(temp,":"); strcat(temp,name); Setattr(n,temp,obj); } name = va_arg(ap, char *); } va_end(ap); /* Save the view */ { String *view = Getattr(n,"view"); if (view) { if (Strcmp(view,ns) != 0) { strcpy(temp,ns); strcat(temp,":view"); Setattr(n,temp,view); Setattr(n,"view",ns); } } else { Setattr(n,"view",ns); } } return 1; } int Swig_save(const char *ns, Node *n, ...) { va_list ap; char *name; DOH *obj; char temp[512]; va_start(ap, n); name = va_arg(ap, char *); while (name) { if (*name == '*') { name++; } else if (*name == '?') { name++; } obj = Getattr(n,name); if (!obj) { obj = DohNone; } strcpy(temp,ns); strcat(temp,":"); strcat(temp,name); if (Setattr(n,temp,obj)) { Printf(stderr,"Swig_save('%s','%s'): Warning, attribute '%s' was already saved.\n", ns, nodeType(n), name); } name = va_arg(ap, char *); } va_end(ap); /* Save the view */ { String *view = Getattr(n,"view"); if (view) { if (Strcmp(view,ns) != 0) { strcpy(temp,ns); strcat(temp,":view"); Setattr(n,temp,view); Setattr(n,"view",ns); } } else { Setattr(n,"view",ns); } } return 1; } void Swig_restore(Node *n) { char temp[512]; int len; List *l; String *ns; Iterator ki; ns = Getattr(n,"view"); assert(ns); l = NewList(); strcpy(temp,Char(ns)); strcat(temp,":"); len = strlen(temp); for (ki = First(n); ki.key; ki = Next(ki)) { if (Strncmp(temp,ki.key,len) == 0) { Append(l,ki.key); } } for (ki = First(l); ki.item; ki = Next(ki)) { DOH *obj = Getattr(n,ki.item); Setattr(n,Char(ki.item)+len,obj); Delattr(n,ki.item); } Delete(l); } cableswig-0.1.0+git20150808.orig/SWIG/Source/Swig/parms.c0000644000175000000620000001115212561312227021235 0ustar stevestaff/* ----------------------------------------------------------------------------- * parms.cxx * * Parameter list class. * * !!! This file is deprecated and is being replaced !!! * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1998-2000. The University of Chicago * Copyright (C) 1995-1998. The University of Utah and The Regents of the * University of California. * * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_parms_c[] = "/cvsroot/SWIG/Source/Swig/parms.c,v 1.8 2004/01/15 22:46:07 cheetah Exp"; #include "swig.h" #define MAXPARMS 16 /* ------------------------------------------------------------------------ * NewParm() * * Create a new parameter from datatype 'type' and name 'n'. * ------------------------------------------------------------------------ */ Parm *NewParm(SwigType *type, const String_or_char *n) { Parm *p = NewHash(); if (type) { Setattr(p,"type", Copy(type)); } Setattr(p,"name",n); return p; } /* ------------------------------------------------------------------------ * CopyParm() * ------------------------------------------------------------------------ */ Parm *CopyParm(Parm *p) { SwigType *t; String *name; String *lname; String *value; String *ignore; String *alttype; String *byname; Parm *np = NewHash(); t = Getattr(p,"type"); name = Getattr(p,"name"); lname = Getattr(p,"lname"); value = Getattr(p,"value"); ignore = Getattr(p,"ignore"); alttype = Getattr(p,"alttype"); byname = Getattr(p, "arg:byname"); if (t) Setattr(np,"type",Copy(t)); if (name) Setattr(np,"name",Copy(name)); if (lname) Setattr(np,"lname", Copy(lname)); if (value) Setattr(np,"value", Copy(value)); if (ignore) Setattr(np,"ignore", Copy(ignore)); if (alttype) Setattr(np,"alttype", Copy(alttype)); if (byname) Setattr(np, "arg:byname", Copy(byname)); Setfile(np,Getfile(p)); Setline(np,Getline(p)); return np; } /* ------------------------------------------------------------------ * CopyParmList() * ------------------------------------------------------------------ */ ParmList * CopyParmList(ParmList *p) { Parm *np; Parm *pp = 0; Parm *fp = 0; if (!p) return 0; while (p) { np = CopyParm(p); if (pp) { set_nextSibling(pp,np); } else { fp = np; } pp = np; p = nextSibling(p); } return fp; } /* ------------------------------------------------------------------ * int ParmList_numarg() * ------------------------------------------------------------------ */ int ParmList_numarg(ParmList *p) { int n = 0; while (p) { if (!Getattr(p,"ignore")) n++; p = nextSibling(p); } return n; } /* ----------------------------------------------------------------------------- * int ParmList_numrequired(). Return number of required arguments * ----------------------------------------------------------------------------- */ int ParmList_numrequired(ParmList *p) { int i = 0; while (p) { SwigType *t = Getattr(p,"type"); String *value = Getattr(p,"value"); if (value) return i; if (!(SwigType_type(t) == T_VOID)) i++; else break; p = nextSibling(p); } return i; } /* ----------------------------------------------------------------------------- * int ParmList_len() * ----------------------------------------------------------------------------- */ int ParmList_len(ParmList *p) { int i = 0; while (p) { i++; p = nextSibling(p); } return i; } /* --------------------------------------------------------------------- * ParmList_str() * * Generates a string of parameters * ---------------------------------------------------------------------- */ String *ParmList_str(ParmList *p) { String *out; SwigType *t; out = NewString(""); while(p) { t = Getattr(p,"type"); Printf(out,"%s", SwigType_str(t,Getattr(p,"name"))); p = nextSibling(p); if (p) Printf(out,","); } return out; } /* --------------------------------------------------------------------- * ParmList_str() * * Generate a prototype string. * ---------------------------------------------------------------------- */ String *ParmList_protostr(ParmList *p) { String *out; SwigType *t; out = NewString(""); while(p) { if (Getattr(p,"hidden")) { p = nextSibling(p); continue; } t = Getattr(p,"type"); Printf(out,"%s", SwigType_str(t,0)); p = nextSibling(p); if (p) Printf(out,","); } return out; } cableswig-0.1.0+git20150808.orig/SWIG/Source/Swig/scanner.c0000644000175000000620000005210112561312227021543 0ustar stevestaff/* ----------------------------------------------------------------------------- * scanner.c * * This file implements a general purpose C/C++ compatible lexical scanner. * This scanner isn't intended to be plugged directly into a parser built * with yacc. Rather, it contains a lot of generic code that could be used * to easily construct yacc-compatible scanners. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_scanner_c[] = "/cvsroot/SWIG/Source/Swig/scanner.c,v 1.13 2003/10/31 17:48:02 beazley Exp"; #include "swig.h" #include struct SwigScanner { String *text; /* Current token value */ List *scanobjs; /* Objects being scanned */ String *str; /* Current object being scanned */ char *idstart; /* Optional identifier start characters */ int nexttoken; /* Next token to be returned */ int start_line; /* Starting line of certain declarations */ int string_start; int line; int yylen; /* Length of text pushed into text */ String *file; }; /* ----------------------------------------------------------------------------- * NewSwigScanner() * * Create a new scanner object * ----------------------------------------------------------------------------- */ SwigScanner * NewSwigScanner() { SwigScanner *s; s = (SwigScanner *) malloc(sizeof(SwigScanner)); s->line = 1; s->file = 0; s->nexttoken = -1; s->start_line = 1; s->string_start = 0; s->yylen = 0; s->idstart = ""; s->scanobjs = NewList(); s->text = NewString(""); s->str = 0; return s; } /* ----------------------------------------------------------------------------- * DelSwigScanner() * * Delete a scanner object. * ----------------------------------------------------------------------------- */ void DelSwigScanner(SwigScanner *s) { assert(s); Delete(s->scanobjs); Delete(s->text); Delete(s->file); free(s); } /* ----------------------------------------------------------------------------- * SwigScanner_clear() * * Clear the contents of a scanner object. * ----------------------------------------------------------------------------- */ void SwigScanner_clear(SwigScanner *s) { assert(s); Delete(s->str); Clear(s->text); Clear(s->scanobjs); s->line = 1; s->nexttoken = -1; s->start_line = 0; s->string_start = 0; s->yylen = 0; } /* ----------------------------------------------------------------------------- * SwigScanner_push() * * Push some new text into the scanner. The scanner will start parsing this text * immediately before returning to the old text. * ----------------------------------------------------------------------------- */ void SwigScanner_push(SwigScanner *s, String *txt) { assert(s && txt); Push(s->scanobjs,txt); if (s->str) Delete(s->str); s->str = txt; DohIncref(s->str); s->line = Getline(txt); } /* ----------------------------------------------------------------------------- * SwigScanner_pushtoken() * * Push a token into the scanner. This token will be returned on the next * call to SwigScanner_token(). * ----------------------------------------------------------------------------- */ void SwigScanner_pushtoken(SwigScanner *s, int nt) { assert(s); assert((nt >= 0) && (nt < SWIG_MAXTOKENS)); s->nexttoken = nt; } /* ----------------------------------------------------------------------------- * SwigScanner_set_location() * * Set the file and line number location of the scanner. * ----------------------------------------------------------------------------- */ void SwigScanner_set_location(SwigScanner *s, String *file, int line) { Setline(s->str,line); Setfile(s->str,file); } /* ----------------------------------------------------------------------------- * SwigScanner_get_file() * * Get the current file. * ----------------------------------------------------------------------------- */ String * SwigScanner_get_file(SwigScanner *s) { return Getfile(s->str); } /* ----------------------------------------------------------------------------- * SwigScanner_get_line() * * Get the current line number * ----------------------------------------------------------------------------- */ int SwigScanner_get_line(SwigScanner *s) { return Getline(s->str); } /* ----------------------------------------------------------------------------- * SwigScanner_idstart() * * Change the set of additional characters that can be used to start an identifier. * ----------------------------------------------------------------------------- */ void SwigScanner_idstart(SwigScanner *s, char *id) { s->idstart = Swig_copy_string(id); } /* ----------------------------------------------------------------------------- * nextchar() * * Returns the next character from the scanner or 0 if end of the string. * ----------------------------------------------------------------------------- */ static char nextchar(SwigScanner *s) { char c[2] = {0,0}; int nc; if (!s->str) return 0; while ((nc = Getc(s->str)) == EOF) { Delete(s->str); s->str = 0; Delitem(s->scanobjs,0); if (Len(s->scanobjs) == 0) return 0; s->str = Getitem(s->scanobjs,0); if (s->str) { s->line = Getline(s->str); DohIncref(s->str); } } if (nc == '\n') s->line++; c[0] = (char) nc; c[1] = 0; Append(s->text,c); return c[0]; } /* ----------------------------------------------------------------------------- * retract() * * Retract n characters * ----------------------------------------------------------------------------- */ static void retract(SwigScanner *s, int n) { int i, l; char *str; str = Char(s->text); l = Len(s->text); assert(n <= l); for (i = 0; i < n; i++) { if (str[l-1] == '\n') { s->line--; } /* // Ungetc(str[l-1],s->str); */ Seek(s->str,-1, SEEK_CUR); Delitem(s->text,DOH_END); } } /* ----------------------------------------------------------------------------- * look() * * Return the raw value of the next token. * ----------------------------------------------------------------------------- */ static int look(SwigScanner *s) { int state; int c = 0; state = 0; Clear(s->text); Setline(s->text, Getline(s->str)); Setfile(s->text, Getfile(s->str)); while(1) { switch(state) { case 0 : if((c = nextchar(s)) == 0) return(0); /* Process delimeters */ if (c == '\n') { return SWIG_TOKEN_ENDLINE; } else if (!isspace(c)) { retract(s,1); state = 1000; Clear(s->text); Setline(s->text, Getline(s->str)); Setfile(s->text, Getfile(s->str)); } break; case 1000: if ((c = nextchar(s)) == 0) return (0); if (c == '%') state = 4; /* Possibly a SWIG directive */ /* Look for possible identifiers */ else if ((isalpha(c)) || (c == '_') || (strchr(s->idstart,c))) state = 7; /* Look for single character symbols */ else if (c == '(') return SWIG_TOKEN_LPAREN; else if (c == ')') return SWIG_TOKEN_RPAREN; else if (c == ';') return SWIG_TOKEN_SEMI; else if (c == ',') return SWIG_TOKEN_COMMA; else if (c == '*') return SWIG_TOKEN_STAR; else if (c == '}') return SWIG_TOKEN_RBRACE; else if (c == '{') return SWIG_TOKEN_LBRACE; else if (c == '=') state = 33; else if (c == '+') return SWIG_TOKEN_PLUS; else if (c == '-') return SWIG_TOKEN_MINUS; else if (c == '&') state = 31; else if (c == '|') state = 32; else if (c == '^') return SWIG_TOKEN_XOR; else if (c == '<') state = 60; else if (c == '>') state = 61; else if (c == '~') return SWIG_TOKEN_NOT; else if (c == '!') state = 3; else if (c == '\\') return SWIG_TOKEN_BACKSLASH; else if (c == '[') return SWIG_TOKEN_LBRACKET; else if (c == ']') return SWIG_TOKEN_RBRACKET; else if (c == '@') return SWIG_TOKEN_AT; else if (c == '$') return SWIG_TOKEN_DOLLAR; else if (c == '#') return SWIG_TOKEN_POUND; /* Look for multi-character sequences */ else if (c == '/') state = 1; /* Comment (maybe) */ else if (c == '\"') { state = 2; /* Possibly a string */ s->string_start = s->line; } else if (c == ':') state = 5; /* maybe double colon */ else if (c == '0') state = 83; /* An octal or hex value */ else if (c == '\'') { s->string_start = s->line; state = 9; /* A character constant */ } else if (c == '`') { s->string_start = s->line; state = 900; } else if (c == '.') state = 100; /* Maybe a number, maybe just a period */ else if (isdigit(c)) state = 8; /* A numerical value */ else state = 99; /* An error */ break; case 1: /* Comment block */ if ((c = nextchar(s)) == 0) return(0); if (c == '/') { state = 10; /* C++ style comment */ Clear(s->text); Setline(s->text, Getline(s->str)); Setfile(s->text, Getfile(s->str)); Append(s->text," "); } else if (c == '*') { state = 11; /* C style comment */ Clear(s->text); Setline(s->text, Getline(s->str)); Setfile(s->text, Getfile(s->str)); Append(s->text," "); } else { retract(s,1); return SWIG_TOKEN_SLASH; } break; case 10: /* C++ style comment */ if ((c = nextchar(s)) == 0) { /* add_error(0,"Unterminated comment",comment_start); */ return 0; } if (c == '\n') { return SWIG_TOKEN_ENDLINE; } else { state = 10; } break; case 11: /* C style comment block */ if ((c = nextchar(s)) == 0) { /* add_error(0,"Unterminated comment",comment_start); */ return 0; } if (c == '*') { state = 12; } else { state = 11; } break; case 12: /* Still in C style comment */ if ((c = nextchar(s)) == 0) { /* add_error(0,"Unterminated comment",comment_start); */ return 0; } if (c == '*') { state = 12; } else if (c == '/') { Clear(s->text); state = 0; } else { state = 11; } break; case 2: /* Processing a string */ if ((c = nextchar(s)) == 0) { /* add_error(0,"Unterminated string", string_start); */ return 0; } if (c == '\"') { return SWIG_TOKEN_STRING; } else if (c == '\\') { state = 21; /* Possibly an escape sequence. */ break; } else state = 2; break; case 21: /* An escape sequence. get next character, then go back to processing strings */ if ((c = nextchar(s)) == 0) return 0; state = 2; break; case 3: /* Maybe a not equals */ if ((c = nextchar(s)) == 0) return SWIG_TOKEN_LNOT; else if (c == '=') return SWIG_TOKEN_NOTEQUAL; else { retract(s,1); return SWIG_TOKEN_LNOT; } break; case 31: /* AND or Logical AND */ if ((c = nextchar(s)) == 0) return SWIG_TOKEN_AND; else if (c == '&') return SWIG_TOKEN_LAND; else { retract(s,1); return SWIG_TOKEN_AND; } break; case 32: /* OR or Logical OR */ if ((c = nextchar(s)) == 0) return SWIG_TOKEN_OR; else if (c == '|') return SWIG_TOKEN_LOR; else { retract(s,1); return SWIG_TOKEN_OR; } break; case 33: /* EQUAL or EQUALTO */ if ((c = nextchar(s)) == 0) return SWIG_TOKEN_EQUAL; else if (c == '=') return SWIG_TOKEN_EQUALTO; else { retract(s,1); return SWIG_TOKEN_EQUAL; } break; case 4: /* A wrapper generator directive (maybe) */ if (( c= nextchar(s)) == 0) return SWIG_TOKEN_PERCENT; if (c == '{') { state = 40; /* Include block */ Clear(s->text); Setline(s->text, Getline(s->str)); Setfile(s->text, Getfile(s->str)); s->start_line = s->line; } else if (strchr(s->idstart,'%') && ((isalpha(c)) || (c == '_'))) state = 7; else { retract(s,1); return SWIG_TOKEN_PERCENT; } break; case 40: /* Process an include block */ if ((c = nextchar(s)) == 0) { /* add_error(0,"Unterminated code block.", start_line); */ return 0; } if (c == '%') state = 41; break; case 41: /* Still processing include block */ if ((c = nextchar(s)) == 0) { /* add_error(0,"Unterminated code block.", start_line); */ return 0; } if (c == '}') { Delitem(s->text,DOH_END); Delitem(s->text,DOH_END); return SWIG_TOKEN_CODEBLOCK; } else { state = 40; } break; case 5: /* Maybe a double colon */ if (( c = nextchar(s)) == 0) return SWIG_TOKEN_COLON; if ( c == ':') return SWIG_TOKEN_DCOLON; else { retract(s,1); return SWIG_TOKEN_COLON; } break; case 60: /* shift operators */ if ((c = nextchar(s)) == 0) return SWIG_TOKEN_LESSTHAN; if (c == '<') return SWIG_TOKEN_LSHIFT; else if (c == '=') return SWIG_TOKEN_LTEQUAL; else { retract(s,1); return SWIG_TOKEN_LESSTHAN; } break; case 61: if ((c = nextchar(s)) == 0) return SWIG_TOKEN_GREATERTHAN; if (c == '>') return SWIG_TOKEN_RSHIFT; else if (c == '=') return SWIG_TOKEN_GTEQUAL; else { retract(s,1); return SWIG_TOKEN_GREATERTHAN; } break; case 7: /* Identifier */ if ((c = nextchar(s)) == 0) return SWIG_TOKEN_ID; if (isalnum(c) || (c == '_') || (c == '$')) { state = 7; } else { retract(s,1); return SWIG_TOKEN_ID; } break; case 8: /* A numerical digit */ if ((c = nextchar(s)) == 0) return SWIG_TOKEN_INT; if (c == '.') {state = 81;} else if ((c == 'e') || (c == 'E')) {state = 86;} else if ((c == 'f') || (c == 'F')) { Delitem(s->text,DOH_END); return SWIG_TOKEN_FLOAT; } else if (isdigit(c)) { state = 8;} else if ((c == 'l') || (c == 'L')) { state = 87; } else if ((c == 'u') || (c == 'U')) { state = 88; } else { retract(s,1); return SWIG_TOKEN_INT; } break; case 81: /* A floating pointer number of some sort */ if ((c = nextchar(s)) == 0) return SWIG_TOKEN_DOUBLE; if (isdigit(c)) state = 81; else if ((c == 'e') || (c == 'E')) state = 82; else if ((c == 'f') || (c == 'F') || (c == 'l') || (c == 'L')) { Delitem(s->text,DOH_END); return SWIG_TOKEN_FLOAT; } else { retract(s,1); return(SWIG_TOKEN_DOUBLE); } break; case 82: if ((c = nextchar(s)) == 0) { retract(s,1); return SWIG_TOKEN_INT; } if ((isdigit(c)) || (c == '-') || (c == '+')) state = 86; else { retract(s,2); return(SWIG_TOKEN_INT); } break; case 83: /* Might be a hexidecimal or octal number */ if ((c = nextchar(s)) == 0) return SWIG_TOKEN_INT; if (isdigit(c)) state = 84; else if ((c == 'x') || (c == 'X')) state = 85; else if (c == '.') state = 81; else if ((c == 'l') || (c == 'L')) { state = 87; } else if ((c == 'u') || (c == 'U')) { state = 88; } else { retract(s,1); return SWIG_TOKEN_INT; } break; case 84: /* This is an octal number */ if ((c = nextchar(s)) == 0) return SWIG_TOKEN_INT; if (isdigit(c)) state = 84; else if ((c == 'l') || (c == 'L')) { state = 87; } else if ((c == 'u') || (c == 'U')) { state = 88; } else { retract(s,1); return SWIG_TOKEN_INT; } break; case 85: /* This is an hex number */ if ((c = nextchar(s)) == 0) return SWIG_TOKEN_INT; if ((isdigit(c)) || (c=='a') || (c=='b') || (c=='c') || (c=='d') || (c=='e') || (c=='f') || (c=='A') || (c=='B') || (c=='C') || (c=='D') || (c=='E') || (c=='F')) state = 85; else if ((c == 'l') || (c == 'L')) { state = 87; } else if ((c == 'u') || (c == 'U')) { state = 88; } else { retract(s,1); return SWIG_TOKEN_INT; } break; case 86: /* Rest of floating point number */ if ((c = nextchar(s)) == 0) return SWIG_TOKEN_DOUBLE; if (isdigit(c)) state = 86; else if ((c == 'f') || (c == 'F')) { Delitem(s->text,DOH_END); return SWIG_TOKEN_FLOAT; } else if ((c == 'l') || (c == 'L')) { Delitem(s->text,DOH_END); return SWIG_TOKEN_DOUBLE; } else { retract(s,1); return SWIG_TOKEN_DOUBLE; } break; case 87 : /* A long integer of some sort */ if ((c = nextchar(s)) == 0) return SWIG_TOKEN_LONG; if ((c == 'u') || (c == 'U')) { return SWIG_TOKEN_ULONG; } else if ((c == 'l') || (c == 'L')) { state = 870; } else { retract(s,1); return SWIG_TOKEN_LONG; } break; /* A long long integer */ case 870: if ((c = nextchar(s)) == 0) return SWIG_TOKEN_LONGLONG; if ((c == 'u') || (c == 'U')) { return SWIG_TOKEN_ULONGLONG; } else { retract(s,1); return SWIG_TOKEN_LONGLONG; } /* An unsigned number */ case 88: if ((c = nextchar(s)) == 0) return SWIG_TOKEN_UINT; if ((c == 'l') || (c == 'L')) { state = 880; } else { retract(s,1); return SWIG_TOKEN_UINT; } break; /* Possibly an unsigned long long or unsigned long */ case 880: if ((c = nextchar(s)) == 0) return SWIG_TOKEN_ULONG; if ((c == 'l') || (c == 'L')) return SWIG_TOKEN_ULONGLONG; else { retract(s,1); return SWIG_TOKEN_ULONG; } /* A character constant */ case 9: if ((c = nextchar(s)) == 0) { /* add_error(0,"Unterminated character constant", string_start); */ return 0; } if (c == '\'') { return(SWIG_TOKEN_CHAR); } else if (c == '\\') state = 91; break; case 91: if ((c = nextchar(s)) == 0) { /* add_error(0,"Unterminated character constant", string_start); */ return 0; } state = 9; break; /* A period or maybe a floating point number */ case 100: if ((c = nextchar(s)) == 0) return (0); if (isdigit(c)) state = 81; else { retract(s,1); return SWIG_TOKEN_PERIOD; } break; /* An illegal character */ /* Reverse string */ case 900: if ((c = nextchar(s)) == 0) { /* add_error(0,"Unterminated character constant", string_start); */ return 0; } if (c == '`') { return(SWIG_TOKEN_RSTRING); } break; default: return SWIG_TOKEN_ILLEGAL; } } } /* ----------------------------------------------------------------------------- * SwigScanner_token() * * Real entry point to return the next token. Returns 0 if at end of input. * ----------------------------------------------------------------------------- */ int SwigScanner_token(SwigScanner *s) { int t; Clear(s->text); if (s->nexttoken >= 0) { t = s->nexttoken; s->nexttoken = -1; return t; } t = look(s); return t; } /* ----------------------------------------------------------------------------- * SwigScanner_text() * * Return the lexene associated with the last returned token. * ----------------------------------------------------------------------------- */ String * SwigScanner_text(SwigScanner *s) { return s->text; } /* ----------------------------------------------------------------------------- * SwigScanner_skip_line() * * Skips to the end of a line * ----------------------------------------------------------------------------- */ void SwigScanner_skip_line(SwigScanner *s) { char c; int done = 0; Clear(s->text); Setfile(s->text,Getfile(s->str)); Setline(s->text,Getline(s->str)); while (!done) { if ((c = nextchar(s)) == 0) return; if (c == '\\') c = nextchar(s); else if (c == '\n') done = 1; } return; } /* ----------------------------------------------------------------------------- * SwigScanner_skip_balanced() * * Skips a piece of code enclosed in begin/end symbols such as '{...}' or * (...). Ignores symbols inside comments or strings. * ----------------------------------------------------------------------------- */ int SwigScanner_skip_balanced(SwigScanner *s, int startchar, int endchar) { char c; int num_levels = 1; int l; int state = 0; char temp[2] = {0,0}; l = s->line; temp[0] = (char) startchar; Clear(s->text); Setfile(s->text,Getfile(s->str)); Setline(s->text,Getline(s->str)); Append(s->text,temp); while (num_levels > 0) { if ((c = nextchar(s)) == 0) { return -1; } switch(state) { case 0: if (c == startchar) num_levels++; else if (c == endchar) num_levels--; else if (c == '/') state = 10; else if (c == '\"') state = 20; else if (c == '\'') state = 30; break; case 10: if (c == '/') state = 11; else if (c == '*') state = 12; else state = 0; break; case 11: if (c == '\n') state = 0; else state = 11; break; case 12: if (c == '*') state = 13; break; case 13: if (c == '*') state = 13; else if (c == '/') state = 0; else state = 12; break; case 20: if (c == '\"') state = 0; else if (c == '\\') state = 21; break; case 21: state = 20; break; case 30: if (c == '\'') state = 0; else if (c == '\\') state = 31; break; case 31: state = 30; break; default: break; } } return 0; } cableswig-0.1.0+git20150808.orig/SWIG/Source/Swig/typesys.c0000644000175000000620000013635012561312227021643 0ustar stevestaff/* ----------------------------------------------------------------------------- * typesys.c * * SWIG type system management. These functions are used to manage * the C++ type system including typenames, typedef, type scopes, * inheritance, and namespaces. Generation of support code for the * run-time type checker is also handled here. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_typesys_c[] = "/cvsroot/SWIG/Source/Swig/typesys.c,v 1.14 2004/02/10 08:37:30 mmatus Exp"; #include "swig.h" /* ----------------------------------------------------------------------------- * Synopsis * * The purpose of this module is to manage type names and scoping issues related * to the C++ type system. The primary use is tracking typenames through typedef * and inheritance. * * New typenames are introduced by typedef, class, and enum declarations. * Each type is declared in a scope. This is either the global scope, a * class, or a namespace. For example: * * typedef int A; // Typename A, in global scope * namespace Foo { * typedef int A; // Typename A, in scope Foo:: * } * class Bar { // Typename Bar, in global scope * typedef int A; // Typename A, in scope Bar:: * } * * To manage scopes, the type system is constructed as a tree of hash tables. Each * hash table contains the following attributes: * * "name" - Scope name * "qname" - Fully qualified typename * "typetab" - Type table containing typenames and typedef information * "symtab" - Hash table of symbols defined in a scope * "inherit" - List of inherited scopes * "parent" - Parent scope * * Typedef information is stored in the "typetab" hash table. For example, * if you have these declarations: * * typedef int A; * typedef A B; * typedef B *C; * * typetab is built as follows: * * "A" : "int" * "B" : "A" * "C" : "p.B" * * To resolve a type back to its root type, one repeatedly expands on the type base. * For example: * * C *[40] ---> a(40).p.C (string type representation, see stype.c) * ---> a(40).p.p.B (C --> p.B) * ---> a(40).p.p.A (B --> A) * ---> a(40).p.p.int (A --> int) * * For inheritance, SWIG tries to resolve types back to the base class. For instance, if * you have this: * * class Foo { * public: * typedef int Integer; * }; * * class Bar : public Foo { * void blah(Integer x); * } * * The argument type of Bar::blah will be set to Foo::Integer. * * The scope-inheritance mechanism is used to manage C++ namespace aliases. * For example, if you have this: * * namespace Foo { * typedef int Integer; * } * * namespace F = Foo; * * In this case, "F::" is defined as a scope that "inherits" from Foo. Internally, * "F::" will merely be an empty scope that refers to Foo. SWIG will never * place new type information into a namespace alias---attempts to do so * will generate a warning message (in the parser) and will place information into * Foo instead. * *----------------------------------------------------------------------------- */ static Typetab *current_scope = 0; /* Current type scope */ static Hash *current_typetab = 0; /* Current type table */ static Hash *current_symtab = 0; /* Current symbol table */ static Typetab *global_scope = 0; /* The global scope */ static Hash *scopes = 0; /* Hash table containing fully qualified scopes */ /* Performance optimization */ #define SWIG_TYPEDEF_RESOLVE_CACHE static Hash *typedef_resolve_cache = 0; static Hash *typedef_all_cache = 0; static Hash *typedef_qualified_cache = 0; /* common attribute keys, to avoid calling find_key all the times */ static String *k_name = 0; static String *k_qname = 0; static String *k_symtab = 0; static String *k_using = 0; static String *k_scope = 0; static String *k_typetab = 0; static String *k_inherit = 0; static String *k_parent = 0; static String *k_value = 0; static void flush_cache() { typedef_resolve_cache = 0; typedef_all_cache = 0; typedef_qualified_cache = 0; } /* Initialize the scoping system */ void SwigType_typesystem_init() { k_name = NewString("name"); k_qname = NewString("qname"); k_symtab = NewString("symtab"); k_using = NewString("using"); k_scope = NewString("scope"); k_typetab = NewString("typetab"); k_inherit = NewString("inherit"); k_parent = NewString("parent"); k_value = NewString("value"); if (global_scope) Delete(global_scope); if (scopes) Delete(scopes); current_scope = NewHash(); global_scope = current_scope; Setattr(current_scope,k_name,""); /* No name for global scope */ current_typetab = NewHash(); Setattr(current_scope,k_typetab, current_typetab); current_symtab = 0; scopes = NewHash(); Setattr(scopes,"",current_scope); } /* ----------------------------------------------------------------------------- * SwigType_typedef() * * Defines a new typedef in the current scope. Returns -1 if the type name is * already defined. * ----------------------------------------------------------------------------- */ int SwigType_typedef(SwigType *type, String_or_char *name) { Typetab *SwigType_find_scope(Typetab *, String *s); if (Getattr(current_typetab, name)) return -1; /* Already defined */ if (Strcmp(type,name) == 0) { /* Can't typedef a name to itself */ return 0; } /* Check if 'type' is already a scope. If so, we create an alias in the type system for it. This is needed to make strange nested scoping problems work correctly. */ { Typetab *t = SwigType_find_scope(current_scope,type); if (t) { SwigType_new_scope(name); SwigType_inherit_scope(t); SwigType_pop_scope(); } } Setattr(current_typetab,name,type); flush_cache(); return 0; } /* ----------------------------------------------------------------------------- * SwigType_typedef_class() * * Defines a class in the current scope. * ----------------------------------------------------------------------------- */ int SwigType_typedef_class(String_or_char *name) { String *cname; /* Printf(stdout,"class : '%s'\n", name); */ if (Getattr(current_typetab, name)) return -1; /* Already defined */ cname = NewString(name); Setmeta(cname,"class","1"); Setattr(current_typetab,cname,cname); Delete(cname); flush_cache(); return 0; } /* ----------------------------------------------------------------------------- * SwigType_scope_name() * * Returns the qualified scope name of a type table * ----------------------------------------------------------------------------- */ String * SwigType_scope_name(Typetab *ttab) { String *qname = NewString(Getattr(ttab,k_name)); ttab = Getattr(ttab,k_parent); while (ttab) { String *pname = Getattr(ttab,k_name); if (Len(pname)) { Insert(qname,0,"::"); Insert(qname,0,pname); } ttab = Getattr(ttab,k_parent); } return qname; } /* ----------------------------------------------------------------------------- * SwigType_new_scope() * * Creates a new scope * ----------------------------------------------------------------------------- */ void SwigType_new_scope(const String_or_char *name) { Typetab *s; Hash *ttab; String *qname; if (!name) { name = ""; } s = NewHash(); Setattr(s,k_name, name); Setattr(s,k_parent, current_scope); ttab = NewHash(); Setattr(s,k_typetab, ttab); /* Build fully qualified name and */ qname = SwigType_scope_name(s); Setattr(scopes,qname,s); Setattr(s,k_qname,qname); Delete(qname); current_scope = s; current_typetab = ttab; current_symtab = 0; flush_cache(); } /* ----------------------------------------------------------------------------- * SwigType_inherit_scope() * * Makes the current scope inherit from another scope. This is used for both * C++ class inheritance, namespaces, and namespace aliases. * ----------------------------------------------------------------------------- */ void SwigType_inherit_scope(Typetab *scope) { List *inherits; int i, len; inherits = Getattr(current_scope,k_inherit); if (!inherits) { inherits = NewList(); Setattr(current_scope,k_inherit, inherits); } assert(scope != current_scope); len = Len(inherits); for (i = 0; i < len; i++) { Node *n = Getitem(inherits,i); if (n == scope) return; } Append(inherits,scope); } /* ----------------------------------------------------------------------------- * SwigType_scope_alias() * * Creates a scope-alias. * ----------------------------------------------------------------------------- */ void SwigType_scope_alias(String *aliasname, Typetab *ttab) { String *q; /* Printf(stdout,"alias: '%s' '%x'\n", aliasname, ttab);*/ q = SwigType_scope_name(current_scope); if (Len(q)) { Append(q,"::"); } Append(q,aliasname); Setattr(scopes,q,ttab); flush_cache(); } /* ----------------------------------------------------------------------------- * SwigType_using_scope() * * Import another scope into this scope. * ----------------------------------------------------------------------------- */ void SwigType_using_scope(Typetab *scope) { SwigType_inherit_scope(scope); { List *ulist; int i, len; ulist = Getattr(current_scope,k_using); if (!ulist) { ulist = NewList(); Setattr(current_scope,k_using, ulist); } assert(scope != current_scope); len = Len(ulist); for (i = 0; i < len; i++) { Typetab *n = Getitem(ulist,i); if (n == scope) return; } Append(ulist,scope); } flush_cache(); } /* ----------------------------------------------------------------------------- * SwigType_pop_scope() * * Pop off the last scope and perform a merge operation. Returns the hash * table for the scope that was popped off. * ----------------------------------------------------------------------------- */ Typetab *SwigType_pop_scope() { Typetab *s, *s1; s = Getattr(current_scope,k_parent); if (!s) { current_scope = 0; current_typetab = 0; current_symtab = 0; return 0; } s1 = current_scope; current_scope = s; current_typetab = Getattr(s,k_typetab); current_symtab = Getattr(s,k_symtab); flush_cache(); return s1; } /* ----------------------------------------------------------------------------- * SwigType_set_scope() * * Set the scope. Returns the old scope. * ----------------------------------------------------------------------------- */ Typetab * SwigType_set_scope(Typetab *t) { Typetab *old = current_scope; if (!t) t = global_scope; current_scope = t; current_typetab = Getattr(t,k_typetab); current_symtab = Getattr(t,k_symtab); flush_cache(); return old; } /* ----------------------------------------------------------------------------- * SwigType_attach_symtab() * * Attaches a symbol table to a type scope * ----------------------------------------------------------------------------- */ void SwigType_attach_symtab(Symtab *sym) { Setattr(current_scope,k_symtab,sym); current_symtab = sym; } /* ----------------------------------------------------------------------------- * SwigType_print_scope() * * Debugging function for printing out current scope * ----------------------------------------------------------------------------- */ void SwigType_print_scope(Typetab *t) { Hash *ttab; Iterator i,j; for (i = First(scopes); i.key; i = Next(i)) { t = i.item; ttab = Getattr(i.item,k_typetab); Printf(stdout,"Type scope '%s' (%x)\n", i.key, i.item); { List *inherit = Getattr(i.item,k_inherit); if (inherit) { Iterator j; for (j = First(inherit); j.item; j = Next(j)) { Printf(stdout," Inherits from '%s' (%x)\n", Getattr(j.item,k_qname), j.item); } } } Printf(stdout,"-------------------------------------------------------------\n"); for (j = First(ttab); j.key; j = Next(j)) { Printf(stdout,"%40s -> %s\n", j.key, j.item); } } } Typetab * SwigType_find_scope(Typetab *s, String *nameprefix) { Typetab *ss; String *nnameprefix = 0; static int check_parent = 1; /* Printf(stdout,"find_scope: %x(%s) '%s'\n", s, Getattr(s,"name"), nameprefix); */ if (SwigType_istemplate(nameprefix)) { nnameprefix = SwigType_typedef_resolve_all(nameprefix); nameprefix = nnameprefix; } ss = s; while (ss) { String *full; String *qname = Getattr(ss,k_qname); if (qname) { full = NewStringf("%s::%s", qname, nameprefix); } else { full = NewString(nameprefix); } if (Getattr(scopes,full)) { s = Getattr(scopes,full); } else { s = 0; } Delete(full); if (s) { if (nnameprefix) Delete(nnameprefix); return s; } if (!s) { /* Check inheritance */ List *inherit; inherit = Getattr(ss,k_using); if (inherit) { Typetab *ttab; int i, len; len = Len(inherit); for (i = 0; i < len; i++) { int oldcp = check_parent; ttab = Getitem(inherit,i); check_parent = 0; s = SwigType_find_scope(ttab,nameprefix); check_parent = oldcp; if (s) { if (nnameprefix) Delete(nnameprefix); return s; } } } } if (!check_parent) break; ss = Getattr(ss,k_parent); } if (nnameprefix) Delete(nnameprefix); return 0; } /* ----------------------------------------------------------------------------- * SwigType_typedef_resolve() * * Resolves a typedef and returns a new type string. Returns 0 if there is no * typedef mapping. base is a name without qualification. * ----------------------------------------------------------------------------- */ static Typetab *resolved_scope = 0; /* Internal function */ static SwigType * typedef_resolve(Typetab *s, String *base) { Hash *ttab; SwigType *type; List *inherit; Typetab *parent; /* if (!s) return 0; *//* now is checked bellow */ /* Printf(stdout,"Typetab %s : %s\n", Getattr(s,"name"), base); */ if (Getmark(s)) return 0; Setmark(s,1); ttab = Getattr(s,k_typetab); type = Getattr(ttab,base); if (type) { resolved_scope = s; Setmark(s,0); return type; } /* Hmmm. Not found in my scope. It could be in an inherited scope */ inherit = Getattr(s,k_inherit); if (inherit) { int i,len; len = Len(inherit); for (i = 0; i < len; i++) { type = typedef_resolve(Getitem(inherit,i), base); if (type) { Setmark(s,0); return type; } } } parent = Getattr(s,k_parent); type = parent ? typedef_resolve(parent, base) : 0; Setmark(s,0); return type; } SwigType *SwigType_typedef_resolve(SwigType *t) { String *base; String *type = 0; String *r = 0; Typetab *s; Hash *ttab; String *namebase = 0; String *nameprefix = 0; int newtype = 0; /* if (!noscope) { noscope = NewString(""); } */ resolved_scope = 0; #ifdef SWIG_TYPEDEF_RESOLVE_CACHE if (!typedef_resolve_cache) { typedef_resolve_cache = NewHash(); } r = Getattr(typedef_resolve_cache,t); if (r) { resolved_scope = Getmeta(r,k_scope); return Copy(r); } #endif base = SwigType_base(t); /* Printf(stdout,"base = '%s'\n", base); */ if (SwigType_issimple(base)) { s = current_scope; ttab = current_typetab; if (Strncmp(base,"::",2) == 0) { s = global_scope; ttab = Getattr(s,k_typetab); Delitem(base,0); Delitem(base,0); } /* Do a quick check in the local scope */ type = Getattr(ttab,base); if (type) { resolved_scope = s; } if (!type) { /* Didn't find in this scope. We need to do a little more searching */ if (Swig_scopename_check(base)) { /* A qualified name. */ nameprefix = Swig_scopename_prefix(base); /* Printf(stdout,"nameprefix = '%s'\n", nameprefix);*/ if (nameprefix) { /* Name had a prefix on it. See if we can locate the proper scope for it */ s = SwigType_find_scope(s,nameprefix); /* Couldn't locate a scope for the type. */ if (!s) { Delete(base); Delete(nameprefix); r = 0; goto return_result; } /* Try to locate the name starting in the scope */ namebase = Swig_scopename_last(base); /* Printf(stdout,"namebase = '%s'\n", namebase); */ type = typedef_resolve(s,namebase); /* Printf(stdout,"%s type = '%s'\n", Getattr(s,"name"), type); */ if ((type) && (!Swig_scopename_check(type))) { Typetab *rtab = resolved_scope; String *qname = Getattr(resolved_scope,k_qname); /* If qualified *and* the typename is defined from the resolved scope, we qualify */ if ((qname) && typedef_resolve(resolved_scope,type)) { type = Copy(type); Insert(type,0,"::"); Insert(type,0,qname); newtype = 1; } resolved_scope = rtab; } } else { /* Name is unqualified. */ type = typedef_resolve(s,base); } } else { /* Name is unqualified. */ type = typedef_resolve(s,base); } } if (type && (Strcmp(base,type) == 0)) { if (newtype) Delete(type); Delete(base); Delete(namebase); Delete(nameprefix); r = 0; goto return_result; } /* If the type is a template, and no typedef was found, we need to check the template arguments one by one to see if they can be resolved. */ if (!type && SwigType_istemplate(base)) { List *tparms; String *suffix; int i,sz; int rep = 0; type = SwigType_templateprefix(base); newtype = 1; suffix = SwigType_templatesuffix(base); Append(type,"<("); tparms = SwigType_parmlist(base); sz = Len(tparms); for (i = 0; i < sz; i++) { SwigType *tpr; SwigType *tp = Getitem(tparms, i); if (!rep) { tpr = SwigType_typedef_resolve(tp); } else { tpr = 0; } if (tpr) { Append(type,tpr); Delete(tpr); rep = 1; } else { Append(type,tp); } if ((i+1) < sz) Append(type,","); } Append(type,")>"); Append(type,suffix); Delete(suffix); Delete(tparms); if (!rep) { Delete(type); type = 0; } } if (namebase) Delete(namebase); if (nameprefix) Delete(nameprefix); namebase = 0; nameprefix = 0; } else { if (SwigType_isfunction(base)) { List *parms; int i,sz; int rep = 0; type = NewString("f("); newtype = 1; parms = SwigType_parmlist(base); sz = Len(parms); for (i = 0; i < sz; i++) { SwigType *tpr; SwigType *tp = Getitem(parms, i); if (!rep) { tpr = SwigType_typedef_resolve(tp); } else { tpr = 0; } if (tpr) { Append(type,tpr); Delete(tpr); rep = 1; } else { Append(type,tp); } if ((i+1) < sz) Append(type,","); } Append(type,")."); Delete(parms); if (!rep) { Delete(type); type = 0; } } else if (SwigType_ismemberpointer(base)) { String *rt; String *mtype = SwigType_parm(base); rt = SwigType_typedef_resolve(mtype); if (rt) { type = NewStringf("m(%s).", rt); newtype = 1; Delete(rt); } Delete(mtype); } else { type = 0; } } r = SwigType_prefix(t); if (!type) { if (r && Len(r)) { if ((Strstr(r,"f(") || (Strstr(r,"m(")))) { SwigType *rt = SwigType_typedef_resolve(r); if (rt) { Delete(r); Append(rt,base); Delete(base); r = rt; goto return_result; } } } Delete(r); Delete(base); r = 0; goto return_result; } Delete(base); Append(r,type); if (newtype) { Delete(type); } return_result: #ifdef SWIG_TYPEDEF_RESOLVE_CACHE { String *key = NewString(t); if (r) { SwigType *r1; Setattr(typedef_resolve_cache,key,r); Setmeta(r,k_scope,resolved_scope); r1 = Copy(r); Delete(r); r = r1; } Delete(key); } #endif return r; } /* ----------------------------------------------------------------------------- * SwigType_typedef_resolve_all() * * Fully resolve a type down to its most basic datatype * ----------------------------------------------------------------------------- */ SwigType *SwigType_typedef_resolve_all(SwigType *t) { SwigType *n; SwigType *r; if (!typedef_all_cache) { typedef_all_cache = NewHash(); } r = Getattr(typedef_all_cache,t); if (r) { return Copy(r); } r = NewString(t); while ((n = SwigType_typedef_resolve(r))) { Delete(r); r = n; } { String *key; SwigType *rr = Copy(r); key = NewString(t); Setattr(typedef_all_cache,key,rr); Delete(key); Delete(rr); } return r; } /* ----------------------------------------------------------------------------- * SwigType_typedef_qualified() * * Given a type declaration, this function tries to fully qualify it according to * typedef scope rules. * ----------------------------------------------------------------------------- */ SwigType *SwigType_typedef_qualified(SwigType *t) { List *elements; String *result; int i,len; if (!typedef_qualified_cache) typedef_qualified_cache = NewHash(); result = Getattr(typedef_qualified_cache,t); if (result) { String *rc = Copy(result); return rc; } result = NewString(""); elements = SwigType_split(t); len = Len(elements); for (i = 0; i < len; i++) { String *e = Getitem(elements,i); if (SwigType_issimple(e)) { if (!SwigType_istemplate(e)) { String *isenum = 0; if (SwigType_isenum(e)) { isenum = e; e = NewString(Char(e)+5); } resolved_scope = 0; if (typedef_resolve(current_scope,e)) { /* resolved_scope contains the scope that actually resolved the symbol */ String *qname = Getattr(resolved_scope,k_qname); if (qname) { Insert(e,0,"::"); Insert(e,0,qname); if (isenum) { Clear(isenum); Printf(isenum, "enum %s", e); Delete(e); } } } else { if (Swig_scopename_check(e)) { String *tqname; String *qlast; String *qname = Swig_scopename_prefix(e); if (qname) { qlast = Swig_scopename_last(e); tqname = SwigType_typedef_qualified(qname); Clear(e); Printf(e,"%s::%s", tqname, qlast); Delete(qname); Delete(qlast); Delete(tqname); } /* Automatic template instantiation might go here??? */ } else { /* It's a bare name. It's entirely possible, that the name is part of a namespace. We'll check this by unrolling out of the current scope */ Typetab *cs = current_scope; while (cs) { String *qs = SwigType_scope_name(cs); if (Len(qs)) { Append(qs,"::"); } Append(qs,e); if (Getattr(scopes,qs)) { Clear(e); Append(e,qs); Delete(qs); break; } Delete(qs); cs = Getattr(cs,k_parent); } } } if (isenum) e = isenum; } else { /* Template. We need to qualify template parameters as well as the template itself */ String *tprefix, *qprefix; String *tsuffix; Iterator pi; Parm *p; List *parms = SwigType_parmlist(e); tprefix = SwigType_templateprefix(e); tsuffix = SwigType_templatesuffix(e); qprefix = SwigType_typedef_qualified(tprefix); Printv(qprefix,"<(",NIL); pi = First(parms); while ((p = pi.item)) { String *qt = SwigType_typedef_qualified(p); if ((Strcmp(qt,p) == 0)) { /* && (!Swig_scopename_check(qt))) { */ /* No change in value. It is entirely possible that the parameter is an integer value. If there is a symbol table associated with this scope, we're going to check for this */ if (current_symtab) { Node *lastnode = 0; String *value = Copy(p); while (1) { Node *n = Swig_symbol_clookup(value,current_symtab); if (n == lastnode) break; lastnode = n; if (n) { if (Strcmp(nodeType(n),"enumitem") == 0) { /* An enum item. Generate a fully qualified name */ String *qn = Swig_symbol_qualified(n); if (Len(qn)) { Append(qn,"::"); Append(qn,Getattr(n,k_name)); Delete(value); value = qn; continue; } else { Delete(qn); break; } } else if ((Strcmp(nodeType(n),"cdecl") == 0) && (Getattr(n,k_value))) { Delete(value); value = Copy(Getattr(n,k_value)); continue; } } break; } Append(qprefix,value); Delete(value); } else { Append(qprefix,p); } } else { Append(qprefix,qt); } Delete(qt); pi= Next(pi); if (pi.item) { Append(qprefix,","); } } Append(qprefix,")>"); Append(qprefix,tsuffix); Delete(tsuffix); Clear(e); Append(e,qprefix); Delete(tprefix); Delete(qprefix); Delete(parms); } if (Strncmp(e,"::",2) == 0) { Delitem(e,0); Delitem(e,0); } Append(result,e); } else if (SwigType_isfunction(e)) { List *parms = SwigType_parmlist(e); String *s = NewString("f("); Iterator pi; pi = First(parms); while (pi.item) { String *pq = SwigType_typedef_qualified(pi.item); Append(s,pq); Delete(pq); pi = Next(pi); if (pi.item) { Append(s,","); } } Append(s,")."); Append(result,s); Delete(s); Delete(parms); } else if (SwigType_isarray(e)) { String *ndim; String *dim = SwigType_parm(e); ndim = Swig_symbol_string_qualify(dim,0); Printf(result,"a(%s).",ndim); Delete(dim); Delete(ndim); } else { Append(result,e); } } Delete(elements); { String *key, *cresult; key = NewString(t); cresult = NewString(result); Setattr(typedef_qualified_cache,key,cresult); Delete(key); Delete(cresult); } return result; } /* ----------------------------------------------------------------------------- * SwigType_istypedef() * * Checks a typename to see if it is a typedef. * ----------------------------------------------------------------------------- */ int SwigType_istypedef(SwigType *t) { String *type; type = SwigType_typedef_resolve(t); if (type) { Delete(type); return 1; } else { return 0; } } /* ----------------------------------------------------------------------------- * SwigType_typedef_using() * * Processes a 'using' declaration to import types from one scope into another. * Name is a qualified name like A::B. * ----------------------------------------------------------------------------- */ int SwigType_typedef_using(String_or_char *name) { String *base; String *td; String *prefix; Typetab *s; Typetab *tt = 0; String *defined_name = 0; /* Printf(stdout,"using %s\n", name);*/ if (!Swig_scopename_check(name)) return -1; /* Not properly qualified */ base = Swig_scopename_last(name); /* See if the base is already defined in this scope */ if (Getattr(current_typetab,base)) { Delete(base); return -1; } /* See if the using name is a scope */ /* tt = SwigType_find_scope(current_scope,name); Printf(stdout,"tt = %x, name = '%s'\n", tt, name); */ /* We set up a typedef B --> A::B */ Setattr(current_typetab,base,name); /* Find the scope name where the symbol is defined */ td = SwigType_typedef_resolve(name); /* Printf(stdout,"td = '%s' %x\n", td, resolved_scope); */ if (resolved_scope) { defined_name = Getattr(resolved_scope,k_qname); if (defined_name) { defined_name = Copy(defined_name); Append(defined_name,"::"); Append(defined_name,base); } } if (td) Delete(td); /* Printf(stdout,"defined_name = '%s'\n", defined_name);*/ tt = SwigType_find_scope(current_scope,defined_name); /* Figure out the scope the using directive refers to */ { prefix = Swig_scopename_prefix(name); s = SwigType_find_scope(current_scope,prefix); if (s) { Hash *ttab = Getattr(s,k_typetab); if (!Getattr(ttab,base) && defined_name) { Setattr(ttab,base, defined_name); } } } if (tt) { /* Using directive had it's own scope. We need to do create a new scope for it */ SwigType_new_scope(base); SwigType_inherit_scope(tt); SwigType_pop_scope(); } if (defined_name) Delete(defined_name); Delete(prefix); Delete(base); return 0; } /* ----------------------------------------------------------------------------- * SwigType_isclass() * * Determines if a type defines a class or not. A class is defined by * its type-table entry maps to itself. Note: a pointer to a class is not * a class. * ----------------------------------------------------------------------------- */ int SwigType_isclass(SwigType *t) { SwigType *qty, *qtys; int isclass = 0; qty = SwigType_typedef_resolve_all(t); qtys = SwigType_strip_qualifiers(qty); if (SwigType_issimple(qtys)) { String *td = SwigType_typedef_resolve(qtys); if (td) { Delete(td); } if (resolved_scope) { isclass = 1; } /* Hmmm. Not a class. If a template, it might be uninstantiated */ if (!isclass && SwigType_istemplate(qtys)) { String *tp = SwigType_templateprefix(qtys); if (Strcmp(tp,t) != 0) { isclass = SwigType_isclass(tp); } Delete(tp); } } Delete(qty); Delete(qtys); return isclass; } /* ----------------------------------------------------------------------------- * SwigType_type() * * Returns an integer code describing the datatype. This is only used for * compatibility with SWIG1.1 language modules and is likely to go away once * everything is based on typemaps. * ----------------------------------------------------------------------------- */ int SwigType_type(SwigType *t) { char *c; /* Check for the obvious stuff */ c = Char(t); if (strncmp(c,"p.",2) == 0) { if (SwigType_type(c+2) == T_CHAR) return T_STRING; else return T_POINTER; } if (strncmp(c,"a(",2) == 0) return T_ARRAY; if (strncmp(c,"r.",2) == 0) return T_REFERENCE; if (strncmp(c,"m(",2) == 0) return T_MPOINTER; if (strncmp(c,"q(",2) == 0) { while(*c && (*c != '.')) c++; if (*c) return SwigType_type(c+1); return T_ERROR; } if (strncmp(c,"f(",2) == 0) return T_FUNCTION; /* Look for basic types */ if (strcmp(c,"int") == 0) return T_INT; if (strcmp(c,"long") == 0) return T_LONG; if (strcmp(c,"short") == 0) return T_SHORT; if (strcmp(c,"unsigned") == 0) return T_UINT; if (strcmp(c,"unsigned short") == 0) return T_USHORT; if (strcmp(c,"unsigned long") == 0) return T_ULONG; if (strcmp(c,"unsigned int") == 0) return T_UINT; if (strcmp(c,"char") == 0) return T_CHAR; if (strcmp(c,"signed char") == 0) return T_SCHAR; if (strcmp(c,"unsigned char") == 0) return T_UCHAR; if (strcmp(c,"float") == 0) return T_FLOAT; if (strcmp(c,"double") == 0) return T_DOUBLE; if (strcmp(c,"void") == 0) return T_VOID; if (strcmp(c,"bool") == 0) return T_BOOL; if (strcmp(c,"long long") == 0) return T_LONGLONG; if (strcmp(c,"unsigned long long") == 0) return T_ULONGLONG; if (strncmp(c,"enum ",5) == 0) return T_INT; if (strcmp(c,"v(...)") == 0) return T_VARARGS; /* Hmmm. Unknown type */ if (SwigType_istypedef(t)) { int r; SwigType *nt = SwigType_typedef_resolve(t); r = SwigType_type(nt); Delete(nt); return r; } return T_USER; } /****************************************************************************** *** * * * WARNING * * * *** *** *** *** Don't even think about modifying anything below this line unless you *** *** are completely on top of *EVERY* subtle aspect of the C++ type system *** *** and you are prepared to suffer endless hours of agony trying to *** *** debug the SWIG run-time type checker after you break it. *** ******************************************************************************/ /* ----------------------------------------------------------------------------- * SwigType_remember() * * This function "remembers" a datatype that was used during wrapper code generation * so that a type-checking table can be generated later on. It is up to the language * modules to actually call this function--it is not done automatically. * * Type tracking is managed through two separate hash tables. The hash 'r_mangled' * is mapping between mangled type names (used in the target language) and * fully-resolved C datatypes used in the source input. The second hash 'r_resolved' * is the inverse mapping that maps fully-resolved C datatypes to all of the mangled * names in the scripting languages. For example, consider the following set of * typedef declarations: * * typedef double Real; * typedef double Float; * typedef double Point[3]; * * Now, suppose that the types 'double *', 'Real *', 'Float *', 'double[3]', and * 'Point' were used in an interface file and "remembered" using this function. * The hash tables would look like this: * * r_mangled { * _p_double : [ p.double, a(3).double ] * _p_Real : [ p.double ] * _p_Float : [ p.double ] * _Point : [ a(3).double ] * * r_resolved { * p.double : [ _p_double, _p_Real, _p_Float ] * a(3).double : [ _p_double, _Point ] * } * * Together these two hash tables can be used to determine type-equivalency between * mangled typenames. To do this, we view the two hash tables as a large graph and * compute the transitive closure. * ----------------------------------------------------------------------------- */ static Hash *r_mangled = 0; /* Hash mapping mangled types to fully resolved types */ static Hash *r_resolved = 0; /* Hash mapping resolved types to mangled types */ static Hash *r_ltype = 0; /* Hash mapping mangled names to their local c type */ static Hash *r_clientdata = 0; /* Hash mapping resolved types to client data */ static Hash *r_remembered = 0; /* Hash of types we remembered already */ static void (*r_tracefunc)(SwigType *t, String *mangled, String *clientdata) = 0; void SwigType_remember_clientdata(SwigType *t, const String_or_char *clientdata) { String *mt; SwigType *lt; Hash *h; SwigType *fr; SwigType *qr; String *tkey; if (!r_mangled) { r_mangled = NewHash(); r_resolved = NewHash(); r_ltype = NewHash(); r_clientdata = NewHash(); r_remembered = NewHash(); } { String *last; last = Getattr(r_remembered,t); if (last && (Cmp(last,clientdata) == 0)) return; } tkey = Copy(t); Setattr(r_remembered, tkey, clientdata ? NewString(clientdata) : (void *) ""); Delete(tkey); mt = SwigType_manglestr(t); /* Create mangled string */ if (r_tracefunc) { (*r_tracefunc)(t,mt, (String *) clientdata); } if (SwigType_istypedef(t)) { lt = Copy(t); } else { lt = SwigType_ltype(t); } Setattr(r_ltype, mt, lt); fr = SwigType_typedef_resolve_all(t); /* Create fully resolved type */ qr = SwigType_typedef_qualified(fr); Delete(fr); /* Added to deal with possible table bug */ fr = SwigType_strip_qualifiers(qr); Delete(qr); /*Printf(stdout,"t = '%s'\n", t); Printf(stdout,"fr= '%s'\n\n", fr); */ if (Strstr(t,"<") && !(Strstr(t,"<("))) { Printf(stdout,"Bad template type passed to SwigType_remember: %s\n", t); assert(0); } h = Getattr(r_mangled,mt); if (!h) { h = NewHash(); Setattr(r_mangled,mt,h); Delete(h); } Setattr(h,fr,mt); h = Getattr(r_resolved, fr); if (!h) { h = NewHash(); Setattr(r_resolved,fr,h); Delete(h); } Setattr(h,mt,fr); if (clientdata) { String *cd = Getattr(r_clientdata,fr); if (cd) { if (Strcmp(clientdata,cd) != 0) { Printf(stderr,"*** Internal error. Inconsistent clientdata for type '%s'\n", SwigType_str(fr,0)); Printf(stderr,"*** '%s' != '%s'\n", clientdata, cd); assert(0); } } else { Setattr(r_clientdata, fr, NewString(clientdata)); } } /* If the remembered type is a reference, we also remember the pointer version. This is to prevent odd problems with mixing pointers and references--especially when different functions are using different typenames (via typedef). */ if (SwigType_isreference(t)) { SwigType *tt = Copy(t); SwigType_del_reference(tt); SwigType_add_pointer(tt); SwigType_remember_clientdata(tt,clientdata); } } void SwigType_remember(SwigType *ty) { SwigType_remember_clientdata(ty,0); } void (*SwigType_remember_trace(void (*tf)(SwigType *, String *, String *)))(SwigType *, String *, String *) { void (*o)(SwigType *, String *, String *) = r_tracefunc; r_tracefunc = tf; return o; } /* ----------------------------------------------------------------------------- * SwigType_equivalent_mangle() * * Return a list of all of the mangled typenames that are equivalent to another * mangled name. This works as follows: For each fully qualified C datatype * in the r_mangled hash entry, we collect all of the mangled names from the * r_resolved hash and combine them together in a list (removing duplicate entries). * ----------------------------------------------------------------------------- */ List *SwigType_equivalent_mangle(String *ms, Hash *checked, Hash *found) { List *l; Hash *h; Hash *ch; Hash *mh; if (found) { h = found; } else { h = NewHash(); } if (checked) { ch = checked; } else { ch = NewHash(); } if (Getattr(ch,ms)) goto check_exit; /* Already checked this type */ Setattr(h,ms,"1"); Setattr(ch, ms, "1"); mh = Getattr(r_mangled,ms); if (mh) { Iterator ki; ki = First(mh); while (ki.key) { Hash *rh; if (Getattr(ch,ki.key)) { ki = Next(ki); continue; } Setattr(ch,ki.key,"1"); rh = Getattr(r_resolved,ki.key); if (rh) { Iterator rk; rk = First(rh); while (rk.key) { Setattr(h,rk.key,"1"); SwigType_equivalent_mangle(rk.key,ch,h); rk = Next(rk); } } ki = Next(ki); } } check_exit: if (!found) { l = Keys(h); Delete(h); Delete(ch); return l; } else { return 0; } } /* ----------------------------------------------------------------------------- * SwigType_clientdata_collect() * * Returns the clientdata field for a mangled type-string. * ----------------------------------------------------------------------------- */ static String *SwigType_clientdata_collect(String *ms, Hash *checked) { Hash *ch; Hash *mh; String *clientdata = 0; if (checked) { ch = checked; } else { ch = NewHash(); } if (Getattr(ch,ms)) goto check_exit; /* Already checked this type */ Setattr(ch, ms, "1"); mh = Getattr(r_mangled,ms); if (mh) { Iterator ki; ki = First(mh); while (ki.key) { Hash *rh; Setattr(ch,ki.key,"1"); clientdata = Getattr(r_clientdata,ki.key); if (clientdata) goto check_exit; rh = Getattr(r_resolved,ki.key); if (rh) { Iterator rk; rk = First(rh); while (rk.key) { /* make sure the key is the same as the string we are looking for */ /* otherwise, we do not want the clientdata from the wrong type */ if(Strcmp(rk.key, ms) == 0) { clientdata = SwigType_clientdata_collect(rk.key,ch); } if (clientdata) goto check_exit; rk = Next(rk); } } ki = Next(ki); } } check_exit: if (!checked) { Delete(ch); } return clientdata; } /* ----------------------------------------------------------------------------- * SwigType_inherit() * * Record information about inheritance. We keep a hash table that keeps * a mapping between base classes and all of the classes that are derived * from them. * * subclass is a hash that maps base-classes to all of the classes derived from them. * ----------------------------------------------------------------------------- */ static Hash *subclass = 0; static Hash *conversions = 0; void SwigType_inherit(String *derived, String *base, String *cast) { Hash *h; if (!subclass) subclass = NewHash(); /* Printf(stdout,"'%s' --> '%s' '%s'\n", derived, base, cast); */ if (SwigType_istemplate(derived)) { derived = SwigType_typedef_qualified(SwigType_typedef_resolve_all(derived)); } if (SwigType_istemplate(base)) { base = SwigType_typedef_qualified(SwigType_typedef_resolve_all(base)); } /* Printf(stdout,"'%s' --> '%s' '%s'\n", derived, base, cast);*/ h = Getattr(subclass,base); if (!h) { h = NewHash(); Setattr(subclass,base,h); } if (!Getattr(h,derived)) { Setattr(h,derived, cast ? cast : (void *) ""); } } /* ----------------------------------------------------------------------------- * SwigType_issubtype() * * Determines if a t1 is a subtype of t2 * ----------------------------------------------------------------------------- */ int SwigType_issubtype(SwigType *t1, SwigType *t2) { SwigType *ft1, *ft2; String *b1, *b2; Hash *h; int r = 0; if (!subclass) return 0; ft1 = SwigType_typedef_resolve_all(t1); ft2 = SwigType_typedef_resolve_all(t2); b1 = SwigType_base(ft1); b2 = SwigType_base(ft2); h = Getattr(subclass,b2); if (h) { if (Getattr(h,b1)) { r = 1; } } Delete(ft1); Delete(ft2); Delete(b1); Delete(b2); /* Printf(stdout, "issubtype(%s,%s) --> %d\n", t1, t2, r); */ return r; } /* ----------------------------------------------------------------------------- * SwigType_inherit_equiv() * * Modify the type table to handle C++ inheritance * ----------------------------------------------------------------------------- */ void SwigType_inherit_equiv(File *out) { String *ckey; String *prefix, *base; Hash *sub; Hash *rh; List *rlist; Iterator rk, bk, ck; if (!conversions) conversions = NewHash(); if (!subclass) subclass = NewHash(); rk = First(r_resolved); while (rk.key) { /* rkey is a fully qualified type. We strip all of the type constructors off of it just to get the base */ base = SwigType_base(rk.key); /* Check to see whether the base is recorded in the subclass table */ sub = Getattr(subclass,base); Delete(base); if (!sub) { rk = Next(rk); continue; } /* This type has subclasses. We now need to walk through these subtypes and generate pointer converion functions */ rh = Getattr(r_resolved, rk.key); rlist = NewList(); for (ck = First(rh); ck.key; ck = Next(ck)) { Append(rlist,ck.key); } /* Printf(stdout,"rk.key = '%s'\n", rk.key); Printf(stdout,"rh = %x '%s'\n", rh,rh); */ bk = First(sub); while (bk.key) { prefix= SwigType_prefix(rk.key); Append(prefix,bk.key); /* Printf(stdout,"set %x = '%s' : '%s'\n", rh, SwigType_manglestr(prefix),prefix); */ Setattr(rh,SwigType_manglestr(prefix),prefix); ckey = NewStringf("%s+%s",SwigType_manglestr(prefix), SwigType_manglestr(rk.key)); if (!Getattr(conversions,ckey)) { String *convname = NewStringf("%sTo%s", SwigType_manglestr(prefix), SwigType_manglestr(rk.key)); Printf(out,"static void *%s(void *x) {\n", convname); Printf(out," return (void *)((%s) %s ((%s) x));\n", SwigType_lstr(rk.key,0), Getattr(sub,bk.key), SwigType_lstr(prefix,0)); Printf(out,"}\n"); Setattr(conversions,ckey,convname); Delete(ckey); /* This inserts conversions for typedefs */ { Hash *r = Getattr(r_resolved, prefix); if (r) { Iterator rrk; rrk=First(r); while (rrk.key) { Iterator rlk; String *rkeymangle; /* Make sure this name equivalence is not due to inheritance */ if (Cmp(prefix, Getattr(r,rrk.key)) == 0) { rkeymangle = SwigType_manglestr(rk.key); ckey = NewStringf("%s+%s", rrk.key, rkeymangle); if (!Getattr(conversions, ckey)) { Setattr(conversions, ckey, convname); } Delete(ckey); for (rlk = First(rlist); rlk.item; rlk = Next(rlk)) { ckey = NewStringf("%s+%s", rrk.key, rlk.item); Setattr(conversions, ckey, convname); Delete(ckey); } Delete(rkeymangle); /* This is needed to pick up other alternative names for the same type. Needed to make templates work */ Setattr(rh,rrk.key,rrk.item); } rrk = Next(rrk); } } } Delete(convname); } Delete(prefix); bk = Next(bk); } rk = Next(rk); } } /* ----------------------------------------------------------------------------- * SwigType_type_table() * * Generate the type-table for the type-checker. * ----------------------------------------------------------------------------- */ void SwigType_emit_type_table(File *f_forward, File *f_table) { Iterator ki; String *types, *table; int i = 0; if (!r_mangled) { r_mangled = NewHash(); r_resolved = NewHash(); } Printf(f_table,"\n/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */\n\n"); SwigType_inherit_equiv(f_table); /* #define DEBUG 1 */ #ifdef DEBUG Printf(stdout,"---r_mangled---\n"); Printf(stdout,"%s\n", r_mangled); Printf(stdout,"---r_resolved---\n"); Printf(stdout,"%s\n", r_resolved); Printf(stdout,"---r_ltype---\n"); Printf(stdout,"%s\n", r_ltype); Printf(stdout,"---subclass---\n"); Printf(stdout,"%s\n", subclass); Printf(stdout,"---conversions---\n"); Printf(stdout,"%s\n", conversions); #endif table = NewString(""); types = NewString(""); Printf(table,"static swig_type_info *swig_types_initial[] = {\n"); ki = First(r_mangled); Printf(f_forward,"\n/* -------- TYPES TABLE (BEGIN) -------- */\n\n"); while (ki.key) { List *el; Iterator ei; SwigType *lt; SwigType *rt; String *nt; String *ln; String *rn; const String *cd; Printf(f_forward,"#define SWIGTYPE%s swig_types[%d] \n", ki.key, i); Printv(types,"static swig_type_info _swigt_", ki.key, "[] = {", NIL); cd = SwigType_clientdata_collect(ki.key,0); if (!cd) cd = "0"; lt = Getattr(r_ltype,ki.key); rt = SwigType_typedef_resolve_all(lt); /* we save the original type and the fully resolved version */ ln = SwigType_str(lt,0); rn = SwigType_str(rt,0); if (Strcmp(ln,rn) == 0) { nt = NewStringf("%s", ln); } else { nt = NewStringf("%s|%s", rn, ln); } Printv(types,"{\"", ki.key, "\", 0, \"",nt,"\", ", cd, ", 0, 0, 0},", NIL); el = SwigType_equivalent_mangle(ki.key,0,0); for (ei = First(el); ei.item; ei = Next(ei)) { String *ckey; String *conv; ckey = NewStringf("%s+%s", ei.item, ki.key); conv = Getattr(conversions,ckey); if (conv) { Printf(types,"{\"%s\", %s, 0, 0, 0, 0, 0},", ei.item, conv); } else { Printf(types,"{\"%s\", 0, 0, 0, 0, 0, 0},", ei.item); } Delete(ckey); } Delete(el); Delete(nt); Delete(rt); Printf(types,"{0, 0, 0, 0, 0, 0, 0}};\n"); Printv(table, "_swigt_", ki.key, ", \n", NIL); ki = Next(ki); i++; } Printf(table, "0\n};\n"); #ifdef __APPLE_CC__ Printf(f_forward,"static swig_type_info **swig_types = new swig_type_info*[%d];\n", i+1); #else Printf(f_forward,"static swig_type_info *swig_types[%d];\n", i+1); #endif Printf(f_forward,"\n/* -------- TYPES TABLE (END) -------- */\n\n"); Printf(f_table,"%s\n", types); Printf(f_table,"%s\n", table); Printf(f_table,"\n/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */\n\n"); Delete(types); Delete(table); } cableswig-0.1.0+git20150808.orig/SWIG/Source/Swig/symbol.c0000644000175000000620000011337712561312227021434 0ustar stevestaff/* ----------------------------------------------------------------------------- * symbol.c * * This file implements the SWIG symbol table. See details below. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_symbol_c[] = "/cvsroot/SWIG/Source/Swig/symbol.c,v 1.9 2004/01/21 21:27:43 cheetah Exp"; #include "swig.h" #include "swigwarn.h" #include /* ----------------------------------------------------------------------------- * Synopsis * * This module provides symbol table management for all of SWIG. In previous * releases, the management of symbols was rather haphazard. This module tries * to correct that. * * All symbols are associated with simple identifiers. For example, here are some * declarations that generate symbol table entries: * * decl symbol * -------------- ------------ * void foo(int); foo * int x; x * typedef int *blah; blah * * Associated with each symbol is a Hash table that can contain any set of * attributes that make sense for that object. For example: * * typedef int *blah; ----> "name" : 'blah' * "type" : 'int' * "decl" : 'p.' * "storage" : 'typedef' * * In some cases, the symbol table needs to manage overloaded entries. For instance, * overloaded functions. In this case, a linked list is built. The "sym:nextSibling" * attribute is reserved to hold a link to the next entry. For example: * * int foo(int); --> "name" : "foo" "name" : "foo" * int foo(int,double); "type" : "int" "type" : "int" * "decl" : "f(int)." "decl" : "f(int,double)." * ... ... * "sym:nextSibling" : --------> "sym:nextSibling": --------> ... * * When more than one symbol has the same name, the symbol declarator is * used to detect duplicates. For example, in the above case, foo(int) and * foo(int,double) are different because their "decl" attribute is different. * However, if a third declaration "foo(int)" was made, it would generate a * conflict (due to having a declarator that matches a previous entry). * * Structures and classes: * * C/C++ symbol tables are normally managed in a few different spaces. The * most visible namespace is reserved for functions, variables, typedef, enum values * and such. In C, a separate tag-space is reserved for 'struct name', 'class name', * and 'union name' declarations. In SWIG, a single namespace is used for everything * this means that certain incompatibilities will arise with some C programs. For instance: * * struct Foo { * ... * } * * int Foo(); // Error. Name clash. Works in C though * * Due to the unified namespace for structures, special handling is performed for * the following: * * typedef struct Foo { * * } Foo; * * In this case, the symbol table contains an entry for the structure itself. The * typedef is left out of the symbol table. * * Target language vs C: * * The symbol tables are normally managed *in the namespace of the target language*. * This means that name-collisions can be resolved using %rename and related * directives. A quirk of this is that sometimes the symbol tables need to * be used for C type resolution as well. To handle this, each symbol table * also has a C-symbol table lurking behind the scenes. This is used to locate * symbols in the C namespace. However, this symbol table is not used for error * reporting nor is it used for anything else during code generation. * * Symbol table structure: * * Symbol tables themselves are a special kind of node that is organized just like * a normal parse tree node. Symbol tables are organized in a tree that can be * traversed using the SWIG-DOM API. The following attributes names are reserved. * * name -- Name of the scope defined by the symbol table (if any) * This name is the C-scope name and is not affected by * %renaming operations * symtab -- Hash table mapping identifiers to nodes. * csymtab -- Hash table mapping C identifiers to nodes. * * Reserved attributes on symbol objects: * * When a symbol is placed in the symbol table, the following attributes * are set: * * sym:name -- Symbol name * sym:nextSibling -- Next symbol (if overloaded) * sym:previousSibling -- Previous symbol (if overloaded) * sym:symtab -- Symbol table object holding the symbol * sym:overloaded -- Set to the first symbol if overloaded * * These names are modeled after XML namespaces. In particular, every attribute * pertaining to symbol table management is prefaced by the "sym:" prefix. * ----------------------------------------------------------------------------- */ static Hash *current = 0; /* The current symbol table hash */ static Hash *ccurrent = 0; /* The current c symbol table hash */ static Hash *current_symtab = 0; /* Current symbol table node */ static Hash *symtabs = 0; /* Hash of all symbol tables by fully-qualified name */ static Hash *global_scope = 0; /* Global scope */ /* ----------------------------------------------------------------------------- * Swig_symbol_new() * * Create a new symbol table object * ----------------------------------------------------------------------------- */ void Swig_symbol_init() { current = NewHash(); current_symtab = NewHash(); ccurrent = NewHash(); set_nodeType(current_symtab,"symboltable"); Setattr(current_symtab,"symtab",current); Setattr(current_symtab,"csymtab", ccurrent); /* Set the global scope */ symtabs = NewHash(); Setattr(symtabs,"",current_symtab); global_scope = current_symtab; } /* ----------------------------------------------------------------------------- * Swig_symbol_setscopename() * * Set the C scopename of the current symbol table. * ----------------------------------------------------------------------------- */ void Swig_symbol_setscopename(const String_or_char *name) { String *qname; assert(!Getattr(current_symtab,"name")); Setattr(current_symtab,"name",name); /* Set nested scope in parent */ qname = Swig_symbol_qualifiedscopename(current_symtab); /* Save a reference to this scope */ Setattr(symtabs,qname,current_symtab); } /* ----------------------------------------------------------------------------- * Swig_symbol_getscopename() * * Get the C scopename of the current symbol table * ----------------------------------------------------------------------------- */ String * Swig_symbol_getscopename() { return Getattr(current_symtab,"name"); } /* ----------------------------------------------------------------------------- * Swig_symbol_getscope() * * Given a fully qualified C scopename, this function returns a symbol table * ----------------------------------------------------------------------------- */ Symtab * Swig_symbol_getscope(const String_or_char *name) { if (!symtabs) return 0; if (Strcmp(name,"::") == 0) name = ""; return Getattr(symtabs,name); } /* ----------------------------------------------------------------------------- * Swig_symbol_qualifiedscopename() * * Get the fully qualified C scopename of a symbol table. Note, this only pertains * to the C/C++ scope name. It is not affected by renaming. * ----------------------------------------------------------------------------- */ String * Swig_symbol_qualifiedscopename(Symtab *symtab) { String *result = 0; Hash *parent; String *name; if (!symtab) symtab = current_symtab; parent = parentNode(symtab); if (parent) { result = Swig_symbol_qualifiedscopename(parent); } name = Getattr(symtab,"name"); if (name) { if (!result) { result = NewString(""); } if (Len(result)) { Printf(result,"::%s",name); } else { Printf(result,"%s",name); } } return result; } /* ----------------------------------------------------------------------------- * Swig_symbol_newscope() * * Create a new scope. Returns the newly created scope. * ----------------------------------------------------------------------------- */ Symtab * Swig_symbol_newscope() { Hash *n; Hash *hsyms, *h; hsyms = NewHash(); h = NewHash(); set_nodeType(h,"symboltable"); Setattr(h,"symtab",hsyms); set_parentNode(h,current_symtab); n = lastChild(current_symtab); if (!n) { set_firstChild(current_symtab,h); } else { set_nextSibling(n,h); } set_lastChild(current_symtab,h); current = hsyms; ccurrent = NewHash(); Setattr(h,"csymtab",ccurrent); current_symtab = h; return current_symtab; } /* ----------------------------------------------------------------------------- * Swig_symbol_setscope() * * Set the current scope. Returns the previous current scope. * ----------------------------------------------------------------------------- */ Symtab * Swig_symbol_setscope(Symtab *sym) { Symtab *ret = current_symtab; current_symtab = sym; current = Getattr(sym,"symtab"); assert(current); ccurrent = Getattr(sym,"csymtab"); assert(ccurrent); return ret; } /* ----------------------------------------------------------------------------- * Swig_symbol_popscope() * * Pop out of the current scope. Returns the popped scope and sets the * scope to the parent scope. * ----------------------------------------------------------------------------- */ Symtab * Swig_symbol_popscope() { Hash *h = current_symtab; current_symtab = parentNode(current_symtab); assert(current_symtab); current = Getattr(current_symtab,"symtab"); assert(current); ccurrent = Getattr(current_symtab,"csymtab"); assert(ccurrent); return h; } /* ----------------------------------------------------------------------------- * Swig_symbol_current() * * Return the current symbol table. * ----------------------------------------------------------------------------- */ Symtab * Swig_symbol_current() { return current_symtab; } /* ----------------------------------------------------------------------------- * Swig_symbol_alias() * * Makes an alias for a symbol in the global symbol table. * ----------------------------------------------------------------------------- */ void Swig_symbol_alias(String_or_char *aliasname, Symtab *s) { String *qname; qname = Swig_symbol_qualifiedscopename(current_symtab); if (qname) { Printf(qname,"::%s", aliasname); } else { qname = NewString(aliasname); } if (!Getattr(symtabs,qname)) { Setattr(symtabs,qname,s); } } /* ----------------------------------------------------------------------------- * Swig_symbol_inherit() * * Inherit symbols from another scope. * ----------------------------------------------------------------------------- */ void Swig_symbol_inherit(Symtab *s) { int i; List *inherit = Getattr(current_symtab,"inherit"); if (!inherit) { inherit = NewList(); Setattr(current_symtab,"inherit", inherit); } assert(s != current_symtab); for (i = 0; i < Len(inherit); i++) { Node *n = Getitem(inherit,i); if (n == s) return; /* Already inherited */ } Append(inherit,s); } /* ----------------------------------------------------------------------------- * Swig_symbol_cadd() * * Adds a node to the C symbol table only. * ----------------------------------------------------------------------------- */ void Swig_symbol_cadd(String_or_char *name, Node *n) { Node *append = 0; Node *cn; /* There are a few options for weak symbols. A "weak" symbol is any symbol that can be replaced by another symbol in the C symbol table. An example would be a forward class declaration. A forward class sits in the symbol table until a real class declaration comes along. Certain symbols are marked as "sym:typename". These are important symbols related to the C++ type-system and take precedence in the C symbol table. An example might be code like this: template T foo(T x); int foo(int); In this case, the template is marked with "sym:typename" so that it stays in the C symbol table (so that it can be expanded using %template). */ if (!name) return; cn = Getattr(ccurrent,name); if (cn && (Getattr(cn,"sym:typename"))) { /* The node in the C symbol table is a typename. Do nothing */ /* We might append the symbol at the end */ append = n; } else if (cn && (Getattr(cn,"sym:weak"))) { /* The node in the symbol table is weak. Replace it */ Setattr(ccurrent,name, n); } else if (cn && (Getattr(n,"sym:weak"))) { /* The node being added is weak. Don't worry about it */ } else if (cn && (Getattr(n,"sym:typename"))) { /* The node being added is a typename. We definitely add it */ Setattr(ccurrent,name,n); append = cn; } else if (cn && (Strcmp(nodeType(cn),"templateparm") == 0)) { Swig_error(Getfile(n),Getline(n), "Declaration of '%s' shadows template parameter,\n", name); Swig_error(Getfile(cn),Getline(cn), "previous template parameter declaration '%s'.\n", name); return; } else if (cn) { append = n; } else if (!cn) { /* No conflict. Add the symbol */ Setattr(ccurrent,name,n); } /* Multiple entries in the C symbol table. We append to to the symbol table */ if (append) { Node *fn, *pn = 0; cn = Getattr(ccurrent,name); fn = cn; while (fn) { pn = fn; if (fn == append) { /* already added. Bail */ return; } fn = Getattr(fn,"csym:nextSibling"); } if (pn) { Setattr(pn,"csym:nextSibling",append); } } /* Special typedef handling. When a typedef node is added to the symbol table, we might have to add a type alias. This would occur if the typedef mapped to another scope in the system. For example: class Foo { }; typedef Foo OtherFoo; In this case, OtherFoo becomes an alias for Foo. */ { Node *td = n; while (td && (Strcmp(nodeType(td),"cdecl") == 0) && (checkAttribute(td,"storage","typedef"))) { SwigType *type; Node *td1; type = Copy(Getattr(td,"type")); SwigType_push(type,Getattr(td,"decl")); td1 = Swig_symbol_clookup(type,0); Delete(type); if (td1 == td) break; td = td1; if (td) { Symtab *st = Getattr(td,"symtab"); if (st) { Swig_symbol_alias(Getattr(n,"name"),st); break; } } } } } /* ----------------------------------------------------------------------------- * Swig_symbol_add() * * Adds a node to the symbol table. Returns the node itself if successfully * added. Otherwise, it returns the symbol table entry of the conflicting node. * * Also places the symbol in a behind-the-scenes C symbol table. This is needed * for namespace support, type resolution, and other issues. * ----------------------------------------------------------------------------- */ Node * Swig_symbol_add(String_or_char *symname, Node *n) { Hash *c, *cn, *cl = 0; SwigType *decl, *ndecl; String *cstorage, *nstorage; int nt = 0, ct = 0; int pn = 0; int u1 = 0, u2 = 0; String *name; /* See if the node has a name. If so, we place in the C symbol table for this scope. We don't worry about overloading here---the primary purpose of this is to record information for type/name resolution for later. Conflicts in C namespaces are errors, but these will be caught by the C++ compiler when compiling the wrapper code */ /* There are a few options for weak symbols. A "weak" symbol is any symbol that can be replaced by another symbol in the C symbol table. An example would be a forward class declaration. A forward class sits in the symbol table until a real class declaration comes along. Certain symbols are marked as "sym:typename". These are important symbols related to the C++ type-system and take precedence in the C symbol table. An example might be code like this: template T foo(T x); int foo(int); In this case, the template is marked with "sym:typename" so that it stays in the C symbol table (so that it can be expanded using %template). */ name = Getattr(n,"name"); if (name) { Swig_symbol_cadd(name,n); } /* No symbol name defined. We return. */ if (!symname) { Setattr(n,"sym:symtab",current_symtab); return n; } /* If node is ignored. We don't proceed any further */ if (Getattr(n,"feature:ignore")) return n; /* See if the symbol already exists in the table */ c = Getattr(current,symname); /* Check for a weak symbol. A weak symbol is allowed to be in the symbol table, but is silently overwritten by other symbols. An example would be a forward class declaration. For instance: class Foo; In this case, "Foo" sits in the symbol table. However, the definition of Foo would replace the entry if it appeared later. */ if (c && Getattr(c,"sym:weak")) { c = 0; } if (c) { /* There is a symbol table conflict. There are a few cases to consider here: (1) A conflict between a class/enum and a typedef declaration is okay. In this case, the symbol table entry is set to the class/enum declaration itself, not the typedef. (2) A conflict between namespaces is okay--namespaces are open (3) Otherwise, overloading is only allowed for functions */ /* Check for namespaces */ if ((Strcmp(nodeType(n),nodeType(c)) == 0) && ((Strcmp(nodeType(n),"namespace") == 0))) { Node *cl, *pcl = 0; cl = c; while (cl) { pcl = cl; cl = Getattr(cl,"sym:nextSibling"); } Setattr(pcl,"sym:nextSibling",n); Setattr(n,"sym:symtab", current_symtab); Setattr(n,"sym:name", symname); Setattr(n,"sym:previousSibling", pcl); return n; } if (Getattr(n,"allows_typedef")) nt = 1; if (Getattr(c,"allows_typedef")) ct = 1; if (nt || ct) { Node *td, *other; String *s; /* At least one of the nodes allows typedef overloading. Make sure that both don't--this would be a conflict */ if (nt && ct) return c; /* Figure out which node allows the typedef */ if (nt) { td = n; other = c; } else { td = c; other = n; } /* Make sure the other node is a typedef */ s = Getattr(other,"storage"); if (!s || (Strcmp(s,"typedef"))) return c; /* No. This is a conflict */ /* Hmmm. This appears to be okay. Make sure the symbol table refers to the allow_type node */ if (td != c) { Setattr(current,symname, td); Setattr(td,"sym:symtab", current_symtab); Setattr(td,"sym:name", symname); } return n; } decl = Getattr(c,"decl"); ndecl = Getattr(n,"decl"); { String *nt1, *nt2; nt1 = nodeType(n); if (Strcmp(nt1,"template") == 0) nt1 = Getattr(n,"templatetype"); nt2 = nodeType(c); if (Strcmp(nt2,"template") == 0) nt2 = Getattr(c,"templatetype"); if (Strcmp(nt1,"using") == 0) u1 = 1; if (Strcmp(nt2,"using") == 0) u2 = 1; if ((Strcmp(nt1,nt2) != 0) && !(u1 || u2)) return c; } if (!(u1 || u2)) { if ((!SwigType_isfunction(decl)) || (!SwigType_isfunction(ndecl))) { /* Symbol table conflict */ return c; } } /* Hmmm. Declarator seems to indicate that this is a function */ /* Look at storage class to see if compatible */ cstorage = Getattr(c,"storage"); nstorage = Getattr(n,"storage"); /* If either one is declared as typedef, forget it. We're hosed */ if (Cmp(cstorage,"typedef") == 0) { return c; } if (Cmp(nstorage,"typedef") == 0) { return c; } /* Okay. Walk down the list of symbols and see if we get a declarator match */ cn = c; pn = 0; while (cn) { decl = Getattr(cn,"decl"); if (!(u1 || u2)) { if (Cmp(ndecl,decl) == 0) { /* Declarator conflict */ return cn; } } cl = cn; cn = Getattr(cn,"sym:nextSibling"); pn++; } /* Well, we made it this far. Guess we can drop the symbol in place */ Setattr(n,"sym:symtab",current_symtab); Setattr(n,"sym:name",symname); /* Printf(stdout,"%s %x\n", Getattr(n,"sym:overname"), current_symtab); */ assert(!Getattr(n,"sym:overname")); Setattr(n,"sym:overname", NewStringf("__SWIG_%d", pn)); /*Printf(stdout,"%s %s %s\n", symname, Getattr(n,"decl"), Getattr(n,"sym:overname")); */ Setattr(cl,"sym:nextSibling",n); Setattr(n,"sym:previousSibling",cl); Setattr(cl,"sym:overloaded",c); Setattr(n,"sym:overloaded",c); return n; } /* No conflict. Just add it */ Setattr(n,"sym:symtab",current_symtab); Setattr(n,"sym:name",symname); /* Printf(stdout,"%s\n", Getattr(n,"sym:overname")); */ Setattr(n,"sym:overname", NewStringf("__SWIG_%d", pn)); /* Printf(stdout,"%s %s %s\n", symname, Getattr(n,"decl"), Getattr(n,"sym:overname")); */ Setattr(current,symname,n); return n; } /* ----------------------------------------------------------------------------- * symbol_lookup_qualified() * * Internal function to handle fully qualified symbol table lookups. This * works from the symbol table supplied in symtab and unwinds its way out * towards the global scope. * * This function operates in the C namespace, not the target namespace. * * The check function is an optional callback that can be used to verify a particular * symbol match. This is only used in some of the more exotic parts of SWIG. For instance, * verifying that a class hierarchy implements all pure virtual methods. * ----------------------------------------------------------------------------- */ static Node * symbol_lookup(String_or_char *name, Symtab *symtab, int (*check)(Node *n)) { Node *n; List *inherit; Hash *sym = Getattr(symtab,"csymtab"); if (Getmark(symtab)) return 0; Setmark(symtab,1); n = Getattr(sym,name); if (n) { /* if a check-function is defined. Call it to determine a match */ if (check) { int c = check(n); if (c == 1) { Setmark(symtab,0); return n; } if (c < 0) { /* Terminate the search right away */ Setmark(symtab,0); return 0; } } else { Setmark(symtab,0); return n; } } inherit = Getattr(symtab,"inherit"); if (inherit) { int i,len; len = Len(inherit); for (i = 0; i < len; i++) { n = symbol_lookup(name, Getitem(inherit,i),check); if (n) { Setmark(symtab,0); return n; } } } Setmark(symtab,0); return 0; } static Node * symbol_lookup_qualified(String_or_char *name, Symtab *symtab, String *prefix, int local, int (*checkfunc)(Node *n)) { /* This is a little funky, we search by fully qualified names */ if (!symtab) return 0; if (!prefix) { Node *n; String *bname; String *prefix; bname = Swig_scopename_last(name); prefix = Swig_scopename_prefix(name); n = symbol_lookup_qualified(bname,symtab,prefix,local,checkfunc); Delete(bname); Delete(prefix); return n; } else { String *qname; Symtab *st; Node *n = 0; /* Make qualified name of current scope */ qname = Swig_symbol_qualifiedscopename(symtab); if (qname && Len(qname)) { if (Len(prefix)) { Append(qname,"::"); Append(qname,prefix); } } else { qname = NewString(prefix); } st = Getattr(symtabs,qname); /* Found a scope match */ if (st) { if (!name) return st; n = symbol_lookup(name, st,checkfunc); } Delete(qname); if (!n) { if (!local) { Node *pn = parentNode(symtab); if (pn) n = symbol_lookup_qualified(name,pn, prefix, local,checkfunc); } else { n = 0; } } return n; } } /* ----------------------------------------------------------------------------- * Swig_symbol_clookup() * * Look up a symbol in the symbol table. This uses the C name, not scripting * names. Note: If we come across a using a directive, we follow it to * to get the real node. * ----------------------------------------------------------------------------- */ Node * Swig_symbol_clookup(String_or_char *name, Symtab *n) { Hash *hsym = 0; Node *s = 0; if (!n) { hsym = current_symtab; } else { if (Strcmp(nodeType(n),"symboltable")) { n = Getattr(n,"sym:symtab"); } assert(n); if (n) { hsym = n; } } if (Swig_scopename_check(name)) { if (Strncmp(name,"::",2) == 0) { String *nname = NewString(Char(name)+2); if (Swig_scopename_check(nname)) { s = symbol_lookup_qualified(nname,global_scope,0,0,0); } } else { String *prefix = Swig_scopename_prefix(name); if (prefix) { s = symbol_lookup_qualified(name,hsym,0,0,0); Delete(prefix); if (!s) { return 0; } } } } if (!s) { while (hsym) { s = symbol_lookup(name,hsym,0); if (s) break; hsym = parentNode(hsym); if (!hsym) break; } } if (!s) { return 0; } /* Check if s is a 'using' node */ while (s && Strcmp(nodeType(s),"using") == 0) { Node *ss; ss = Swig_symbol_clookup(Getattr(s,"uname"), Getattr(s,"sym:symtab")); if (!ss) { Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", Getattr(s,"uname")); } s = ss; } return s; } /* ----------------------------------------------------------------------------- * Swig_symbol_clookup_check() * * This function is identical to Swig_symbol_clookup() except that it * accepts a callback function that is invoked to determine a symbol match. * The purpose of this function is to support complicated algorithms that need * to examine multiple definitions of the same symbol that might appear in an * inheritance hierarchy. * ----------------------------------------------------------------------------- */ Node * Swig_symbol_clookup_check(String_or_char *name, Symtab *n, int (*checkfunc)(Node *n)) { Hash *hsym = 0; Node *s = 0; if (!n) { hsym = current_symtab; } else { if (Strcmp(nodeType(n),"symboltable")) { n = Getattr(n,"sym:symtab"); } assert(n); if (n) { hsym = n; } } if (Swig_scopename_check(name)) { if (Strncmp(name,"::",2) == 0) { String *nname = NewString(Char(name)+2); if (Swig_scopename_check(nname)) { s = symbol_lookup_qualified(nname,global_scope,0,0,checkfunc); } } else { String *prefix = Swig_scopename_prefix(name); if (prefix) { s = symbol_lookup_qualified(name,hsym,0,0,checkfunc); Delete(prefix); if (!s) { return 0; } } } } if (!s) { while (hsym) { s = symbol_lookup(name,hsym,checkfunc); if (s) break; hsym = parentNode(hsym); if (!hsym) break; } } if (!s) { return 0; } /* Check if s is a 'using' node */ while (s && Strcmp(nodeType(s),"using") == 0) { Node *ss; ss = Swig_symbol_clookup(Getattr(s,"uname"), Getattr(s,"sym:symtab")); if (!ss && !checkfunc) { Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", Getattr(s,"uname")); } s = ss; } return s; } Node * Swig_symbol_clookup_local(String_or_char *name, Symtab *n) { Hash *h, *hsym; Node *s = 0; if (!n) { hsym = current_symtab; h = ccurrent; } else { if (Strcmp(nodeType(n),"symboltable")) { n = Getattr(n,"sym:symtab"); } assert(n); hsym = n; h = Getattr(n,"csymtab"); } if (Swig_scopename_check(name)) { if (Strncmp(name,"::",2) == 0) { s = symbol_lookup_qualified(Char(name)+2,global_scope,0,0,0); } else { s = symbol_lookup_qualified(name,hsym,0,0,0); } } if (!s) { s = symbol_lookup(name,hsym,0); } if (!s) return 0; /* Check if s is a 'using' node */ while (s && Strcmp(nodeType(s),"using") == 0) { Node *ss = Swig_symbol_clookup_local(Getattr(s,"uname"), Getattr(s,"sym:symtab")); if (!ss) { Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", Getattr(s,"uname")); } s = ss; } return s; } Node * Swig_symbol_clookup_local_check(String_or_char *name, Symtab *n, int (*checkfunc)(Node *)) { Hash *h, *hsym; Node *s = 0; if (!n) { hsym = current_symtab; h = ccurrent; } else { if (Strcmp(nodeType(n),"symboltable")) { n = Getattr(n,"sym:symtab"); } assert(n); hsym = n; h = Getattr(n,"csymtab"); } if (Swig_scopename_check(name)) { if (Strncmp(name,"::",2) == 0) { s = symbol_lookup_qualified(Char(name)+2,global_scope,0,0,checkfunc); } else { s = symbol_lookup_qualified(name,hsym,0,0,checkfunc); } } if (!s) { s = symbol_lookup(name,hsym,checkfunc); } if (!s) return 0; /* Check if s is a 'using' node */ while (s && Strcmp(nodeType(s),"using") == 0) { Node *ss = Swig_symbol_clookup_local_check(Getattr(s,"uname"), Getattr(s,"sym:symtab"),checkfunc); if (!ss && !checkfunc) { Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", Getattr(s,"uname")); } s = ss; } return s; } /* ----------------------------------------------------------------------------- * Swig_symbol_cscope() * * Look up a scope name. * ----------------------------------------------------------------------------- */ Symtab * Swig_symbol_cscope(String_or_char *name, Symtab *symtab) { if (Strncmp(name,"::",2) == 0) return symbol_lookup_qualified(0, global_scope, name, 0,0); return symbol_lookup_qualified(0,symtab,name,0,0); } /* ----------------------------------------------------------------------------- * Swig_symbol_remove() * * Remove a symbol * ----------------------------------------------------------------------------- */ void Swig_symbol_remove(Node *n) { Symtab *symtab; String *symname; Node *symprev; Node *symnext; symtab = Getattr(n,"sym:symtab"); /* Get symbol table object */ symtab = Getattr(symtab,"symtab"); /* Get actual hash table of symbols */ symname = Getattr(n,"sym:name"); symprev = Getattr(n,"sym:previousSibling"); symnext = Getattr(n,"sym:nextSibling"); /* If previous symbol, just fix the links */ if (symprev) { if (symnext) { Setattr(symprev,"sym:nextSibling",symnext); } else { Delattr(symprev,"sym:nextSibling"); } } else { /* If no previous symbol, see if there is a next symbol */ if (symnext) { Setattr(symtab,symname,symnext); } else { Delattr(symtab,symname); } } if (symnext) { if (symprev) { Setattr(symnext,"sym:previousSibling",symprev); } else { Delattr(symnext,"sym:previousSibling"); } } Delattr(n,"sym:symtab"); Delattr(n,"sym:previousSibling"); Delattr(n,"sym:nextSibling"); Delattr(n,"csym:nextSibling"); Delattr(n,"sym:overname"); Delattr(n,"csym:previousSibling"); Delattr(n,"sym:overloaded"); return; #if 0 symtab = Getattr(n,"sym:symtab"); /* Get symbol table object */ symtab = Getattr(symtab,"csymtab"); /* Get actual hash table of symbols */ symprev = Getattr(n,"csym:previousSibling"); symnext = Getattr(n,"csym:nextSibling"); /* If previous symbol, just fix the links */ if (symprev) { if (symnext) { Setattr(symprev,"csym:nextSibling",symnext); } else { Delattr(symprev,"csym:nextSibling"); } } else { /* If no previous symbol, see if there is a next symbol */ if (symnext) { Setattr(symtab,Getattr(n,"name"),symnext); } else { Delattr(symtab,Getattr(n,"name")); } } Delattr(n,"sym:symtab"); Delattr(n,"csym:previousSibling"); Delattr(n,"csym:nextSibling"); #endif } /* ----------------------------------------------------------------------------- * Swig_symbol_qualified() * * Return the qualified name of a symbol * ----------------------------------------------------------------------------- */ String * Swig_symbol_qualified(Node *n) { Hash *symtab; if (Strcmp(nodeType(n),"symboltable") == 0) { symtab = n; } else { symtab = Getattr(n,"sym:symtab"); } if (!symtab) return NewString(""); return Swig_symbol_qualifiedscopename(symtab); } /* ----------------------------------------------------------------------------- * Swig_symbol_isoverloaded() * * Check if a symbol is overloaded. Returns the first symbol if so. * ----------------------------------------------------------------------------- */ Node * Swig_symbol_isoverloaded(Node *n) { return Getattr(n,"sym:overloaded"); } /* ----------------------------------------------------------------------------- * Swig_symbol_type_qualify() * * Create a fully qualified type name * ----------------------------------------------------------------------------- */ SwigType * Swig_symbol_type_qualify(SwigType *t, Symtab *st) { List *elements; String *result; int i,len; result = NewString(""); elements = SwigType_split(t); len = Len(elements); for (i = 0; i < len; i++) { String *e = Getitem(elements,i); if (SwigType_issimple(e)) { Node *n = Swig_symbol_clookup(e,st); if (n) { String *name = Getattr(n,"name"); Clear(e); Append(e,name); if (!Swig_scopename_check(name)) { String *qname = Swig_symbol_qualified(n); if (Len(qname)) { Insert(e,0,"::"); Insert(e,0,qname); } Delete(qname); } } else if (SwigType_istemplate(e)) { String *tprefix, *tsuffix; SwigType *qprefix; List *targs; Iterator ti; tprefix = SwigType_templateprefix(e); tsuffix = SwigType_templatesuffix(e); qprefix = Swig_symbol_type_qualify(tprefix,st); targs = SwigType_parmlist(e); Printf(qprefix,"<("); for (ti = First(targs); ti.item;) { String *qparm = Swig_symbol_type_qualify(ti.item,st); /* Printf(stdout,"qparm = '%s', tparm = '%s'\n", qparm, ti.item);*/ while (1) { /* It is possible for an integer to show up here. If so, we need to evaluate it */ { Node *nn = Swig_symbol_clookup(qparm,st); if ((nn) && (Strcmp(nodeType(nn),"cdecl") == 0)) { String *nv = Getattr(nn,"value"); if (nv) { Clear(qparm); Append(qparm,nv); } else { break; } } else if ((nn) && (Strcmp(nodeType(nn),"enumitem") == 0)) { String *qn = Swig_symbol_qualified(nn); if (Len(qn)) { Append(qn,"::"); Append(qn,Getattr(nn,"name")); Clear(qparm); Append(qparm,qn); } Delete(qn); break; } else { break; } } } Append(qprefix,qparm); ti = Next(ti); if (ti.item) { Putc(',',qprefix); } Delete(qparm); } Append(qprefix,")>"); Append(qprefix,tsuffix); Clear(e); Append(e,qprefix); Delete(tprefix); Delete(tsuffix); Delete(qprefix); } if (Strncmp(e,"::",2) == 0) { Delitem(e,0); Delitem(e,0); } Append(result,e); } else if (SwigType_isfunction(e)) { Iterator pi; List *parms = SwigType_parmlist(e); String *s = NewString("f("); pi = First(parms); while (pi.item) { Append(s,Swig_symbol_type_qualify(pi.item,st)); pi = Next(pi); if (pi.item) { Append(s,","); } } Append(s,")."); Append(result,s); Delete(s); } else { Append(result,e); } } Delete(elements); return result; } /* ----------------------------------------------------------------------------- * Swig_symbol_typedef_reduce() * * Chase a typedef through symbol tables looking for a match. * ----------------------------------------------------------------------------- */ SwigType *Swig_symbol_typedef_reduce(SwigType *ty, Symtab *tab) { SwigType *prefix, *base; Node *n; base = SwigType_base(ty); prefix = SwigType_prefix(ty); n = Swig_symbol_clookup(base,tab); if (!n) { Delete(base); Delete(prefix); return Copy(ty); } if (Strcmp(nodeType(n),"using") == 0) { String *uname = Getattr(n,"uname"); if (uname) { n = Swig_symbol_clookup(base,Getattr(n,"sym:symtab")); if (!n) { Delete(base); Delete(prefix); return Copy(ty); } } } if (Strcmp(nodeType(n),"cdecl") == 0) { String *storage = Getattr(n,"storage"); if (Strcmp(storage,"typedef") == 0) { SwigType *decl; SwigType *rt; SwigType *nt = Copy(Getattr(n,"type")); decl = Getattr(n,"decl"); if (decl) { SwigType_push(nt,decl); } SwigType_push(nt,prefix); Delete(base); Delete(prefix); rt = Swig_symbol_typedef_reduce(nt, Getattr(n,"sym:symtab")); Delete(nt); return rt; } } Delete(base); Delete(prefix); return Copy(ty); } /* ----------------------------------------------------------------------------- * Swig_symbol_string_qualify() * * This function takes a string and looks for identifiers. Identifiers are * then qualified according to scope rules. This function is used in a number * of settings including expression evaluation, scoping of conversion operators, * and so forth. * ----------------------------------------------------------------------------- */ String * Swig_symbol_string_qualify(String *s, Symtab *st) { char *c; String *id, *r; int have_id = 0; id = NewString(""); r = NewString(""); c = Char(s); while (*c) { if (isalpha((int)*c) || (*c == '_') || (*c == ':')) { Putc(*c,id); have_id = 1; } else { if (have_id) { String *qid = Swig_symbol_type_qualify(id,st); Append(r,qid); Clear(id); Delete(qid); have_id = 0; } Putc(*c,r); } c++; } if (have_id) { String *qid = Swig_symbol_type_qualify(id,st); Append(r,qid); Delete(qid); } Delete(id); return r; } cableswig-0.1.0+git20150808.orig/SWIG/Source/Swig/error.c0000644000175000000620000001465112561312227021253 0ustar stevestaff/* ----------------------------------------------------------------------------- * error.c * * Error handling functions. These are used to issue warnings and * error messages. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ #include "swig.h" #include #include char cvsroot_error_c[] = "/cvsroot/SWIG/Source/Swig/error.c,v 1.7 2004/01/15 08:33:12 mmatus Exp"; /* ----------------------------------------------------------------------------- * Commentary on the warning filter. * * The warning filter is a string of numbers prefaced by (-) or (+) to * indicate whether or not a warning message is displayed. For example: * * "-304-201-140+210+201" * * The filter string is scanned left to right and the first occurrence * of a warning number is used to determine printing behavior. * * The same number may appear more than once in the string. For example, in the * above string, "201" appears twice. This simply means that warning 201 * was disabled after it was previously enabled. This may only be temporary * setting--the first number may be removed later in which case the warning * is reenabled. * ----------------------------------------------------------------------------- */ #if defined(_WIN32) # define DEFAULT_ERROR_MSG_FORMAT EMF_MICROSOFT #else # define DEFAULT_ERROR_MSG_FORMAT EMF_STANDARD #endif static ErrorMessageFormat msg_format = DEFAULT_ERROR_MSG_FORMAT; static int silence = 0; /* Silent operation */ static String *filter = 0; /* Warning filter */ static int warnall = 0; static int nwarning = 0; static int init_fmt = 0; static char wrn_wnum_fmt[64]; static char wrn_nnum_fmt[64]; static char err_line_fmt[64]; static char err_eof_fmt[64]; /* ----------------------------------------------------------------------------- * Swig_warning() * * Issue a warning message * ----------------------------------------------------------------------------- */ void Swig_warning(int wnum, const String_or_char *filename, int line, const char *fmt, ...) { String *out; char *msg; int wrn = 1; va_list ap; if (silence) return; if (!init_fmt) Swig_error_msg_format(DEFAULT_ERROR_MSG_FORMAT); va_start(ap,fmt); out = NewString(""); vPrintf(out,fmt,ap); { char temp[64], *t; t = temp; msg = Char(out); while (isdigit((int) *msg)) { *(t++) = *(msg++); } if (t != temp) { msg++; *t = 0; wnum = atoi(temp); } } /* Check in the warning filter */ if (filter) { char temp[32]; char *c; sprintf(temp,"%d",wnum); c = Strstr(filter,temp); if (c) { if (*(c-1) == '-') wrn = 0; /* Warning disabled */ if (*(c-1) == '+') wrn = 1; /* Warning enabled */ } } if (warnall || wrn) { if (wnum) { Printf(stderr, wrn_wnum_fmt, filename, line, wnum); } else { Printf(stderr, wrn_nnum_fmt, filename, line); } Printf(stderr,"%s",msg); nwarning++; } Delete(out); va_end(ap); } /* ----------------------------------------------------------------------------- * Swig_error() * * Issue an error message * ----------------------------------------------------------------------------- */ static int nerrors = 0; void Swig_error(const String_or_char *filename, int line, const char *fmt, ...) { va_list ap; if (silence) return; if (!init_fmt) Swig_error_msg_format(DEFAULT_ERROR_MSG_FORMAT); va_start(ap,fmt); if (line > 0) { Printf(stderr, err_line_fmt, filename, line); } else { Printf(stderr, err_eof_fmt, filename); } vPrintf(stderr,fmt,ap); va_end(ap); nerrors++; } /* ----------------------------------------------------------------------------- * Swig_error_count() * * Returns number of errors received. * ----------------------------------------------------------------------------- */ int Swig_error_count(void) { return nerrors; } /* ----------------------------------------------------------------------------- * Swig_error_silent() * * Set silent flag * ----------------------------------------------------------------------------- */ void Swig_error_silent(int s) { silence = s; } /* ----------------------------------------------------------------------------- * Swig_warnfilter() * * Takes a comma separate list of warning numbers and puts in the filter. * ----------------------------------------------------------------------------- */ void Swig_warnfilter(const String_or_char *wlist, int add) { char *c; String *s; if (!filter) filter = NewString(""); s = NewString(wlist); c = Char(s); c = strtok(c,", "); while (c) { if (isdigit((int) *c) || (*c == '+') || (*c == '-')) { if (add) { Insert(filter,0,c); if (isdigit((int) *c)) { Insert(filter,0,"-"); } } else { char temp[32]; if (isdigit((int) *c)) { sprintf(temp,"-%s",c); } else { strcpy(temp,c); } Replace(filter,temp,"", DOH_REPLACE_FIRST); } } c = strtok(NULL,", "); } Delete(s); } void Swig_warnall(void) { warnall = 1; } /* ----------------------------------------------------------------------------- * Swig_warn_count() * * Return the number of warnings * ----------------------------------------------------------------------------- */ int Swig_warn_count(void) { return nwarning; } /* ----------------------------------------------------------------------------- * Swig_error_msg_format() * * Set the type of error/warning message display * ----------------------------------------------------------------------------- */ void Swig_error_msg_format(ErrorMessageFormat format) { const char* error = "Error"; const char* warning = "Warning"; const char* fmt_eof = "%s:EOF"; /* here 'format' could be directly a string instead of an enum, but by now a switch is used to translated into one. */ const char* fmt_line = 0; switch (format) { case EMF_MICROSOFT: fmt_line = "%s(%d)"; break; case EMF_STANDARD: default: fmt_line = "%s:%d"; } sprintf(wrn_wnum_fmt, "%s: %s(%%d): ", fmt_line, warning); sprintf(wrn_nnum_fmt, "%s: %s: ", fmt_line, warning); sprintf(err_line_fmt, "%s: %s: ", fmt_line, error); sprintf(err_eof_fmt, "%s: %s: ", fmt_eof, error); msg_format = format; init_fmt = 1; } cableswig-0.1.0+git20150808.orig/SWIG/Source/Swig/wrapfunc.c0000644000175000000620000002774112561312227021753 0ustar stevestaff/* ----------------------------------------------------------------------------- * wrapfunc.c * * This file defines a object for creating wrapper functions. Primarily * this is used for convenience since it allows pieces of a wrapper function * to be created in a piecemeal manner. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1998-2000. The University of Chicago * Copyright (C) 1995-1998. The University of Utah and The Regents of the * University of California. * * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_wrapfunc_c[] = "/cvsroot/SWIG/Source/Swig/wrapfunc.c,v 1.24 2003/04/30 17:42:24 beazley Exp"; #include "swig.h" #include static int Compact_mode = 0; /* set to 0 on default */ static int Max_line_size = 128; /* ----------------------------------------------------------------------------- * NewWrapper() * * Create a new wrapper function object. * ----------------------------------------------------------------------------- */ Wrapper * NewWrapper() { Wrapper *w; w = (Wrapper *) malloc(sizeof(Wrapper)); w->localh = NewHash(); w->locals = NewString(""); w->code = NewString(""); w->def = NewString(""); return w; } /* ----------------------------------------------------------------------------- * DelWrapper() * * Delete a wrapper function object. * ----------------------------------------------------------------------------- */ void DelWrapper(Wrapper *w) { Delete(w->localh); Delete(w->locals); Delete(w->code); Delete(w->def); free(w); } /* ----------------------------------------------------------------------------- * Wrapper_compact_print_mode_set() * * Set compact_mode. * ----------------------------------------------------------------------------- */ void Wrapper_compact_print_mode_set(int flag) { Compact_mode = flag; } /* ----------------------------------------------------------------------------- * Wrapper_pretty_print() * * Formats a wrapper function and fixes up the indentation. * ----------------------------------------------------------------------------- */ void Wrapper_pretty_print(String *str, File *f) { String *ts; int level = 0; int c, i; int empty = 1; ts = NewString(""); Seek(str,0, SEEK_SET); Clear(ts); while ((c = Getc(str)) != EOF) { if (c == '\"') { Putc(c,ts); while ((c = Getc(str)) != EOF) { if (c == '\\') { Putc(c,ts); c = Getc(str); } Putc(c,ts); if (c == '\"') break; } empty = 0; } else if (c == '\'') { Putc(c,ts); while ((c = Getc(str)) != EOF) { if (c == '\\') { Putc(c,ts); c = Getc(str); } Putc(c,ts); if (c == '\'') break; } empty = 0; } else if (c == '{') { Putc(c,ts); Putc('\n',ts); for (i = 0; i < level; i++) Putc(' ',f); Printf(f,"%s", ts); Clear(ts); level+=4; while ((c = Getc(str)) != EOF) { if (!isspace(c)) { Ungetc(c,str); break; } } empty = 0; } else if (c == '}') { if (!empty) { Putc('\n',ts); for (i = 0; i < level; i++) Putc(' ',f); Printf(f,"%s",ts); Clear(ts); } level-=4; Putc(c,ts); empty = 0; } else if (c == '\n') { Putc(c,ts); empty = 0; if (!empty) { if ((Char(ts))[0] != '#') { for (i = 0; i < level; i++) Putc(' ',f); } Printf(f,"%s",ts); } Clear(ts); empty = 1; } else if (c == '/') { empty = 0; Putc(c,ts); c = Getc(str); if (c != EOF) { Putc(c,ts); if (c == '/') { /* C++ comment */ while ((c = Getc(str)) != EOF) { if (c == '\n') { Ungetc(c,str); break; } Putc(c,ts); } } else if (c == '*') { /* C comment */ int endstar = 0; while ((c = Getc(str)) != EOF) { if (endstar && c == '/') { /* end of C comment */ Putc(c,ts); break; } endstar = (c == '*'); Putc(c,ts); if (c == '\n') { /* multi-line C comment. Could be improved slightly. */ for (i = 0; i < level; i++) Putc(' ',ts); } } } } } else { if (!empty || !isspace(c)) { Putc(c,ts); empty = 0; } } } if (!empty) Printf(f,"%s",ts); Delete(ts); Printf(f,"\n"); } /* ----------------------------------------------------------------------------- * Wrapper_compact_print() * * Formats a wrapper function and fixes up the indentation. * Print out in compact format, with Compact enabled. * ----------------------------------------------------------------------------- */ void Wrapper_compact_print(String *str, File *f) { String *ts, *tf; /*temp string & temp file */ int level = 0; int c, i; int empty = 1; ts = NewString(""); tf = NewString(""); Seek(str,0, SEEK_SET); Clear(ts); Clear(tf); while ((c = Getc(str)) != EOF) { if (c == '\"') { /* string 1 */ empty = 0; Putc(c,ts); while ((c = Getc(str)) != EOF) { if (c == '\\') { Putc(c,ts); c = Getc(str); } Putc(c,ts); if (c == '\"') break; } } else if (c == '\'') { /* string 2 */ empty = 0; Putc(c,ts); while ((c = Getc(str)) != EOF) { if (c == '\\') { Putc(c,ts); c = Getc(str); } Putc(c,ts); if (c == '\'') break; } } else if (c == '{') { /* start of {...} */ empty = 0; Putc(c,ts); if (Len(tf) == 0) { for (i = 0; i < level; i++) Putc(' ',tf); } else if ((Len(tf) + Len(ts)) < Max_line_size) { Putc(' ',tf); } else { Putc('\n',tf); Printf(f,"%s", tf); Clear(tf); for (i = 0; i < level; i++) Putc(' ',tf); } Printf(tf,"%s",ts); Clear(ts); level+=4; while ((c = Getc(str)) != EOF) { if (!isspace(c)) { Ungetc(c,str); break; } } } else if (c == '}') { /* end of {...} */ empty = 0; if (Len(tf) == 0) { for (i = 0; i < level; i++) Putc(' ',tf); } else if ((Len(tf) + Len(ts)) < Max_line_size) { Putc(' ',tf); } else { Putc('\n',tf); Printf(f,"%s", tf); Clear(tf); for (i = 0; i < level; i++) Putc(' ',tf); } Printf(tf, "%s", ts); Putc(c, tf); Clear(ts); level-=4; } else if (c == '\n') { /* line end */ while ((c = Getc(str)) != EOF) { if (!isspace(c)) break; } if (c == '#'){ Putc('\n',ts); } else if (c == '}') { Putc(' ',ts); } else if ( (c != EOF) || (Len(ts)!=0) ){ if (Len(tf) == 0) { for (i = 0; i < level; i++) Putc(' ',tf); } else if ((Len(tf) + Len(ts)) < Max_line_size) { Putc(' ',tf); } else { Putc('\n',tf); Printf(f,"%s", tf); Clear(tf); for (i = 0; i < level; i++) Putc(' ',tf); } Printf(tf,"%s",ts); Clear(ts); } Ungetc(c,str); empty = 1; } else if (c == '/') { /* comment */ empty = 0; c = Getc(str); if (c != EOF) { if (c == '/') { /* C++ comment */ while ((c = Getc(str)) != EOF) { if (c == '\n') { Ungetc(c,str); break; } } } else if (c == '*') { /* C comment */ int endstar = 0; while ((c = Getc(str)) != EOF) { if (endstar && c == '/') { /* end of C comment */ break; } endstar = (c == '*'); } } else { Putc('/',ts); Putc(c,ts); } } } else if (c == '#') { /* Preprocessor line */ Putc('#', ts); while ((c = Getc(str)) != EOF) { Putc(c, ts); if (c == '\\') { /* Continued line of the same PP */ c = Getc(str); if (c == '\n') Putc(c, ts); else Ungetc(c, str); } else if (c == '\n') break; } if (!empty) { Printf(tf,"\n"); } Printf(tf,"%s",ts); Printf(f, "%s", tf); Clear(tf); Clear(ts); for (i = 0; i < level; i++) Putc(' ',tf); empty = 1; } else { if (!empty || !isspace(c)) { Putc(c,ts); empty = 0; } } } if (!empty) { Printf(tf,"%s",ts); } if (Len(tf) != 0) Printf(f,"%s",tf); Delete(ts); Delete(tf); Printf(f,"\n"); } /* ----------------------------------------------------------------------------- * Wrapper_print() * * Print out a wrapper function. Does pretty or compact printing as well. * ----------------------------------------------------------------------------- */ void Wrapper_print(Wrapper *w, File *f) { String *str; str = NewString(""); Printf(str,"%s\n", w->def); Printf(str,"%s\n", w->locals); Printf(str,"%s\n", w->code); if (Compact_mode == 1) Wrapper_compact_print(str,f); else Wrapper_pretty_print(str,f); } /* ----------------------------------------------------------------------------- * Wrapper_add_local() * * Adds a new local variable declaration to a function. Returns -1 if already * present (which may or may not be okay to the caller). * ----------------------------------------------------------------------------- */ int Wrapper_add_local(Wrapper *w, const String_or_char *name, const String_or_char *decl) { /* See if the local has already been declared */ if (Getattr(w->localh,name)) { return -1; } Setattr(w->localh,name,decl); Printf(w->locals,"%s;\n", decl); return 0; } /* ----------------------------------------------------------------------------- * Wrapper_add_localv() * * Same as add_local(), but allows a NULL terminated list of strings to be * used as a replacement for decl. This saves the caller the trouble of having * to manually construct the 'decl' string before calling. * ----------------------------------------------------------------------------- */ int Wrapper_add_localv(Wrapper *w, const String_or_char *name, ...) { va_list ap; int ret; String *decl; DOH *obj; decl = NewString(""); va_start(ap,name); obj = va_arg(ap,void *); while (obj) { Printv(decl,obj,NIL); Putc(' ', decl); obj = va_arg(ap, void *); } va_end(ap); ret = Wrapper_add_local(w,name,decl); Delete(decl); return ret; } /* ----------------------------------------------------------------------------- * Wrapper_check_local() * * Check to see if a local name has already been declared * ----------------------------------------------------------------------------- */ int Wrapper_check_local(Wrapper *w, const String_or_char *name) { if (Getattr(w->localh,name)) { return 1; } return 0; } /* ----------------------------------------------------------------------------- * Wrapper_new_local() * * Adds a new local variable with a guarantee that a unique local name will be * used. Returns the name that was actually selected. * ----------------------------------------------------------------------------- */ char * Wrapper_new_local(Wrapper *w, const String_or_char *name, const String_or_char *decl) { int i; String *nname = NewString(name); String *ndecl = NewString(decl); char *ret; i = 0; while (Wrapper_check_local(w,nname)) { Clear(nname); Printf(nname,"%s%d",name,i); i++; } Replace(ndecl, name, nname, DOH_REPLACE_ID); Setattr(w->localh,nname,ndecl); Printf(w->locals,"%s;\n", ndecl); ret = Char(nname); Delete(nname); Delete(ndecl); return ret; /* Note: nname should still exists in the w->localh hash */ } /* ----------------------------------------------------------------------------- * Wrapper_add_localv() * * Same as add_local(), but allows a NULL terminated list of strings to be * used as a replacement for decl. This saves the caller the trouble of having * to manually construct the 'decl' string before calling. * ----------------------------------------------------------------------------- */ char * Wrapper_new_localv(Wrapper *w, const String_or_char *name, ...) { va_list ap; char *ret; String *decl; DOH *obj; decl = NewString(""); va_start(ap,name); obj = va_arg(ap,void *); while (obj) { Printv(decl,obj,NIL); Putc(' ',decl); obj = va_arg(ap, void *); } va_end(ap); ret = Wrapper_new_local(w,name,decl); Delete(decl); return ret; } cableswig-0.1.0+git20150808.orig/SWIG/Source/Swig/swig.i0000644000175000000620000006131612561312227021101 0ustar stevestaff/* -*- c -*- */ /* ------------------------------------------------------------------------- * swig.i * * Interface file for the SWIG core. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * Dustin Mitchell (djmitche@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * * /cvsroot/SWIG/Source/Swig/swig.i,v 1.11 2002/11/30 22:10:17 beazley Exp * ------------------------------------------------------------------------- */ /* todo: implement callable stuff -- ternaryfunc? */ /* todo: new DOH type to wrap Python objects. geesh. */ /* todo: Delattr -> return errors */ %module swig %{ #include "doh.h" %} %typemap(python,in) FILE * { $target = PyFile_AsFile($source); } %typemap(python,out) FILE * { $target = PyFile_FromFile($source, "unknown", "?", fclose); } %{ /* ------------------------------------------------------------------------- * An extension type for DOH objects -- we could use shadow classes, * but this will be lots faster, and provide a slightly cleaner interface. * ------------------------------------------------------------------------- */ typedef struct PyDOH { PyObject_HEAD DOH *doh; } PyDOH; staticforward PyTypeObject PyDOHSequenceType, PyDOHMappingType; /* --------------------------------------------------------------------- */ /* meta-functions */ /* Given a DOH object, return an equivalent PyObject. Note that when the PyObject is destroyed, the DOH's reference count will decrease; thus this is refcount-safe on both the DOH and Python sides. */ static PyObject * Swig_PyDOH_new(DOH *in) { PyDOH *self; if (!in) { Incref(Py_None); return Py_None; } if (DohIsMapping(in)) self = PyObject_NEW(PyDOH, &PyDOHMappingType); else self = PyObject_NEW(PyDOH, &PyDOHSequenceType); if (!self) return (PyObject *)self; self->doh = in; Incref(in); /* increase the DOH refcount */ return (PyObject *)self; } static void Swig_PyDOH_delete(PyDOH *self) { Delete(self->doh); /* decrease the DOH refcount */ PyMem_DEL(self); } static int Swig_PyDOH_check(void *self) { return ((PyObject *)self)->ob_type == &PyDOHMappingType || ((PyObject *)self)->ob_type == &PyDOHSequenceType; } /* Given a PyObject, return an equivalent DOH object */ static PyDOH *Swig_PyDOH_as_DOH(PyObject *source) { DOH *target; if (Swig_PyDOH_check(source)) target = ((PyDOH *)source)->doh; else if (PyString_Check(source)) target = (DOH *)PyString_AsString(source); else if (PySequence_Check(source)) printf("Sequence -> NULL\n"), target = NULL; else if (PyMapping_Check(source)) printf("Mapping -> NULL\n"), target = NULL; else if (PyNumber_Check(source)) target = (DOH *)source; else if (PyFile_Check(source)) target = (DOH *)PyFile_AsFile(source); else printf("?? -> NULL\n"), target = NULL; return target; } /* --------------------------------------------------------------------- */ /* sequence methods */ static int Swig_PyDOH_length(PyDOH *self) { return Len(self->doh); /* also a mapping method */ } static PyObject *Swig_PyDOH_item(PyDOH *self, int index) { DOH *r = Getitem(self->doh, index); if (r) return Swig_PyDOH_new(r); /* return an exception */ PyErr_SetObject(PyExc_KeyError, PyInt_FromLong(index)); return NULL; } static int Swig_PyDOH_ass_item(PyDOH *self, int index, PyObject *v) { int result; if (v) result = Setitem(self->doh, index, Swig_PyDOH_as_DOH(v)); else /* NULL v => delete item */ result = Delitem(self->doh, index); /* post an exception if necessary */ if (result == -1) PyErr_SetObject(PyExc_KeyError, PyInt_FromLong(index)); return result; } static PySequenceMethods Swig_PyDOH_as_sequence = { (inquiry)Swig_PyDOH_length, (binaryfunc)NULL, /* sq_concat */ (intargfunc)NULL, /* sq_repeat */ (intargfunc)Swig_PyDOH_item, (intintargfunc)NULL, /* sq_slice */ (intobjargproc)Swig_PyDOH_ass_item, (intintobjargproc)NULL /* sq_ass_slice */ }; /* --------------------------------------------------------------------- */ /* Mapping methods */ static PyObject *Swig_PyDOH_subscript(PyDOH *self, PyObject *k) { DOH *r = Getattr(self->doh, Swig_PyDOH_as_DOH(k)); if (r) return Swig_PyDOH_new(r); PyErr_SetObject(PyExc_KeyError, k); return NULL; } static int Swig_PyDOH_ass_subscript(PyDOH *self, PyObject *k, PyObject *v) { int result = 0; if (v) result = Setattr(self->doh, Swig_PyDOH_as_DOH(k), Swig_PyDOH_as_DOH(v)); else Delattr(self->doh, Swig_PyDOH_as_DOH(k)); if (result == -1) PyErr_SetObject(PyExc_KeyError, k); return result; } static PyMappingMethods Swig_PyDOH_as_mapping = { (inquiry)Swig_PyDOH_length, (binaryfunc)Swig_PyDOH_subscript, (objobjargproc)Swig_PyDOH_ass_subscript }; /* --------------------------------------------------------------------- */ /* named methods */ static PyObject *Swig_PyDOH_Copy(PyDOH *self, PyObject *args) { DOH * _result; if(!PyArg_ParseTuple(args,":Copy")) return NULL; _result = (DOH *)DohCopy(self->doh); return Swig_PyDOH_new(_result); } static PyObject *Swig_PyDOH_Clear(PyDOH *self, PyObject *args) { if(!PyArg_ParseTuple(args,":Clear")) return NULL; DohClear(self->doh); Py_INCREF(Py_None); return Py_None; } static PyObject *Swig_PyDOH_SetScope(PyDOH *self, PyObject *args) { int _arg1; if(!PyArg_ParseTuple(args,"i:SetScope",&_arg1)) return NULL; DohSetScope(self->doh,_arg1); Py_INCREF(Py_None); return Py_None; } static PyObject *Swig_PyDOH_Dump(PyDOH *self, PyObject *args) { PyObject * _resultobj; int _result; DOH * _arg1; PyObject * _obj1 = 0; if(!PyArg_ParseTuple(args,"O:Dump",&_obj1)) return NULL; _arg1 = Swig_PyDOH_as_DOH(_obj1); _result = (int )DohDump(self->doh,_arg1); return PyInt_FromLong(_result); } static PyObject *Swig_PyDOH_Firstkey(PyDOH *self, PyObject *args) { PyObject * _resultobj; DOH * _result; if(!PyArg_ParseTuple(args,":Firstkey")) return NULL; _result = (DOH *)DohFirstkey(self->doh); _resultobj = Swig_PyDOH_new(_result); return _resultobj; } static PyObject *Swig_PyDOH_Nextkey(PyDOH *self, PyObject *args) { PyObject * _resultobj; DOH * _result; if(!PyArg_ParseTuple(args,":Nextkey")) return NULL; _result = (DOH *)DohNextkey(self->doh); _resultobj = Swig_PyDOH_new(_result); return _resultobj; } static PyObject *Swig_PyDOH_GetInt(PyDOH *self, PyObject *args) { PyObject * _resultobj; int _result; DOH * _arg1; PyObject * _obj1 = 0; if(!PyArg_ParseTuple(args,"O:GetInt",&_obj1)) return NULL; _arg1 = Swig_PyDOH_as_DOH(_obj1); _result = (int )DohGetInt(self->doh,_arg1); _resultobj = Py_BuildValue("i",_result); return _resultobj; } static PyObject *Swig_PyDOH_GetDouble(PyDOH *self, PyObject *args) { PyObject * _resultobj; double _result; DOH * _arg1; PyObject * _obj1 = 0; if(!PyArg_ParseTuple(args,"O:GetDouble",&_obj1)) return NULL; _arg1 = Swig_PyDOH_as_DOH(_obj1); _result = (double )DohGetDouble(self->doh,_arg1); _resultobj = Py_BuildValue("d",_result); return _resultobj; } static PyObject *Swig_PyDOH_GetChar(PyDOH *self, PyObject *args) { PyObject * _resultobj; char * _result; DOH * _arg1; PyObject * _obj1 = 0; if(!PyArg_ParseTuple(args,"O:GetChar",&_obj1)) return NULL; _arg1 = Swig_PyDOH_as_DOH(_obj1); _result = (char *)DohGetChar(self->doh,_arg1); _resultobj = Py_BuildValue("s", _result); return _resultobj; } static PyObject *Swig_PyDOH_SetInt(PyDOH *self, PyObject *args) { PyObject * _resultobj; DOH * _arg1; int _arg2; PyObject * _obj1 = 0; if(!PyArg_ParseTuple(args,"Oi:SetInt",&_obj1,&_arg2)) return NULL; _arg1 = Swig_PyDOH_as_DOH(_obj1); DohSetInt(self->doh,_arg1,_arg2); Py_INCREF(Py_None); _resultobj = Py_None; return _resultobj; } static PyObject *Swig_PyDOH_SetDouble(PyDOH *self, PyObject *args) { PyObject * _resultobj; DOH * _arg1; double _arg2; PyObject * _obj1 = 0; if(!PyArg_ParseTuple(args,"Od:SetDouble",&_obj1,&_arg2)) return NULL; _arg1 = Swig_PyDOH_as_DOH(_obj1); DohSetDouble(self->doh,_arg1,_arg2); Py_INCREF(Py_None); _resultobj = Py_None; return _resultobj; } static PyObject *Swig_PyDOH_Insertitem(PyDOH *self, PyObject *args) { PyObject * _resultobj; int _result; int _arg1; DOH * _arg2; PyObject * _obj2 = 0; if(!PyArg_ParseTuple(args,"iO:Insertitem",&_arg1,&_obj2)) return NULL; _arg2 = Swig_PyDOH_as_DOH(_obj2); _result = (int )DohInsertitem(self->doh,_arg1,_arg2); _resultobj = Py_BuildValue("i",_result); return _resultobj; } static PyObject *Swig_PyDOH_Firstitem(PyDOH *self, PyObject *args) { PyObject * _resultobj; DOH * _result; if(!PyArg_ParseTuple(args,":Firstitem")) return NULL; _result = (DOH *)DohFirstitem(self->doh); _resultobj = Swig_PyDOH_new(_result); return _resultobj; } static PyObject *Swig_PyDOH_Nextitem(PyDOH *self, PyObject *args) { PyObject * _resultobj; DOH * _result; if(!PyArg_ParseTuple(args,":Nextitem")) return NULL; _result = (DOH *)DohNextitem(self->doh); _resultobj = Swig_PyDOH_new(_result); return _resultobj; } static PyObject *Swig_PyDOH_Write(PyDOH *self, PyObject *args) { PyObject * _resultobj; int _result; int _arg2; char * _arg1 = 0; if(!PyArg_ParseTuple(args,"si:Write",&_arg1,&_arg2)) return NULL; _result = (int )DohWrite(self->doh,_arg1,_arg2); _resultobj = Py_BuildValue("i",_result); return _resultobj; } static PyObject *Swig_PyDOH_Read(PyDOH *self, PyObject *args) { PyObject * _resultobj; int _result; int _arg2; char *buffer; if(!PyArg_ParseTuple(args,"i:Read",&_arg2)) return NULL; buffer = DohMalloc(_arg2); if (!buffer) { PyErr_SetString(PyExc_MemoryError, "Not enough memory for Read buffer"); return NULL; } _result = (int )DohRead(self->doh,buffer,_arg2); _resultobj = Py_BuildValue("(is)",_result, buffer); DohFree(buffer); return _resultobj; } static PyObject *Swig_PyDOH_Seek(PyDOH *self, PyObject *args) { PyObject * _resultobj; int _result; long _arg1; int _arg2; if(!PyArg_ParseTuple(args,"li:Seek",&_arg1,&_arg2)) return NULL; _result = (int )DohSeek(self->doh,_arg1,_arg2); _resultobj = Py_BuildValue("i",_result); return _resultobj; } static PyObject *Swig_PyDOH_Tell(PyDOH *self, PyObject *args) { PyObject * _resultobj; long _result; if(!PyArg_ParseTuple(args,":Tell")) return NULL; _result = (long )DohTell(self->doh); _resultobj = Py_BuildValue("l",_result); return _resultobj; } static PyObject *Swig_PyDOH_Getc(PyDOH *self, PyObject *args) { PyObject * _resultobj; int _result; if(!PyArg_ParseTuple(args,":Getc")) return NULL; _result = (int )DohGetc(self->doh); if (_result > 0) { char c[2] = { (char)_result, 0 }; _resultobj = PyString_FromString(c); } else { Py_INCREF(Py_None); _resultobj = Py_None; } return _resultobj; } static PyObject *Swig_PyDOH_Putc(PyDOH *self, PyObject *args) { PyObject * _resultobj; int _result; int _arg0; if(!PyArg_ParseTuple(args,"i:Putc",&_arg0)) return NULL; _result = (int )DohPutc(_arg0, self->doh); _resultobj = Py_BuildValue("i",_result); return _resultobj; } static PyObject *Swig_PyDOH_Ungetc(PyDOH *self, PyObject *args) { PyObject * _resultobj; int _result; int _arg0; if(!PyArg_ParseTuple(args,"iO:Ungetc",&_arg0)) return NULL; _result = (int )DohUngetc(_arg0,self->doh); _resultobj = Py_BuildValue("i",_result); return _resultobj; } static PyObject *Swig_PyDOH_Getline(PyDOH *self, PyObject *args) { PyObject * _resultobj; int _result; if(!PyArg_ParseTuple(args,":Getline")) return NULL; _result = (int )DohGetline(self->doh); _resultobj = Py_BuildValue("i",_result); return _resultobj; } static PyObject *Swig_PyDOH_Setline(PyDOH *self, PyObject *args) { PyObject * _resultobj; int _arg1; if(!PyArg_ParseTuple(args,"i:Setline",&_arg1)) return NULL; DohSetline(self->doh,_arg1); Py_INCREF(Py_None); _resultobj = Py_None; return _resultobj; } static PyObject *Swig_PyDOH_Getfile(PyDOH *self, PyObject *args) { PyObject * _resultobj; DOH * _result; if(!PyArg_ParseTuple(args,":Getfile")) return NULL; _result = (DOH *)DohGetfile(self->doh); _resultobj = Swig_PyDOH_new(_result); return _resultobj; } static PyObject *Swig_PyDOH_Setfile(PyDOH *self, PyObject *args) { PyObject * _resultobj; DOH * _arg1; PyObject * _obj1 = 0; if(!PyArg_ParseTuple(args,"O:Setfile",&_obj1)) return NULL; _arg1 = Swig_PyDOH_as_DOH(_obj1); DohSetfile(self->doh,_arg1); Py_INCREF(Py_None); _resultobj = Py_None; return _resultobj; } static struct PyMethodDef Swig_PyDOH_methods[] = { {"copy", (PyCFunction)Swig_PyDOH_Copy, METH_VARARGS}, {"clear", (PyCFunction)Swig_PyDOH_Clear, METH_VARARGS}, {"setscope", (PyCFunction)Swig_PyDOH_SetScope, METH_VARARGS}, {"dump", (PyCFunction)Swig_PyDOH_Dump, METH_VARARGS}, {"firstkey", (PyCFunction)Swig_PyDOH_Firstkey, METH_VARARGS}, {"nextkey", (PyCFunction)Swig_PyDOH_Nextkey, METH_VARARGS}, {"getint", (PyCFunction)Swig_PyDOH_GetInt, METH_VARARGS}, {"getdouble", (PyCFunction)Swig_PyDOH_GetDouble, METH_VARARGS}, {"getchar", (PyCFunction)Swig_PyDOH_GetChar, METH_VARARGS}, {"setint", (PyCFunction)Swig_PyDOH_SetInt, METH_VARARGS}, {"setdouble", (PyCFunction)Swig_PyDOH_SetDouble, METH_VARARGS}, {"insertitem", (PyCFunction)Swig_PyDOH_Insertitem, METH_VARARGS}, {"insert", (PyCFunction)Swig_PyDOH_Insertitem, METH_VARARGS}, {"firstitem", (PyCFunction)Swig_PyDOH_Firstitem, METH_VARARGS}, {"nextitem", (PyCFunction)Swig_PyDOH_Nextitem, METH_VARARGS}, {"write", (PyCFunction)Swig_PyDOH_Write, METH_VARARGS}, {"read", (PyCFunction)Swig_PyDOH_Read, METH_VARARGS}, {"seek", (PyCFunction)Swig_PyDOH_Seek, METH_VARARGS}, {"tell", (PyCFunction)Swig_PyDOH_Tell, METH_VARARGS}, {"getc", (PyCFunction)Swig_PyDOH_Getc, METH_VARARGS}, {"putc", (PyCFunction)Swig_PyDOH_Putc, METH_VARARGS}, {"ungetc", (PyCFunction)Swig_PyDOH_Ungetc, METH_VARARGS}, {"getline", (PyCFunction)Swig_PyDOH_Getline, METH_VARARGS}, {"setline", (PyCFunction)Swig_PyDOH_Setline, METH_VARARGS}, {"getfile", (PyCFunction)Swig_PyDOH_Getfile, METH_VARARGS}, {"setfile", (PyCFunction)Swig_PyDOH_Setfile, METH_VARARGS}, {NULL, NULL} }; /* --------------------------------------------------------------------- */ /* general methods */ static PyObject *Swig_PyDOH_getattr(PyDOH *self, char *name) { return Py_FindMethod(Swig_PyDOH_methods, (PyObject *)self, name); } static int Swig_PyDOH_setattr(PyDOH *self, char *name, PyObject *v) { return Setattr(self->doh, name, Swig_PyDOH_as_DOH(v)); } static int Swig_PyDOH_cmp(PyDOH *self, PyObject *other) { return Cmp(self->doh, Swig_PyDOH_as_DOH(other)); } static PyObject *Swig_PyDOH_repr(PyDOH *self) { char *str = Char(self->doh); char buffer[1024] = ""; str = Char(self->doh); if (!str) { /* give up! */ sprintf(buffer, "", self->doh); str = buffer; } return PyString_FromString(str); } static long Swig_PyDOH_hash(PyDOH *self) { return (long)Hashval(self->doh); } static char PyDOH_docstring[] = "Interface to DOH objects from Python. DOH objects behave largely\n\ like Python objects, although some functionality may be different."; /* Type objects (one for mappings, one for everything else) */ static PyTypeObject PyDOHSequenceType = { PyObject_HEAD_INIT(&PyType_Type) 0, "DOH", sizeof(PyDOH), 0, (destructor)Swig_PyDOH_delete, (printfunc)0, (getattrfunc)Swig_PyDOH_getattr, (setattrfunc)Swig_PyDOH_setattr, (cmpfunc)Swig_PyDOH_cmp, (reprfunc)Swig_PyDOH_repr, 0, /* tp_as_number */ &Swig_PyDOH_as_sequence, 0, /* tp_as_mapping */ (hashfunc)Swig_PyDOH_hash, (ternaryfunc)0, /* tp_call */ (reprfunc)0, /* tp_str */ (getattrofunc)0, (setattrofunc)0, 0, /* tp_as_buffer */ 0, /* tp_xxx4 */ PyDOH_docstring }; static PyTypeObject PyDOHMappingType = { PyObject_HEAD_INIT(&PyType_Type) 0, "DOH_hash", sizeof(PyDOH), 0, (destructor)Swig_PyDOH_delete, (printfunc)0, (getattrfunc)Swig_PyDOH_getattr, (setattrfunc)Swig_PyDOH_setattr, (cmpfunc)Swig_PyDOH_cmp, (reprfunc)Swig_PyDOH_repr, 0, /* tp_as_number */ 0, /* tp_as_sequence */ &Swig_PyDOH_as_mapping, (hashfunc)Swig_PyDOH_hash, (ternaryfunc)0, /* tp_call */ (reprfunc)0, /* tp_str */ (getattrofunc)0, (setattrofunc)0, 0, /* tp_as_buffer */ 0, /* tp_xxx4 */ PyDOH_docstring }; %} %typemap(python,in) DOH * { $target = Swig_PyDOH_as_DOH($source); } %typemap(python,out) DOH * { $target = Swig_PyDOH_new($source); } %typemap(python,in) char * { if (Swig_PyDOH_check($source)) $target = Char(((PyDOH *)$source)->doh); else $target = PyString_AsString($source); } %title "SWIG", after %section "DOH Objects", before %subsection "Constants" /* The beginning of a sequence */ #define DOH_BEGIN -1 /* The end of a sequence */ #define DOH_END -2 /* The current point in a sequence */ #define DOH_CUR -3 /* Synonymous with DOH_CUR */ #define DOH_CURRENT -3 /* Replace any matches of the given text */ #define DOH_REPLACE_ANY 0x00 /* Replace, but not inside of quotes */ #define DOH_REPLACE_NOQUOTE 0x01 /* Replace only full identifiers */ #define DOH_REPLACE_ID 0x02 /* Replace only the first match */ #define DOH_REPLACE_FIRST 0x04 %subsection "SuperStrings" /* SuperString constructor */ extern DOH *NewSuperString(char *string, DOH *filename, int firstline); /* Is this a SuperString? */ extern int SuperString_check(DOH *); %subsection "Strings" /* String constructor */ extern DOH *NewString(const DOH *c); /* Is this a string? */ extern int String_check(const DOH *); %subsection "Files" /* File constructor */ extern DOH *NewFile(DOH *file, char *mode); /* File constructor from Python file */ extern DOH *NewFileFromFile(FILE *file); /* File constructor from a file descriptor */ extern DOH *NewFileFromFd(int fd); /* Copy from file to file */ %name(CopyTo) extern int DohCopyto(DOH *input, DOH *output); %subsection "Lists" /* List constructor */ extern DOH *NewList(); /* Is this a list? */ extern int List_check(const DOH *); /* Sort a list */ extern void List_sort(DOH *); %subsection "Hash tables" /* Hash table constructor */ extern DOH *NewHash(); /* Is this a hash table? */ extern int Hash_check(const DOH *); /* Get a List of the keys in a hash table */ extern DOH *Hash_keys(DOH *); %section "Files" extern void Swig_add_directory(DOH *dirname); extern DOH *Swig_last_file(); extern DOH *Swig_search_path(); extern FILE *Swig_open(DOH *name); extern DOH *Swig_read_file(FILE *file); extern DOH *Swig_include(DOH *name); #define SWIG_FILE_DELIMETER "/" %section "Command Line Parsing" extern void Swig_init_args(int argc, char **argv); extern void Swig_mark_arg(int n); extern void Swig_check_options(); extern void Swig_arg_error(); %section "Miscelaneous", after extern int DohNewScope(); /* create a new scope */ extern void DohDelScope(int); /* Delete a scope */ extern void DohIntern(DOH *); /* Intern an object */ extern void DohDebug(int d); /* set debugging level */ %section "Scanner Interface" /* typedef struct SwigScanner SwigScanner; */ /* extern SwigScanner *NewSwigScanner(); */ /* extern void DelSwigScanner(SwigScanner *); */ /* extern void SwigScanner_clear(SwigScanner *); */ /* extern void SwigScanner_push(SwigScanner *, DOH *); */ /* extern void SwigScanner_pushtoken(SwigScanner *, int); */ /* extern int SwigScanner_token(SwigScanner *); */ /* extern DOH *SwigScanner_text(SwigScanner *); */ /* extern void SwigScanner_skip_line(SwigScanner *); */ /* extern int SwigScanner_skip_balanced(SwigScanner *, int startchar, int endchar); */ /* extern void SwigScanner_set_location(SwigScanner *, DOH *file, int line); */ /* extern DOH *SwigScanner_get_file(SwigScanner *); */ /* extern int SwigScanner_get_line(SwigScanner *); */ /* extern void SwigScanner_idstart(SwigScanner *, char *idchar); */ /* #define SWIG_MAXTOKENS 512 */ /* #define SWIG_TOKEN_LPAREN 1 */ /* #define SWIG_TOKEN_RPAREN 2 */ /* #define SWIG_TOKEN_SEMI 3 */ /* #define SWIG_TOKEN_COMMA 4 */ /* #define SWIG_TOKEN_STAR 5 */ /* #define SWIG_TOKEN_LBRACE 6 */ /* #define SWIG_TOKEN_RBRACE 7 */ /* #define SWIG_TOKEN_EQUAL 8 */ /* #define SWIG_TOKEN_EQUALTO 9 */ /* #define SWIG_TOKEN_NOTEQUAL 10 */ /* #define SWIG_TOKEN_PLUS 11 */ /* #define SWIG_TOKEN_MINUS 12 */ /* #define SWIG_TOKEN_AND 13 */ /* #define SWIG_TOKEN_LAND 14 */ /* #define SWIG_TOKEN_OR 15 */ /* #define SWIG_TOKEN_LOR 16 */ /* #define SWIG_TOKEN_XOR 17 */ /* #define SWIG_TOKEN_LESSTHAN 18 */ /* #define SWIG_TOKEN_GREATERTHAN 19 */ /* #define SWIG_TOKEN_LTEQUAL 20 */ /* #define SWIG_TOKEN_GTEQUAL 21 */ /* #define SWIG_TOKEN_NOT 22 */ /* #define SWIG_TOKEN_LNOT 23 */ /* #define SWIG_TOKEN_LBRACKET 24 */ /* #define SWIG_TOKEN_RBRACKET 25 */ /* #define SWIG_TOKEN_SLASH 26 */ /* #define SWIG_TOKEN_BACKSLASH 27 */ /* #define SWIG_TOKEN_ENDLINE 28 */ /* #define SWIG_TOKEN_STRING 29 */ /* #define SWIG_TOKEN_POUND 30 */ /* #define SWIG_TOKEN_PERCENT 31 */ /* #define SWIG_TOKEN_COLON 32 */ /* #define SWIG_TOKEN_DCOLON 33 */ /* #define SWIG_TOKEN_LSHIFT 34 */ /* #define SWIG_TOKEN_RSHIFT 35 */ /* #define SWIG_TOKEN_ID 36 */ /* #define SWIG_TOKEN_FLOAT 37 */ /* #define SWIG_TOKEN_DOUBLE 38 */ /* #define SWIG_TOKEN_INT 39 */ /* #define SWIG_TOKEN_UINT 40 */ /* #define SWIG_TOKEN_LONG 41 */ /* #define SWIG_TOKEN_ULONG 42 */ /* #define SWIG_TOKEN_CHAR 43 */ /* #define SWIG_TOKEN_PERIOD 44 */ /* #define SWIG_TOKEN_AT 45 */ /* #define SWIG_TOKEN_DOLLAR 46 */ /* #define SWIG_TOKEN_CODEBLOCK 47 */ /* #define SWIG_TOKEN_ILLEGAL 98 */ /* #define SWIG_TOKEN_LAST 99 */ %section "SWIG types" /* #define SWIG_TYPE_BYTE 1 */ /* #define SWIG_TYPE_UBYTE 2 */ /* #define SWIG_TYPE_SHORT 3 */ /* #define SWIG_TYPE_USHORT 4 */ /* #define SWIG_TYPE_INT 5 */ /* #define SWIG_TYPE_UINT 6 */ /* #define SWIG_TYPE_LONG 7 */ /* #define SWIG_TYPE_ULONG 8 */ /* #define SWIG_TYPE_LONGLONG 9 */ /* #define SWIG_TYPE_ULONGLONG 10 */ /* #define SWIG_TYPE_FLOAT 11 */ /* #define SWIG_TYPE_DOUBLE 12 */ /* #define SWIG_TYPE_QUAD 13 */ /* #define SWIG_TYPE_CHAR 14 */ /* #define SWIG_TYPE_WCHAR 15 */ /* #define SWIG_TYPE_VOID 16 */ /* #define SWIG_TYPE_ENUM 17 */ /* #define SWIG_TYPE_VARARGS 18 */ /* #define SWIG_TYPE_TYPEDEF 19 */ /* #define SWIG_TYPE_POINTER 50 */ /* #define SWIG_TYPE_REFERENCE 51 */ /* #define SWIG_TYPE_FUNCTION 52 */ /* #define SWIG_TYPE_ARRAY 53 */ /* #define SWIG_TYPE_RECORD 54 */ /* #define SWIG_TYPE_NAME 55 */ /* DOH *NewSwigType(int tc, DOH *value); */ cableswig-0.1.0+git20150808.orig/SWIG/Source/Include/0002755000175000000620000000000012561312227020423 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Source/Include/swigconfig.h.cmake.in0000644000175000000620000000724712561312227024427 0ustar stevestaff/* Source/Include/swigconfig.h.in. Generated from configure.in by autoheader. */ /* define to 1 if the compiler supports bool type */ #cmakedefine HAVE_BOOL @HAVE_BOOL@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_DLFCN_H @HAVE_DLFCN_H@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_INTTYPES_H @HAVE_INTTYPES_H@ /* Define to 1 if you have the `dl' library (-ldl). */ #cmakedefine HAVE_LIBDL @HAVE_LIBDL@ /* Define to 1 if you have the `dld' library (-ldld). */ #cmakedefine HAVE_LIBDLD @HAVE_LIBDLD@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_MEMORY_H @HAVE_MEMORY_H@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STDINT_H @HAVE_STDINT_H@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STDLIB_H @HAVE_STDLIB_H@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STRINGS_H @HAVE_STRINGS_H@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_STRING_H @HAVE_STRING_H@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_STAT_H @HAVE_SYS_STAT_H@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_SYS_TYPES_H @HAVE_SYS_TYPES_H@ /* Define to 1 if you have the header file. */ #cmakedefine HAVE_UNISTD_H @HAVE_UNISTD_H@ /* Runtime library installation directory */ #cmakedefine LIBDIR @LIBDIR@ /* Define to 1 if your C compiler doesn't accept -c and -o together. */ #cmakedefine NO_MINUS_C_MINUS_O @NO_MINUS_C_MINUS_O@ /* Name of package */ #cmakedefine PACKAGE @PACKAGE@ /* Define to the address where bug reports for this package should be sent. */ #cmakedefine PACKAGE_BUGREPORT @PACKAGE_BUGREPORT@ /* Define to the full name of this package. */ #cmakedefine PACKAGE_NAME @PACKAGE_NAME@ /* Define to the full name and version of this package. */ #cmakedefine PACKAGE_STRING @PACKAGE_STRING@ /* Define to the one symbol short name of this package. */ #cmakedefine PACKAGE_TARNAME @PACKAGE_TARNAME@ /* Define to the version of this package. */ #cmakedefine PACKAGE_VERSION @PACKAGE_VERSION@ /* Executable and runtime libraries release suffix for co-existence with older versions */ #cmakedefine RELEASE_SUFFIX @RELEASE_SUFFIX@ /* Define to 1 if you have the ANSI C header files. */ #cmakedefine STDC_HEADERS @STDC_HEADERS@ /* Compiler that built SWIG */ #cmakedefine SWIG_CXX @SWIG_CXX@ /* Directory for SWIG system-independent libraries */ #cmakedefine SWIG_LIB @SWIG_LIB@ /* Directory for SWIG system-independent libraries in source tree */ #define SWIG_SOURCE_LIB "@SWIG_SOURCE_DIR@/Lib" /* Platform that SWIG is built for */ #cmakedefine SWIG_PLATFORM @SWIG_PLATFORM@ /* Version number of package */ #cmakedefine VERSION @VERSION@ #cmakedefine SWIG_LIB_INSTALL "@SWIG_LIB_INSTALL@" /* Default language */ #define SWIG_LANG "-tcl" /* Values returned by SWIG when invoked with the -ldflags option */ #define SWIG_GUILE_RUNTIME "-L" LIBDIR " -lswigguile" RELEASE_SUFFIX #define SWIG_GUILESCM_RUNTIME "-L" LIBDIR " -lswigguilescm" RELEASE_SUFFIX #define SWIG_MZSCHEME_RUNTIME "-L" LIBDIR " -lswigmz" RELEASE_SUFFIX #define SWIG_PERL_RUNTIME "-L" LIBDIR " -lswigpl" RELEASE_SUFFIX #define SWIG_PIKE_RUNTIME "-L" LIBDIR " -lswigpike" RELEASE_SUFFIX #define SWIG_PHP_RUNTIME "-L" LIBDIR " -lswigphp4" RELEASE_SUFFIX #define SWIG_PYTHON_RUNTIME "-L" LIBDIR " -lswigpy" RELEASE_SUFFIX #define SWIG_RUBY_RUNTIME "-L" LIBDIR " -lswigrb" RELEASE_SUFFIX #define SWIG_TCL_RUNTIME "-L" LIBDIR " -lswigtcl" RELEASE_SUFFIX #define SWIG_CHICKEN_RUNTIME "-L" LIBDIR " -lswigchicken" RELEASE_SUFFIX cableswig-0.1.0+git20150808.orig/SWIG/Source/Include/.cvsignore0000644000175000000620000000004412561312227022417 0ustar stevestaffstamp* swigconfig.h swigconfig.h.in cableswig-0.1.0+git20150808.orig/SWIG/Source/Include/swigwarn.h0000644000175000000620000002023612561312227022436 0ustar stevestaff/* SWIG warning message numbers This file serves as the main registry of warning message numbers. Some of these numbers are used internally in the C/C++ source code of SWIG. However, some of the numbers are used in SWIG configuration files (swig.swg and others). The numbers are roughly organized into a few different classes by functionality. Even though symbolic constants are used in the SWIG source, this is not always the case in SWIG interface files. Do not change the numbers in this file. */ #ifndef _SWIGWARN_H #define _SWIGWARN_H 1 #define WARN_NONE 0 /* -- Deprecated features -- */ #define WARN_DEPRECATED_EXTERN 101 #define WARN_DEPRECATED_VAL 102 #define WARN_DEPRECATED_OUT 103 #define WARN_DEPRECATED_DISABLEDOC 104 #define WARN_DEPRECATED_ENABLEDOC 105 #define WARN_DEPRECATED_DOCONLY 106 #define WARN_DEPRECATED_STYLE 107 #define WARN_DEPRECATED_LOCALSTYLE 108 #define WARN_DEPRECATED_TITLE 109 #define WARN_DEPRECATED_SECTION 110 #define WARN_DEPRECATED_SUBSECTION 111 #define WARN_DEPRECATED_SUBSUBSECTION 112 #define WARN_DEPRECATED_ADDMETHODS 113 #define WARN_DEPRECATED_READONLY 114 #define WARN_DEPRECATED_READWRITE 115 #define WARN_DEPRECATED_EXCEPT 116 #define WARN_DEPRECATED_NEW 117 #define WARN_DEPRECATED_EXCEPT_TM 118 #define WARN_DEPRECATED_IGNORE_TM 119 #define WARN_DEPRECATED_OPTC 120 /* -- Preprocessor -- */ #define WARN_PP_MISSING_FILE 201 #define WARN_PP_EVALUATION 202 /* -- C/C++ Parser -- */ #define WARN_PARSE_CLASS_KEYWORD 301 #define WARN_PARSE_REDEFINED 302 #define WARN_PARSE_EXTEND_UNDEF 303 #define WARN_PARSE_UNSUPPORTED_VALUE 304 #define WARN_PARSE_BAD_VALUE 305 #define WARN_PARSE_PRIVATE 306 #define WARN_PARSE_BAD_DEFAULT 307 #define WARN_PARSE_NAMESPACE_ALIAS 308 #define WARN_PARSE_PRIVATE_INHERIT 309 #define WARN_PARSE_TEMPLATE_REPEAT 310 #define WARN_PARSE_TEMPLATE_PARTIAL 311 #define WARN_PARSE_NESTED_CLASS 312 #define WARN_PARSE_UNDEFINED_EXTERN 313 #define WARN_PARSE_KEYWORD 314 #define WARN_PARSE_USING_UNDEF 315 #define WARN_PARSE_MODULE_REPEAT 316 #define WARN_PARSE_TEMPLATE_SP_UNDEF 317 #define WARN_PARSE_TEMPLATE_AMBIG 318 #define WARN_PARSE_NO_ACCESS 319 #define WARN_PARSE_EXPLICIT_TEMPLATE 320 #define WARN_PARSE_BUILTIN_NAME 321 #define WARN_PARSE_REDUNDANT 322 #define WARN_IGNORE_OPERATOR_NEW 350 /* new */ #define WARN_IGNORE_OPERATOR_DELETE 351 /* delete */ #define WARN_IGNORE_OPERATOR_PLUS 352 /* + */ #define WARN_IGNORE_OPERATOR_MINUS 353 /* - */ #define WARN_IGNORE_OPERATOR_MUL 354 /* * */ #define WARN_IGNORE_OPERATOR_DIV 355 /* / */ #define WARN_IGNORE_OPERATOR_MOD 356 /* % */ #define WARN_IGNORE_OPERATOR_XOR 357 /* ^ */ #define WARN_IGNORE_OPERATOR_AND 358 /* & */ #define WARN_IGNORE_OPERATOR_OR 359 /* | */ #define WARN_IGNORE_OPERATOR_NOT 360 /* ~ */ #define WARN_IGNORE_OPERATOR_LNOT 361 /* ! */ #define WARN_IGNORE_OPERATOR_EQ 362 /* = */ #define WARN_IGNORE_OPERATOR_LT 363 /* < */ #define WARN_IGNORE_OPERATOR_GT 364 /* > */ #define WARN_IGNORE_OPERATOR_PLUSEQ 365 /* += */ #define WARN_IGNORE_OPERATOR_MINUSEQ 366 /* -= */ #define WARN_IGNORE_OPERATOR_MULEQ 367 /* *= */ #define WARN_IGNORE_OPERATOR_DIVEQ 368 /* /= */ #define WARN_IGNORE_OPERATOR_MODEQ 369 /* %= */ #define WARN_IGNORE_OPERATOR_XOREQ 370 /* ^= */ #define WARN_IGNORE_OPERATOR_ANDEQ 371 /* &= */ #define WARN_IGNORE_OPERATOR_OREQ 372 /* |= */ #define WARN_IGNORE_OPERATOR_LSHIFT 373 /* << */ #define WARN_IGNORE_OPERATOR_RSHIFT 374 /* >> */ #define WARN_IGNORE_OPERATOR_LSHIFTEQ 375 /* <<= */ #define WARN_IGNORE_OPERATOR_RSHIFTEQ 376 /* >>= */ #define WARN_IGNORE_OPERATOR_EQUALTO 377 /* == */ #define WARN_IGNORE_OPERATOR_NOTEQUAL 378 /* != */ #define WARN_IGNORE_OPERATOR_LTEQUAL 379 /* <= */ #define WARN_IGNORE_OPERATOR_GTEQUAL 380 /* >= */ #define WARN_IGNORE_OPERATOR_LAND 381 /* && */ #define WARN_IGNORE_OPERATOR_LOR 382 /* || */ #define WARN_IGNORE_OPERATOR_PLUSPLUS 383 /* ++ */ #define WARN_IGNORE_OPERATOR_MINUSMINUS 384 /* -- */ #define WARN_IGNORE_OPERATOR_COMMA 385 /* , */ #define WARN_IGNORE_OPERATOR_ARROWSTAR 386 /* ->* */ #define WARN_IGNORE_OPERATOR_ARROW 387 /* -> */ #define WARN_IGNORE_OPERATOR_CALL 388 /* () */ #define WARN_IGNORE_OPERATOR_INDEX 389 /* [] */ #define WARN_IGNORE_OPERATOR_UPLUS 390 /* + */ #define WARN_IGNORE_OPERATOR_UMINUS 391 /* - */ #define WARN_IGNORE_OPERATOR_UMUL 392 /* * */ #define WARN_IGNORE_OPERATOR_UAND 393 /* & */ #define WARN_IGNORE_OPERATOR_NEWARR 394 /* new [] */ #define WARN_IGNORE_OEPRATOR_DELARR 395 /* delete [] */ /* 394-399 are reserved */ /* -- Type system and typemaps -- */ #define WARN_TYPE_UNDEFINED_CLASS 401 #define WARN_TYPE_INCOMPLETE 402 #define WARN_TYPE_ABSTRACT 403 #define WARN_TYPE_REDEFINED 404 #define WARN_TYPEMAP_SOURCETARGET 450 #define WARN_TYPEMAP_CHARLEAK 451 #define WARN_TYPEMAP_SWIGTYPE 452 #define WARN_TYPEMAP_APPLY_UNDEF 453 #define WARN_TYPEMAP_IN_UNDEF 460 #define WARN_TYPEMAP_OUT_UNDEF 461 #define WARN_TYPEMAP_VARIN_UNDEF 462 #define WARN_TYPEMAP_VAROUT_UNDEF 463 #define WARN_TYPEMAP_CONST_UNDEF 464 #define WARN_TYPEMAP_UNDEF 465 #define WARN_TYPEMAP_VAR_UNDEF 466 #define WARN_TYPEMAP_TYPECHECK 467 #define WARN_TYPEMAP_THROW 468 #define WARN_TYPEMAP_DIRECTORIN_UNDEF 469 /* -- General code generation -- */ #define WARN_LANG_OVERLOAD_DECL 501 #define WARN_LANG_OVERLOAD_CONSTRUCT 502 #define WARN_LANG_IDENTIFIER 503 #define WARN_LANG_RETURN_TYPE 504 #define WARN_LANG_VARARGS 505 #define WARN_LANG_VARARGS_KEYWORD 506 #define WARN_LANG_NATIVE_UNIMPL 507 #define WARN_LANG_DEREF_SHADOW 508 #define WARN_LANG_OVERLOAD_SHADOW 509 #define WARN_LANG_FRIEND_IGNORE 510 #define WARN_LANG_OVERLOAD_KEYWORD 511 #define WARN_LANG_OVERLOAD_CONST 512 #define WARN_LANG_CLASS_UNNAMED 513 #define WARN_LANG_DIRECTOR_VDESTRUCT 514 #define WARN_LANG_DISCARD_CONST 515 #define WARN_LANG_OVERLOAD_IGNORED 516 /* -- Reserved (600-799) -- */ /* -- Language module specific warnings (800 - 999) -- */ #define WARN_RUBY_WRONG_NAME 801 #define WARN_RUBY_MULTIPLE_INHERITANCE 802 #define WARN_JAVA_TYPEMAP_JNI_UNDEF 810 #define WARN_JAVA_TYPEMAP_JTYPE_UNDEF 811 #define WARN_JAVA_TYPEMAP_JSTYPE_UNDEF 812 #define WARN_JAVA_MULTIPLE_INHERITANCE 813 #define WARN_JAVA_TYPEMAP_GETCPTR_UNDEF 814 #define WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF 815 #define WARN_JAVA_TYPEMAP_PTRCONSTMOD_UNDEF 816 #define WARN_JAVA_TYPEMAP_JAVAOUT_UNDEF 817 #define WARN_JAVA_TYPEMAP_JAVAIN_UNDEF 818 #define WARN_JAVA_TYPEMAP_JAVADIRECTORIN_UNDEF 819 #define WARN_JAVA_TYPEMAP_JAVADIRECTOROUT_UNDEF 820 #define WARN_JAVA_TYPEMAP_NODIRECTOR_CODE 821 #define WARN_JAVA_COVARIANT_RET 822 /* please leave 810-829 free for Java */ #define WARN_CSHARP_TYPEMAP_CTYPE_UNDEF 830 #define WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF 831 #define WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF 832 #define WARN_CSHARP_MULTIPLE_INHERITANCE 833 #define WARN_CSHARP_TYPEMAP_GETCPTR_UNDEF 834 #define WARN_CSHARP_TYPEMAP_CLASSMOD_UNDEF 835 #define WARN_CSHARP_TYPEMAP_PTRCONSTMOD_UNDEF 836 #define WARN_CSHARP_TYPEMAP_CSOUT_UNDEF 837 #define WARN_CSHARP_TYPEMAP_CSIN_UNDEF 838 #define WARN_CSHARP_TYPEMAP_CSDIRECTORIN_UNDEF 839 #define WARN_CSHARP_TYPEMAP_CSDIRECTOROUT_UNDEF 840 #define WARN_CSHARP_TYPEMAP_NODIRECTOR_CODE 841 #define WARN_CSHARP_COVARIANT_RET 842 /* please leave 830-849 free for C# */ /* Feel free to claim any number in this space that's not currently being used. Just make sure you add an entry here */ #endif cableswig-0.1.0+git20150808.orig/SWIG/Source/.cvsignore0000644000175000000620000000006212561312227021034 0ustar stevestaffMakefile Makefile.in .deps swig eswig *.ilk *.pdb cableswig-0.1.0+git20150808.orig/SWIG/Source/Makefile.am0000644000175000000620000000454612561312227021103 0ustar stevestaff## Process this file with automake to produce Makefile.in # subdir-objects generates object files using the directory structure of the source files. AUTOMAKE_OPTIONS = foreign nostdinc subdir-objects 1.7.2 SOURCE_DIR=$(top_srcdir)/Source BUILD_SOURCE_DIR=$(top_builddir)/Source SWIG_CXX_DEFS = @SWILL@ AM_CFLAGS = -I$(BUILD_SOURCE_DIR)/Include \ -I$(BUILD_SOURCE_DIR)/CParse \ -I$(SOURCE_DIR)/Include \ -I$(SOURCE_DIR)/DOH \ -I$(SOURCE_DIR)/CParse \ -I$(SOURCE_DIR)/Preprocessor \ -I$(SOURCE_DIR)/Swig \ -I$(SOURCE_DIR)/Modules AM_CXXFLAGS = $(AM_CFLAGS) \ $(SWIG_CXX_DEFS) AM_YFLAGS = -d BUILT_SOURCES = CParse/parser.h eswig_SOURCES = CParse/cscanner.c \ CParse/parser.y \ CParse/templ.c \ CParse/util.c \ DOH/base.c \ DOH/file.c \ DOH/fio.c \ DOH/hash.c \ DOH/list.c \ DOH/memory.c \ DOH/string.c \ DOH/void.c \ Modules/allocate.cxx \ Modules/browser.cxx \ Modules/chicken.cxx \ Modules/contract.cxx \ Modules/csharp.cxx \ Modules/directors.cxx \ Modules/emit.cxx \ Modules/guile.cxx \ Modules/java.cxx \ Modules/lang.cxx \ Modules/main.cxx \ Modules/module.cxx \ Modules/mzscheme.cxx \ Modules/ocaml.cxx \ Modules/overload.cxx \ Modules/perl5.cxx \ Modules/php4.cxx \ Modules/pike.cxx \ Modules/python.cxx \ Modules/ruby.cxx \ Modules/s-exp.cxx \ Modules/swigmain.cxx \ Modules/tcl8.cxx \ Modules/typepass.cxx \ Modules/utils.cxx \ Modules/xml.cxx \ Preprocessor/cpp.c \ Preprocessor/expr.c \ Swig/cwrap.c \ Swig/error.c \ Swig/fragment.c \ Swig/getopt.c \ Swig/include.c \ Swig/misc.c \ Swig/naming.c \ Swig/parms.c \ Swig/scanner.c \ Swig/stype.c \ Swig/symbol.c \ Swig/tree.c \ Swig/typeobj.c \ Swig/typemap.c \ Swig/typesys.c \ Swig/warn.c \ Swig/wrapfunc.c bin_PROGRAMS = eswig eswig_LDADD = @SWIGLIBS@ # Override the link stage to avoid using Libtool CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ # The executable is copied to the root directory for installation and running the test-suite. # This occurs on each invocation of make and is a step towards providing support for multiple # build directories. all-local: eswig@EXEEXT@ cp eswig@EXEEXT@ ../swig@release_suffix@@EXEEXT@ clean-local: rm -f ../swig@release_suffix@@EXEEXT@ cableswig-0.1.0+git20150808.orig/SWIG/Source/DOH/0002755000175000000620000000000012561312227017452 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Source/DOH/string.c0000644000175000000620000006242112561312227021127 0ustar stevestaff/* ----------------------------------------------------------------------------- * string.c * * Implements a string object that supports both sequence operations and * file semantics. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_string_c[] = "/cvsroot/SWIG/Source/DOH/string.c,v 1.10 2004/01/22 22:42:13 cheetah Exp"; #include "dohint.h" extern DohObjInfo DohStringType; typedef struct String { DOH *file; int line; int maxsize; /* Max size allocated */ int len; /* Current length */ int hashkey; /* Hash key value */ int sp; /* Current position */ char *str; /* String data */ } String; /* ----------------------------------------------------------------------------- * void *String_data() - Return as a 'void *' * ----------------------------------------------------------------------------- */ static void * String_data(DOH *so) { String *s = (String *) ObjData(so); s->str[s->len] = 0; return (void *) s->str; } /* ----------------------------------------------------------------------------- * int String_dump() - Serialize a string onto out * ----------------------------------------------------------------------------- */ static int String_dump(DOH *so, DOH *out) { int nsent; int ret; String *s = (String *) ObjData(so); nsent = 0; while (nsent < s->len) { ret = Write(out,s->str+nsent,(s->len-nsent)); if (ret < 0) return ret; nsent += ret; } return nsent; } /* ----------------------------------------------------------------------------- * CopyString() - Copy a string * ----------------------------------------------------------------------------- */ static DOH * CopyString(DOH *so) { int max; String *str; String *s = (String *) ObjData(so); str = (String *) DohMalloc(sizeof(String)); str->hashkey = -1; str->sp = s->sp; str->line = s->line; str->file = s->file; if (str->file) Incref(str->file); max = s->maxsize; str->str = (char *) DohMalloc(max+1); memmove(str->str, s->str, max); str->maxsize= max; str->len = s->len; str->str[str->len] = 0; return DohObjMalloc(&DohStringType,str); } /* ----------------------------------------------------------------------------- * DelString() - Delete a string * ----------------------------------------------------------------------------- */ static void DelString(DOH *so) { String *s = (String *) ObjData(so); s->hashkey = -1; DohFree(s->str); s->str = 0; DohFree(s); } /* ----------------------------------------------------------------------------- * String_len() - Length of a string * ----------------------------------------------------------------------------- */ static int String_len(DOH *so) { String *s = (String *) ObjData(so); return s->len; } /* ----------------------------------------------------------------------------- * int String_cmp() - Compare two strings * ----------------------------------------------------------------------------- */ static int String_cmp(DOH *so1, DOH *so2) { String *s1, *s2; char *c1, *c2; int maxlen,i; s1 = (String *) ObjData(so1); s2 = (String *) ObjData(so2); maxlen = s1->len; if (s2->len < maxlen) maxlen = s2->len; c1 = s1->str; c2 = s2->str; for (i = 0; i < maxlen; i++,c1++,c2++) { if (*c1 != *c2) break; } if (i < maxlen) { if (*c1 < *c2) return -1; else return 1; } if (s1->len == s2->len) return 0; if (s1->len > s2->len) return 1; return -1; } /* ----------------------------------------------------------------------------- * int String_hash() - Compute string hash value * ----------------------------------------------------------------------------- */ static int String_hash(DOH *so) { String *s = (String *) ObjData(so); char *c; int i, h = 0, len; if (s->hashkey >= 0) return s->hashkey; c = s->str; len = s->len > 50 ? 50 : s->len; for (i = 0; i < len; i++) { h = (((h << 5) + *(c++))); } h = h & 0x7fffffff; s->hashkey = h; return h; } /* ----------------------------------------------------------------------------- * static add(String *s, const char *newstr) - Append to s * ----------------------------------------------------------------------------- */ static void add(String *s, const char *newstr) { int oldlen, newlen, newmaxsize, l, i, sp; char *tc; if (!newstr) return; s->hashkey = -1; l = (int) strlen(newstr); oldlen = s->len; newlen = oldlen+l + 1; if (newlen >= s->maxsize-1) { newmaxsize = 2*s->maxsize; if (newlen >= newmaxsize -1) newmaxsize = newlen + 1; s->str = (char *) DohRealloc(s->str,newmaxsize); assert(s->str); s->maxsize = newmaxsize; } tc = s->str; strcpy(tc+oldlen,newstr); sp = s->sp; if (sp >= oldlen) { tc += sp; for (i = sp; i < oldlen+l; i++,tc++) { if (*tc == '\n') s->line++; } s->sp = oldlen+l; } s->len += l; } /* ----------------------------------------------------------------------------- * void String_clear() - Clear a string * ----------------------------------------------------------------------------- */ static void String_clear(DOH *so) { String *s = (String *) ObjData(so); s->hashkey = -1; s->len = 0; *(s->str) = 0; s->sp = 0; s->line = 1; } /* ----------------------------------------------------------------------------- * void String_insert() - Insert a string * ----------------------------------------------------------------------------- */ static int String_insert(DOH *so, int pos, DOH *str) { String *s = (String *) ObjData(so); char *nstr; int len; char *data; data = (char *) DohData(str); nstr = s->str; s->hashkey = -1; if (pos == DOH_END) { add(s, data); return 0; } if (pos < 0) pos = 0; else if (pos > s->len) pos = s->len; /* See if there is room to insert the new data */ len = Len(str); while (s->maxsize <= s->len+len) { s->str = (char *) DohRealloc(s->str,2*s->maxsize); assert(s->str); s->maxsize *= 2; } memmove(s->str+pos+len, s->str+pos, (s->len - pos)); memcpy(s->str+pos,data,len); if (s->sp >= pos) { int i; for (i = 0; i < len; i++) { if (data[i] == '\n') s->line++; } s->sp+=len; } s->len += len; s->str[s->len] = 0; return 0; } /* ----------------------------------------------------------------------------- * int String_delitem() - Delete a character * ----------------------------------------------------------------------------- */ static int String_delitem(DOH *so, int pos) { String *s = (String *) ObjData(so); s->hashkey = -1; if (pos == DOH_END) pos = s->len-1; if (pos == DOH_BEGIN) pos = 0; if (s->len == 0) return 0; if (s->sp > pos) { s->sp--; assert (s->sp >= 0); if (s->str[pos] == '\n') s->line--; } memmove(s->str+pos, s->str+pos+1, ((s->len-1) - pos)); s->len--; s->str[s->len] = 0; return 0; } /* ----------------------------------------------------------------------------- * int String_delslice() - Delete a range * ----------------------------------------------------------------------------- */ static int String_delslice(DOH *so, int sindex, int eindex) { String *s = (String *) ObjData(so); int size; s->hashkey = -1; if (eindex == DOH_END) eindex = s->len; if (sindex == DOH_BEGIN) sindex = 0; if (s->len == 0) return 0; size = eindex - sindex; if (s->sp > eindex) { /* Adjust the file pointer and line count */ char *c = s->str + sindex; int i; for (i = 0; i < size; i++) { if (*c == '\n') s->line--; } s->sp -= size; assert(s->sp >= 0); } memmove(s->str+sindex,s->str+eindex, ((s->len-size) - sindex)); s->len -= size; s->str[s->len] = 0; return 0; } /* ----------------------------------------------------------------------------- * DOH *String_str() - Returns a string (used by printing commands) * ----------------------------------------------------------------------------- */ static DOH * String_str(DOH *so) { String *s = (String *) ObjData(so); s->str[s->len] = 0; return NewString(s->str); } /* ----------------------------------------------------------------------------- * int String_read() - Read data from a string * ----------------------------------------------------------------------------- */ static int String_read(DOH *so, void *buffer, int len) { int reallen, retlen; char *cb; String *s = (String *) ObjData(so); if ((s->sp + len) > s->len) reallen = (s->len - s->sp); else reallen = len; cb = (char *) buffer; retlen = reallen; if (reallen > 0) { memmove(cb, s->str+s->sp, reallen); s->sp += reallen; } return retlen; } /* ----------------------------------------------------------------------------- * int String_write() - Write data to a string * ----------------------------------------------------------------------------- */ static int String_write(DOH *so, void *buffer, int len) { int newlen; String *s = (String *) ObjData(so); s->hashkey = -1; if (s->sp > s->len) s->sp = s->len; newlen = s->sp + len+1; if (newlen > s->maxsize) { s->str = (char *) DohRealloc(s->str,newlen); assert(s->str); s->maxsize = newlen; s->len = s->sp + len; } if ((s->sp+len) > s->len) s->len = s->sp + len; memmove(s->str+s->sp,buffer,len); s->sp += len; s->str[s->len] = 0; return len; } /* ----------------------------------------------------------------------------- * int String_seek() - Seek to a new position * ----------------------------------------------------------------------------- */ static int String_seek(DOH *so, long offset, int whence) { int pos, nsp, inc; int prev; String *s = (String *) ObjData(so); if (whence == SEEK_SET) pos = 0; else if (whence == SEEK_CUR) pos = s->sp; else if (whence == SEEK_END) { pos = s->len; offset = -offset; } else pos = s->sp; nsp = pos + offset; if (nsp < 0) nsp = 0; if (s->len > 0 && nsp >= s->len) nsp = s->len-1; inc = (nsp > s->sp) ? 1 : -1; { register int sp = s->sp; register char *tc = s->str; register int len = s->len; while (sp != nsp) { prev = sp + inc; if (prev>=0 && prev<=len && tc[prev] == '\n') s->line += inc; sp+=inc; } s->sp = sp; } assert (s->sp >= 0); return 0; } /* ----------------------------------------------------------------------------- * long String_tell() - Return current position * ----------------------------------------------------------------------------- */ static long String_tell(DOH *so) { String *s = (String *) ObjData(so); return (long) (s->sp); } /* ----------------------------------------------------------------------------- * int String_putc() * ----------------------------------------------------------------------------- */ static int String_putc(DOH *so, int ch) { register int len, maxsize, sp; String *s = (String *) ObjData(so); s->hashkey = -1; len = s->len; sp = s->sp; if (sp >= len) { register char *tc; maxsize = s->maxsize; if (len > (maxsize-2)) { s->str = (char *) DohRealloc(s->str,2*maxsize); assert(s->str); s->maxsize = 2*maxsize; } tc = s->str + len; *(tc++) = ch; if (sp >= len) { s->sp = len+1; *tc = 0; if (ch == '\n') s->line++; } s->len = len+1; } else { s->str[s->sp++] = (char) ch; if (ch == '\n') s->line++; } return ch; } /* ----------------------------------------------------------------------------- * int String_getc() * ----------------------------------------------------------------------------- */ static int String_getc(DOH *so) { int c; String *s = (String *) ObjData(so); if (s->sp >= s->len) c = EOF; else c = (int) s->str[s->sp++]; if (c == '\n') s->line++; return c; } /* ----------------------------------------------------------------------------- * int String_ungetc() * ----------------------------------------------------------------------------- */ static int String_ungetc(DOH *so, int ch) { String *s = (String *) ObjData(so); if (ch == EOF) return ch; if (s->sp <= 0) return EOF; s->sp--; if (ch == '\n') s->line--; return ch; } /* ----------------------------------------------------------------------------- * replace_simple(String *str, char *token, char *rep, int flags, int count) * * Replaces count non-overlapping occurrences of token with rep in a string. * ----------------------------------------------------------------------------- */ static char * end_quote(char *s) { char *qs; char qc; char *q; char *nl; qc = *s; qs = s; while (1) { q = strpbrk(s+1,"\"\'"); nl = strchr(s+1,'\n'); if (nl && (nl < q)) { /* A new line appears before the end of the string */ if (*(nl-1) == '\\') { s = nl+1; continue; } /* String was terminated by a newline. Wing it */ return qs; } if (!q && nl) { return qs; } if (!q) return 0; if ((*q == qc) && (*(q-1) != '\\')) return q; s = q; } } static char * match_simple(char *base, char *s, char *token, int tokenlen) { (void)base; (void)tokenlen; return strstr(s,token); } static char * match_identifier(char *base, char *s, char *token, int tokenlen) { while (s) { s = strstr(s,token); if (!s) return 0; if ((s > base) && (isalnum((int) *(s-1)) || (*(s-1) == '_'))) { s += tokenlen; continue; } if (isalnum((int)*(s+tokenlen)) || (*(s+tokenlen) == '_')) { s += tokenlen; continue; } return s; } return 0; } static char * match_identifier_begin(char *base, char *s, char *token, int tokenlen) { while (s) { s = strstr(s,token); if (!s) return 0; if ((s > base) && (isalnum((int)*(s-1)) || (*(s-1) == '_'))) { s += tokenlen; continue; } return s; } return 0; } static char * match_identifier_end(char *base, char *s, char *token, int tokenlen) { (void)base; while (s) { s = strstr(s,token); if (!s) return 0; if (isalnum((int)*(s+tokenlen)) || (*(s+tokenlen) == '_')) { s += tokenlen; continue; } return s; } return 0; } static int replace_simple(String *str, char *token, char *rep, int flags, int count, char *(*match)(char *, char *, char *, int)) { int tokenlen; /* Length of the token */ int replen; /* Length of the replacement */ int delta, expand = 0; int ic; int rcount = 0; int noquote = 0; char *c, *s, *t, *first; char *q, *q2; register char *base; int i; str->hashkey = -1; /* Figure out if anything gets replaced */ if (!strlen(token)) return 0; base = str->str; tokenlen = strlen(token); s = (*match)(base,base,token,tokenlen); if (!s) return 0; /* No matches. Who cares */ if (flags & DOH_REPLACE_NOQUOTE) noquote = 1; /* If we are not replacing inside quotes, we need to do a little extra work */ if (noquote) { q = strpbrk(base,"\"\'"); if (!q) { noquote = 0; /* Well, no quotes to worry about. Oh well */ } else { while (q && (q < s)) { /* First match was found inside a quote. Try to find another match */ q2 = end_quote(q); if (!q2) { return 0; } if (q2 > s) { /* Find next match */ s = (*match)(base,q2+1,token,tokenlen); } if (!s) return 0; /* Oh well, no matches */ q = strpbrk(q2+1,"\"\'"); if (!q) noquote = 0; /* No more quotes */ } } } first = s; replen = strlen(rep); delta = (replen - tokenlen); if (delta <= 0) { /* String is either shrinking or staying the same size */ /* In this case, we do the replacement in place without memory reallocation */ ic = count; t = s; /* Target of memory copies */ while (ic && s) { if (replen) { memcpy(t,rep,replen); t += replen; } rcount++; expand += delta; /* Find the next location */ s += tokenlen; if (ic == 1) break; c = (*match)(base,s,token,tokenlen); if (noquote) { q = strpbrk(s,"\"\'"); if (!q) { noquote = 0; } else { while (q && (q < c)) { /* First match was found inside a quote. Try to find another match */ q2 = end_quote(q); if (!q2) { c = 0; break; } if (q2 > c) c = (*match)(base,q2+1,token,tokenlen); if (!c) break; q = strpbrk(q2+1,"\"\'"); if (!q) noquote = 0; /* No more quotes */ } } } if (delta) { if (c) { memmove(t,s,c-s); t += (c-s); } else { memmove(t,s,(str->str + str->len) - s + 1); } } else { t += (c-s); } s = c; ic--; } if (s && delta) { memmove(t,s,(str->str + str->len) - s + 1); } str->len += expand; str->str[str->len] = 0; if (str->sp >= str->len) str->sp += expand; /* Fix the end of file pointer */ return rcount; } /* The string is expanding as a result of the replacement */ /* Figure out how much expansion is going to occur and allocate a new string */ { char *ns; int newsize; rcount++; ic = count -1; s += tokenlen; while (ic && (c = (*match)(base,s,token,tokenlen))) { if (noquote) { q = strpbrk(s,"\"\'"); if (!q) { break; } else { while (q && (q < c)) { /* First match was found inside a quote. Try to find another match */ q2 = end_quote(q); if (!q2) { c = 0; break; } if (q2 > c) { c = (*match)(base,q2+1,token,tokenlen); if (!c) break; } q = strpbrk(q2+1,"\"\'"); if (!q) noquote = 0; } } } if (c) { rcount++; ic--; s = c + tokenlen; } else { break; } } expand = delta*rcount; /* Total amount of expansion for the replacement */ newsize = str->maxsize; while ((str->len + expand) >= newsize) newsize *= 2; ns = (char *) DohMalloc(newsize); assert(ns); t = ns; s = first; /* Copy the first part of the string */ if (first > str->str) { memcpy(t,str->str,(first - str->str)); t += (first-str->str); } for (i = 0; i < rcount; i++) { memcpy(t,rep,replen); t += replen; s += tokenlen; c = (*match)(base,s,token,tokenlen); if (noquote) { q = strpbrk(s,"\"\'"); if (!q) { noquote = 0; } else { while (q && (q < c)) { /* First match was found inside a quote. Try to find another match */ q2 = end_quote(q); if (!q2) { c = 0; break; } if (q2 > c) { c = (*match)(base,q2+1,token,tokenlen); if (!c) break; } q = strpbrk(q2+1,"\"\'"); if (!q) noquote = 0; /* No more quotes */ } } } if (i < (rcount - 1)) { memcpy(t,s,c-s); t += (c-s); } else { memcpy(t,s,(str->str + str->len) - s + 1); } s = c; } c = str->str; str->str = ns; if (str->sp >= str->len) str->sp += expand; str->len += expand; str->str[str->len] = 0; str->maxsize = newsize; DohFree(c); return rcount; } } /* ----------------------------------------------------------------------------- * int String_replace() * ----------------------------------------------------------------------------- */ static int String_replace(DOH *stro, DOH *token, DOH *rep, int flags) { int count = -1; String *str = (String *) ObjData(stro); if (flags & DOH_REPLACE_FIRST) count = 1; if (flags & DOH_REPLACE_ID_END) { return replace_simple(str,Char(token),Char(rep),flags, count, match_identifier_end); } else if (flags & DOH_REPLACE_ID_BEGIN) { return replace_simple(str,Char(token),Char(rep),flags, count, match_identifier_begin); } else if (flags & DOH_REPLACE_ID) { return replace_simple(str,Char(token),Char(rep),flags, count, match_identifier); } else { return replace_simple(str,Char(token), Char(rep), flags, count, match_simple); } } /* ----------------------------------------------------------------------------- * void String_chop(DOH *str) * ----------------------------------------------------------------------------- */ static void String_chop(DOH *so) { char *c; String *str = (String *) ObjData(so); /* Replace trailing whitespace */ c = str->str + str->len - 1; while ((str->len > 0) && (isspace((int)*c))) { if (str->sp >= str->len) { str->sp--; if (*c == '\n') str->line--; } str->len--; c--; } str->str[str->len] = 0; assert (str->sp >= 0); str->hashkey = -1; } static void String_setfile(DOH *so, DOH *file) { DOH *fo; String *str = (String *) ObjData(so); if (!DohCheck(file)) { fo = NewString(file); Decref(fo); } else fo = file; Incref(fo); Delete(str->file); str->file = fo; } static DOH * String_getfile(DOH *so) { String *str = (String *) ObjData(so); return str->file; } static void String_setline(DOH *so, int line) { String *str = (String *) ObjData(so); str->line = line; } static int String_getline(DOH *so) { String *str = (String *) ObjData(so); return str->line; } static DohListMethods StringListMethods = { 0, /* doh_getitem */ 0, /* doh_setitem */ String_delitem, /* doh_delitem */ String_insert, /* doh_insitem */ String_delslice, /* doh_delslice */ }; static DohFileMethods StringFileMethods = { String_read, String_write, String_putc, String_getc, String_ungetc, String_seek, String_tell, 0, /* close */ }; static DohStringMethods StringStringMethods = { String_replace, String_chop, }; DohObjInfo DohStringType = { "String", /* objname */ DelString, /* doh_del */ CopyString, /* doh_copy */ String_clear, /* doh_clear */ String_str, /* doh_str */ String_data, /* doh_data */ String_dump, /* doh_dump */ String_len, /* doh_len */ String_hash, /* doh_hash */ String_cmp, /* doh_cmp */ 0, /* doh_first */ 0, /* doh_next */ String_setfile, /* doh_setfile */ String_getfile, /* doh_getfile */ String_setline, /* doh_setline */ String_getline, /* doh_getline */ 0, /* doh_mapping */ &StringListMethods, /* doh_sequence */ &StringFileMethods, /* doh_file */ &StringStringMethods, /* doh_string */ 0, /* doh_position */ 0, }; #define INIT_MAXSIZE 16 /* ----------------------------------------------------------------------------- * NewString(const char *c) - Create a new string * ----------------------------------------------------------------------------- */ DOHString * DohNewString(const DOH *so) { int l = 0, max; String *str; char *s; if (DohCheck(so)) s = Char(so); else s = (char *) so; str = (String *) DohMalloc(sizeof(String)); str->hashkey = -1; str->sp = 0; str->line = 1; str->file = 0; max = INIT_MAXSIZE; if (s) { l = (int) strlen(s); if ((l+1) > max) max = l+1; } str->str = (char *) DohMalloc(max); str->maxsize = max; if (s) { strcpy(str->str,s); str->len = l; str->sp = l; } else { str->str[0] = 0; str->len = 0; } return DohObjMalloc(&DohStringType,str); } /* ----------------------------------------------------------------------------- * NewStringWithSize(const char *c, int len) - Create a new string * ----------------------------------------------------------------------------- */ DOHString * DohNewStringWithSize(const DOH *so, int len) { int l = 0, max; String *str; char *s; if (DohCheck(so)) s = Char(so); else s = (char *) so; str = (String *) DohMalloc(sizeof(String)); str->hashkey = -1; str->sp = 0; str->line = 1; str->file = 0; max = INIT_MAXSIZE; if (s) { l = (int) len; if ((l+1) > max) max = l+1; } str->str = (char *) DohMalloc(max); str->maxsize = max; if (s) { strncpy(str->str,s,len); str->len = l; str->sp = l; } else { str->str[0] = 0; str->len = 0; } return DohObjMalloc(&DohStringType,str); } /* ----------------------------------------------------------------------------- * NewStringf(DOH *fmt, ...) * * Create a new string from a list of objects. * ----------------------------------------------------------------------------- */ DOHString * DohNewStringf(const DOH *fmt, ...) { va_list ap; DOH *r; va_start(ap,fmt); r = NewString(""); DohvPrintf(r,Char(fmt),ap); va_end(ap); return (DOHString *) r; } /* ----------------------------------------------------------------------------- * Strcmp() * Strncmp() * Strstr() * Strchr() * * Some utility functions. * ----------------------------------------------------------------------------- */ int DohStrcmp(const DOHString_or_char *s1, const DOHString_or_char *s2) { return strcmp(Char(s1),Char(s2)); } int DohStrncmp(const DOHString_or_char *s1, const DOHString_or_char *s2, int n) { return strncmp(Char(s1),Char(s2),n); } char *DohStrstr(const DOHString_or_char *s1, const DOHString_or_char *s2) { char* p1 = Char(s1); char* p2 = Char(s2); return p2 == 0 || *p2 == '\0' ? p1 : strstr(p1,p2); } char *DohStrchr(const DOHString_or_char *s1, int ch) { return strchr(Char(s1),ch); } cableswig-0.1.0+git20150808.orig/SWIG/Source/DOH/dohint.h0000644000175000000620000001224312561312227021110 0ustar stevestaff /* ----------------------------------------------------------------------------- * dohint.h * * This file describes internally managed objects. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * * /cvsroot/SWIG/Source/DOH/dohint.h,v 1.3 2003/09/11 20:26:53 beazley Exp * ----------------------------------------------------------------------------- */ #ifndef _DOHINT_H #define _DOHINT_H #include #include #include #include #include #include #include "doh.h" /* Hash objects */ typedef struct { DOH *(*doh_getattr)(DOH *obj, DOH *name); /* Get attribute */ int (*doh_setattr)(DOH *obj, DOH *name, DOH *value); /* Set attribute */ int (*doh_delattr)(DOH *obj, DOH *name); /* Del attribute */ DOH *(*doh_keys)(DOH *obj); /* All keys as a list */ } DohHashMethods; /* List objects */ typedef struct { DOH *(*doh_getitem)(DOH *obj, int index); /* Get item */ int (*doh_setitem)(DOH *obj, int index, DOH *value); /* Set item */ int (*doh_delitem)(DOH *obj, int index); /* Delete item */ int (*doh_insitem)(DOH *obj, int index, DOH *value); /* Insert item */ int (*doh_delslice)(DOH *obj, int sindex, int eindex); /* Delete slice */ } DohListMethods; /* File methods */ typedef struct { int (*doh_read)(DOH *obj, void *buffer, int nbytes); /* Read bytes */ int (*doh_write)(DOH *obj, void *buffer, int nbytes); /* Write bytes */ int (*doh_putc)(DOH *obj, int ch); /* Put character */ int (*doh_getc)(DOH *obj); /* Get character */ int (*doh_ungetc)(DOH *obj, int ch); /* Unget character */ int (*doh_seek)(DOH *obj, long offset, int whence); /* Seek */ long (*doh_tell)(DOH *obj); /* Tell */ int (*doh_close)(DOH *obj); /* Close */ } DohFileMethods; /* String methods */ typedef struct { int (*doh_replace)(DOH *obj, DOH *old, DOH *rep, int flags); void (*doh_chop)(DOH *obj); } DohStringMethods; /* ----------------------------------------------------------------------------- * DohObjInfo * ----------------------------------------------------------------------------- */ typedef struct DohObjInfo { char *objname; /* Object name */ /* Basic object methods */ void (*doh_del)(DOH *obj); /* Delete object */ DOH *(*doh_copy)(DOH *obj); /* Copy and object */ void (*doh_clear)(DOH *obj); /* Clear an object */ /* I/O methods */ DOH *(*doh_str)(DOH *obj); /* Make a full string */ void *(*doh_data)(DOH *obj); /* Return raw data */ int (*doh_dump)(DOH *obj, DOH *out); /* Serialize on out */ /* Length and hash values */ int (*doh_len)(DOH *obj); int (*doh_hashval)(DOH *obj); /* Compare */ int (*doh_cmp)(DOH *obj1, DOH *obj2); /* Iterators */ DohIterator (*doh_first)(DOH *obj); DohIterator (*doh_next)(DohIterator ); /* Positional */ void (*doh_setfile)(DOH *obj, DOHString_or_char *file); DOH *(*doh_getfile)(DOH *obj); void (*doh_setline)(DOH *obj, int line); int (*doh_getline)(DOH *obj); DohHashMethods *doh_hash; /* Hash methods */ DohListMethods *doh_list; /* List methods */ DohFileMethods *doh_file; /* File methods */ DohStringMethods *doh_string; /* String methods */ void *doh_reserved; /* Reserved */ void *clientdata; /* User data */ } DohObjInfo; typedef struct { void *data; /* Data pointer */ DohObjInfo *type; void *meta; /* Meta data */ int flag_intern : 1; /* Interned object */ int flag_marked : 1; /* Mark flag. Used to avoid recursive loops in places */ int flag_user : 1; /* User flag */ int flag_usermark : 1; /* User marked */ int refcount : 28; /* Reference count (max 16 million) */ } DohBase; /* Macros for decrefing and increfing (safe for null objects). */ #define Decref(a) if (a) ((DohBase *) a)->refcount-- #define Incref(a) if (a) ((DohBase *) a)->refcount++ #define Refcount(a) ((DohBase *) a)->refcount /* Macros for manipulating objects in a safe manner */ #define ObjData(a) ((DohBase *)a)->data #define ObjSetMark(a,x) ((DohBase *)a)->flag_marked = x #define ObjGetMark(a) ((DohBase *)a)->flag_marked #define ObjType(a) ((DohBase *)a)->type extern DOH *DohObjMalloc(DohObjInfo *type, void *data); /* Allocate a DOH object */ extern void DohObjFree(DOH *ptr); /* Free a DOH object */ #endif /* DOHINT_H */ cableswig-0.1.0+git20150808.orig/SWIG/Source/DOH/.cvsignore0000644000175000000620000000002012561312227021440 0ustar stevestaff.deps .dirstamp cableswig-0.1.0+git20150808.orig/SWIG/Source/DOH/doh.h0000644000175000000620000003615612561312227020406 0ustar stevestaff/* ----------------------------------------------------------------------------- * doh.h * * This file describes of the externally visible functions in DOH. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * * /cvsroot/SWIG/Source/DOH/doh.h,v 1.8 2003/10/31 17:36:37 beazley Exp * ----------------------------------------------------------------------------- */ #ifndef _DOH_H #define _DOH_H /* Set the namespace prefix for DOH API functions. This can be used to control visibility of the functions in libraries */ /* Set this macro if you want to change DOH linkage. You would do this if you wanted to hide DOH in a library using a different set of names. Note: simply change "Doh" to a new name. */ /* #define DOH_NAMESPACE(x) Doh ## x */ #ifdef DOH_NAMESPACE /* Namespace control. These macros define all of the public API names in DOH */ #define DohCheck DOH_NAMESPACE(Check) #define DohIntern DOH_NAMESPACE(Intern) #define DohDelete DOH_NAMESPACE(Delete) #define DohCopy DOH_NAMESPACE(Copy) #define DohClear DOH_NAMESPACE(Clear) #define DohStr DOH_NAMESPACE(Str) #define DohData DOH_NAMESPACE(Data) #define DohDump DOH_NAMESPACE(Dump) #define DohLen DOH_NAMESPACE(Len) #define DohHashval DOH_NAMESPACE(Hashval) #define DohCmp DOH_NAMESPACE(Cmp) #define DohIncref DOH_NAMESPACE(Incref) #define DohGetattr DOH_NAMESPACE(Getattr) #define DohSetattr DOH_NAMESPACE(Setattr) #define DohDelattr DOH_NAMESPACE(Delattr) #define DohKeys DOH_NAMESPACE(Keys) #define DohGetInt DOH_NAMESPACE(GetInt) #define DohGetDouble DOH_NAMESPACE(GetDouble) #define DohGetChar DOH_NAMESPACE(GetChar) #define DohSetChar DOH_NAMESPACE(SetChar) #define DohSetInt DOH_NAMESPACE(SetInt) #define DohSetDouble DOH_NAMESPACE(SetDouble) #define DohSetVoid DOH_NAMESPACE(SetVoid) #define DohGetVoid DOH_NAMESPACE(GetVoid) #define DohGetitem DOH_NAMESPACE(Getitem) #define DohSetitem DOH_NAMESPACE(Setitem) #define DohDelitem DOH_NAMESPACE(Delitem) #define DohInsertitem DOH_NAMESPACE(Insertitem) #define DohDelslice DOH_NAMESPACE(Delslice) #define DohWrite DOH_NAMESPACE(Write) #define DohRead DOH_NAMESPACE(Read) #define DohSeek DOH_NAMESPACE(Seek) #define DohTell DOH_NAMESPACE(Tell) #define DohGetc DOH_NAMESPACE(Getc) #define DohPutc DOH_NAMESPACE(Putc) #define DohUngetc DOH_NAMESPACE(Ungetc) #define DohGetline DOH_NAMESPACE(Getline) #define DohSetline DOH_NAMESPACE(Setline) #define DohGetfile DOH_NAMESPACE(Getfile) #define DohSetfile DOH_NAMESPACE(Setfile) #define DohReplace DOH_NAMESPACE(Replace) #define DohChop DOH_NAMESPACE(Chop) #define DohGetmeta DOH_NAMESPACE(Getmeta) #define DohSetmeta DOH_NAMESPACE(Setmeta) #define DohDelmeta DOH_NAMESPACE(Delmeta) #define DohEncoding DOH_NAMESPACE(Encoding) #define DohPrintf DOH_NAMESPACE(Printf) #define DohvPrintf DOH_NAMESPACE(vPrintf) #define DohPrintv DOH_NAMESPACE(Printv) #define DohReadline DOH_NAMESPACE(Readline) #define DohIsMapping DOH_NAMESPACE(IsMapping) #define DohIsSequence DOH_NAMESPACE(IsSequence) #define DohIsString DOH_NAMESPACE(IsString) #define DohIsFile DOH_NAMESPACE(IsFile) #define DohNewString DOH_NAMESPACE(NewString) #define DohNewStringWithSize DOH_NAMESPACE(NewStringWithSize) #define DohNewStringf DOH_NAMESPACE(NewStringf) #define DohStrcmp DOH_NAMESPACE(Strcmp) #define DohStrncmp DOH_NAMESPACE(Strncmp) #define DohStrstr DOH_NAMESPACE(Strstr) #define DohStrchr DOH_NAMESPACE(Strchr) #define DohNewFile DOH_NAMESPACE(NewFile) #define DohNewFileFromFile DOH_NAMESPACE(NewFileFromFile) #define DohNewFileFromFd DOH_NAMESPACE(NewFileFromFd) #define DohClose DOH_NAMESPACE(Close) #define DohCopyto DOH_NAMESPACE(Copyto) #define DohNewList DOH_NAMESPACE(NewList) #define DohNewHash DOH_NAMESPACE(NewHash) #define DohNewVoid DOH_NAMESPACE(NewVoid) #define DohSplit DOH_NAMESPACE(Split) #define DohSplitLines DOH_NAMESPACE(SplitLines) #define DohNone DOH_NAMESPACE(None) #define DohCall DOH_NAMESPACE(Call) #define DohObjMalloc DOH_NAMESPACE(ObjMalloc) #define DohObjFree DOH_NAMESPACE(ObjFree) #define DohMemoryDebug DOH_NAMESPACE(MemoryDebug) #define DohStringType DOH_NAMESPACE(StringType) #define DohListType DOH_NAMESPACE(ListType) #define DohHashType DOH_NAMESPACE(HashType) #define DohFileType DOH_NAMESPACE(FileType) #define DohVoidType DOH_NAMESPACE(VoidType) #define DohIterator DOH_NAMESPACE(Iterator) #define DohFirst DOH_NAMESPACE(First) #define DohNext DOH_NAMESPACE(Next) #endif #include #include #define DOH_MAJOR_VERSION 0 #define DOH_MINOR_VERSION 1 typedef void DOH; /* * With dynamic typing, all DOH objects are technically of type 'void *'. * However, to clarify the reading of source code, the following symbolic * names are used. */ #define DOHString DOH #define DOHList DOH #define DOHHash DOH #define DOHFile DOH #define DOHVoid DOH #define DOHString_or_char DOH #define DOHObj_or_char DOH #define DOH_BEGIN -1 #define DOH_END -2 #define DOH_CUR -3 #define DOH_CURRENT -3 /* Iterator objects */ typedef struct { void *key; /* Current key (if any) */ void *item; /* Current item */ void *object; /* Object being iterated over */ void *_current; /* Internal use */ int _index; /* Internal use */ } DohIterator; /* Memory management */ #ifndef DohMalloc #define DohMalloc malloc #endif #ifndef DohRealloc #define DohRealloc realloc #endif #ifndef DohFree #define DohFree free #endif extern int DohCheck(const DOH *ptr); /* Check if a DOH object */ extern void DohIntern(DOH *); /* Intern an object */ /* Basic object methods. Common to most objects */ extern void DohDelete(DOH *obj); /* Delete an object */ extern DOH *DohCopy(const DOH *obj); extern void DohClear(DOH *obj); extern DOHString *DohStr(const DOH *obj); extern void *DohData(const DOH *obj); extern int DohDump(const DOH *obj, DOHFile *out); extern int DohLen(const DOH *obj); extern int DohHashval(const DOH *obj); extern int DohCmp(const DOH *obj1, const DOH *obj2); extern void DohIncref(DOH *obj); /* Mapping methods */ extern DOH *DohGetattr(DOH *obj, const DOHString_or_char *name); extern int DohSetattr(DOH *obj, const DOHString_or_char *name, const DOHObj_or_char *value); extern int DohDelattr(DOH *obj, const DOHString_or_char *name); extern DOH *DohKeys(DOH *obj); extern int DohGetInt(DOH *obj, const DOHString_or_char *name); extern double DohGetDouble(DOH *obj, const DOHString_or_char *name); extern char *DohGetChar(DOH *obj, const DOHString_or_char *name); extern void DohSetInt(DOH *obj, const DOHString_or_char *name, int); extern void DohSetDouble(DOH *obj, const DOHString_or_char *name, double); extern void *DohGetVoid(DOH *obj, const DOHString_or_char *name); extern void DohSetVoid(DOH *obj, const DOHString_or_char *name, void *value); /* Sequence methods */ extern DOH *DohGetitem(DOH *obj, int index); extern int DohSetitem(DOH *obj, int index, const DOHObj_or_char *value); extern int DohDelitem(DOH *obj, int index); extern int DohInsertitem(DOH *obj, int index, const DOHObj_or_char *value); extern int DohDelslice(DOH *obj, int sindex, int eindex); /* File methods */ extern int DohWrite(DOHFile *obj, void *buffer, int length); extern int DohRead(DOHFile *obj, void *buffer, int length); extern int DohSeek(DOHFile *obj, long offset, int whence); extern long DohTell(DOHFile *obj); extern int DohGetc(DOHFile *obj); extern int DohPutc(int ch, DOHFile *obj); extern int DohUngetc(int ch, DOHFile *obj); /* Iterators */ extern DohIterator DohFirst(DOH *obj); extern DohIterator DohNext(DohIterator x); /* Positional */ extern int DohGetline(DOH *obj); extern void DohSetline(DOH *obj, int line); extern DOH *DohGetfile(DOH *obj); extern void DohSetfile(DOH *obj, DOH *file); /* String Methods */ extern int DohReplace(DOHString *src, const DOHString_or_char *token, const DOHString_or_char *rep, int flags); extern void DohChop(DOHString *src); /* Meta-variables */ extern DOH *DohGetmeta(DOH *, const DOH *); extern int DohSetmeta(DOH *, const DOH *, const DOH *value); extern int DohDelmeta(DOH *, const DOH *); /* Utility functions */ extern void DohEncoding(char *name, DOH *(*fn)(DOH *s)); extern int DohPrintf(DOHFile *obj, const char *format, ...); extern int DohvPrintf(DOHFile *obj, const char *format, va_list ap); extern int DohPrintv(DOHFile *obj, ...); extern DOH *DohReadline(DOHFile *in); /* Miscellaneous */ extern int DohIsMapping(const DOH *obj); extern int DohIsSequence(const DOH *obj); extern int DohIsString(const DOH *obj); extern int DohIsFile(const DOH *obj); extern void DohSetmark(DOH *obj, int x); extern int DohGetmark(DOH *obj); /* ----------------------------------------------------------------------------- * Strings. * ----------------------------------------------------------------------------- */ extern DOHString *DohNewString(const DOH *c); extern DOHString *DohNewStringWithSize(const DOH *c, int len); extern DOHString *DohNewStringf(const DOH *fmt, ...); extern int DohStrcmp(const DOHString_or_char *s1, const DOHString_or_char *s2); extern int DohStrncmp(const DOHString_or_char *s1, const DOHString_or_char *s2, int n); extern char *DohStrstr(const DOHString_or_char *s1, const DOHString_or_char *s2); extern char *DohStrchr(const DOHString_or_char *s1, int ch); /* String replacement flags */ #define DOH_REPLACE_ANY 0x01 #define DOH_REPLACE_NOQUOTE 0x02 #define DOH_REPLACE_ID 0x04 #define DOH_REPLACE_FIRST 0x08 #define DOH_REPLACE_ID_BEGIN 0x10 #define DOH_REPLACE_ID_END 0x20 #define Replaceall(s,t,r) DohReplace(s,t,r,DOH_REPLACE_ANY) #define Replaceid(s,t,r) DohReplace(s,t,r,DOH_REPLACE_ID) /* ----------------------------------------------------------------------------- * Files * ----------------------------------------------------------------------------- */ extern DOHFile *DohNewFile(DOH *file, const char *mode); extern DOHFile *DohNewFileFromFile(FILE *f); extern DOHFile *DohNewFileFromFd(int fd); extern int DohClose(DOH *file); extern int DohCopyto(DOHFile *input, DOHFile *output); /* ----------------------------------------------------------------------------- * List * ----------------------------------------------------------------------------- */ extern DOHList *DohNewList(); /* ----------------------------------------------------------------------------- * Hash * ----------------------------------------------------------------------------- */ extern DOHHash *DohNewHash(); /* ----------------------------------------------------------------------------- * Void * ----------------------------------------------------------------------------- */ extern DOHVoid *DohNewVoid(void *ptr, void (*del)(void *)); extern DOHList *DohSplit(DOHFile *input, char ch, int nsplits); extern DOHList *DohSplitLines(DOHFile *input); extern DOH *DohNone; extern void DohMemoryDebug(void); #ifndef DOH_LONG_NAMES /* Macros to invoke the above functions. Includes the location of the caller to simplify debugging if something goes wrong */ #define Delete DohDelete #define Copy DohCopy #define Clear DohClear #define Str DohStr #define Dump DohDump #define Getattr DohGetattr #define Setattr DohSetattr #define Delattr DohDelattr #define Hashval DohHashval #define Getitem DohGetitem #define Setitem DohSetitem #define Delitem DohDelitem #define Insert DohInsertitem #define Delslice DohDelslice #define Append(s,x) DohInsertitem(s,DOH_END,x) #define Push(s,x) DohInsertitem(s,DOH_BEGIN,x) #define Len DohLen #define Data DohData #define Char (char *) Data #define Cmp DohCmp #define Setline DohSetline #define Getline DohGetline #define Setfile DohSetfile #define Getfile DohGetfile #define Write DohWrite #define Read DohRead #define Seek DohSeek #define Tell DohTell #define Printf DohPrintf #define Printv DohPrintv #define Getc DohGetc #define Putc DohPutc #define Ungetc DohUngetc #define Close DohClose #define vPrintf DohvPrintf #define GetInt DohGetInt #define GetDouble DohGetDouble #define GetChar DohGetChar #define GetVoid DohGetVoid #define SetInt DohSetInt #define SetDouble DohSetDouble #define SetChar DohSetattr #define SetVoid DohSetVoid #define Readline DohReadline #define Replace DohReplace #define Chop DohChop #define Getmeta DohGetmeta #define Setmeta DohSetmeta #define Delmeta DohDelmeta #define NewString DohNewString #define NewStringWithSize DohNewStringWithSize #define NewStringf DohNewStringf #define NewHash DohNewHash #define NewList DohNewList #define NewFile DohNewFile #define NewFileFromFile DohNewFileFromFile #define NewFileFromFd DohNewFileFromFd #define Close DohClose #define NewVoid DohNewVoid #define Keys DohKeys #define Strcmp DohStrcmp #define Strncmp DohStrncmp #define Strstr DohStrstr #define Strchr DohStrchr #define Copyto DohCopyto #define Split DohSplit #define SplitLines DohSplitLines #define Setmark DohSetmark #define Getmark DohGetmark #define None DohNone #define Call DohCall #define First DohFirst #define Next DohNext #define Iterator DohIterator #endif #ifdef NIL #undef NIL #endif #define NIL (char *) NULL #endif /* DOH_H */ cableswig-0.1.0+git20150808.orig/SWIG/Source/DOH/fio.c0000644000175000000620000003054412561312227020377 0ustar stevestaff/* ----------------------------------------------------------------------------- * fio.c * * This file implements a number of standard I/O operations included * formatted output, readline, and splitting. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_fio_c[] = "/cvsroot/SWIG/Source/DOH/fio.c,v 1.4 2004/01/15 22:46:04 cheetah Exp"; #include "dohint.h" #define OBUFLEN 512 static DOH *encodings = 0; /* Encoding hash */ /* ----------------------------------------------------------------------------- * Writen() * * Write's N characters of output and retries until all characters are * written. This is useful should a write operation encounter a spurious signal. * ----------------------------------------------------------------------------- */ static int Writen(DOH *out, void *buffer, int len) { int nw = len, ret; char *cb = (char *) buffer; while (nw) { ret = Write(out,cb,nw); if (ret < 0) return -1; nw = nw - ret; cb += ret; } return len; } /* ----------------------------------------------------------------------------- * DohEncoding() * * Registers a new printf encoding method. An encoder function should accept * two file-like objects and operate as a filter. * ----------------------------------------------------------------------------- */ void DohEncoding(char *name, DOH *(*fn)(DOH *s)) { if (!encodings) encodings = NewHash(); Setattr(encodings,(void *) name, NewVoid((void *)fn,0)); } /* internal function for processing an encoding */ static DOH *encode(char *name, DOH *s) { DOH *handle, *ns; DOH *(*fn)(DOH *); long pos; if (!encodings || !(handle = Getattr(encodings,name))) { return Copy(s); } pos = Tell(s); Seek(s,0,SEEK_SET); fn = (DOH *(*)(DOH *)) Data(handle); ns = (*fn)(s); Seek(s,pos,SEEK_SET); return ns; } /* ----------------------------------------------------------------------------- * DohvPrintf() * * DOH implementation of printf. Output can be directed to any file-like object * including bare FILE * objects. The same formatting codes as printf are * recognized with two extensions: * * %s - Prints a "char *" or the string representation of any * DOH object. This will implicitly result in a call to * Str(obj). * * %(encoder)* - Filters the output through an encoding function registered * with DohEncoder(). * * Note: This function is not particularly memory efficient with large strings. * It's better to use Dump() or some other method instead. * ----------------------------------------------------------------------------- */ int DohvPrintf(DOH *so, const char *format, va_list ap) { static char *fmt_codes = "dioxXucsSfeEgGpn"; int state = 0; const char *p = format; char newformat[256]; char obuffer[OBUFLEN]; char *fmt = 0; char temp[64]; int widthval = 0; int precval = 0; int maxwidth; char *w = 0; int ivalue; double dvalue; void *pvalue; char *stemp; int nbytes = 0; char encoder[128], *ec = 0; memset (newformat, 0, sizeof (char *)); while (*p) { switch(state) { case 0: /* Ordinary text */ if (*p != '%') { Putc(*p,so); nbytes++; } else{ fmt = newformat; widthval = 0; precval = 0; *(fmt++) = *p; encoder[0] = 0; state = 10; } break; case 10: /* Look for a width and precision */ if (isdigit((int)*p) && (*p != '0')) { w = temp; *(w++) = *p; *(fmt++) = *p; state = 20; } else if (strchr(fmt_codes,*p)) { /* Got one of the formatting codes */ p--; state = 100; } else if (*p == '*') { /* Width field is specified in the format list */ widthval = va_arg(ap,int); sprintf(temp,"%d",widthval); for (w = temp; *w; w++) { *(fmt++) = *w; } state = 30; } else if (*p == '%') { Putc(*p,so); fmt = newformat; nbytes++; state = 0; } else if (*p == '(') { ec = encoder; state = 60; } else { *(fmt++) = *p; } break; case 20: /* Hmmm. At the start of a width field */ if (isdigit((int)*p)) { *(w++) = *p; *(fmt++) = *p; } else if (strchr(fmt_codes,*p)) { /* Got one of the formatting codes */ /* Figure out width */ *w = 0; widthval = atoi(temp); p--; state = 100; } else if (*p == '.') { *w = 0; widthval = atoi(temp); w = temp; *(fmt++) = *p; state = 40; } else { /* ??? */ *w = 0; widthval = atoi(temp); state = 50; } break; case 30: /* Parsed a width from an argument. Look for a . */ if (*p == '.') { w = temp; *(fmt++) = *p; state = 40; } else if (strchr(fmt_codes,*p)) { /* Got one of the formatting codes */ /* Figure out width */ p--; state = 100; } else { /* hmmm. Something else. */ state = 50; } break; case 40: /* Start of precision expected */ if (isdigit((int)*p) && (*p != '0')) { *(fmt++) = *p; *(w++) = *p; state = 41; } else if (*p == '*') { /* Precision field is specified in the format list */ precval = va_arg(ap,int); sprintf(temp,"%d",precval); for (w = temp; *w; w++) { *(fmt++) = *w; } state = 50; } else if (strchr(fmt_codes,*p)) { p--; state = 100; } else { *(fmt++) = *p; state = 50; } break; case 41: if (isdigit((int)*p)) { *(fmt++) = *p; *(w++) = *p; } else if (strchr(fmt_codes,*p)) { /* Got one of the formatting codes */ /* Figure out width */ *w = 0; precval = atoi(temp); p--; state = 100; } else { *w = 0; precval = atoi(temp); *(fmt++) = *p; state = 50; } break; /* Hang out, wait for format specifier */ case 50: if (strchr(fmt_codes,*p)) { p--; state = 100; } else { *(fmt++) = *p; } break; /* Got an encoding header */ case 60: if (*p == ')') { *ec = 0; state = 10; } else { *ec = *p; ec++; } break; case 100: /* Got a formatting code */ if (widthval < precval) maxwidth = precval; else maxwidth = widthval; if ((*p == 's') || (*p == 'S')) { /* Null-Terminated string */ DOH *doh; DOH *Sval; DOH *enc = 0; doh = va_arg(ap, DOH *); if (DohCheck(doh)) { /* Is a DOH object. */ if (DohIsString(doh)) { Sval = doh; } else { Sval = Str(doh); } if (strlen(encoder)) { enc = encode(encoder,Sval); maxwidth = maxwidth+strlen(newformat)+Len(enc); } else { maxwidth = maxwidth+strlen(newformat)+Len(Sval); } *(fmt++) = 's'; *fmt = 0; if ((maxwidth + 1) < OBUFLEN) { stemp = obuffer; } else { stemp = (char *) DohMalloc(maxwidth+1); } if (enc) { nbytes+=sprintf(stemp,newformat,Data(enc)); } else { nbytes+=sprintf(stemp,newformat,Data(Sval)); } if (Writen(so,stemp,strlen(stemp)) < 0) return -1; if ((DOH *) Sval != doh) { Delete(Sval); } if (enc) Delete(enc); if (*p == 'S') { Delete(doh); } if (stemp != obuffer) { DohFree(stemp); } } else { if (!doh) doh = (char *)""; if (strlen(encoder)) { DOH *s = NewString(doh); Seek(s,0, SEEK_SET); enc = encode(encoder,s); Delete(s); doh = Char(enc); } else { enc = 0; } maxwidth = maxwidth+strlen(newformat)+strlen((char *) doh); *(fmt++) = 's'; *fmt = 0; if ((maxwidth+1) < OBUFLEN) { stemp = obuffer; } else { stemp = (char *) DohMalloc(maxwidth + 1); } nbytes+=sprintf(stemp,newformat,doh); if (Writen(so,stemp,strlen(stemp)) < 0) return -1; if (stemp != obuffer) { DohFree(stemp); } if (enc) Delete(enc); } } else { *(fmt++) = *p; *fmt = 0; maxwidth = maxwidth+strlen(newformat)+64; /* Only allocate a buffer if it is too big to fit. Shouldn't have to do this very often */ if (maxwidth < OBUFLEN) stemp = obuffer; else stemp = (char *) DohMalloc(maxwidth+1); switch(*p) { case 'd': case 'i': case 'o': case 'u': case 'x': case 'X': case 'c': ivalue = va_arg(ap,int); nbytes+=sprintf(stemp,newformat,ivalue); break; case 'f': case 'g': case 'e': case 'E': case 'G': dvalue = va_arg(ap,double); nbytes+=sprintf(stemp,newformat,dvalue); break; case 'p': pvalue = va_arg(ap,void *); nbytes+=sprintf(stemp,newformat,pvalue); break; default: break; } if (Writen(so,stemp,strlen(stemp)) < 0) return -1; if (stemp != obuffer) DohFree(stemp); } state = 0; break; } p++; } if (state) { int r; *fmt = 0; r = Writen(so,fmt,strlen(fmt)); if (r < 0) return -1; nbytes += r; } return nbytes; } /* ----------------------------------------------------------------------------- * DohPrintf() * * Variable length argument entry point to Printf * ----------------------------------------------------------------------------- */ int DohPrintf(DOH *obj, const char *format, ...) { va_list ap; int ret; va_start(ap,format); ret = DohvPrintf(obj,format,ap); va_end(ap); return ret; } /* ----------------------------------------------------------------------------- * DohPrintv() * * Print a null-terminated variable length list of DOH objects * ----------------------------------------------------------------------------- */ int DohPrintv(DOHFile *f, ...) { va_list ap; int ret = 0; DOH *obj; va_start(ap,f); while(1) { obj = va_arg(ap,void *); if ((!obj) || (obj == DohNone)) break; if (DohCheck(obj)) { ret += DohDump(obj,f); } else { ret += DohWrite(f,obj,strlen((char *) obj)); } } va_end(ap); return ret; } /* ----------------------------------------------------------------------------- * DohCopyto() * * Copies all of the input from an input stream to an output stream. Returns the * number of bytes copied. * ----------------------------------------------------------------------------- */ int DohCopyto(DOH *in, DOH *out) { int nbytes = 0, ret; int nwrite = 0, wret; char *cw; char buffer[16384]; if ((!in) || (!out)) return 0; while (1) { ret = Read(in,buffer,16384); if (ret > 0) { nwrite = ret; cw = buffer; while (nwrite) { wret = Write(out,cw,nwrite); if (wret < 0) return -1; nwrite = nwrite - wret; cw += wret; } nbytes += ret; } else { return nbytes; } } } /* ----------------------------------------------------------------------------- * DohSplit() * * Split an input stream into a list of strings delimited by the specified * character. Optionally accepts a maximum number of splits to perform. * ----------------------------------------------------------------------------- */ DOH * DohSplit(DOH *in, char ch, int nsplits) { DOH *list; DOH *str; int c; list = NewList(); if (DohIsString(in)) { Seek(in,0,SEEK_SET); } while (1) { str = NewString(""); do { c = Getc(in); } while ((c != EOF) && (c == ch)); if (c != EOF) { Putc(c,str); while (1) { c = Getc(in); if ((c == EOF) || ((c == ch) && (nsplits != 0))) break; Putc(c,str); } nsplits--; } Append(list,str); Delete(str); if (c == EOF) break; } return list; } /* ----------------------------------------------------------------------------- * DohSplitLines() * * Split an input stream into a list of strings delimited by newline characters. * ----------------------------------------------------------------------------- */ DOH * DohSplitLines(DOH *in) { DOH *list; DOH *str; int c = 0; list = NewList(); if (DohIsString(in)) { Seek(in,0,SEEK_SET); } while (c != EOF) { str = NewString(""); while ((c = Getc(in)) != '\n' && c != EOF) { Putc(c, str); } Append(list,str); Delete(str); } return list; } /* ----------------------------------------------------------------------------- * DohReadline() * * Read a single input line and return it as a string. * ----------------------------------------------------------------------------- */ DOH * DohReadline(DOH *in) { char c; int n = 0; DOH *s = NewString(""); while (1) { if (Read(in,&c,1) < 0) { if (n == 0) { Delete(s); return 0; } return s; } if (c == '\n') return s; if (c == '\r') continue; Putc(c,s); n++; } } cableswig-0.1.0+git20150808.orig/SWIG/Source/DOH/file.c0000644000175000000620000001620212561312227020534 0ustar stevestaff/* ----------------------------------------------------------------------------- * file.c * * This file implements a file-like object that can be built around an * ordinary FILE * or integer file descriptor. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_file_c[] = "/cvsroot/SWIG/Source/DOH/file.c,v 1.2 2003/09/11 20:26:53 beazley Exp"; #include "dohint.h" #ifdef DOH_INTFILE #include #endif typedef struct { FILE *filep; int fd; int closeondel; } DohFile; /* ----------------------------------------------------------------------------- * DelFile() * ----------------------------------------------------------------------------- */ static void DelFile(DOH *fo) { DohFile *f = (DohFile *) ObjData(fo); if (f->closeondel) { if (f->filep) { fclose(f->filep); } #ifdef DOH_INTFILE if (f->fd) { close(f->fd); } #endif } DohFree(f); } /* ----------------------------------------------------------------------------- * File_read() * ----------------------------------------------------------------------------- */ static int File_read(DOH *fo, void *buffer, int len) { DohFile *f = (DohFile *) ObjData(fo); if (f->filep) { return fread(buffer,1,len,f->filep); } else if (f->fd) { #ifdef DOH_INTFILE return read(f->fd,buffer,len); #endif } return -1; } /* ----------------------------------------------------------------------------- * File_write() * ----------------------------------------------------------------------------- */ static int File_write(DOH *fo, void *buffer, int len) { DohFile *f = (DohFile *) ObjData(fo); if (f->filep) { return fwrite(buffer,1,len,f->filep); } else if (f->fd) { #ifdef DOH_INTFILE return write(f->fd,buffer,len); #endif } return -1; } /* ----------------------------------------------------------------------------- * File_seek() * ----------------------------------------------------------------------------- */ static int File_seek(DOH *fo, long offset, int whence) { DohFile *f = (DohFile *) ObjData(fo); if (f->filep) { return fseek(f->filep,offset,whence); } else if (f->fd) { #ifdef DOH_INTFILE return lseek(f->fd, offset, whence); #endif } return -1; } /* ----------------------------------------------------------------------------- * File_tell() * ----------------------------------------------------------------------------- */ static long File_tell(DOH *fo) { DohFile *f = (DohFile *) ObjData(fo); if (f->filep) { return ftell(f->filep); } else if (f->fd) { #ifdef DOH_INTFILE return lseek(f->fd, 0, SEEK_CUR); #endif } return -1; } /* ----------------------------------------------------------------------------- * File_putc() * ----------------------------------------------------------------------------- */ static int File_putc(DOH *fo, int ch) { DohFile *f = (DohFile *) ObjData(fo); if (f->filep) { return fputc(ch,f->filep); } else if (f->fd) { #ifdef DOH_INTFILE char c; c = (char) ch; return write(f->fd,&c,1); #endif } return -1; } /* ----------------------------------------------------------------------------- * File_getc() * ----------------------------------------------------------------------------- */ static int File_getc(DOH *fo) { DohFile *f = (DohFile *) ObjData(fo); if (f->filep) { return fgetc(f->filep); } else if (f->fd) { #ifdef DOH_INTFILE char c; if (read(f->fd,&c,1) < 0) return EOF; return c; #endif } return EOF; } /* ----------------------------------------------------------------------------- * File_ungetc() * * Put a character back onto the input * ----------------------------------------------------------------------------- */ static int File_ungetc(DOH *fo, int ch) { DohFile *f = (DohFile *) ObjData(fo); if (f->filep) { return ungetc(ch, f->filep); } else if (f->fd) { #ifdef DOH_INTFILE /* Not implemented yet */ #endif } return -1; } /* ----------------------------------------------------------------------------- * File_close() * * Close the file * ----------------------------------------------------------------------------- */ static int File_close(DOH *fo) { int ret = 0; DohFile *f = (DohFile *) ObjData(fo); if (f->filep) { ret = fclose(f->filep); f->filep = 0; } else if (f->fd) { #ifdef DOH_INTFILE ret = close(f->fd); f->fd = 0; #endif } return ret; } static DohFileMethods FileFileMethods = { File_read, File_write, File_putc, File_getc, File_ungetc, File_seek, File_tell, File_close, /* close */ }; static DohObjInfo DohFileType = { "DohFile", /* objname */ DelFile, /* doh_del */ 0, /* doh_copy */ 0, /* doh_clear */ 0, /* doh_str */ 0, /* doh_data */ 0, /* doh_dump */ 0, /* doh_len */ 0, /* doh_hash */ 0, /* doh_cmp */ 0, /* doh_first */ 0, /* doh_next */ 0, /* doh_setfile */ 0, /* doh_getfile */ 0, /* doh_setline */ 0, /* doh_getline */ 0, /* doh_mapping */ 0, /* doh_sequence */ &FileFileMethods,/* doh_file */ 0, /* doh_string */ 0, /* doh_callable */ 0, /* doh_position */ }; /* ----------------------------------------------------------------------------- * NewFile() * * Create a new file from a given filename and mode. * ----------------------------------------------------------------------------- */ DOH * DohNewFile(DOH *fn, const char *mode) { DohFile *f; FILE *file; char *filename; filename = Char(fn); file = fopen(filename,mode); if (!file) return 0; f = (DohFile *) DohMalloc(sizeof(DohFile)); if (!f) { fclose(file); return 0; } f->filep = file; f->fd = 0; f->closeondel = 1; return DohObjMalloc(&DohFileType,f); } /* ----------------------------------------------------------------------------- * NewFileFromFile() * * Create a file object from an already open FILE *. * ----------------------------------------------------------------------------- */ DOH * DohNewFileFromFile(FILE *file) { DohFile *f; f = (DohFile *) DohMalloc(sizeof(DohFile)); if (!f) return 0; f->filep = file; f->fd = 0; f->closeondel = 0; return DohObjMalloc(&DohFileType,f); } /* ----------------------------------------------------------------------------- * NewFileFromFd() * * Create a file object from an already open FILE *. * ----------------------------------------------------------------------------- */ DOH * DohNewFileFromFd(int fd) { DohFile *f; f = (DohFile *) DohMalloc(sizeof(DohFile)); if (!f) return 0; f->filep = 0; f->fd = fd; f->closeondel = 0; return DohObjMalloc(&DohFileType,f); } cableswig-0.1.0+git20150808.orig/SWIG/Source/DOH/hash.c0000644000175000000620000003121312561312227020537 0ustar stevestaff/* ----------------------------------------------------------------------------- * hash.c * * Implements a simple hash table object. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_hash_c[] = "/cvsroot/SWIG/Source/DOH/hash.c,v 1.2 2003/09/11 20:26:54 beazley Exp"; #include "dohint.h" extern DohObjInfo DohHashType; /* Hash node */ typedef struct HashNode { DOH *key; DOH *object; struct HashNode *next; } HashNode; /* Hash object */ typedef struct Hash { DOH *file; int line; HashNode **hashtable; int hashsize; int nitems; } Hash; /* Key interning structure */ typedef struct KeyValue { char *cstr; DOH *sstr; struct KeyValue *left; struct KeyValue *right; } KeyValue; static KeyValue *root = 0; /* Find or create a key in the interned key table */ static DOH *find_key (DOH *doh_c) { char *c = (char *) doh_c; KeyValue *r, *s; int d = 0; /* OK, sure, we use a binary tree for maintaining interned symbols. Then we use their hash values for accessing secondary hash tables. */ r = root; s = 0; while (r) { s = r; d = strcmp(r->cstr,c); if (d == 0) return r->sstr; if (d < 0) r = r->left; else r = r->right; } /* fprintf(stderr,"Interning '%s'\n", c);*/ r = (KeyValue *) DohMalloc(sizeof(KeyValue)); r->cstr = (char *) DohMalloc(strlen(c)+1); strcpy(r->cstr,c); r->sstr = NewString(c); DohIntern(r->sstr); r->left = 0; r->right = 0; if (!s) { root = r; } else { if (d < 0) s->left = r; else s->right = r; } return r->sstr; } #define HASH_INIT_SIZE 7 /* Create a new hash node */ static HashNode *NewNode(DOH *k, void *obj) { HashNode *hn = (HashNode *) DohMalloc(sizeof(HashNode)); hn->key = k; Incref(hn->key); hn->object = obj; Incref(obj); hn->next = 0; return hn; } /* Delete a hash node */ static void DelNode(HashNode *hn) { Delete(hn->key); Delete(hn->object); DohFree(hn); } /* ----------------------------------------------------------------------------- * DelHash() * * Delete a hash table. * ----------------------------------------------------------------------------- */ static void DelHash(DOH *ho) { Hash *h = (Hash *) ObjData(ho); HashNode *n,*next; int i; for (i = 0; i < h->hashsize; i++) { if ((n = h->hashtable[i])) { while (n) { next = n->next; DelNode(n); n = next; } } } DohFree(h->hashtable); h->hashtable = 0; h->hashsize = 0; DohFree(h); } /* ----------------------------------------------------------------------------- * Hash_clear() * * Clear all of the entries in the hash table. * ----------------------------------------------------------------------------- */ static void Hash_clear(DOH *ho) { Hash *h = (Hash *) ObjData(ho); HashNode *n,*next; int i; for (i = 0; i < h->hashsize; i++) { if ((n = h->hashtable[i])) { while (n) { next = n->next; DelNode(n); n = next; } } h->hashtable[i] = 0; } h->nitems = 0; } /* resize the hash table */ static void resize(Hash *h) { HashNode *n, *next, **table; int oldsize, newsize; int i, p, hv; if (h->nitems < 2*h->hashsize) return; /* Too big. We have to rescale everything now */ oldsize = h->hashsize; /* Calculate a new size */ newsize = 2*oldsize+1; p = 3; while (p < (newsize >> 1)) { if (((newsize/p)*p) == newsize) { newsize+=2; p = 3; continue; } p = p + 2; } table = (HashNode **) DohMalloc(newsize*sizeof(HashNode *)); for (i = 0; i < newsize; i++ ) { table[i] = 0; } /* Walk down the old set of nodes and re-place */ h->hashsize = newsize; for (i = 0; i < oldsize; i++) { n = h->hashtable[i]; while (n) { hv = Hashval(n->key) % newsize; next = n->next; n->next = table[hv]; table[hv] = n; n = next; } } DohFree(h->hashtable); h->hashtable = table; } /* ----------------------------------------------------------------------------- * Hash_setattr() * * Set an attribute in the hash table. Deletes the existing entry if it already * exists. * ----------------------------------------------------------------------------- */ static int Hash_setattr(DOH *ho, DOH *k, DOH *obj) { int hv; HashNode *n, *prev; Hash *h = (Hash *) ObjData(ho); if (!obj) { return DohDelattr(ho,k); } if (!DohCheck(k)) k = find_key(k); if (!DohCheck(obj)) { obj = NewString((char *) obj); Decref(obj); } hv = (Hashval(k)) % h->hashsize; n = h->hashtable[hv]; prev = 0; while (n) { if (Cmp(n->key,k) == 0) { /* Node already exists. Just replace its contents */ if (n->object == obj) { /* Whoa. Same object. Do nothing */ return 1; } Delete(n->object); n->object = obj; Incref(obj); return 1; /* Return 1 to indicate a replacement */ } else { prev = n; n = n->next; } } /* Add this to the table */ n = NewNode(k,obj); if (prev) prev->next = n; else h->hashtable[hv] = n; h->nitems++; resize(h); return 0; } /* ----------------------------------------------------------------------------- * Hash_getattr() * * Get an attribute from the hash table. Returns 0 if it doesn't exist. * ----------------------------------------------------------------------------- */ static DOH * Hash_getattr(DOH *ho, DOH *k) { int hv; HashNode *n; Hash *h = (Hash *) ObjData(ho); if (!DohCheck(k)) k = find_key(k); hv = Hashval(k) % h->hashsize; n = h->hashtable[hv]; while (n) { if (Cmp(n->key, k) == 0) return n->object; n = n->next; } return 0; } /* ----------------------------------------------------------------------------- * Hash_delattr() * * Delete an object from the hash table. * ----------------------------------------------------------------------------- */ static int Hash_delattr(DOH *ho, DOH *k) { HashNode *n, *prev; int hv; Hash *h = (Hash *) ObjData(ho); if (!DohCheck(k)) k = find_key(k); hv = Hashval(k) % h->hashsize; n = h->hashtable[hv]; prev = 0; while (n) { if (Cmp(n->key, k) == 0) { /* Found it, kill it */ if (prev) { prev->next = n->next; } else { h->hashtable[hv] = n->next; } DelNode(n); h->nitems--; return 1; } prev = n; n = n->next; } return 0; } static DohIterator Hash_firstiter(DOH *ho) { DohIterator iter; Hash *h = (Hash *) ObjData(ho); iter.object = ho; iter._current = 0; iter.item = 0; iter.key = 0; iter._index = 0; /* Index in hash table */ while ((iter._index < h->hashsize) && !h->hashtable[iter._index]) iter._index++; if (iter._index >= h->hashsize) { return iter; } iter._current = h->hashtable[iter._index]; iter.item = ((HashNode *) iter._current)->object; iter.key = ((HashNode *) iter._current)->key; /* Actually save the next slot in the hash. This makes it possible to delete the item being iterated over without trashing the universe */ iter._current = ((HashNode*)iter._current)->next; return iter; } static DohIterator Hash_nextiter(DohIterator iter) { Hash *h = (Hash *) ObjData(iter.object); if (!iter._current) { iter._index++; while ((iter._index < h->hashsize) && !h->hashtable[iter._index]) { iter._index++; } if (iter._index >= h->hashsize) { iter.item = 0; iter.key = 0; iter._current = 0; return iter; } iter._current = h->hashtable[iter._index]; } iter.key = ((HashNode *) iter._current)->key; iter.item = ((HashNode *) iter._current)->object; /* Store the next node to iterator on */ iter._current = ((HashNode*)iter._current)->next; return iter; } /* ----------------------------------------------------------------------------- * Hash_keys(DOH *) * * Return a list of keys * ----------------------------------------------------------------------------- */ static DOH * Hash_keys(DOH *so) { DOH *keys; Iterator i; keys = NewList(); for (i = First(so); i.key; i = Next(i)) { Append(keys,i.key); } return keys; } /* ----------------------------------------------------------------------------- * Hash_str() * * Create a string representation of a hash table (mainly for debugging). * ----------------------------------------------------------------------------- */ static DOH * Hash_str(DOH *ho) { int i,j; HashNode *n; DOH *s; static int indent = 4; Hash *h = (Hash *) ObjData(ho); s = NewString(""); if (ObjGetMark(ho)) { Printf(s,"Hash(0x%x)",ho); return s; } ObjSetMark(ho,1); Printf(s,"Hash {\n"); for (i = 0; i < h->hashsize; i++) { n = h->hashtable[i]; while (n) { for (j = 0; j < indent; j++) Putc(' ',s); indent+=4; Printf(s,"'%s' : %s, \n", n->key, n->object); indent-=4; n = n->next; } } for (j = 0; j < (indent-4); j++) Putc(' ',s); Printf(s,"}\n"); ObjSetMark(ho,0); return s; } /* ----------------------------------------------------------------------------- * Hash_len() * * Return number of entries in the hash table. * ----------------------------------------------------------------------------- */ static int Hash_len(DOH *ho) { Hash *h = (Hash *) ObjData(ho); return h->nitems; } /* ----------------------------------------------------------------------------- * CopyHash() * * Make a copy of a hash table. Note: this is a shallow copy. * ----------------------------------------------------------------------------- */ static DOH * CopyHash(DOH *ho) { Hash *h, *nh; HashNode *n; DOH *nho; int i; h = (Hash *) ObjData(ho); nh = (Hash *) DohMalloc(sizeof(Hash)); nh->hashsize = h->hashsize; nh->hashtable = (HashNode **) DohMalloc(nh->hashsize*sizeof(HashNode *)); for (i = 0; i < nh->hashsize; i++) { nh->hashtable[i] = 0; } nh->nitems = 0; nh->line = h->line; nh->file = h->file; if (nh->file) Incref(nh->file); nho = DohObjMalloc(&DohHashType, nh); for (i = 0; i < h->hashsize; i++) { if ((n = h->hashtable[i])) { while (n) { Hash_setattr(nho, n->key, n->object); n = n->next; } } } return nho; } static void Hash_setfile(DOH *ho, DOH *file) { DOH *fo; Hash *h = (Hash *) ObjData(ho); if (!DohCheck(file)) { fo = NewString(file); Decref(fo); } else fo = file; Incref(fo); Delete(h->file); h->file = fo; } static DOH * Hash_getfile(DOH *ho) { Hash *h = (Hash *) ObjData(ho); return h->file; } static void Hash_setline(DOH *ho, int line) { Hash *h = (Hash *) ObjData(ho); h->line = line; } static int Hash_getline(DOH *ho) { Hash *h = (Hash *) ObjData(ho); return h->line; } /* ----------------------------------------------------------------------------- * type information * ----------------------------------------------------------------------------- */ static DohHashMethods HashHashMethods = { Hash_getattr, Hash_setattr, Hash_delattr, Hash_keys, }; DohObjInfo DohHashType = { "Hash", /* objname */ DelHash, /* doh_del */ CopyHash, /* doh_copy */ Hash_clear, /* doh_clear */ Hash_str, /* doh_str */ 0, /* doh_data */ 0, /* doh_dump */ Hash_len, /* doh_len */ 0, /* doh_hash */ 0, /* doh_cmp */ Hash_firstiter, /* doh_first */ Hash_nextiter, /* doh_next */ Hash_setfile, /* doh_setfile */ Hash_getfile, /* doh_getfile */ Hash_setline, /* doh_setline */ Hash_getline, /* doh_getline */ &HashHashMethods, /* doh_mapping */ 0, /* doh_sequence */ 0, /* doh_file */ 0, /* doh_string */ 0, /* doh_positional */ 0, }; /* ----------------------------------------------------------------------------- * NewHash() * * Create a new hash table. * ----------------------------------------------------------------------------- */ DOH * DohNewHash() { Hash *h; int i; h = (Hash *) DohMalloc(sizeof(Hash)); h->hashsize = HASH_INIT_SIZE; h->hashtable = (HashNode **) DohMalloc(h->hashsize*sizeof(HashNode *)); for (i = 0; i < h->hashsize; i++) { h->hashtable[i] = 0; } h->nitems = 0; h->file = 0; h->line = 0; return DohObjMalloc(&DohHashType,h); } cableswig-0.1.0+git20150808.orig/SWIG/Source/DOH/base.c0000644000175000000620000005520212561312227020532 0ustar stevestaff/* ----------------------------------------------------------------------------- * base.c * * This file contains the function entry points for dispatching methods on * DOH objects. A number of small utility functions are also included. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_base_c[] = "/cvsroot/SWIG/Source/DOH/base.c,v 1.7 2004/01/15 22:46:04 cheetah Exp"; #include "dohint.h" /* ----------------------------------------------------------------------------- * DohDelete() * ----------------------------------------------------------------------------- */ void DohDelete(DOH *obj) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (!obj) return; if (!DohCheck(b)) { fputs("DOH: Fatal error. Attempt to delete a non-doh object.\n",stderr); abort(); } if (b->flag_intern) return; assert(b->refcount > 0); b->refcount--; if (b->refcount <= 0) { objinfo = b->type; if (objinfo->doh_del) { (objinfo->doh_del)(b); } else { if (b->data) DohFree(b->data); } DohObjFree(b); } } /* ----------------------------------------------------------------------------- * DohCopy() * ----------------------------------------------------------------------------- */ DOH * DohCopy(const DOH *obj) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (!obj) return 0; objinfo = b->type; if (objinfo->doh_copy) { DohBase *bc = (DohBase *) (objinfo->doh_copy)(b); if ((bc) && b->meta) { bc->meta = Copy(b->meta); } return (DOH *) bc; } return 0; } void DohIncref(DOH *obj) { Incref(obj); } /* ----------------------------------------------------------------------------- * DohClear() * ----------------------------------------------------------------------------- */ void DohClear(DOH *obj) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo = b->type; if (objinfo->doh_clear) (objinfo->doh_clear)(b); } /* ----------------------------------------------------------------------------- * DohStr() * ----------------------------------------------------------------------------- */ DOH * DohStr(const DOH *obj) { char buffer[512]; DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (DohCheck(b)) { objinfo = b->type; if (objinfo->doh_str) { return (objinfo->doh_str)(b); } sprintf(buffer,"", objinfo->objname, (void *)b); return NewString(buffer); } else { return NewString(obj); } } /* ----------------------------------------------------------------------------- * DohDump() * ----------------------------------------------------------------------------- */ int DohDump(const DOH *obj, DOH *out) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo = b->type; if (objinfo->doh_dump) { return (objinfo->doh_dump)(b,out); } return 0; } /* ----------------------------------------------------------------------------- * DohLen() - Defaults to strlen() if not a DOH object * ----------------------------------------------------------------------------- */ int DohLen(const DOH *obj) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (!b) return 0; if (DohCheck(b)) { objinfo = b->type; if (objinfo->doh_len) { return (objinfo->doh_len)(b); } return 0; } else { return strlen((char *) obj); } } /* ----------------------------------------------------------------------------- * DohHashVal() * ----------------------------------------------------------------------------- */ int DohHashval(const DOH *obj) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (DohCheck(b)) { objinfo = b->type; if (objinfo->doh_hashval) { return (objinfo->doh_hashval)(b); } } return 0; } /* ----------------------------------------------------------------------------- * DohData() * ----------------------------------------------------------------------------- */ void * DohData(const DOH *obj) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (DohCheck(obj)) { objinfo = b->type; if (objinfo->doh_data) { return (objinfo->doh_data)(b); } return 0; } return (void *) obj; } /* ----------------------------------------------------------------------------- * DohCmp() * ----------------------------------------------------------------------------- */ int DohCmp(const DOH *obj1, const DOH *obj2) { DohBase *b1, *b2; DohObjInfo *b1info, *b2info; b1 = (DohBase *) obj1; b2 = (DohBase *) obj2; if ((!DohCheck(b1)) || (!DohCheck(b2))) { if ((b1 == 0) && (b2 == 0)) return 0; if (b1 && !b2) return 1; if (!b1 && b2) return -1; return strcmp((char *) DohData(b1),(char *) DohData(b2)); } b1info = b1->type; b2info = b2->type; if ((b1info == b2info) && (b1info->doh_cmp)) return (b1info->doh_cmp)(b1,b2); return 1; } /* ----------------------------------------------------------------------------- * DohFirst() * ----------------------------------------------------------------------------- */ DohIterator DohFirst(DOH *obj) { DohIterator iter; DohBase *b; DohObjInfo *binfo; b = (DohBase *) obj; if (DohCheck(b)) { binfo = b->type; if (binfo->doh_first) { return (binfo->doh_first)(b); } } iter.object = 0; iter.item = 0; iter.key = 0; return iter; } /* ----------------------------------------------------------------------------- * DohNext() * ----------------------------------------------------------------------------- */ DohIterator DohNext(DohIterator iter) { DohIterator niter; if (iter.object) { DohBase *b; DohObjInfo *binfo; b = (DohBase *) iter.object; binfo = b->type; if (binfo->doh_next) { return (binfo->doh_next)(iter); } } niter = iter; return niter; } /* ----------------------------------------------------------------------------- * DohIsMapping() * ----------------------------------------------------------------------------- */ int DohIsMapping(const DOH *obj) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (!DohCheck(b)) return 0; objinfo = b->type; if (objinfo->doh_hash) return 1; else return 0; } /* ----------------------------------------------------------------------------- * DohGetattr() * ----------------------------------------------------------------------------- */ DOH * DohGetattr(DOH *obj, const DOH *name) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo = b->type; if (objinfo->doh_hash && objinfo->doh_hash->doh_getattr) { DOH *r = (objinfo->doh_hash->doh_getattr)(b,(DOH *) name); return (r == DohNone) ? 0 : r; } return 0; } /* ----------------------------------------------------------------------------- * DohSetattr() * ----------------------------------------------------------------------------- */ int DohSetattr(DOH *obj, const DOH *name, const DOH *value) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo = b->type; if (objinfo->doh_hash && objinfo->doh_hash->doh_setattr) { return (objinfo->doh_hash->doh_setattr)(b,(DOH *) name,(DOH *) value); } return 0; } /* ----------------------------------------------------------------------------- * DohDelattr() * ----------------------------------------------------------------------------- */ int DohDelattr(DOH *obj, const DOH *name) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo = b->type; if (objinfo->doh_hash && objinfo->doh_hash->doh_delattr) { return (objinfo->doh_hash->doh_delattr)(b,(DOH *) name); } return 0; } /* ----------------------------------------------------------------------------- * DohKeys() * ----------------------------------------------------------------------------- */ DOH * DohKeys(DOH *obj) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo = b->type; if (objinfo && objinfo->doh_hash->doh_keys) { return (objinfo->doh_hash->doh_keys)(b); } return 0; } /* ----------------------------------------------------------------------------- * DohGetInt() * ----------------------------------------------------------------------------- */ int DohGetInt(DOH *obj, const DOH *name) { DOH *val; val = Getattr(obj,(DOH *) name); if (!val) return 0; if (DohIsString(val)) { return atoi((char *) Data(val)); } return 0; } /* ----------------------------------------------------------------------------- * DohGetDouble() * ----------------------------------------------------------------------------- */ double DohGetDouble(DOH *obj, const DOH *name) { DOH *val; val = Getattr(obj,(DOH *) name); if (!val) return 0; if (DohIsString(val)) { return atof((char *) Data(val)); } return 0; } /* ----------------------------------------------------------------------------- * DohGetChar() * ----------------------------------------------------------------------------- */ char * DohGetChar(DOH *obj, const DOH *name) { DOH *val; val = Getattr(obj,(DOH *) name); if (!val) return 0; if (DohIsString(val)) { return (char *) Data(val); } return 0; } /* ----------------------------------------------------------------------------- * DohGetVoid() * ----------------------------------------------------------------------------- */ void * DohGetVoid(DOH *obj, const DOH *name) { DOH *val; val = Getattr(obj,(DOH *) name); if (!val) return 0; return (void *) Data(val); } /* ----------------------------------------------------------------------------- * DohSetInt() * ----------------------------------------------------------------------------- */ void DohSetInt(DOH *obj, const DOH *name, int value) { DOH *temp; temp = NewString(""); Printf(temp,"%d",value); Setattr(obj,(DOH *) name,temp); } /* ----------------------------------------------------------------------------- * DohSetDouble() * ----------------------------------------------------------------------------- */ void DohSetDouble(DOH *obj, const DOH *name, double value) { DOH *temp; temp = NewString(""); Printf(temp,"%0.17f",value); Setattr(obj,(DOH *) name,temp); } /* ----------------------------------------------------------------------------- * DohSetChar() * ----------------------------------------------------------------------------- */ void DohSetChar(DOH *obj, const DOH *name, char *value) { Setattr(obj,(DOH *) name,NewString(value)); } /* ----------------------------------------------------------------------------- * DohSetVoid() * ----------------------------------------------------------------------------- */ void DohSetVoid(DOH *obj, const DOH *name, void *value) { Setattr(obj,(DOH *) name,NewVoid(value,0)); } /* ----------------------------------------------------------------------------- * DohIsSequence() * ----------------------------------------------------------------------------- */ int DohIsSequence(const DOH *obj) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (!DohCheck(b)) return 0; objinfo = b->type; if (objinfo->doh_list) return 1; else return 0; } /* ----------------------------------------------------------------------------- * DohGetitem() * ----------------------------------------------------------------------------- */ DOH * DohGetitem(DOH *obj, int index) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo = b->type; if (objinfo->doh_list && objinfo->doh_list->doh_getitem) { return (objinfo->doh_list->doh_getitem)(b,index); } return 0; } /* ----------------------------------------------------------------------------- * DohSetitem() * ----------------------------------------------------------------------------- */ int DohSetitem(DOH *obj, int index, const DOH *value) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo = b->type; if (objinfo->doh_list && objinfo->doh_list->doh_setitem) { return (objinfo->doh_list->doh_setitem)(b,index,(DOH *) value); } return -1; } /* ----------------------------------------------------------------------------- * DohDelitem() * ----------------------------------------------------------------------------- */ int DohDelitem(DOH *obj, int index) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo = b->type; if (objinfo->doh_list && objinfo->doh_list->doh_delitem) { return (objinfo->doh_list->doh_delitem)(b,index); } return -1; } /* ----------------------------------------------------------------------------- * DohInsertitem() * ----------------------------------------------------------------------------- */ int DohInsertitem(DOH *obj, int index, const DOH *value) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo = b->type; if (objinfo->doh_list && objinfo->doh_list->doh_insitem) { return (objinfo->doh_list->doh_insitem)(b,index,(DOH *) value); } return -1; } /* ----------------------------------------------------------------------------- * DohDelslice() * ----------------------------------------------------------------------------- */ int DohDelslice(DOH *obj, int sindex, int eindex) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo = b->type; if (objinfo->doh_list && objinfo->doh_list->doh_delslice) { return (objinfo->doh_list->doh_delslice)(b,sindex,eindex); } return -1; } /* ----------------------------------------------------------------------------- * DohIsFile() * ----------------------------------------------------------------------------- */ int DohIsFile(const DOH *obj) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (!DohCheck(b)) return 0; objinfo = b->type; if (objinfo->doh_file) return 1; else return 0; } /* ----------------------------------------------------------------------------- * DohRead() * ----------------------------------------------------------------------------- */ int DohRead(DOH *obj, void *buffer, int length) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (DohCheck(obj)) { objinfo = b->type; if ((objinfo->doh_file) && (objinfo->doh_file->doh_read)) { return (objinfo->doh_file->doh_read)(b,buffer,length); } return -1; } /* Hmmm. Not a file. Maybe it's a real FILE */ return fread(buffer,1,length,(FILE *) b); } /* ----------------------------------------------------------------------------- * DohWrite() * ----------------------------------------------------------------------------- */ int DohWrite(DOH *obj, void *buffer, int length) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (DohCheck(obj)) { objinfo = b->type; if ((objinfo->doh_file) && (objinfo->doh_file->doh_write)) { return (objinfo->doh_file->doh_write)(b,buffer,length); } return -1; } /* Hmmm. Not a file. Maybe it's a real FILE */ return fwrite(buffer,1,length,(FILE *) b); } /* ----------------------------------------------------------------------------- * DohSeek() * ----------------------------------------------------------------------------- */ int DohSeek(DOH *obj, long offset, int whence) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (DohCheck(obj)) { objinfo = b->type; if ((objinfo->doh_file) && (objinfo->doh_file->doh_seek)) { return (objinfo->doh_file->doh_seek)(b,offset,whence); } return -1; } return fseek((FILE *) b, offset, whence); } /* ----------------------------------------------------------------------------- * DohTell() * ----------------------------------------------------------------------------- */ long DohTell(DOH *obj) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (DohCheck(obj)) { objinfo = b->type; if ((objinfo->doh_file) && (objinfo->doh_file->doh_tell)) { return (objinfo->doh_file->doh_tell)(b); } return -1; } return ftell((FILE *) b); } /* ----------------------------------------------------------------------------- * DohGetc() * ----------------------------------------------------------------------------- */ int DohGetc(DOH *obj) { static DOH *lastdoh = 0; DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (obj == lastdoh) { objinfo = b->type; return (objinfo->doh_file->doh_getc)(b); } if (DohCheck(obj)) { objinfo = b->type; if (objinfo->doh_file->doh_getc) { lastdoh = obj; return (objinfo->doh_file->doh_getc)(b); } return EOF; } return fgetc((FILE *) b); } /* ----------------------------------------------------------------------------- * DohPutc() * ----------------------------------------------------------------------------- */ int DohPutc(int ch, DOH *obj) { static DOH *lastdoh = 0; DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (obj == lastdoh) { objinfo = b->type; return (objinfo->doh_file->doh_putc)(b,ch); } if (DohCheck(obj)) { objinfo = b->type; if (objinfo->doh_file->doh_putc) { lastdoh = obj; return (objinfo->doh_file->doh_putc)(b,ch); } return EOF; } return fputc(ch,(FILE *) b); } /* ----------------------------------------------------------------------------- * DohUngetc() * ----------------------------------------------------------------------------- */ int DohUngetc(int ch, DOH *obj) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (DohCheck(obj)) { objinfo = b->type; if (objinfo->doh_file->doh_ungetc) { return (objinfo->doh_file->doh_ungetc)(b,ch); } return EOF; } return ungetc(ch,(FILE *) b); } /* ----------------------------------------------------------------------------- * DohClose() * ----------------------------------------------------------------------------- */ int DohClose(DOH *obj) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (DohCheck(obj)) { objinfo = b->type; if (objinfo->doh_file->doh_close) { return (objinfo->doh_file->doh_close)(b); } return 0; } return fclose((FILE *) obj); } /* ----------------------------------------------------------------------------- * DohIsString() * ----------------------------------------------------------------------------- */ int DohIsString(const DOH *obj) { DohBase *b = (DohBase *) obj; DohObjInfo *objinfo; if (!DohCheck(b)) return 0; objinfo = b->type; if (objinfo->doh_string) return 1; else return 0; } /* ----------------------------------------------------------------------------- * DohReplace() * ----------------------------------------------------------------------------- */ int DohReplace(DOH *src, const DOH *token, const DOH *rep, int flags) { DohBase *b = (DohBase *) src; DohObjInfo *objinfo; if (!token) return 0; if (!rep) rep = ""; if (DohIsString(src)) { objinfo = b->type; if (objinfo->doh_string->doh_replace) { return (objinfo->doh_string->doh_replace)(b,(DOH *) token, (DOH *) rep,flags); } } return 0; } /* ----------------------------------------------------------------------------- * DohChop() * ----------------------------------------------------------------------------- */ void DohChop(DOH *src) { DohBase *b = (DohBase *) src; DohObjInfo *objinfo; if (DohIsString(src)) { objinfo = b->type; if (objinfo->doh_string->doh_chop) { (objinfo->doh_string->doh_chop)(b); } } } /* ----------------------------------------------------------------------------- * DohSetFile() * ----------------------------------------------------------------------------- */ void DohSetfile(DOH *ho, DOH *file) { DohBase *h = (DohBase *) ho; DohObjInfo *objinfo; if (!h) return; objinfo = h->type; if (objinfo->doh_setfile) (objinfo->doh_setfile)(h,file); } /* ----------------------------------------------------------------------------- * DohGetFile() * ----------------------------------------------------------------------------- */ DOH * DohGetfile(DOH *ho) { DohBase *h = (DohBase *) ho; DohObjInfo *objinfo; if (!h) return 0; objinfo = h->type; if (objinfo->doh_getfile) return (objinfo->doh_getfile)(h); return 0; } /* ----------------------------------------------------------------------------- * DohSetLine() * ----------------------------------------------------------------------------- */ void DohSetline(DOH *ho, int l) { DohBase *h = (DohBase *) ho; DohObjInfo *objinfo; if (!h) return; objinfo = h->type; if (objinfo->doh_setline) (objinfo->doh_setline)(h,l); } /* ----------------------------------------------------------------------------- * DohGetLine() * ----------------------------------------------------------------------------- */ int DohGetline(DOH *ho) { DohBase *h = (DohBase *) ho; DohObjInfo *objinfo; if (!h) return 0; objinfo = h->type; if (objinfo->doh_getline) return (objinfo->doh_getline)(h); return 0; } /* ----------------------------------------------------------------------------- * DohGetmeta() * ----------------------------------------------------------------------------- */ DOH * DohGetmeta(DOH *ho, const DOH *name) { DohBase *h = (DohBase *) ho; if (!DohCheck(ho)) return 0; if (!h->meta) return 0; return DohGetattr(h->meta,name); } /* ----------------------------------------------------------------------------- * DohGetmeta() * ----------------------------------------------------------------------------- */ int DohSetmeta(DOH *ho, const DOH *name, const DOH *value) { DohBase *h = (DohBase *) ho; if (!DohCheck(ho)) return 0; if (!h->meta) h->meta = NewHash(); return DohSetattr(h->meta, name, value); } /* ----------------------------------------------------------------------------- * DohDelmeta() * ----------------------------------------------------------------------------- */ int DohDelmeta(DOH *ho, const DOH *name) { DohBase *h = (DohBase *) ho; if (!DohCheck(ho)) return 0; if (!h->meta) return 0; return DohDelattr(h->meta, name); } /* ----------------------------------------------------------------------------- * DohSetmark() * ----------------------------------------------------------------------------- */ void DohSetmark(DOH *ho, int x) { DohBase *h = (DohBase *) ho; h->flag_usermark = x; } int DohGetmark(DOH *ho) { DohBase *h = (DohBase *) ho; return h->flag_usermark; } /* ----------------------------------------------------------------------------- * DohCall() * * Invokes a function via DOH. A Function is represented by a hash table with * the following attributes: * * "builtin" - Pointer to built-in function (if any) * * (Additional attributes may be added later) * * Returns a DOH object with result on success. Returns NULL on error * ----------------------------------------------------------------------------- */ DOH * DohCall(DOH *func, DOH *args) { DOH *result; DOH *(*builtin)(DOH *); builtin = (DOH *(*)(DOH *)) GetVoid(func,"builtin"); if (!builtin) return 0; result = (*builtin)(args); return result; } cableswig-0.1.0+git20150808.orig/SWIG/Source/DOH/memory.c0000644000175000000620000001336512561312227021134 0ustar stevestaff/* ----------------------------------------------------------------------------- * memory.c * * This file implements all of DOH's memory management including allocation * of objects and checking of objects. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_memory_c[] = "/cvsroot/SWIG/Source/DOH/memory.c,v 1.5 2004/01/15 22:46:05 cheetah Exp"; #include "dohint.h" #ifndef DOH_POOL_SIZE #define DOH_POOL_SIZE 16384 #endif static int PoolSize = DOH_POOL_SIZE; DOH *DohNone = 0; /* The DOH None object */ typedef struct pool { DohBase *ptr; /* Start of pool */ int len; /* Length of pool */ int blen; /* Byte length of pool */ int current; /* Current position for next allocation */ struct pool *next; /* Next pool */ } Pool; static DohBase *FreeList = 0; /* List of free objects */ static Pool *Pools = 0; static int pools_initialized = 0; /* ---------------------------------------------------------------------- * CreatePool() - Create a new memory pool * ---------------------------------------------------------------------- */ static void CreatePool() { Pool *p = 0; p = (Pool *) DohMalloc(sizeof(Pool)); assert(p); p->ptr = (DohBase *) DohMalloc(sizeof(DohBase)*PoolSize); assert(p->ptr); memset(p->ptr,0,sizeof(DohBase)*PoolSize); p->len = PoolSize; p->blen = PoolSize*sizeof(DohBase); p->current = 0; p->next = Pools; Pools = p; } /* ---------------------------------------------------------------------- * InitPools() - Initialize the memory allocator * ---------------------------------------------------------------------- */ static void InitPools() { if (pools_initialized) return; CreatePool(); /* Create initial pool */ pools_initialized = 1; DohNone = NewVoid(0,0); /* Create the None object */ DohIntern(DohNone); } /* ---------------------------------------------------------------------- * DohCheck() * * Returns 1 if an arbitrary pointer is a DOH object. * ---------------------------------------------------------------------- */ int DohCheck(const DOH *ptr) { Pool *p = Pools; register char *cptr = (char *) ptr; register char *pptr; while (p) { pptr = (char *) p->ptr; if ((cptr >= pptr) && (cptr < (pptr + p->blen))) return 1; /* pptr = (char *) p->ptr; if ((cptr >= pptr) && (cptr < (pptr+(p->current*sizeof(DohBase))))) return 1; */ p = p->next; } return 0; } /* ----------------------------------------------------------------------------- * DohIntern() * ----------------------------------------------------------------------------- */ void DohIntern(DOH *obj) { DohBase *b = (DohBase *) obj; b->flag_intern = 1; } /* ---------------------------------------------------------------------- * DohObjMalloc() * * Allocate memory for a new object. * ---------------------------------------------------------------------- */ DOH * DohObjMalloc(DohObjInfo *type, void *data) { DohBase *obj; if (!pools_initialized) InitPools(); if (FreeList) { obj = FreeList; FreeList = (DohBase *) obj->data; } else { while (Pools->current == Pools->len) { PoolSize *= 2; CreatePool(); } obj = Pools->ptr + Pools->current; Pools->current++; } obj->type = type; obj->data = data; obj->meta = 0; obj->refcount = 1; obj->flag_intern = 0; obj->flag_marked = 0; obj->flag_user = 0; obj->flag_usermark = 0; return (DOH *) obj; } /* ---------------------------------------------------------------------- * DohObjFree() - Free a DOH object * ---------------------------------------------------------------------- */ void DohObjFree(DOH *ptr) { DohBase *b, *meta; b = (DohBase *) ptr; if (b->flag_intern) return; meta = (DohBase *)b->meta; b->data = (void *) FreeList; b->meta = 0; b->type = 0; FreeList = b; if (meta) { Delete(meta); } } /* ---------------------------------------------------------------------- * DohMemoryDebug() * * Display memory usage statistics * ---------------------------------------------------------------------- */ void DohMemoryDebug(void) { extern DohObjInfo DohStringType; extern DohObjInfo DohListType; extern DohObjInfo DohHashType; Pool *p; int totsize = 0; int totused = 0; int totfree = 0; int numstring = 0; int numlist = 0; int numhash = 0; printf("Memory statistics:\n\n"); printf("Pools:\n"); p = Pools; while(p) { /* Calculate number of used, free items */ int i; int nused = 0, nfree = 0; for (i = 0; i < p->len; i++) { if (p->ptr[i].refcount <= 0) nfree++; else { nused++; if (p->ptr[i].type == &DohStringType) numstring++; else if (p->ptr[i].type == &DohListType) numlist++; else if (p->ptr[i].type == &DohHashType) numhash++; } } printf(" Pool %8p: size = %10d. used = %10d. free = %10d\n", (void *)p, p->len, nused, nfree); totsize += p->len; totused+= nused; totfree+= nfree; p = p->next; } printf("\n Total: size = %10d, used = %10d, free = %10d\n", totsize, totused, totfree); printf("\nObject types\n"); printf(" Strings : %d\n", numstring); printf(" Lists : %d\n", numlist); printf(" Hashes : %d\n", numhash); #if 0 p = Pools; while(p) { int i; for (i = 0; i < p->len; i++) { if (p->ptr[i].refcount > 0) { if (p->ptr[i].type == &DohStringType) { Printf(stdout,"%s\n", p->ptr+i); } } } p = p->next; } #endif } cableswig-0.1.0+git20150808.orig/SWIG/Source/DOH/void.c0000644000175000000620000000610612561312227020560 0ustar stevestaff/* ----------------------------------------------------------------------------- * void.c * * Implements a "void" object that is really just a DOH container around * an arbitrary C object represented as a void *. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_void_c[] = "/cvsroot/SWIG/Source/DOH/void.c,v 1.2 2003/09/11 20:26:54 beazley Exp"; #include "dohint.h" typedef struct { void *ptr; void (*del)(void *); } VoidObj; /* ----------------------------------------------------------------------------- * Void_delete() * * Delete a void object. Invokes the destructor supplied at the time of creation. * ----------------------------------------------------------------------------- */ static void Void_delete(DOH *vo) { VoidObj *v = (VoidObj *) ObjData(vo); if (v->del) (*v->del)(v->ptr); DohFree(v); } /* ----------------------------------------------------------------------------- * Void_copy() * * Copies a void object. This is only a shallow copy. The object destruction * function is not copied in order to avoid potential double-free problems. * ----------------------------------------------------------------------------- */ static DOH * Void_copy(DOH *vo) { VoidObj *v = (VoidObj *) ObjData(vo); return NewVoid(v->ptr,0); } /* ----------------------------------------------------------------------------- * Void_data() * * Returns the void * stored in the object. * ----------------------------------------------------------------------------- */ static void * Void_data(DOH *vo) { VoidObj *v = (VoidObj *) ObjData(vo); return v->ptr; } static DohObjInfo DohVoidType = { "VoidObj", /* objname */ Void_delete, /* doh_del */ Void_copy, /* doh_copy */ 0, /* doh_clear */ 0, /* doh_str */ Void_data, /* doh_data */ 0, /* doh_dump */ 0, /* doh_len */ 0, /* doh_hash */ 0, /* doh_cmp */ 0, /* doh_first */ 0, /* doh_next */ 0, /* doh_setfile */ 0, /* doh_getfile */ 0, /* doh_setline */ 0, /* doh_getline */ 0, /* doh_mapping */ 0, /* doh_sequence */ 0, /* doh_file */ 0, /* doh_string */ 0, /* doh_reserved */ 0, /* clientdata */ }; /* ----------------------------------------------------------------------------- * NewVoid() * * Creates a new Void object given a void * and an optional destructor function. * ----------------------------------------------------------------------------- */ DOH * DohNewVoid(void *obj, void (*del)(void *)) { VoidObj *v; v = (VoidObj *) DohMalloc(sizeof(VoidObj)); v->ptr = obj; v->del = del; return DohObjMalloc(&DohVoidType,v); } cableswig-0.1.0+git20150808.orig/SWIG/Source/DOH/README0000644000175000000620000001107312561312227020332 0ustar stevestaffDOH (Dave's Object Hack) Overview: --------- DOH is a small C library that provides a number of simple yet powerful data structures. The data structures are built around a dynamic typing model in which any given object is allowed to support one or more classes of operations. Furthermore, a simple garbage collection scheme and a variety of interesting library methods are available. All and all, the operation of DOH makes massive abuse of the C type system and would probably make the language purists scream and performance addicts run away in horror. However, I really don't care--so there! However, for the rest of us, DOH is actually kind of fun to use. This is only a short description of the methods and is no way meant to be exhaustive. Common Operations (for all types) --------------------------------- Delete(obj) Decrease the reference count and destroy if zero Copy(obj) Make a copy of an object. Clear(obj) Clear an object. Setscope(obj) Set scope of an object (guru's only) Str(obj) Create a string representation of obj. Data(obj) Return pointer to raw data in an object Char(obj) Convert to a char * Len(obj) Length of an object Hash(obj) Hash value (used for mapping) Cmp(obj1,obj2) Compare two objects. Name(obj) Return the object name First(obj) Return first object (iterator) Next(obj) Return next object Dump(obj,out) Serialize on out Load(in) Unserialize from in First(obj) Iterator Next(iter) Next iterator Mapping Operations (for hash table behavior) -------------------------------------------- Getattr(hash,key) Get an attribute Setattr(hash,key,value) Set an attribute Delattr(hash,key) Delete an attribute Firstkey(hash) Get first key Nextkey(hash) Get next key First(hash) Get first object Next(hash) Get next object GetInt(hash,key) Get attribute as an 'int' SetInt(hash,key,ivalue) Set attribute as an 'int' GetDouble(hash,key) Get attribute as a 'double' SetDouble(hash,key,dvalue) Set Attribute as a 'double' GetChar(hash,key) Get attribute as a 'char *' Sequence Operations ------------------- Getitem(list,index) Get an item Setitem(list,index,val) Set an item Delitem(list,index,val) Delete an item Insert(list,index,val) Insert an item Append(list,val) Append to end Push(list,val) Insert at beginning File Operations --------------- Read(obj,buffer,len) Read data Write(obj,buffer,len) Write data Getc(obj) Get a character Putc(ch,obj) Put a character Ungetc(ch,obj) Put character back on input stream Seek(obj,offset,whence) Seek Tell(obj) Return file pointer Close(obj) Close String Operations ----------------- Replace(obj, orig, rep, flags) Replace occurences of orig with rep. Chop(obj) Remove trailing whitespace flags is one of the following: DOH_REPLACE_ANY DOH_REPLACE_NOQUOTE DOH_REPLACE_ID DOH_REPLACE_FIRST Callable Operations ------------------- Call(obj, args) Perform a function call with arguments args. Miscellaneous library functions ------------------------------- NewScope() Create a new scope DelScope(s) Delete scope s Readline(in) Read a line of input from in Printf(out,fmt,...) Formatted output DohEncoding(name, fn) Register a format encoding for Printf Currently Available datatypes ------------------------------ NewString(char *initial) Strings NewHash() Hash NewList() List NewVoid(void *ptr, void (*del)(void *)) Void NewFile(char *file, char *mode) File NewCallable(DOH *(*func)(DOH *, DOH *)) Callable object Odds and ends: 1. All objects are of type 'DOH *' 2. When in doubt, see rule (1) 3. In certain cases, DOH performs implicit conversions of 'char *' to an appropriate DOH string representation. For operations involving files, DOH works with many kinds of objects including FILE *, DOH File objects, and DOH strings. Don't even ask how this works. 4. More complete documentation is forthcoming. cableswig-0.1.0+git20150808.orig/SWIG/Source/DOH/list.c0000644000175000000620000002233612561312227020575 0ustar stevestaff/* ----------------------------------------------------------------------------- * list.c * * Implements a simple list object. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_list_c[] = "/cvsroot/SWIG/Source/DOH/list.c,v 1.3 2003/09/11 20:26:54 beazley Exp"; #include "dohint.h" typedef struct List { int maxitems; /* Max size */ int nitems; /* Num items */ DOH *file; int line; DOH **items; } List; extern DohObjInfo DohListType; /* Doubles amount of memory in a list */ static void more(List *l) { l->items = (void **) DohRealloc(l->items, l->maxitems*2*sizeof(void *)); assert(l->items); l->maxitems *= 2; } /* ----------------------------------------------------------------------------- * CopyList() * * Make a shallow copy of a list. * ----------------------------------------------------------------------------- */ static DOH * CopyList(DOH *lo) { List *l,*nl; int i; l = (List *) ObjData(lo); nl = (List *) DohMalloc(sizeof(List)); nl->nitems = l->nitems; nl->maxitems = l->maxitems; nl->items = (void **) DohMalloc(l->maxitems*sizeof(void *)); for (i = 0; i < l->nitems; i++) { nl->items[i] = l->items[i]; Incref(nl->items[i]); } nl->file = l->file; if (nl->file) Incref(nl->file); nl->line = l->line; return DohObjMalloc(&DohListType, nl); } /* ----------------------------------------------------------------------------- * DelList() * * Delete a list. * ----------------------------------------------------------------------------- */ static void DelList(DOH *lo) { List *l = (List *) ObjData(lo); int i; for (i = 0; i < l->nitems; i++) Delete(l->items[i]); DohFree(l->items); DohFree(l); } /* ----------------------------------------------------------------------------- * List_clear() * * Remove all of the list entries, but keep the list object intact. * ----------------------------------------------------------------------------- */ static void List_clear(DOH *lo) { List *l = (List *) ObjData(lo); int i; for (i = 0; i < l->nitems; i++) { Delete(l->items[i]); } l->nitems = 0; } /* ----------------------------------------------------------------------------- * List_insert() * * Insert an item into the list. If the item is not a DOH object, it is assumed * to be a 'char *' and is used to construct an equivalent string object. * ----------------------------------------------------------------------------- */ static int List_insert(DOH *lo, int pos, DOH *item) { List *l = (List *) ObjData(lo); int i; if (!item) return -1; if (!DohCheck(item)) { item = NewString(item); Decref(item); } if (pos == DOH_END) pos = l->nitems; if (pos < 0) pos = 0; if (pos > l->nitems) pos = l->nitems; if (l->nitems == l->maxitems) more(l); for (i = l->nitems; i > pos; i--) { l->items[i] = l->items[i-1]; } l->items[pos] = item; Incref(item); l->nitems++; return 0; } /* ----------------------------------------------------------------------------- * List_remove() * * Remove an item from a list. * ----------------------------------------------------------------------------- */ static int List_remove(DOH *lo, int pos) { List *l = (List *) ObjData(lo); int i; if (pos == DOH_END) pos = l->nitems-1; if (pos == DOH_BEGIN) pos = 0; assert(!((pos < 0) || (pos >= l->nitems))); Delete(l->items[pos]); for (i = pos; i < l->nitems-1; i++) { l->items[i] = l->items[i+1]; } l->nitems--; return 0; } /* ----------------------------------------------------------------------------- * List_len() * * Return the number of elements in the list * ----------------------------------------------------------------------------- */ static int List_len(DOH *lo) { List *l = (List *) ObjData(lo); return l->nitems; } /* ----------------------------------------------------------------------------- * List_get() * * Get the nth item from the list. * ----------------------------------------------------------------------------- */ static DOH * List_get(DOH *lo, int n) { List *l = (List *) ObjData(lo); if (n == DOH_END) n = l->nitems-1; if (n == DOH_BEGIN) n = 0; assert(!((n < 0) || (n >= l->nitems))); return l->items[n]; } /* ----------------------------------------------------------------------------- * List_set() * * Set the nth item in the list replacing any previous item. * ----------------------------------------------------------------------------- */ static int List_set(DOH *lo, int n, DOH *val) { List *l = (List *) ObjData(lo); if (!val) return -1; assert(!((n < 0) || (n >= l->nitems))); if (!DohCheck(val)) { val = NewString(val); Decref(val); } Delete(l->items[n]); l->items[n] = val; Incref(val); Delete(val); return 0; } /* ----------------------------------------------------------------------------- * List_first() * * Return the first item in the list. * ----------------------------------------------------------------------------- */ static DohIterator List_first(DOH *lo) { DohIterator iter; List *l = (List *) ObjData(lo); iter.object = lo; iter._index = 0; iter.key = 0; if (l->nitems > 0) { iter.item = l->items[0]; } else { iter.item = 0; } return iter; } /* ----------------------------------------------------------------------------- * List_next() * * Return the next item in the list. * ----------------------------------------------------------------------------- */ static DohIterator List_next(DohIterator iter) { List *l = (List *) ObjData(iter.object); iter._index = iter._index + 1; if (iter._index >= l->nitems) { iter.item = 0; iter.key = 0; } else { iter.item = l->items[iter._index]; } return iter; } /* ----------------------------------------------------------------------------- * List_str() * * Create a string representation of the list. * ----------------------------------------------------------------------------- */ static DOH * List_str(DOH *lo) { DOH *s; int i; List *l = (List *) ObjData(lo); s = NewString(""); if (ObjGetMark(lo)) { Printf(s,"List(%x)", lo); return s; } ObjSetMark(lo,1); Printf(s,"List[ "); for (i = 0; i < l->nitems; i++) { Printf(s, "%s", l->items[i]); if ((i+1) < l->nitems) Printf(s,", "); } Printf(s," ]\n"); ObjSetMark(lo,0); return s; } /* ----------------------------------------------------------------------------- * List_dump() * * Dump the items to an output stream. * ----------------------------------------------------------------------------- */ static int List_dump(DOH *lo, DOH *out) { int nsent = 0; int i,ret; List *l = (List *) ObjData(lo); for (i = 0; i < l->nitems; i++) { ret = Dump(l->items[i],out); if (ret < 0) return -1; nsent += ret; } return nsent; } static void List_setfile(DOH *lo, DOH *file) { DOH *fo; List *l = (List *) ObjData(lo); if (!DohCheck(file)) { fo = NewString(file); Decref(fo); } else fo = file; Incref(fo); Delete(l->file); l->file = fo; } static DOH * List_getfile(DOH *lo) { List *l = (List *) ObjData(lo); return l->file; } static void List_setline(DOH *lo, int line) { List *l = (List *) ObjData(lo); l->line = line; } static int List_getline(DOH *lo) { List *l = (List *) ObjData(lo); return l->line; } static DohListMethods ListListMethods = { List_get, List_set, List_remove, List_insert, 0, /* delslice */ }; DohObjInfo DohListType = { "List", /* objname */ DelList, /* doh_del */ CopyList, /* doh_copy */ List_clear, /* doh_clear */ List_str, /* doh_str */ 0, /* doh_data */ List_dump, /* doh_dump */ List_len, /* doh_len */ 0, /* doh_hash */ 0, /* doh_cmp */ List_first, /* doh_first */ List_next, /* doh_next */ List_setfile, /* doh_setfile */ List_getfile, /* doh_getfile */ List_setline, /* doh_setline */ List_getline, /* doh_getline */ 0, /* doh_mapping */ &ListListMethods, /* doh_sequence */ 0, /* doh_file */ 0, /* doh_string */ 0, /* doh_callable */ 0, /* doh_position */ }; /* ----------------------------------------------------------------------------- * NewList() * * Create a new list. * ----------------------------------------------------------------------------- */ #define MAXLISTITEMS 8 DOH * DohNewList() { List *l; int i; l = (List *) DohMalloc(sizeof(List)); l->nitems = 0; l->maxitems = MAXLISTITEMS; l->items = (void **) DohMalloc(l->maxitems*sizeof(void *)); for (i = 0; i < MAXLISTITEMS; i++) { l->items[i] = 0; } l->file = 0; l->line = 0; return DohObjMalloc(&DohListType,l); } cableswig-0.1.0+git20150808.orig/SWIG/Source/README0000644000175000000620000000161112561312227017715 0ustar stevestaffSWIG Source directory This directory currently contains a mix of legacy SWIG1.1 code and recent development work. As a result, it's still a little messy. Here is a rough breakdown of the directories: Source/DOH - A core set of basic datatypes including strings, lists, hashes, and files. Used extensively by the rest of SWIG. Source/Swig - Swig core. Type-system, utility functions. Source/Preprocessor - SWIG C Preprocessor Source/CParse - SWIG C Parser (still messy) Source/Modules - Language modules. The following directories may be in CVS, but are largely deprecated: Source/Modules1.1 - Old SWIG-1.1 modules. Empty. Source/LParse - Experimental parser. Officially dead as CParse is more capable. Source/SWIG1.1 - Old SWIG1.1 core. Completely empty now. cableswig-0.1.0+git20150808.orig/SWIG/Source/Modules/0002755000175000000620000000000012561312227020450 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Source/Modules/guile.cxx0000644000175000000620000016015312561312227022305 0ustar stevestaff/****************************************************************************** * Simplified Wrapper and Interface Generator (SWIG) * * Author : David Beazley * * Department of Computer Science * University of Chicago * 1100 E 58th Street * Chicago, IL 60637 * beazley@cs.uchicago.edu * * Please read the file LICENSE for the copyright and terms by which SWIG * can be used and distributed. *****************************************************************************/ char cvsroot_guile_cxx[] = "/cvsroot/SWIG/Source/Modules/guile.cxx,v 1.15 2004/02/10 15:26:22 mkoeppe Exp"; /*********************************************************************** * /cvsroot/SWIG/Source/Modules/guile.cxx,v 1.15 2004/02/10 15:26:22 mkoeppe Exp * * guile.cxx * * Definitions for adding functions to Guile ***********************************************************************/ /*********************************************************************** * GOOPS Support added by John Lenz in June, 2003 * Base code copied from chicken module, writen by Jonah Beckford ***********************************************************************/ #include "swigmod.h" #include // Note string broken in half for compilers that can't handle long strings static const char *guile_usage = (char*)"\ Guile Options (available with -guile)\n\ -ldflags - Print runtime libraries to link with\n\ -prefix - Use as prefix [default \"gswig_\"]\n\ -package - Set the path of the module to \n\ (default NULL)\n\ -emitsetters - Emit procedures-with-setters for variables\n\ and structure slots.\n\ -onlysetters - Don't emit traditional getter and setter\n\ procedures for structure slots,\n\ only emit procedures-with-setters.\n\ -procdoc - Output procedure documentation to \n\ -procdocformat - Output procedure documentation in ;\n\ one of `guile-1.4', `plain', `texinfo'\n\ -linkage - Use linkage protocol (default `simple')\n\ Use `module' for native Guile module linking\n\ (requires Guile >= 1.5.0). Use `passive' for\n\ passive linking (no C-level module-handling code),\n\ `ltdlmod' for Guile's old dynamic module\n\ convention (Guile <= 1.4), or `hobbit' for hobbit\n\ modules.\n\ -scmstub - Output Scheme file with module declaration and\n\ exports; only with `passive' and `simple' linkage\n\ -gh - Use the gh_ Guile API. (Guile <= 1.8, default) \n\ -scm - Use the scm Guile API. (Guile >= 1.6) \n\ -shadow - Export GOOPS class definitions\n\ -emitslotaccessors - Emit accessor methods for all GOOPS slots\n" "\ -primsuffix - Name appended to primitive module when exporting\n\ GOOPS classes. (default = \"primitive\")\n\ -goopsprefix - Prepend to all goops identifiers\n\ -useclassprefix - Prepend the class name to all goops identifiers\n\ -exportprimitive - Add the (export ...) code from scmstub into the\n\ GOOPS file.\n"; static File *f_runtime = 0; static File *f_header = 0; static File *f_wrappers = 0; static File *f_init = 0; static char *prefix = (char *) "gswig_"; static char *module = 0; static char *package = 0; static enum { GUILE_LSTYLE_SIMPLE, // call `SWIG_init()' GUILE_LSTYLE_PASSIVE, // passive linking (no module code) GUILE_LSTYLE_MODULE, // native guile module linking (Guile >= 1.4.1) GUILE_LSTYLE_LTDLMOD_1_4, // old (Guile <= 1.4) dynamic module convention GUILE_LSTYLE_HOBBIT // use (hobbit4d link) } linkage = GUILE_LSTYLE_SIMPLE; static File *procdoc = 0; static bool scmstub = false; static String *scmtext; static bool goops = false; static String *goopstext; static String *goopscode; static String *goopsexport; static enum { GUILE_1_4, PLAIN, TEXINFO } docformat = GUILE_1_4; static int emit_setters = 0; static int only_setters = 0; static int emit_slot_accessors = 0; static int struct_member = 0; static String *beforereturn = 0; static String *return_nothing_doc = 0; static String *return_one_doc = 0; static String *return_multi_doc = 0; static String *exported_symbols = 0; static int use_scm_interface = 0; static int exporting_destructor = 0; static String *swigtype_ptr = 0; /* GOOPS stuff */ static String *primsuffix = 0; static String *class_name = 0; static String *short_class_name = 0; static String *goops_class_methods; static int in_class = 0; static int have_constructor = 0; static int useclassprefix = 0; // -useclassprefix argument static String *goopsprefix = 0; // -goopsprefix argument static int primRenamer = 0; // if (use-modules ((...) :renamer ...) is exported to GOOPS file static int exportprimitive = 0; // -exportprimitive argument static String *memberfunction_name = 0; class GUILE : public Language { public: /* ------------------------------------------------------------ * main() * ------------------------------------------------------------ */ virtual void main (int argc, char *argv[]) { int i, orig_len; SWIG_library_directory("guile"); SWIG_typemap_lang("guile"); // Look for certain command line options for (i = 1; i < argc; i++) { if (argv[i]) { if (strcmp (argv[i], "-help") == 0) { fputs (guile_usage, stderr); SWIG_exit (EXIT_SUCCESS); } else if (strcmp (argv[i], "-prefix") == 0) { if (argv[i + 1]) { prefix = new char[strlen (argv[i + 1]) + 2]; strcpy (prefix, argv[i + 1]); Swig_mark_arg (i); Swig_mark_arg (i + 1); i++; } else { Swig_arg_error(); } } else if (strcmp (argv[i], "-package") == 0) { if (argv[i + 1]) { package = new char[strlen (argv[i + 1]) + 2]; strcpy (package, argv [i + 1]); Swig_mark_arg (i); Swig_mark_arg (i + 1); i++; } else { Swig_arg_error(); } } else if (strcmp (argv[i], "-ldflags") == 0) { printf("%s\n", use_scm_interface ? SWIG_GUILESCM_RUNTIME : SWIG_GUILE_RUNTIME); SWIG_exit (EXIT_SUCCESS); } else if (strcmp (argv[i], "-Linkage") == 0 || strcmp (argv[i], "-linkage") == 0) { if (argv[i + 1]) { if (0 == strcmp (argv[i + 1], "ltdlmod")) linkage = GUILE_LSTYLE_LTDLMOD_1_4; else if (0 == strcmp (argv[i + 1], "hobbit")) linkage = GUILE_LSTYLE_HOBBIT; else if (0 == strcmp (argv[i + 1], "simple")) linkage = GUILE_LSTYLE_SIMPLE; else if (0 == strcmp (argv[i + 1], "passive")) linkage = GUILE_LSTYLE_PASSIVE; else if (0 == strcmp (argv[i + 1], "module")) linkage = GUILE_LSTYLE_MODULE; else Swig_arg_error (); Swig_mark_arg (i); Swig_mark_arg (i + 1); i++; } else { Swig_arg_error(); } } else if (strcmp (argv[i], "-procdoc") == 0) { if (argv[i + 1]) { procdoc = NewFile(argv[i + 1], (char *) "w"); Swig_mark_arg (i); Swig_mark_arg (i + 1); i++; } else { Swig_arg_error(); } } else if (strcmp (argv[i], "-procdocformat") == 0) { if (strcmp(argv[i+1], "guile-1.4") == 0) docformat = GUILE_1_4; else if (strcmp(argv[i+1], "plain") == 0) docformat = PLAIN; else if (strcmp(argv[i+1], "texinfo") == 0) docformat = TEXINFO; else Swig_arg_error(); Swig_mark_arg(i); Swig_mark_arg(i+1); i++; } else if (strcmp (argv[i], "-emit-setters") == 0 || strcmp (argv[i], "-emitsetters") == 0) { emit_setters = 1; Swig_mark_arg (i); } else if (strcmp (argv[i], "-only-setters") == 0 || strcmp (argv[i], "-onlysetters") == 0) { emit_setters = 1; only_setters = 1; Swig_mark_arg (i); } else if (strcmp (argv[i], "-emit-slot-accessors") == 0 || strcmp (argv[i], "-emitslotaccessors") == 0) { emit_slot_accessors = 1; Swig_mark_arg (i); } else if (strcmp (argv[i], "-scmstub") == 0) { scmstub = true; Swig_mark_arg(i); } else if (strcmp (argv[i], "-shadow") == 0) { goops = true; Swig_mark_arg(i); } else if (strcmp(argv[i], "-gh") == 0) { use_scm_interface = 0; Swig_mark_arg(i); } else if (strcmp(argv[i], "-scm") == 0) { use_scm_interface = 1; Swig_mark_arg(i); } else if (strcmp(argv[i], "-primsuffix") == 0) { if (argv[i+1]) { primsuffix = NewString(argv[i+1]); Swig_mark_arg (i); Swig_mark_arg (i + 1); i++; } else { Swig_arg_error(); } } else if (strcmp(argv[i], "-goopsprefix") == 0) { if (argv[i+1]) { goopsprefix = NewString(argv[i+1]); Swig_mark_arg (i); Swig_mark_arg (i + 1); i++; } else { Swig_arg_error(); } } else if (strcmp(argv[i], "-useclassprefix") == 0) { useclassprefix = 1; Swig_mark_arg(i); } else if (strcmp(argv[i], "-exportprimitive") == 0) { exportprimitive = 1; // should use Swig_warning() here? Swig_mark_arg(i); } } } // set default value for primsuffix if (primsuffix == NULL) primsuffix = NewString("primitive"); //goops support can only be enabled if passive or module linkage is used if (goops) { if (linkage != GUILE_LSTYLE_PASSIVE && linkage != GUILE_LSTYLE_MODULE) { Printf(stderr, "guile: GOOPS support requires passive or module linkage\n"); exit(1); } } if (goops) { // -shadow implies -emit-setters emit_setters = 1; } if ((linkage == GUILE_LSTYLE_PASSIVE && scmstub) || linkage == GUILE_LSTYLE_MODULE) primRenamer = 1; if (exportprimitive && primRenamer) { // should use Swig_warning() ? Printf(stderr, "guile: Warning: -exportprimitive only makes sense with passive linkage without a scmstub.\n"); } // Make sure `prefix' ends in an underscore orig_len = strlen (prefix); if (prefix[orig_len - 1] != '_') { prefix[1 + orig_len] = 0; prefix[orig_len] = '_'; } /* Add a symbol for this module */ Preprocessor_define ("SWIGGUILE 1",0); /* Read in default typemaps */ if (use_scm_interface) SWIG_config_file("guile_scm.swg"); else SWIG_config_file("guile_gh.swg"); allow_overloading(); } /* ------------------------------------------------------------ * top() * ------------------------------------------------------------ */ virtual int top(Node *n) { /* Initialize all of the output files */ String *outfile = Getattr(n,"outfile"); f_runtime = NewFile(outfile,"w"); if (!f_runtime) { Printf(stderr,"*** Can't open '%s'\n", outfile); SWIG_exit(EXIT_FAILURE); } f_init = NewString(""); f_header = NewString(""); f_wrappers = NewString(""); /* Register file targets with the SWIG file handler */ Swig_register_filebyname("header",f_header); Swig_register_filebyname("wrapper",f_wrappers); Swig_register_filebyname("runtime",f_runtime); Swig_register_filebyname("init",f_init); scmtext = NewString(""); Swig_register_filebyname("scheme", scmtext); exported_symbols = NewString(""); goopstext = NewString(""); Swig_register_filebyname("goops", goopstext); goopscode = NewString(""); goopsexport = NewString(""); Printf(f_runtime, "/* -*- buffer-read-only: t -*- vi: set ro: */\n"); Swig_banner (f_runtime); Printf (f_runtime, "/* Implementation : GUILE */\n\n"); /* Write out directives and declarations */ if (NoInclude) { Printf(f_runtime, "#define SWIG_NOINCLUDE\n"); } module = Swig_copy_string(Char(Getattr(n,"name"))); if (CPlusPlus) { Printf(f_runtime, "extern \"C\" {\n\n"); } switch (linkage) { case GUILE_LSTYLE_SIMPLE: /* Simple linkage; we have to export the SWIG_init function. The user can rename the function by a #define. */ Printf (f_runtime, "extern void\nSWIG_init (void)\n;\n"); Printf (f_init, "extern void\nSWIG_init (void)\n{\n"); break; default: /* Other linkage; we make the SWIG_init function static */ Printf (f_runtime, "static void\nSWIG_init (void)\n;\n"); Printf (f_init, "static void\nSWIG_init (void)\n{\n"); break; } if (CPlusPlus) { Printf(f_runtime, "\n}\n"); } Language::top(n); /* Close module */ Printf(f_wrappers,"#ifdef __cplusplus\nextern \"C\" {\n#endif\n"); SwigType_emit_type_table (f_runtime, f_wrappers); Printf (f_init, "}\n\n"); Printf (f_init, "#ifdef __cplusplus\n}\n#endif\n"); String *module_name = NewString(""); if (!module) Printv(module_name, "swig", NIL); else { if (package) Printf(module_name,"%s/%s", package, module); else Printv(module_name,module,NIL); } emit_linkage (module_name); Delete(module_name); if (procdoc) { Delete(procdoc); procdoc = NULL; } Delete(goopscode); Delete(goopsexport); Delete(goopstext); /* Close all of the files */ Dump(f_header,f_runtime); Dump(f_wrappers,f_runtime); Wrapper_pretty_print(f_init,f_runtime); Delete(f_header); Delete(f_wrappers); Delete(f_init); Close(f_runtime); Delete(f_runtime); return SWIG_OK; } void emit_linkage (String *module_name) { String *module_func = NewString(""); if (CPlusPlus) { Printf(f_init, "extern \"C\" {\n\n"); } Printv(module_func,module_name,NIL); if (goops) Replaceall(module_func,"-", "_"); switch (linkage) { case GUILE_LSTYLE_SIMPLE: Printf (f_init, "\n/* Linkage: simple */\n"); break; case GUILE_LSTYLE_PASSIVE: Printf (f_init, "\n/* Linkage: passive */\n"); Replaceall(module_func,"/", "_"); Insert(module_func,0, "scm_init_"); Append(module_func,"_module"); Printf (f_init, "SCM\n%s (void)\n{\n", module_func); Printf (f_init, " SWIG_init();\n"); Printf (f_init, " return SCM_UNSPECIFIED;\n"); Printf (f_init, "}\n"); break; case GUILE_LSTYLE_LTDLMOD_1_4: Printf (f_init, "\n/* Linkage: ltdlmod */\n"); Replaceall(module_func,"/", "_"); Insert(module_func,0, "scm_init_"); Append(module_func,"_module"); Printf (f_init, "SCM\n%s (void)\n{\n", module_func); { String *mod = NewString(module_name); Replaceall(mod,"/", " "); Printf (f_init, " scm_register_module_xxx (\"%s\", (void *) SWIG_init);\n", mod); Printf (f_init, " return SCM_UNSPECIFIED;\n"); Delete(mod); } Printf (f_init, "}\n"); break; case GUILE_LSTYLE_MODULE: Printf (f_init, "\n/* Linkage: module */\n"); Replaceall(module_func,"/", "_"); Insert(module_func,0, "scm_init_"); Append(module_func,"_module"); Printf (f_init, "static void SWIG_init_helper(void *data)\n"); Printf (f_init, "{\n SWIG_init();\n"); if (Len(exported_symbols) > 0) Printf (f_init, " scm_c_export(%sNULL);", exported_symbols); Printf (f_init, "\n}\n\n"); Printf (f_init, "SCM\n%s (void)\n{\n", module_func); { String *mod = NewString(module_name); if (goops) Printv(mod,"-",primsuffix,NIL); Replaceall(mod,"/", " "); Printf(f_init, " SCM module = scm_c_define_module(\"%s\",\n", mod); Printf(f_init, " SWIG_init_helper, NULL);\n"); Printf(f_init, " return SCM_UNSPECIFIED;\n"); Delete(mod); } Printf (f_init, "}\n"); break; case GUILE_LSTYLE_HOBBIT: Printf (f_init, "\n/* Linkage: hobbit */\n"); Replaceall(module_func,"/", "_slash_"); Insert(module_func,0, "scm_init_"); Printf (f_init, "SCM\n%s (void)\n{\n", module_func); { String *mod = NewString(module_name); Replaceall(mod,"/", " "); Printf (f_init, " scm_register_module_xxx (\"%s\", (void *) SWIG_init);\n", mod); Printf (f_init, " return SCM_UNSPECIFIED;\n"); Delete(mod); } Printf (f_init, "}\n"); break; default: abort(); // for now } if (scmstub) { /* Emit Scheme stub if requested */ String *primitive_name = NewString(module_name); if (goops) Printv(primitive_name,"-",primsuffix,NIL); String *mod = NewString(primitive_name); Replaceall(mod, "/", " "); String *fname = NewStringf("%s%s.scm", SWIG_output_directory(), primitive_name); Delete(primitive_name); File *scmstubfile = NewFile(fname, (char *) "w"); if (!scmstubfile) { Printf(stderr,"*** Can't open '%s' for writing\n", fname); SWIG_exit(EXIT_FAILURE); } Delete(fname); Printf (scmstubfile, ";;; -*- buffer-read-only: t -*- vi: set ro: */\n"); Printf (scmstubfile, ";;; Automatically generated by SWIG; do not edit.\n\n"); if (linkage == GUILE_LSTYLE_SIMPLE || linkage == GUILE_LSTYLE_PASSIVE) Printf (scmstubfile, "(define-module (%s))\n\n", mod); Delete(mod); Printf (scmstubfile, "%s", scmtext); if ((linkage == GUILE_LSTYLE_SIMPLE || linkage == GUILE_LSTYLE_PASSIVE) && Len(exported_symbols) > 0) { String *ex = NewString(exported_symbols); Replaceall(ex, ", ", "\n "); Replaceall(ex, "\"", ""); Chop(ex); Printf(scmstubfile, "\n(export %s)\n", ex); Delete(ex); } } if (goops) { String *mod = NewString(module_name); Replaceall(mod, "/", " "); String *fname = NewStringf("%s%s.scm", SWIG_output_directory(), module_name); File *goopsfile = NewFile(fname, (char *)"w"); if (!goopsfile) { Printf(stderr,"*** Can't open '%s' for writing\n", fname); SWIG_exit(EXIT_FAILURE); } Delete(fname); Printf (goopsfile, ";;; -*- buffer-read-only: t -*- vi: set ro: */\n"); Printf (goopsfile, ";;; Automatically generated by SWIG; do not edit.\n\n"); Printf (goopsfile, "(define-module (%s))\n", mod); Printf (goopsfile, "%s\n", goopstext); Printf (goopsfile, "(use-modules (oop goops) (Swig common))\n"); if (primRenamer) { Printf (goopsfile, "(use-modules ((%s-%s) :renamer (symbol-prefix-proc 'primitive:)))\n", mod, primsuffix); } Printf (goopsfile, "%s\n(export %s)", goopscode, goopsexport); if (exportprimitive) { String *ex = NewString(exported_symbols); Replaceall(ex, ", ", "\n "); Replaceall(ex, "\"", ""); Chop(ex); Printf(goopsfile, "\n(export %s)", ex); Delete(ex); } Delete(mod); Delete(goopsfile); } Delete(module_func); if (CPlusPlus) { Printf(f_init, "\n}\n"); } } /* Return true iff T is a pointer type */ int is_a_pointer (SwigType *t) { return SwigType_ispointer(SwigType_typedef_resolve_all(t)); } /* Report an error handling the given type. */ void throw_unhandled_guile_type_error (SwigType *d) { Swig_warning(WARN_TYPEMAP_UNDEF, input_file, line_number, "Unable to handle type %s.\n", SwigType_str(d,0)); } /* Write out procedure documentation */ void write_doc(const String *proc_name, const String *signature, const String *doc, const String *signature2 = NULL) { switch (docformat) { case GUILE_1_4: Printv(procdoc, "\f\n", NIL); Printv(procdoc, "(", signature, ")\n", NIL); if (signature2) Printv(procdoc, "(", signature2, ")\n", NIL); Printv(procdoc, doc, "\n", NIL); break; case PLAIN: Printv(procdoc, "\f", proc_name, "\n\n", NIL); Printv(procdoc, "(", signature, ")\n", NIL); if (signature2) Printv(procdoc, "(", signature2, ")\n", NIL); Printv(procdoc, doc, "\n\n", NIL); break; case TEXINFO: Printv(procdoc, "\f", proc_name, "\n", NIL); Printv(procdoc, "@deffn primitive ", signature, "\n", NIL); if (signature2) Printv(procdoc, "@deffnx primitive ", signature2, "\n", NIL); Printv(procdoc, doc, "\n", NIL); Printv(procdoc, "@end deffn\n\n", NIL); break; } } /* returns false if the typemap is an empty string */ bool handle_documentation_typemap(String *output, const String *maybe_delimiter, Parm *p, const String *typemap, const String *default_doc) { String *tmp = NewString(""); String *tm; if (!(tm = Getattr(p, typemap))) { Printf(tmp, "%s", default_doc); tm = tmp; } bool result = (Len(tm) > 0); if (maybe_delimiter && Len(output) > 0 && Len(tm) > 0) { Printv(output, maybe_delimiter, NIL); } String *pn = Getattr(p,"name"); String *pt = Getattr(p,"type"); Replaceall(tm, "$name", pn); // legacy for $parmname Replaceall(tm, "$type", SwigType_str(pt,0)); /* $NAME is like $name, but marked-up as a variable. */ String *ARGNAME = NewString(""); if (docformat == TEXINFO) Printf(ARGNAME, "@var{%s}", pn); else Printf(ARGNAME, "%(upper)s", pn); Replaceall(tm, "$NAME", ARGNAME); Replaceall(tm, "$PARMNAME", ARGNAME); Printv(output,tm,NIL); Delete(tmp); return result; } /* ------------------------------------------------------------ * functionWrapper() * Create a function declaration and register it with the interpreter. * ------------------------------------------------------------ */ virtual int functionWrapper(Node *n) { String *iname = Getattr(n,"sym:name"); SwigType *d = Getattr(n,"type"); ParmList *l = Getattr(n,"parms"); Parm *p; String *proc_name = 0; char source[256], target[256]; Wrapper *f = NewWrapper();; String *cleanup = NewString(""); String *outarg = NewString(""); String *signature = NewString(""); String *doc_body = NewString(""); String *returns = NewString(""); String *method_signature = NewString(""); String *primitive_args = NewString(""); Hash *scheme_arg_names = NewHash(); int num_results = 1; String *tmp = NewString(""); String *tm; int i; int numargs = 0; int numreq = 0; String *overname = 0; int args_passed_as_array = 0; int scheme_argnum = 0; // Make a wrapper name for this String *wname = Swig_name_wrapper(iname); if (Getattr(n,"sym:overloaded")) { overname = Getattr(n,"sym:overname"); args_passed_as_array = 1; } else { if (!addSymbol(iname,n)) return SWIG_ERROR; } if (overname) { Append(wname, overname); } Setattr(n,"wrap:name",wname); // Build the name for scheme. proc_name = NewString(iname); Replaceall(proc_name,"_", "-"); /* Emit locals etc. into f->code; figure out which args to ignore */ emit_args (d, l, f); /* Attach the standard typemaps */ emit_attach_parmmaps(l,f); Setattr(n,"wrap:parms",l); /* Get number of required and total arguments */ numargs = emit_num_arguments(l); numreq = emit_num_required(l); /* Declare return variable */ Wrapper_add_local (f,"gswig_result", "SCM gswig_result"); Wrapper_add_local (f,"gswig_list_p", "int gswig_list_p = 0"); /* Get the output typemap so we can start generating documentation. Don't worry, the returned string is saved as 'tmap:out' */ Swig_typemap_lookup_new("out",n,"result",0); if ((tm = Getattr(n,"tmap:out:doc"))) { Printv(returns,tm,NIL); if (Len(tm) > 0) num_results = 1; else num_results = 0; } else { String *s = SwigType_str(d,0); Chop(s); Printf(returns,"<%s>",s); Delete(s); num_results = 1; } /* Open prototype and signature */ Printv(f->def, "static SCM\n", wname," (", NIL); if (args_passed_as_array) { Printv(f->def, "int argc, SCM *argv", NIL); } Printv(signature, proc_name, NIL); /* Now write code to extract the parameters */ for (i = 0, p = l; i < numargs; i++) { while (checkAttribute(p,"tmap:in:numinputs","0")) { p = Getattr(p,"tmap:in:next"); } SwigType *pt = Getattr(p,"type"); String *ln = Getattr(p,"lname"); int opt_p = (i >= numreq); // Produce names of source and target if (args_passed_as_array) sprintf(source, "argv[%d]", i); else sprintf(source,"s_%d",i); sprintf(target,"%s", Char(ln)); if (!args_passed_as_array) { if (i!=0) Printf(f->def,", "); Printf(f->def,"SCM s_%d", i); } if (opt_p) { Printf(f->code," if (%s != SCM_UNDEFINED) {\n", source); } if ((tm = Getattr(p,"tmap:in"))) { Replaceall(tm,"$source",source); Replaceall(tm,"$target",target); Replaceall(tm,"$input",source); Setattr(p,"emit:input", source); Printv(f->code,tm,"\n",NIL); if (procdoc) { if (i == numreq) { /* First optional argument */ Printf(signature, " #:optional"); } /* Add to signature (arglist) */ handle_documentation_typemap(signature, " ", p, "tmap:in:arglist", "$name"); /* Document the type of the arg in the documentation body */ handle_documentation_typemap(doc_body, ", ", p, "tmap:in:doc", "$NAME is of type <$type>"); } if (goops) { if (i < numreq) { SwigType *pb = SwigType_typedef_resolve_all(SwigType_base(pt)); SwigType *pn = Getattr(p,"name"); String *argname; scheme_argnum++; if (pn && !Getattr(scheme_arg_names, pn)) argname = pn; else { /* Anonymous arg or re-used argument name -- choose a name that cannot clash */ argname = NewStringf("%%arg%d", scheme_argnum); } if (strcmp("void", Char(pt)) != 0) { Node *class_node = Swig_symbol_clookup(pb, Getattr(n, "sym:symtab")); String *goopsclassname = (class_node == NULL) ? NULL : Getattr(class_node, "guile:goopsclassname"); /* do input conversion */ if (goopsclassname) { Printv(method_signature, " (", argname, " ", goopsclassname, ")", NIL); } else { Printv(method_signature, " ", argname, NIL); } Printv(primitive_args, " ", argname, NIL); Setattr(scheme_arg_names, argname, p); } if (!pn) { Delete(argname); } } } p = Getattr(p,"tmap:in:next"); } else { throw_unhandled_guile_type_error (pt); p = nextSibling(p); } if (opt_p) Printf(f->code," }\n"); } if (Len(doc_body) > 0) Printf(doc_body, ".\n"); /* Insert constraint checking code */ for (p = l; p;) { if ((tm = Getattr(p,"tmap:check"))) { Replaceall(tm,"$target",Getattr(p,"lname")); Printv(f->code,tm,"\n",NIL); p = Getattr(p,"tmap:check:next"); } else { p = nextSibling(p); } } /* Pass output arguments back to the caller. */ /* Insert argument output code */ for (p = l; p;) { if ((tm = Getattr(p,"tmap:argout"))) { Replaceall(tm,"$source",Getattr(p,"lname")); Replaceall(tm,"$target",Getattr(p,"lname")); Replaceall(tm,"$arg",Getattr(p,"emit:input")); Replaceall(tm,"$input",Getattr(p,"emit:input")); Printv(outarg,tm,"\n",NIL); if (procdoc) { if (handle_documentation_typemap(returns, ", ", p, "tmap:argout:doc", "$NAME (of type $type)")) { /* A documentation typemap that is not the empty string indicates that a value is returned to Scheme. */ num_results++; } } p = Getattr(p,"tmap:argout:next"); } else { p = nextSibling(p); } } /* Insert cleanup code */ for (p = l; p;) { if ((tm = Getattr(p,"tmap:freearg"))) { Replaceall(tm,"$target",Getattr(p,"lname")); Replaceall(tm,"$input",Getattr(p,"emit:input")); Printv(cleanup,tm,"\n",NIL); p = Getattr(p,"tmap:freearg:next"); } else { p = nextSibling(p); } } if (use_scm_interface && exporting_destructor) { /* Mark the destructor's argument as destroyed. */ String *tm = NewString("SWIG_Guile_MarkPointerDestroyed($input);"); Replaceall(tm,"$input",Getattr(l,"emit:input")); Printv(cleanup, tm, "\n", NIL); Delete(tm); } /* Close prototype */ Printf(f->def, ")\n{\n"); /* Define the scheme name in C. This define is used by several Guile macros. */ Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL); // Now write code to make the function call if (!use_scm_interface) Printv(f->code, tab4, "gh_defer_ints();\n", NIL); emit_action(n,f); if (!use_scm_interface) Printv(f->code, tab4, "gh_allow_ints();\n", NIL); // Now have return value, figure out what to do with it. if ((tm = Getattr(n,"tmap:out"))) { Replaceall(tm,"$result","gswig_result"); Replaceall(tm,"$target","gswig_result"); Replaceall(tm,"$source","result"); if (Getattr(n, "feature:new")) Replaceall(tm, "$owner", "1"); else Replaceall(tm, "$owner", "0"); Printv(f->code,tm,"\n",NIL); } else { throw_unhandled_guile_type_error (d); } // Dump the argument output code Printv(f->code,outarg,NIL); // Dump the argument cleanup code Printv(f->code,cleanup,NIL); // Look for any remaining cleanup if (Getattr(n,"feature:new")) { if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) { Replaceall(tm,"$source","result"); Printv(f->code,tm,"\n",NIL); } } // Free any memory allocated by the function being wrapped.. if ((tm = Swig_typemap_lookup_new("ret",n,"result",0))) { Replaceall(tm,"$source","result"); Printv(f->code,tm,"\n",NIL); } // Wrap things up (in a manner of speaking) if (beforereturn) Printv(f->code, beforereturn, "\n", NIL); Printv(f->code, "return gswig_result;\n", NIL); // Undefine the scheme name Printf(f->code, "#undef FUNC_NAME\n"); Printf(f->code, "}\n"); Wrapper_print (f, f_wrappers); if (!Getattr(n, "sym:overloaded")) { if (numargs > 10) { int i; /* gh_new_procedure would complain: too many args */ /* Build a wrapper wrapper */ Printv(f_wrappers, "static SCM\n", wname,"_rest (SCM rest)\n", NIL); Printv(f_wrappers, "{\n", NIL); Printf(f_wrappers, "SCM arg[%d];\n", numargs); Printf(f_wrappers, "SWIG_Guile_GetArgs (arg, rest, %d, %d, \"%s\");\n", numreq, numargs-numreq, proc_name); Printv(f_wrappers, "return ", wname, "(", NIL); Printv(f_wrappers, "arg[0]", NIL); for (i = 1; i3) { int len = Len(proc_name); const char *pc = Char(proc_name); /* MEMBER-set and MEMBER-get functions. */ int is_setter = (pc[len - 3] == 's'); if (is_setter) { Printf(f_init, "SCM setter = "); struct_member = 2; /* have a setter */ } else Printf(f_init, "SCM getter = "); if (use_scm_interface) { /* GOOPS support uses the MEMBER-set and MEMBER-get functions, so ignore only_setters in this case. */ if (only_setters && !goops) Printf(f_init, "scm_c_make_gsubr(\"%s\", %d, %d, 0, (swig_guile_proc) %s);\n", proc_name, numreq, numargs-numreq, wname); else Printf(f_init, "scm_c_define_gsubr(\"%s\", %d, %d, 0, (swig_guile_proc) %s);\n", proc_name, numreq, numargs-numreq, wname); } else { if (only_setters && !goops) Printf(f_init, "scm_make_gsubr(\"%s\", %d, %d, 0, (swig_guile_proc) %s);\n", proc_name, numreq, numargs-numreq, wname); else Printf (f_init, "gh_new_procedure(\"%s\", (swig_guile_proc) %s, %d, %d, 0);\n", proc_name, wname, numreq, numargs-numreq); } if (!is_setter) { /* Strip off "-get" */ char *pws_name = (char*) malloc(sizeof(char) * (len - 3)); strncpy(pws_name, pc, len - 3); pws_name[len - 4] = 0; if (struct_member==2) { /* There was a setter, so create a procedure with setter */ if (use_scm_interface) { Printf(f_init, "scm_c_define"); } else { Printf(f_init, "gh_define"); } Printf (f_init, "(\"%s\", " "scm_make_procedure_with_setter(getter, setter));\n", pws_name); } else { /* There was no setter, so make an alias to the getter */ if (use_scm_interface) { Printf(f_init, "scm_c_define"); } else { Printf(f_init, "gh_define"); } Printf (f_init, "(\"%s\", getter);\n", pws_name); } Printf (exported_symbols, "\"%s\", ", pws_name); free(pws_name); } } else { /* Register the function */ if (use_scm_interface) { if (exporting_destructor) { Printf(f_init, "((swig_guile_clientdata *)(SWIGTYPE%s->clientdata))->destroy = (guile_destructor) %s;\n", swigtype_ptr, wname); //Printf(f_init, "SWIG_TypeClientData(SWIGTYPE%s, (void *) %s);\n", swigtype_ptr, wname); } Printf(f_init, "scm_c_define_gsubr(\"%s\", %d, %d, 0, (swig_guile_proc) %s);\n", proc_name, numreq, numargs-numreq, wname); } else { Printf (f_init, "gh_new_procedure(\"%s\", (swig_guile_proc) %s, %d, %d, 0);\n", proc_name, wname, numreq, numargs-numreq); } } } else { /* overloaded function; don't export the single methods */ if (!Getattr(n,"sym:nextSibling")) { /* Emit overloading dispatch function */ int maxargs; String *dispatch = Swig_overload_dispatch(n,"return %s(argc,argv);",&maxargs); /* Generate a dispatch wrapper for all overloaded functions */ Wrapper *df = NewWrapper(); String *dname = Swig_name_wrapper(iname); Printv(df->def, "static SCM\n", dname, "(SCM rest)\n{\n", NIL); Printf(df->code, "SCM argv[%d];\n", maxargs); Printf(df->code, "int argc = SWIG_Guile_GetArgs (argv, rest, %d, %d, \"%s\");\n", 0, maxargs, proc_name); Printv(df->code,dispatch,"\n",NIL); Printf(df->code,"scm_misc_error(\"%s\", \"No matching method for generic function `%s'\", SCM_EOL);\n", proc_name, iname); Printv(df->code,"}\n",NIL); Wrapper_print(df,f_wrappers); if (use_scm_interface) { Printf(f_init, "scm_c_define_gsubr(\"%s\", 0, 0, 1, (swig_guile_proc) %s);\n", proc_name, dname); } else { Printf(f_init, "gh_new_procedure(\"%s\", (swig_guile_proc) %s, 0, 0, 1);\n", proc_name, dname); } DelWrapper(df); Delete(dispatch); Delete(dname); } } Printf (exported_symbols, "\"%s\", ", proc_name); if (!in_class || memberfunction_name) { // export wrapper into goops file String *method_def = NewString(""); String *goops_name; if (in_class) goops_name = NewString(memberfunction_name); else goops_name = goopsNameMapping(proc_name, (char *)""); String *primitive_name = NewString(""); if (primRenamer) Printv(primitive_name, "primitive:", proc_name, NIL); else Printv(primitive_name, proc_name, NIL); Replaceall(method_signature, "_", "-"); Replaceall(primitive_args, "_", "-"); if (numreq == numargs) { Printv(method_def, "(define-method (", goops_name, method_signature, ")\n", NIL); Printv(method_def, " (", primitive_name, primitive_args, "))\n", NIL); } else { /* Handle optional args. For the rest argument, use a name that cannot clash.*/ Printv(method_def, "(define-method (", goops_name, method_signature, " . %args)\n", NIL); Printv(method_def, " (apply ", primitive_name, primitive_args, " %args))\n", NIL); } if (in_class) { /* Defer method definition till end of class definition. */ Printv(goops_class_methods, method_def, NIL); } else { Printv(goopscode, method_def, NIL); } Printf(goopsexport, "%s ", goops_name); Delete(primitive_name); Delete(goops_name); Delete(method_def); } if (procdoc) { String *returns_text = NewString(""); if (num_results == 0) Printv(returns_text, return_nothing_doc, NIL); else if (num_results == 1) Printv(returns_text, return_one_doc, NIL); else Printv(returns_text, return_multi_doc, NIL); /* Substitute documentation variables */ static const char *numbers[] = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve"}; if (num_results <= 12) Replaceall(returns_text, "$num_values", numbers[num_results]); else { String *num_results_str = NewStringf("%d", num_results); Replaceall(returns_text, "$num_values", num_results_str); Delete(num_results_str); } Replaceall(returns_text, "$values", returns); Printf(doc_body, "\n%s", returns_text); write_doc(proc_name, signature, doc_body); Delete(returns_text); } Delete(proc_name); Delete(outarg); Delete(cleanup); Delete(signature); Delete(method_signature); Delete(primitive_args); Delete(doc_body); Delete(returns); Delete(tmp); Delete(scheme_arg_names); DelWrapper(f); return SWIG_OK; } /* ------------------------------------------------------------ * variableWrapper() * * Create a link to a C variable. * This creates a single function PREFIX_var_VARNAME(). * This function takes a single optional argument. If supplied, it means * we are setting this variable to some value. If omitted, it means we are * simply evaluating this variable. Either way, we return the variables * value. * ------------------------------------------------------------ */ virtual int variableWrapper(Node *n) { char *name = GetChar(n,"name"); char *iname = GetChar(n,"sym:name"); SwigType *t = Getattr(n,"type"); String *proc_name; char var_name[256]; Wrapper *f; String *tm; if (!addSymbol(iname,n)) return SWIG_ERROR; f = NewWrapper(); // evaluation function names strcpy(var_name, Char(Swig_name_wrapper(iname))); // Build the name for scheme. proc_name = NewString(iname); Replaceall(proc_name,"_", "-"); if (1 || (SwigType_type(t) != T_USER) || (is_a_pointer(t))) { Printf (f->def, "static SCM\n%s(SCM s_0)\n{\n", var_name); /* Define the scheme name in C. This define is used by several Guile macros. */ Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL); Wrapper_add_local (f, "gswig_result", "SCM gswig_result"); if (!Getattr(n,"feature:immutable")) { /* Check for a setting of the variable value */ Printf (f->code, "if (s_0 != SCM_UNDEFINED) {\n"); if ((tm = Swig_typemap_lookup_new("varin",n,name,0))) { Replaceall(tm,"$source","s_0"); Replaceall(tm,"$input","s_0"); Replaceall(tm,"$target",name); Printv(f->code,tm,"\n",NIL); } else { throw_unhandled_guile_type_error (t); } Printf (f->code, "}\n"); } // Now return the value of the variable (regardless // of evaluating or setting) if ((tm = Swig_typemap_lookup_new("varout",n,name,0))) { Replaceall(tm,"$source",name); Replaceall(tm,"$target","gswig_result"); Replaceall(tm,"$result", "gswig_result"); Printv(f->code,tm,"\n",NIL); } else { throw_unhandled_guile_type_error (t); } Printf (f->code, "\nreturn gswig_result;\n"); Printf (f->code, "#undef FUNC_NAME\n"); Printf (f->code, "}\n"); Wrapper_print (f, f_wrappers); // Now add symbol to the Guile interpreter if (!emit_setters || Getattr(n,"feature:immutable")) { /* Read-only variables become a simple procedure returning the value; read-write variables become a simple procedure with an optional argument. */ if (use_scm_interface) { Printf(f_init, "scm_c_define_gsubr(\"%s\", 0, %d, 0, (swig_guile_proc) %s);\n", proc_name, Getattr(n, "feature:immutable") ? 0 : 1, var_name); } else { Printf (f_init, "\t gh_new_procedure(\"%s\", (swig_guile_proc) %s, 0, %d, 0);\n", proc_name, var_name, Getattr(n,"feature:immutable") ? 0 : 1); } } else { /* Read/write variables become a procedure with setter. */ if (use_scm_interface) { Printf(f_init, "{ SCM p = scm_c_define_gsubr(\"%s\", 0, 1, 0, (swig_guile_proc) %s);\n", proc_name, var_name); Printf(f_init, "scm_c_define"); } else { Printf (f_init, "\t{ SCM p = gh_new_procedure(\"%s\", (swig_guile_proc) %s, 0, 1, 0);\n", proc_name, var_name); Printf(f_init, "gh_define"); } Printf (f_init, "(\"%s\", " "scm_make_procedure_with_setter(p, p)); }\n", proc_name); } Printf (exported_symbols, "\"%s\", ", proc_name); // export wrapper into goops file if (!in_class) { // only if the variable is not part of a class String *class_name = SwigType_typedef_resolve_all(SwigType_base(t)); String *goops_name = goopsNameMapping(proc_name, (char*)""); String *primitive_name = NewString(""); if (primRenamer) Printv(primitive_name, "primitive:", NIL); Printv(primitive_name, proc_name, NIL); /* Simply re-export the procedure */ Printv(goopscode, "(define ", goops_name, " ", primitive_name, ")\n", NIL); Printf(goopsexport, "%s ", goops_name); Delete(primitive_name); Delete(class_name); Delete(goops_name); } if (procdoc) { /* Compute documentation */ String *signature = NewString(""); String *signature2 = NULL; String *doc = NewString(""); if (Getattr(n,"feature:immutable")) { Printv(signature, proc_name, NIL); Printv(doc, "Returns constant ", NIL); if ((tm = Getattr(n,"tmap:varout:doc"))) { Printv(doc,tm,NIL); } else { String *s = SwigType_str(t,0); Chop(s); Printf(doc,"<%s>",s); Delete(s); } } else if (emit_setters) { Printv(signature, proc_name, NIL); signature2 = NewString(""); Printv(signature2, "set! (", proc_name, ") ", NIL); handle_documentation_typemap(signature2, NIL, n, "tmap:varin:arglist", "new-value"); Printv(doc, "Get or set the value of the C variable, \n", NIL); Printv(doc, "which is of type ", NIL); handle_documentation_typemap(doc, NIL, n, "tmap:varout:doc", "$1_type"); Printv(doc, "."); } else { Printv(signature, proc_name, " #:optional ", NIL); if ((tm = Getattr(n,"tmap:varin:doc"))) { Printv(signature,tm,NIL); } else { String *s = SwigType_str(t,0); Chop(s); Printf(signature,"new-value <%s>",s); Delete(s); } Printv(doc, "If NEW-VALUE is provided, " "set C variable to this value.\n", NIL); Printv(doc, "Returns variable value ", NIL); if ((tm = Getattr(n,"tmap:varout:doc"))) { Printv(doc,tm,NIL); } else { String *s = SwigType_str(t,0); Chop(s); Printf(doc,"<%s>",s); Delete(s); } } write_doc(proc_name, signature, doc, signature2); Delete(signature); if (signature2) Delete(signature2); Delete(doc); } } else { Swig_warning(WARN_TYPEMAP_VAR_UNDEF, input_file, line_number, "Unsupported variable type %s (ignored).\n", SwigType_str(t,0)); } Delete(proc_name); DelWrapper(f); return SWIG_OK; } /* ------------------------------------------------------------ * constantWrapper() * * We create a read-only variable. * ------------------------------------------------------------ */ virtual int constantWrapper(Node *n) { char *name = GetChar(n,"name"); char *iname = GetChar(n,"sym:name"); SwigType *type = Getattr(n,"type"); String *value = Getattr(n,"value"); String *proc_name; char var_name[256]; String *rvalue; Wrapper *f; SwigType *nctype; String *tm; f = NewWrapper(); // Make a static variable; sprintf (var_name, "%sconst_%s", prefix, iname); // Strip const qualifier from type if present nctype = NewString(type); if (SwigType_isconst(nctype)) { Delete(SwigType_pop(nctype)); } // Build the name for scheme. proc_name = NewString(iname); Replaceall(proc_name,"_", "-"); if ((SwigType_type(nctype) == T_USER) && (!is_a_pointer(nctype))) { Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n"); return SWIG_NOWRAP; } // See if there's a typemap if (SwigType_type(nctype) == T_STRING) { rvalue = NewStringf("\"%s\"", value); } else if (SwigType_type(nctype) == T_CHAR) { rvalue = NewStringf("\'%s\'", value); } else { rvalue = NewString(value); } if ((tm = Swig_typemap_lookup_new("constant",n,name,0))) { Replaceall(tm,"$source",rvalue); Replaceall(tm,"$value",rvalue); Replaceall(tm,"$target",name); Printv(f_header,tm,"\n",NIL); } else { // Create variable and assign it a value Printf (f_header, "static %s = %s;\n", SwigType_lstr(nctype,var_name), rvalue); } { /* Hack alert: will cleanup later -- Dave */ Node *n = NewHash(); Setattr(n,"name",var_name); Setattr(n,"sym:name",iname); Setattr(n,"type", nctype); Setattr(n,"feature:immutable", "1"); variableWrapper(n); Delete(n); } Delete(nctype); Delete(proc_name); Delete(rvalue); DelWrapper(f); return SWIG_OK; } /* ------------------------------------------------------------ * classDeclaration() * ------------------------------------------------------------ */ virtual int classDeclaration(Node *n) { String *class_name = NewStringf("<%s>", Getattr(n, "sym:name")); Setattr(n, "guile:goopsclassname", class_name); return Language::classDeclaration(n); } /* ------------------------------------------------------------ * classHandler() * ------------------------------------------------------------ */ virtual int classHandler(Node *n) { /* Create new strings for building up a wrapper function */ have_constructor = 0; class_name = NewString(""); short_class_name = NewString(""); Printv(class_name, "<", Getattr(n,"sym:name"), ">", NIL); Printv(short_class_name, Getattr(n,"sym:name"), NIL); Replaceall(class_name, "_", "-"); Replaceall(short_class_name, "_", "-"); if (!addSymbol(class_name,n)) return SWIG_ERROR; /* Handle inheritance */ String *base_class = NewString("<"); List *baselist = Getattr(n,"bases"); if (baselist && Len(baselist)) { Iterator i = First(baselist); while (i.item) { Printv(base_class,Getattr(i.item, "sym:name"),NIL); i = Next(i); if (i.item) { Printf(base_class, "> <"); } } } Printf(base_class, ">"); Replaceall(base_class, "_", "-"); Printv(goopscode,"(define-class ", class_name, " ", NIL); Printf(goopsexport, "%s ", class_name); if (Len(base_class) > 2) { Printv(goopscode,"(", base_class, ")\n", NIL); } else { Printv(goopscode,"()\n", NIL); } SwigType *ct = NewStringf("p.%s", Getattr(n, "name")); swigtype_ptr = SwigType_manglestr(ct); String *mangled_classname = Swig_name_mangle(Getattr(n, "sym:name")); /* Export clientdata structure */ if (use_scm_interface) { Printf(f_runtime, "static swig_guile_clientdata _swig_guile_clientdata%s = { NULL, SCM_EOL };\n", mangled_classname); Printv(f_init, "SWIG_TypeClientData(SWIGTYPE", swigtype_ptr, ", (void *) &_swig_guile_clientdata", mangled_classname, ");\n", NIL); SwigType_remember(ct); } Delete(ct); /* Emit all of the members */ goops_class_methods = NewString(""); in_class = 1; Language::classHandler(n); in_class = 0; Printv(goopscode," #:metaclass \n",NIL); if (have_constructor) Printv(goopscode," #:new-function ", primRenamer ? "primitive:" : "", "new-", short_class_name, "\n", NIL); Printf(goopscode,")\n%s\n", goops_class_methods); Delete(goops_class_methods); goops_class_methods = 0; /* export class initialization function */ if (goops) { /* export the wrapper function */ String *funcName = NewString(mangled_classname); Printf(funcName, "_swig_guile_setgoopsclass"); String *guileFuncName = NewString(funcName); Replaceall(guileFuncName, "_", "-"); Printv(f_wrappers, "static SCM ", funcName, "(SCM cl) \n", NIL); Printf(f_wrappers, "#define FUNC_NAME %s\n{\n", guileFuncName); Printv(f_wrappers, " ((swig_guile_clientdata *)(SWIGTYPE", swigtype_ptr, "->clientdata))->goops_class = cl;\n", NIL); Printf(f_wrappers, " return SCM_UNSPECIFIED;\n"); Printf(f_wrappers, "}\n#undef FUNC_NAME\n\n"); Printf(f_init, "scm_c_define_gsubr(\"%s\", 1, 0, 0, (swig_guile_proc) %s);\n", guileFuncName, funcName); Printf(exported_symbols, "\"%s\", ", guileFuncName); /* export the call to the wrapper function */ Printf(goopscode, "(%s%s %s)\n\n", primRenamer ? "primitive:" : "", guileFuncName, class_name); Delete(guileFuncName); Delete(funcName); } Delete(mangled_classname); Delete(swigtype_ptr); swigtype_ptr = 0; Delete(class_name); Delete(short_class_name); class_name = 0; short_class_name = 0; return SWIG_OK; } /* ------------------------------------------------------------ * memberfunctionHandler() * ------------------------------------------------------------ */ int memberfunctionHandler(Node *n) { String *iname = Getattr(n,"sym:name"); String *proc = NewString(iname); Replaceall(proc,"_", "-"); memberfunction_name = goopsNameMapping(proc, short_class_name); Language::memberfunctionHandler(n); Delete(memberfunction_name); memberfunction_name = NULL; Delete(proc); return SWIG_OK; } /* ------------------------------------------------------------ * membervariableHandler() * ------------------------------------------------------------ */ int membervariableHandler(Node *n) { String *iname = Getattr(n,"sym:name"); if (emit_setters) { struct_member = 1; Printf(f_init, "{\n"); } Language::membervariableHandler(n); if (emit_setters) { Printf(f_init, "}\n"); struct_member = 0; } String *proc = NewString(iname); Replaceall(proc,"_", "-"); String *goops_name = goopsNameMapping(proc, short_class_name); /* The slot name is never qualified with the class, even if useclassprefix is true. */ Printv(goopscode, " (", proc, " #:allocation #:virtual", NIL); /* GOOPS (at least in Guile 1.6.3) only accepts closures, not primitive procedures for slot-ref and slot-set. */ Printv(goopscode, "\n #:slot-ref (lambda (obj) (", primRenamer ? "primitive:" : "", short_class_name, "-", proc, "-get", " obj))", NIL); if (!Getattr(n,"feature:immutable")) { Printv(goopscode, "\n #:slot-set! (lambda (obj value) (", primRenamer ? "primitive:" : "", short_class_name, "-", proc, "-set", " obj value))", NIL); } else { Printf(goopscode, "\n #:slot-set! (lambda (obj value) (error \"Immutable slot\"))"); } if (emit_slot_accessors) { if (Getattr(n, "feature:immutable")) { Printv(goopscode, "\n #:getter ", goops_name, NIL); } else { Printv(goopscode, "\n #:accessor ", goops_name, NIL); } Printf(goopsexport, "%s ", goops_name); } Printv(goopscode, ")\n", NIL); Delete(proc); Delete(goops_name); return SWIG_OK; } /* ------------------------------------------------------------ * constructorHandler() * ------------------------------------------------------------ */ int constructorHandler(Node *n) { Language::constructorHandler(n); have_constructor = 1; return SWIG_OK; } /* ------------------------------------------------------------ * destructorHandler() * ------------------------------------------------------------ */ virtual int destructorHandler(Node *n) { exporting_destructor = true; Language::destructorHandler(n); exporting_destructor = false; return SWIG_OK; } /* ------------------------------------------------------------ * pragmaDirective() * ------------------------------------------------------------ */ virtual int pragmaDirective(Node *n) { if (!ImportMode) { String *lang = Getattr(n,"lang"); String *cmd = Getattr(n,"name"); String *value = Getattr(n,"value"); # define store_pragma(PRAGMANAME) \ if (Strcmp(cmd, #PRAGMANAME) == 0) { \ if (PRAGMANAME) Delete(PRAGMANAME); \ PRAGMANAME = value ? NewString(value) : NULL; \ } if (Strcmp(lang,"guile") == 0) { store_pragma(beforereturn) store_pragma(return_nothing_doc) store_pragma(return_one_doc) store_pragma(return_multi_doc); # undef store_pragma } } return Language::pragmaDirective(n); } /* ------------------------------------------------------------ * goopsNameMapping() * Maps the identifier from C++ to the GOOPS based * on command * line paramaters and such. * If class_name = "" that means the mapping is for a function or * variable not attached to any class. * ------------------------------------------------------------ */ String *goopsNameMapping(String *name, String_or_char *class_name) { String *n = NewString(""); if (Strcmp(class_name, "") == 0) { // not part of a class, so no class name to prefix if (goopsprefix) { Printf(n, "%s%s", goopsprefix, name); } else { Printf(n, "%s", name); } } else { if (useclassprefix) { Printf(n, "%s-%s", class_name, name); } else { if (goopsprefix) { Printf(n, "%s%s", goopsprefix, name); } else { Printf(n, "%s", name); } } } return n; } /* ------------------------------------------------------------ * validIdentifier() * ------------------------------------------------------------ */ virtual int validIdentifier(String *s) { char *c = Char(s); /* Check whether we have an R5RS identifier. Guile supports a superset of R5RS identifiers, but it's probably a bad idea to use those. */ /* --> * | */ /* --> | */ if (!(isalpha(*c) || (*c == '!') || (*c == '$') || (*c == '%') || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':') || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?') || (*c == '^') || (*c == '_') || (*c == '~'))) { /* --> + | - | ... */ if ((strcmp(c, "+") == 0) || strcmp(c, "-") == 0 || strcmp(c, "...") == 0) return 1; else return 0; } /* --> | | */ while (*c) { if (!(isalnum(*c) || (*c == '!') || (*c == '$') || (*c == '%') || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':') || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?') || (*c == '^') || (*c == '_') || (*c == '~') || (*c == '+') || (*c == '-') || (*c == '.') || (*c == '@'))) return 0; c++; } return 1; } }; /* ----------------------------------------------------------------------------- * swig_guile() - Instantiate module * ----------------------------------------------------------------------------- */ static Language * new_swig_guile() { return new GUILE(); } extern "C" Language * swig_guile(void) { return new_swig_guile(); } cableswig-0.1.0+git20150808.orig/SWIG/Source/Modules/perl5.cxx0000644000175000000620000012552112561312227022227 0ustar stevestaff/* ---------------------------------------------------------------------------- * perl5.cxx * * Generate Perl5 wrappers * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * Loic Dachary (loic@ceic.com) * David Fletcher * Gary Holt * Jason Stewart (jason@openinformatics.com) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ------------------------------------------------------------------------- */ char cvsroot_perl5_cxx[] = "/cvsroot/SWIG/Source/Modules/perl5.cxx,v 1.10 2004/01/22 22:42:16 cheetah Exp"; #include "swigmod.h" static const char *usage = (char*)"\ Perl5 Options (available with -perl5)\n\ -ldflags - Print runtime libraries to link with\n\ -static - Omit code related to dynamic loading\n\ -nopm - Do not generate the .pm file\n\ -proxy - Create proxy classes\n\ -noproxy - Don't create proxy classes\n\ -const - Wrap constants as constants and not variables (implies -proxy)\n\ -compat - Compatibility mode\n\n"; static int compat = 0; static int no_pmfile = 0; static int export_all = 0; /* * pmfile * set by the -pm flag, overrides the name of the .pm file */ static String *pmfile = 0; /* * module * set by the %module directive, e.g. "Xerces". It will determine * the name of the .pm file, and the dynamic library. */ static String *module = 0; /* * fullmodule * the fully namespace qualified name of the module, e.g. "XML::Xerces" * it will be used to set the package namespace in the .pm file, as * well as the name of the initialization methods in the glue library */ static String *fullmodule = 0; /* * cmodule * the namespace of the internal glue code, set to the value of * module with a 'c' appended */ static String *cmodule = 0; static String *command_tab = 0; static String *constant_tab = 0; static String *variable_tab = 0; static File *f_runtime = 0; static File *f_header = 0; static File *f_wrappers = 0; static File *f_init = 0; static File *f_pm = 0; static String *pm; /* Package initialization code */ static String *magic; /* Magic variable wrappers */ static int is_static = 0; /* The following variables are used to manage Perl5 classes */ static int blessed = 1; /* Enable object oriented features */ static int do_constants = 0; /* Constant wrapping */ static List *classlist = 0; /* List of classes */ static int have_constructor = 0; static int have_destructor= 0; static int have_data_members = 0; static String *class_name = 0; /* Name of the class (what Perl thinks it is) */ static String *real_classname = 0; /* Real name of C/C++ class */ static String *fullclassname = 0; static String *pcode = 0; /* Perl code associated with each class */ /* static String *blessedmembers = 0; */ /* Member data associated with each class */ static int member_func = 0; /* Set to 1 when wrapping a member function */ static String *func_stubs = 0; /* Function stubs */ static String *const_stubs = 0; /* Constant stubs */ static int num_consts = 0; /* Number of constants */ static String *var_stubs = 0; /* Variable stubs */ static String *exported = 0; /* Exported symbols */ static String *pragma_include = 0; static Hash *operators = 0; static int have_operators = 0; class PERL5 : public Language { public: /* Test to see if a type corresponds to something wrapped with a shadow class */ Node *is_shadow(SwigType *t) { Node *n; n = classLookup(t); /* Printf(stdout,"'%s' --> '%x'\n", t, n); */ if (n) { if (!Getattr(n,"perl5:proxy")) { setclassname(n); } return Getattr(n,"perl5:proxy"); } return 0; } /* ------------------------------------------------------------ * main() * ------------------------------------------------------------ */ virtual void main(int argc, char *argv[]) { int i = 1; SWIG_library_directory("perl5"); for (i = 1; i < argc; i++) { if (argv[i]) { if(strcmp(argv[i],"-package") == 0) { Printf(stderr,"*** -package is no longer supported\n*** use the directive '%module A::B::C' in your interface file instead\n*** see the Perl section in the manual for details.\n"); SWIG_exit(EXIT_FAILURE); } else if(strcmp(argv[i],"-interface") == 0) { Printf(stderr,"*** -interface is no longer supported\n*** use the directive '%module A::B::C' in your interface file instead\n*** see the Perl section in the manual for details.\n"); SWIG_exit(EXIT_FAILURE); } else if (strcmp(argv[i],"-exportall") == 0) { export_all = 1; Swig_mark_arg(i); } else if (strcmp(argv[i],"-static") == 0) { is_static = 1; Swig_mark_arg(i); } else if ((strcmp(argv[i],"-shadow") == 0) || ((strcmp(argv[i],"-proxy") == 0))) { blessed = 1; Swig_mark_arg(i); } else if ((strcmp(argv[i],"-noproxy") == 0)) { blessed =0; Swig_mark_arg(i); } else if (strcmp(argv[i],"-const") == 0) { do_constants = 1; blessed = 1; Swig_mark_arg(i); } else if (strcmp(argv[i],"-nopm") == 0) { no_pmfile = 1; Swig_mark_arg(i); } else if (strcmp(argv[i],"-pm") == 0) { Swig_mark_arg(i); i++; pmfile = NewString(argv[i]); Swig_mark_arg(i); } else if (strcmp(argv[i],"-compat") == 0) { compat = 1; Swig_mark_arg(i); } else if (strcmp(argv[i],"-help") == 0) { fputs(usage,stderr); } else if (strcmp (argv[i], "-ldflags") == 0) { printf("%s\n", SWIG_PERL_RUNTIME); SWIG_exit (EXIT_SUCCESS); } } } Preprocessor_define("SWIGPERL 1", 0); Preprocessor_define("SWIGPERL5 1", 0); SWIG_typemap_lang("perl5"); SWIG_config_file("perl5.swg"); allow_overloading(); } /* ------------------------------------------------------------ * top() * ------------------------------------------------------------ */ virtual int top(Node *n) { /* Initialize all of the output files */ String *outfile = Getattr(n,"outfile"); f_runtime = NewFile(outfile,"w"); if (!f_runtime) { Printf(stderr,"*** Can't open '%s'\n", outfile); SWIG_exit(EXIT_FAILURE); } f_init = NewString(""); f_header = NewString(""); f_wrappers = NewString(""); /* Register file targets with the SWIG file handler */ Swig_register_filebyname("header",f_header); Swig_register_filebyname("wrapper",f_wrappers); Swig_register_filebyname("runtime",f_runtime); Swig_register_filebyname("init",f_init); classlist = NewList(); pm = NewString(""); func_stubs = NewString(""); var_stubs = NewString(""); const_stubs = NewString(""); exported = NewString(""); magic = NewString(""); pragma_include = NewString(""); command_tab = NewString("static swig_command_info swig_commands[] = {\n"); constant_tab = NewString("static swig_constant_info swig_constants[] = {\n"); variable_tab = NewString("static swig_variable_info swig_variables[] = {\n"); Swig_banner(f_runtime); if (NoInclude) { Printf(f_runtime,"#define SWIG_NOINCLUDE\n"); } module = Copy(Getattr(n,"name")); /* If we're in blessed mode, change the package name to "packagec" */ if (blessed) { cmodule = NewStringf("%sc",module); } else { cmodule = NewString(module); } fullmodule = NewString(module); /* Create a .pm file * Need to strip off any prefixes that might be found in * the module name */ if (no_pmfile) { f_pm = NewString(0); } else { if (pmfile == NULL) { char *m = Char(module) + Len(module); while (m != Char(module)) { if (*m == ':') { m++; break; } m--; } pmfile = NewStringf("%s.pm", m); } String *filen = NewStringf("%s%s", SWIG_output_directory(),pmfile); if ((f_pm = NewFile(filen,"w")) == 0) { Printf(stderr,"Unable to open %s\n", filen); SWIG_exit (EXIT_FAILURE); } Delete(filen); filen = NULL; Swig_register_filebyname("pm",f_pm); } { String *tmp = NewString(fullmodule); Replaceall(tmp,":","_"); Printf(f_header,"#define SWIG_init boot_%s\n\n", tmp); Printf(f_header,"#define SWIG_name \"%s::boot_%s\"\n", cmodule, tmp); Printf(f_header,"#define SWIG_prefix \"%s::\"\n", cmodule); Delete(tmp); } Printf(f_pm,"# This file was automatically generated by SWIG\n"); Printf(f_pm,"package %s;\n",fullmodule); Printf(f_pm,"require Exporter;\n"); if (!is_static) { Printf(f_pm,"require DynaLoader;\n"); Printf(f_pm,"@ISA = qw(Exporter DynaLoader);\n"); } else { Printf(f_pm,"@ISA = qw(Exporter);\n"); } /* Start creating magic code */ Printv(magic, "#ifdef PERL_OBJECT\n", "#define MAGIC_CLASS _wrap_", module, "_var::\n", "class _wrap_", module, "_var : public CPerlObj {\n", "public:\n", "#else\n", "#define MAGIC_CLASS\n", "#endif\n", "SWIGCLASS_STATIC int swig_magic_readonly(pTHX_ SV *sv, MAGIC *mg) {\n", tab4, "MAGIC_PPERL\n", tab4, "sv = sv; mg = mg;\n", tab4, "croak(\"Value is read-only.\");\n", tab4, "return 0;\n", "}\n", NIL); Printf(f_wrappers,"#ifdef __cplusplus\nextern \"C\" {\n#endif\n"); /* emit wrappers */ Language::top(n); String *base = NewString(""); /* Dump out variable wrappers */ Printv(magic, "\n\n#ifdef PERL_OBJECT\n", "};\n", "#endif\n", NIL); Printf(f_header,"%s\n", magic); String *type_table = NewString(""); SwigType_emit_type_table(f_runtime,type_table); /* Patch the type table to reflect the names used by shadow classes */ if (blessed) { Iterator cls; for (cls = First(classlist); cls.item; cls = Next(cls)) { if (Getattr(cls.item,"perl5:proxy")) { SwigType *type = Copy(Getattr(cls.item,"classtype")); if (!type) continue; /* If unnamed class, no type will be found */ SwigType_add_pointer(type); String *mangle = NewStringf("\"%s\"", SwigType_manglestr(type)); String *rep = NewStringf("\"%s\"", Getattr(cls.item,"perl5:proxy")); Replaceall(type_table,mangle,rep); Delete(mangle); Delete(rep); Delete(type); } } } Printf(f_wrappers,"%s",type_table); Delete(type_table); Printf(constant_tab,"{0}\n};\n"); Printv(f_wrappers,constant_tab,NIL); Printf(f_wrappers,"#ifdef __cplusplus\n}\n#endif\n"); Printf(f_init,"\t ST(0) = &PL_sv_yes;\n"); Printf(f_init,"\t XSRETURN(1);\n"); Printf(f_init,"}\n"); /* Finish off tables */ Printf(variable_tab, "{0}\n};\n"); Printv(f_wrappers,variable_tab,NIL); Printf(command_tab,"{0,0}\n};\n"); Printv(f_wrappers,command_tab,NIL); Printf(f_pm,"package %s;\n", cmodule); if (!is_static) { Printf(f_pm,"bootstrap %s;\n", fullmodule); } else { String *tmp = NewString(fullmodule); Replaceall(tmp,":","_"); Printf(f_pm,"boot_%s();\n", tmp); Delete(tmp); } Printf(f_pm,"%s",pragma_include); Printf(f_pm,"package %s;\n", fullmodule); Printf(f_pm,"@EXPORT = qw( %s);\n",exported); if (blessed) { Printv(base, "\n# ---------- BASE METHODS -------------\n\n", "package ", fullmodule, ";\n\n", NIL); /* Write out the TIE method */ Printv(base, "sub TIEHASH {\n", tab4, "my ($classname,$obj) = @_;\n", tab4, "return bless $obj, $classname;\n", "}\n\n", NIL); /* Output a CLEAR method. This is just a place-holder, but by providing it we * can make declarations such as * %$u = ( x => 2, y=>3, z =>4 ); * * Where x,y,z are the members of some C/C++ object. */ Printf(base,"sub CLEAR { }\n\n"); /* Output default firstkey/nextkey methods */ Printf(base, "sub FIRSTKEY { }\n\n"); Printf(base, "sub NEXTKEY { }\n\n"); /* Output a FETCH method. This is actually common to all classes */ Printv(base, "sub FETCH {\n", tab4, "my ($self,$field) = @_;\n", tab4, "my $member_func = \"swig_${field}_get\";\n", tab4, "$self->$member_func();\n", "}\n\n", NIL); /* Output a STORE method. This is also common to all classes (might move to base class) */ Printv(base, "sub STORE {\n", tab4, "my ($self,$field,$newval) = @_;\n", tab4, "my $member_func = \"swig_${field}_set\";\n", tab4, "$self->$member_func($newval);\n", "}\n\n", NIL); /* Output a 'this' method */ Printv(base, "sub this {\n", tab4, "my $ptr = shift;\n", tab4, "return tied(%$ptr);\n", "}\n\n", NIL); Printf(f_pm,"%s",base); /* Emit function stubs for stand-alone functions */ Printf(f_pm,"\n# ------- FUNCTION WRAPPERS --------\n\n"); Printf(f_pm,"package %s;\n\n",fullmodule); Printf(f_pm,"%s",func_stubs); /* Emit package code for different classes */ Printf(f_pm,"%s",pm); if (num_consts > 0) { /* Emit constant stubs */ Printf(f_pm,"\n# ------- CONSTANT STUBS -------\n\n"); Printf(f_pm,"package %s;\n\n",fullmodule); Printf(f_pm,"%s",const_stubs); } /* Emit variable stubs */ Printf(f_pm,"\n# ------- VARIABLE STUBS --------\n\n"); Printf(f_pm,"package %s;\n\n",fullmodule); Printf(f_pm,"%s",var_stubs); } Printf(f_pm,"1;\n"); Close(f_pm); Delete(f_pm); Delete(base); /* Close all of the files */ Dump(f_header,f_runtime); Dump(f_wrappers,f_runtime); Wrapper_pretty_print(f_init,f_runtime); Delete(f_header); Delete(f_wrappers); Delete(f_init); Close(f_runtime); Delete(f_runtime); return SWIG_OK; } /* ------------------------------------------------------------ * importDirective(Node *n) * ------------------------------------------------------------ */ virtual int importDirective(Node *n) { if (blessed) { String *modname = Getattr(n,"module"); if (modname) { Printf(f_pm,"require %s;\n", modname); } } return Language::importDirective(n); } /* ------------------------------------------------------------ * functionWrapper() * ------------------------------------------------------------ */ virtual int functionWrapper(Node *n) { String *name = Getattr(n,"name"); String *iname = Getattr(n,"sym:name"); SwigType *d = Getattr(n,"type"); ParmList *l = Getattr(n,"parms"); String *overname = 0; Parm *p; int i; Wrapper *f; char source[256],target[256],temp[256]; String *tm; String *cleanup, *outarg; int num_saved = 0; int num_arguments, num_required; int varargs = 0; if (Getattr(n,"sym:overloaded")) { overname = Getattr(n,"sym:overname"); } else { if (!addSymbol(iname,n)) return SWIG_ERROR; } f = NewWrapper(); cleanup = NewString(""); outarg = NewString(""); String *wname = Swig_name_wrapper(iname); if (overname) { Append(wname,overname); } Setattr(n,"wrap:name",wname); Printv(f->def, "XS(", wname, ") {\n", "{\n", /* scope to destroy C++ objects before croaking */ NIL ); emit_args(d, l, f); emit_attach_parmmaps(l,f); Setattr(n,"wrap:parms",l); num_arguments = emit_num_arguments(l); num_required = emit_num_required(l); varargs = emit_isvarargs(l); Wrapper_add_local(f,"argvi","int argvi = 0"); /* Check the number of arguments */ if (!varargs) { Printf(f->code," if ((items < %d) || (items > %d)) {\n", num_required, num_arguments); } else { Printf(f->code," if (items < %d) {\n", num_required); } Printf(f->code," SWIG_croak(\"Usage: %s\");\n", usage_func(Char(iname),d,l)); Printf(f->code,"}\n"); /* Write code to extract parameters. */ i = 0; for (i = 0, p = l; i < num_arguments; i++) { /* Skip ignored arguments */ while (checkAttribute(p,"tmap:in:numinputs","0")) { p = Getattr(p,"tmap:in:next"); } SwigType *pt = Getattr(p,"type"); String *ln = Getattr(p,"lname"); /* Produce string representation of source and target arguments */ sprintf(source,"ST(%d)",i); sprintf(target,"%s", Char(ln)); if (i >= num_required) { Printf(f->code," if (items > %d) {\n", i); } if ((tm = Getattr(p,"tmap:in"))) { Replaceall(tm,"$target",target); Replaceall(tm,"$source",source); Replaceall(tm,"$input", source); Setattr(p,"emit:input",source); /* Save input location */ Printf(f->code,"%s\n",tm); p = Getattr(p,"tmap:in:next"); } else { Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n",SwigType_str(pt,0)); p = nextSibling(p); } if (i >= num_required) { Printf(f->code," }\n"); } } if (varargs) { if (p && (tm = Getattr(p,"tmap:in"))) { sprintf(source,"ST(%d)",i); Replaceall(tm,"$input", source); Setattr(p,"emit:input", source); Printf(f->code,"if (items >= %d) {\n", i); Printv(f->code, tm, "\n", NIL); Printf(f->code,"}\n"); } } /* Insert constraint checking code */ for (p = l; p;) { if ((tm = Getattr(p,"tmap:check"))) { Replaceall(tm,"$target",Getattr(p,"lname")); Printv(f->code,tm,"\n",NIL); p = Getattr(p,"tmap:check:next"); } else { p = nextSibling(p); } } /* Insert cleanup code */ for (i = 0, p = l; p; i++) { if ((tm = Getattr(p,"tmap:freearg"))) { Replaceall(tm,"$source",Getattr(p,"lname")); Replaceall(tm,"$arg",Getattr(p,"emit:input")); Replaceall(tm,"$input",Getattr(p,"emit:input")); Printv(cleanup,tm,"\n",NIL); p = Getattr(p,"tmap:freearg:next"); } else { p = nextSibling(p); } } /* Insert argument output code */ num_saved = 0; for (i=0,p = l; p;i++) { if ((tm = Getattr(p,"tmap:argout"))) { Replaceall(tm,"$source",Getattr(p,"lname")); Replaceall(tm,"$target","ST(argvi)"); Replaceall(tm,"$result","ST(argvi)"); String *in = Getattr(p,"emit:input"); if (in) { sprintf(temp,"_saved[%d]", num_saved); Replaceall(tm,"$arg",temp); Replaceall(tm,"$input",temp); Printf(f->code,"_saved[%d] = %s;\n", num_saved, in); num_saved++; } Printv(outarg,tm,"\n",NIL); p = Getattr(p,"tmap:argout:next"); } else { p = nextSibling(p); } } /* If there were any saved arguments, emit a local variable for them */ if (num_saved) { sprintf(temp,"_saved[%d]",num_saved); Wrapper_add_localv(f,"_saved","SV *",temp,NIL); } /* Now write code to make the function call */ emit_action(n,f); if ((tm = Swig_typemap_lookup_new("out",n,"result",0))) { SwigType *t = Getattr(n,"type"); Replaceall(tm,"$source","result"); Replaceall(tm,"$target","ST(argvi)"); Replaceall(tm,"$result", "ST(argvi)"); if (is_shadow(t)) { Replaceall(tm, "$shadow", "SWIG_SHADOW"); } else { Replaceall(tm, "$shadow", "0"); } if ((!SwigType_ispointer(t) && !SwigType_isreference(t)) || Getattr(n,"feature:new")) { Replaceall(tm,"$owner","SWIG_OWNER"); } else { Replaceall(tm,"$owner","0"); } Printf(f->code, "%s\n", tm); } else { Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d,0), name); } /* If there were any output args, take care of them. */ Printv(f->code,outarg,NIL); /* If there was any cleanup, do that. */ Printv(f->code,cleanup,NIL); if (Getattr(n,"feature:new")) { if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) { Replaceall(tm,"$source","result"); Printf(f->code,"%s\n",tm); } } if ((tm = Swig_typemap_lookup_new("ret",n,"result", 0))) { Replaceall(tm,"$source","result"); Printf(f->code,"%s\n", tm); } Printv(f->code, "XSRETURN(argvi);\n", "fail:\n", cleanup, ";\n", /* empty statement */ "}\n", "croak(Nullch);\n" "}\n", NIL); /* Add the dXSARGS last */ Wrapper_add_local(f,"dXSARGS","dXSARGS"); /* Substitute the cleanup code */ Replaceall(f->code,"$cleanup",cleanup); Replaceall(f->code,"$symname",iname); /* Dump the wrapper function */ Wrapper_print(f,f_wrappers); /* Now register the function */ if (!Getattr(n,"sym:overloaded")) { Printf(command_tab,"{\"%s::%s\", %s},\n", cmodule, iname, wname); } else if (!Getattr(n,"sym:nextSibling")) { /* Generate overloaded dispatch function */ int maxargs, ii; String *dispatch = Swig_overload_dispatch(n,"(*PL_markstack_ptr++);SWIG_CALLXS(%s); return;",&maxargs); /* Generate a dispatch wrapper for all overloaded functions */ Wrapper *df = NewWrapper(); String *dname = Swig_name_wrapper(iname); Printv(df->def, "XS(", dname, ") {\n", NIL); Wrapper_add_local(df,"dXSARGS", "dXSARGS"); Replaceid(dispatch,"argc","items"); for (ii = 0; ii < maxargs; ii++) { char pat[128]; char rep[128]; sprintf(pat,"argv[%d]",ii); sprintf(rep,"ST(%d)",ii); Replaceall(dispatch,pat,rep); } Printv(df->code,dispatch,"\n",NIL); Printf(df->code,"croak(\"No matching function for overloaded '%s'\");\n", iname); Printf(df->code,"XSRETURN(0);\n"); Printv(df->code,"}\n",NIL); Wrapper_print(df,f_wrappers); Printf(command_tab,"{\"%s::%s\", %s},\n", cmodule, iname, dname); DelWrapper(df); Delete(dispatch); Delete(dname); } if (!Getattr(n,"sym:nextSibling")) { if (export_all) { Printf(exported,"%s ", iname); } /* -------------------------------------------------------------------- * Create a stub for this function, provided it's not a member function * -------------------------------------------------------------------- */ if ((blessed) && (!member_func)) { Printv(func_stubs,"*", iname, " = *", cmodule, "::", iname, ";\n", NIL); } } Delete(cleanup); Delete(outarg); DelWrapper(f); return SWIG_OK; } /* ------------------------------------------------------------ * variableWrapper() * ------------------------------------------------------------ */ virtual int variableWrapper(Node *n) { String *name = Getattr(n,"name"); String *iname = Getattr(n,"sym:name"); SwigType *t = Getattr(n,"type"); Wrapper *getf, *setf; String *tm; String *set_name = NewStringf("_wrap_set_%s", iname); String *val_name = NewStringf("_wrap_val_%s", iname); if (!addSymbol(iname,n)) return SWIG_ERROR; getf = NewWrapper(); setf = NewWrapper(); /* Create a Perl function for setting the variable value */ if (!Getattr(n,"feature:immutable")) { Printf(setf->def,"SWIGCLASS_STATIC int %s(pTHX_ SV* sv, MAGIC *mg) {\n", set_name); Printv(setf->code, tab4, "MAGIC_PPERL\n", tab4, "mg = mg;\n", NIL); /* Check for a few typemaps */ tm = Swig_typemap_lookup_new("varin",n,name,0); if (tm) { Replaceall(tm,"$source","sv"); Replaceall(tm,"$target",name); Replaceall(tm,"$input","sv"); Printf(setf->code,"%s\n", tm); } else { Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t,0)); return SWIG_NOWRAP; } Printf(setf->code," return 1;\n}\n"); Replaceall(setf->code,"$symname",iname); Wrapper_print(setf,magic); } /* Now write a function to evaluate the variable */ Printf(getf->def,"SWIGCLASS_STATIC int %s(pTHX_ SV *sv, MAGIC *mg) {\n", val_name); Printv(getf->code, tab4, "MAGIC_PPERL\n", tab4, "mg = mg;\n", NIL); if ((tm = Swig_typemap_lookup_new("varout",n,name,0))) { Replaceall(tm,"$target","sv"); Replaceall(tm,"$result","sv"); Replaceall(tm,"$source",name); Printf(getf->code,"%s\n", tm); } else { Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t,0)); return SWIG_NOWRAP; } Printf(getf->code," return 1;\n}\n"); Replaceall(getf->code,"$symname",iname); Wrapper_print(getf,magic); String *tt = Getattr(n,"tmap:varout:type"); if (tt) { String *tm = NewStringf("&SWIGTYPE%s", SwigType_manglestr(t)); if (Replaceall(tt,"$1_descriptor", tm)) { SwigType_remember(t); } Delete(tm); SwigType *st = Copy(t); SwigType_add_pointer(st); tm = NewStringf("&SWIGTYPE%s", SwigType_manglestr(st)); if (Replaceall(tt,"$&1_descriptor", tm)) { SwigType_remember(st); } Delete(tm); Delete(st); } else { tt = (String *) "0"; } /* Now add symbol to the PERL interpreter */ if (Getattr(n,"feature:immutable")) { Printv(variable_tab, tab4, "{ \"", cmodule, "::", iname, "\", MAGIC_CLASS swig_magic_readonly, MAGIC_CLASS ", val_name,",", tt, " },\n",NIL); } else { Printv(variable_tab, tab4, "{ \"", cmodule, "::", iname, "\", MAGIC_CLASS ", set_name, ", MAGIC_CLASS ", val_name, ",", tt, " },\n",NIL); } /* If we're blessed, try to figure out what to do with the variable 1. If it's a Perl object of some sort, create a tied-hash around it. 2. Otherwise, just hack Perl's symbol table */ if (blessed) { if (is_shadow(t)) { Printv(var_stubs, "\nmy %__", iname, "_hash;\n", "tie %__", iname, "_hash,\"", is_shadow(t), "\", $", cmodule, "::", iname, ";\n", "$", iname, "= \\%__", iname, "_hash;\n", "bless $", iname, ", ", is_shadow(t), ";\n", NIL); } else { Printv(var_stubs, "*", iname, " = *", cmodule, "::", iname, ";\n", NIL); } } if (export_all) Printf(exported,"$%s ", iname); DelWrapper(setf); DelWrapper(getf); Delete(set_name); Delete(val_name); return SWIG_OK; } /* ------------------------------------------------------------ * constantWrapper() * ------------------------------------------------------------ */ virtual int constantWrapper(Node *n) { String *name = Getattr(n,"name"); String *iname = Getattr(n,"sym:name"); SwigType *type = Getattr(n,"type"); String *value = Getattr(n,"value"); String *tm; if (!addSymbol(iname,n)) return SWIG_ERROR; /* Special hook for member pointer */ if (SwigType_type(type) == T_MPOINTER) { String *wname = Swig_name_wrapper(iname); Printf(f_wrappers, "static %s = %s;\n", SwigType_str(type,wname), value); value = Char(wname); } if ((tm = Swig_typemap_lookup_new("consttab",n,name,0))) { Replaceall(tm,"$source",value); Replaceall(tm,"$target",name); Replaceall(tm,"$value",value); Printf(constant_tab,"%s,\n", tm); } else if ((tm = Swig_typemap_lookup_new("constcode", n, name, 0))) { Replaceall(tm,"$source", value); Replaceall(tm,"$target", name); Replaceall(tm,"$value",value); Printf(f_init, "%s\n", tm); } else { Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n"); return SWIG_NOWRAP; } if (blessed) { if (is_shadow(type)) { Printv(var_stubs, "\nmy %__", iname, "_hash;\n", "tie %__", iname, "_hash,\"", is_shadow(type), "\", $", cmodule, "::", iname, ";\n", "$", iname, "= \\%__", iname, "_hash;\n", "bless $", iname, ", ", is_shadow(type), ";\n", NIL); } else if (do_constants) { Printv(const_stubs,"sub ", name, " () { $", cmodule, "::", name, " }\n", NIL); num_consts++; } else { Printv(var_stubs, "*",iname," = *", cmodule, "::", iname, ";\n", NIL); } } if (export_all) { if (do_constants && !is_shadow(type)) { Printf(exported,"%s ",name); } else { Printf(exported,"$%s ",iname); } } return SWIG_OK; } /* ------------------------------------------------------------ * usage_func() * ------------------------------------------------------------ */ char *usage_func(char *iname, SwigType *, ParmList *l) { static String *temp = 0; Parm *p; int i; if (!temp) temp = NewString(""); Clear(temp); Printf(temp,"%s(",iname); /* Now go through and print parameters */ p = l; i = 0; while (p != 0) { SwigType *pt = Getattr(p,"type"); String *pn = Getattr(p,"name"); if (!Getattr(p,"ignore")) { /* If parameter has been named, use that. Otherwise, just print a type */ if (SwigType_type(pt) != T_VOID) { if (Len(pn) > 0) { Printf(temp,"%s",pn); } else { Printf(temp,"%s",SwigType_str(pt,0)); } } i++; p = nextSibling(p); if (p) if (!Getattr(p,"ignore")) Putc(',',temp); } else { p = nextSibling(p); if (p) if ((i>0) && (!Getattr(p,"ignore"))) Putc(',',temp); } } Printf(temp,");"); return Char(temp); } /* ------------------------------------------------------------ * nativeWrapper() * ------------------------------------------------------------ */ virtual int nativeWrapper(Node *n) { String *name = Getattr(n,"sym:name"); String *funcname = Getattr(n,"wrap:name"); if (!addSymbol(funcname,n)) return SWIG_ERROR; Printf(command_tab,"{\"%s::%s\", %s},\n", cmodule,name,funcname); if (export_all) Printf(exported,"%s ",name); if (blessed) { Printv(func_stubs,"*", name, " = *", cmodule, "::", name, ";\n", NIL); } return SWIG_OK; } /**************************************************************************** *** OBJECT-ORIENTED FEATURES **************************************************************************** *** These extensions provide a more object-oriented interface to C++ *** classes and structures. The code here is based on extensions *** provided by David Fletcher and Gary Holt. *** *** I have generalized these extensions to make them more general purpose *** and to resolve object-ownership problems. *** *** The approach here is very similar to the Python module : *** 1. All of the original methods are placed into a single *** package like before except that a 'c' is appended to the *** package name. *** *** 2. All methods and function calls are wrapped with a new *** perl function. While possibly inefficient this allows *** us to catch complex function arguments (which are hard to *** track otherwise). *** *** 3. Classes are represented as tied-hashes in a manner similar *** to Gary Holt's extension. This allows us to access *** member data. *** *** 4. Stand-alone (global) C functions are modified to take *** tied hashes as arguments for complex datatypes (if *** appropriate). *** *** 5. Global variables involving a class/struct is encapsulated *** in a tied hash. *** ****************************************************************************/ void setclassname(Node *n) { String *symname = Getattr(n,"sym:name"); String *fullname; String *actualpackage; Node *clsmodule = Getattr(n,"module"); if (!clsmodule) { /* imported module does not define a module name. Oh well */ return; } /* Do some work on the class name */ actualpackage = Getattr(clsmodule,"name"); if ((!compat) && (!Strchr(symname,':'))) { fullname = NewStringf("%s::%s",actualpackage,symname); } else { fullname = NewString(symname); } Setattr(n,"perl5:proxy", fullname); } /* ------------------------------------------------------------ * classDeclaration() * ------------------------------------------------------------ */ virtual int classDeclaration(Node *n) { /* Do some work on the class name */ if (blessed) { setclassname(n); Append(classlist,n); } return Language::classDeclaration(n); } /* ------------------------------------------------------------ * classHandler() * ------------------------------------------------------------ */ virtual int classHandler(Node *n) { if (blessed) { have_constructor = 0; have_operators = 0; have_destructor = 0; have_data_members = 0; operators = NewHash(); class_name = Getattr(n,"sym:name"); if (!addSymbol(class_name,n)) return SWIG_ERROR; /* Use the fully qualified name of the Perl class */ if (!compat) { fullclassname = NewStringf("%s::%s",fullmodule,class_name); } else { fullclassname = NewString(class_name); } real_classname = Getattr(n,"name"); pcode = NewString(""); // blessedmembers = NewString(""); } /* Emit all of the members */ Language::classHandler(n); /* Finish the rest of the class */ if (blessed) { /* Generate a client-data entry */ SwigType *ct = NewStringf("p.%s", real_classname); Printv(f_init,"SWIG_TypeClientData(SWIGTYPE", SwigType_manglestr(ct),", (void*) \"", fullclassname, "\");\n", NIL); SwigType_remember(ct); Delete(ct); Printv(pm, "\n############# Class : ", fullclassname, " ##############\n", "\npackage ", fullclassname, ";\n", NIL); if (have_operators) { Printf(pm, "use overload\n"); Iterator ki; for (ki = First(operators); ki.key; ki = Next(ki)) { char *name = Char(ki.key); // fprintf(stderr,"found name: <%s>\n", name); if (strstr(name, "operator_equal_to")) { Printv(pm, tab4, "\"==\" => sub { $_[0]->operator_equal_to($_[1])},\n",NIL); } else if (strstr(name, "operator_not_equal_to")) { Printv(pm, tab4, "\"!=\" => sub { $_[0]->operator_not_equal_to($_[1])},\n",NIL); } else if (strstr(name, "operator_assignment")) { Printv(pm, tab4, "\"=\" => sub { $_[0]->operator_assignment($_[1])},\n",NIL); } else { fprintf(stderr,"Unknown operator: %s\n", name); } } Printv(pm, tab4, "\"fallback\" => 1;\n",NIL); } /* If we are inheriting from a base class, set that up */ Printv(pm, "@ISA = qw( ", NIL); if (!compat || Cmp(fullmodule, fullclassname)) { Printv(pm, fullmodule, NIL); } /* Handle inheritance */ List *baselist = Getattr(n,"bases"); if (baselist && Len(baselist)) { Iterator b; b = First(baselist); while (b.item) { String *bname = Getattr(b.item, "perl5:proxy"); if (!bname) { b = Next(b); continue; } Printv(pm," ", bname, NIL); b = Next(b); } } Printf(pm, " );\n"); /* Dump out a hash table containing the pointers that we own */ Printf(pm, "%%OWNER = ();\n"); if (have_data_members || have_destructor) Printf(pm, "%%ITERATORS = ();\n"); /* Dump out the package methods */ Printv(pm,pcode,NIL); Delete(pcode); /* Output methods for managing ownership */ Printv(pm, "sub DISOWN {\n", tab4, "my $self = shift;\n", tab4, "my $ptr = tied(%$self);\n", tab4, "delete $OWNER{$ptr};\n", "}\n\n", "sub ACQUIRE {\n", tab4, "my $self = shift;\n", tab4, "my $ptr = tied(%$self);\n", tab4, "$OWNER{$ptr} = 1;\n", "}\n\n", NIL); /* Only output the following methods if a class has member data */ Delete(operators); operators = 0; } return SWIG_OK; } /* ------------------------------------------------------------ * memberfunctionHandler() * ------------------------------------------------------------ */ virtual int memberfunctionHandler(Node *n) { String *symname = Getattr(n,"sym:name"); member_func = 1; Language::memberfunctionHandler(n); member_func = 0; if ((blessed) && (!Getattr(n,"sym:nextSibling"))) { if (Strstr(symname, "operator") == symname) { if (Strstr(symname, "operator_equal_to")) { DohSetInt(operators,"operator_equal_to",1); have_operators = 1; } else if (Strstr(symname, "operator_not_equal_to")) { DohSetInt(operators,"operator_not_equal_to",1); have_operators = 1; } else if (Strstr(symname, "operator_assignment")) { DohSetInt(operators,"operator_assignment",1); have_operators = 1; } else { Printf(stderr,"Unknown operator: %s\n", symname); } // fprintf(stderr,"Found member_func operator: %s\n", symname); } Printv(pcode,"*",symname," = *", cmodule, "::", Swig_name_member(class_name,symname), ";\n", NIL); } return SWIG_OK; } /* ------------------------------------------------------------ * membervariableHandler() * * Adds an instance member. * ----------------------------------------------------------------------------- */ virtual int membervariableHandler(Node *n) { String *symname = Getattr(n,"sym:name"); /* SwigType *t = Getattr(n,"type"); */ /* Emit a pair of get/set functions for the variable */ member_func = 1; Language::membervariableHandler(n); member_func = 0; if (blessed) { Printv(pcode,"*swig_", symname, "_get = *", cmodule, "::", Swig_name_get(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); /* Now we need to generate a little Perl code for this */ /* if (is_shadow(t)) { *//* This is a Perl object that we have already seen. Add an entry to the members list*//* Printv(blessedmembers, tab4, symname, " => '", is_shadow(t), "',\n", NIL); } */ } have_data_members++; return SWIG_OK; } /* ------------------------------------------------------------ * constructorDeclaration() * * Emits a blessed constructor for our class. In addition to our construct * we manage a Perl hash table containing all of the pointers created by * the constructor. This prevents us from accidentally trying to free * something that wasn't necessarily allocated by malloc or new * ------------------------------------------------------------ */ virtual int constructorHandler(Node *n) { String *symname = Getattr(n,"sym:name"); member_func = 1; Language::constructorHandler(n); if ((blessed) && (!Getattr(n,"sym:nextSibling"))) { if ((Cmp(symname,class_name) == 0)) { /* Emit a blessed constructor */ Printf(pcode, "sub new {\n"); } else { /* Constructor doesn't match classname so we'll just use the normal name */ Printv(pcode, "sub ", Swig_name_construct(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); have_constructor = 1; } member_func = 0; return SWIG_OK; } /* ------------------------------------------------------------ * destructorHandler() * ------------------------------------------------------------ */ virtual int destructorHandler(Node *n) { String *symname = Getattr(n,"sym:name"); member_func = 1; Language::destructorHandler(n); if (blessed) { Printv(pcode, "sub DESTROY {\n", tab4, "return unless $_[0]->isa('HASH');\n", tab4, "my $self = tied(%{$_[0]});\n", tab4, "return unless defined $self;\n", tab4, "delete $ITERATORS{$self};\n", tab4, "if (exists $OWNER{$self}) {\n", tab8, cmodule, "::", Swig_name_destroy(symname), "($self);\n", tab8, "delete $OWNER{$self};\n", tab4, "}\n}\n\n", NIL); have_destructor = 1; } member_func = 0; return SWIG_OK; } /* ------------------------------------------------------------ * staticmemberfunctionHandler() * ------------------------------------------------------------ */ virtual int staticmemberfunctionHandler(Node *n) { member_func = 1; Language::staticmemberfunctionHandler(n); member_func = 0; if ((blessed) && (!Getattr(n,"sym:nextSibling"))) { String *symname = Getattr(n,"sym:name"); Printv(pcode,"*",symname," = *", cmodule, "::", Swig_name_member(class_name,symname), ";\n", NIL); } return SWIG_OK; } /* ------------------------------------------------------------ * staticmembervariableHandler() * ------------------------------------------------------------ */ virtual int staticmembervariableHandler(Node *n) { Language::staticmembervariableHandler(n); if (blessed) { String *symname = Getattr(n,"sym:name"); Printv(pcode,"*",symname," = *", cmodule, "::", Swig_name_member(class_name,symname), ";\n", NIL); } return SWIG_OK; } /* ------------------------------------------------------------ * memberconstantHandler() * ------------------------------------------------------------ */ virtual int memberconstantHandler(Node *n) { String *symname = Getattr(n,"sym:name"); int oldblessed = blessed; /* Create a normal constant */ blessed = 0; Language::memberconstantHandler(n); blessed = oldblessed; if (blessed) { Printv(pcode, "*", symname, " = *", cmodule, "::", Swig_name_member(class_name,symname), ";\n", NIL); } return SWIG_OK; } /* ------------------------------------------------------------ * pragma() * * Pragma directive. * * %pragma(perl5) code="String" # Includes a string in the .pm file * %pragma(perl5) include="file.pl" # Includes a file in the .pm file * ------------------------------------------------------------ */ virtual int pragmaDirective(Node *n) { String *lang; String *code; String *value; if (!ImportMode) { lang = Getattr(n,"lang"); code = Getattr(n,"name"); value = Getattr(n,"value"); if (Strcmp(lang,"perl5") == 0) { if (Strcmp(code,"code") == 0) { /* Dump the value string into the .pm file */ if (value) { Printf(pragma_include, "%s\n", value); } } else if (Strcmp(code,"include") == 0) { /* Include a file into the .pm file */ if (value) { FILE *f = Swig_open(value); if (!f) { Printf(stderr,"%s : Line %d. Unable to locate file %s\n", input_file, line_number,value); } else { char buffer[4096]; while (fgets(buffer,4095,f)) { Printf(pragma_include,"%s",buffer); } } } } else { Printf(stderr,"%s : Line %d. Unrecognized pragma.\n", input_file,line_number); } } } return Language::pragmaDirective(n); } }; /* ----------------------------------------------------------------------------- * swig_perl5() - Instantiate module * ----------------------------------------------------------------------------- */ static Language * new_swig_perl5() { return new PERL5(); } extern "C" Language * swig_perl5(void) { return new_swig_perl5(); } cableswig-0.1.0+git20150808.orig/SWIG/Source/Modules/ocaml.cxx0000644000175000000620000016253212561312227022276 0ustar stevestaff/****************************************************************************** * Simplified Wrapper and Interface Generator (SWIG) * * Author : Art Yerkes * Modified from mzscheme.cxx : David Beazley * * Please read the file LICENSE for the copyright and terms by which SWIG * can be used and distributed. *****************************************************************************/ char cvsroot_ocaml_cxx[] = "/cvsroot/SWIG/Source/Modules/ocaml.cxx,v 1.42 2004/01/22 22:42:16 cheetah Exp"; /*********************************************************************** * /cvsroot/SWIG/Source/Modules/ocaml.cxx,v 1.42 2004/01/22 22:42:16 cheetah Exp * * ocaml.cxx * * Definitions for adding functions to Ocaml 101 ***********************************************************************/ #include "swigmod.h" #include static const char *usage = (char*) ("Ocaml Options (available with -ocaml)\n" "-prefix - Set a prefix to be prepended to all names\n" "-where - Emit library location\n" "-suffix - Change .cxx to something else\n" "\n"); static int classmode = 0; static int in_constructor = 0, in_destructor = 0, in_copyconst = 0; static int const_enum = 0; static int static_member_function = 0; static int generate_sizeof = 0; static char *prefix=0; static char *ocaml_path=(char*)"ocaml"; static String *classname=0; static String *module=0; static String *init_func_def = 0; static String *f_classtemplate = 0; static String *name_qualifier = 0; static Hash *seen_enums = 0; static Hash *seen_enumvalues = 0; static Hash *seen_constructors = 0; static File *f_header = 0; static File *f_runtime = 0; static File *f_wrappers = 0; static File *f_directors = 0; static File *f_directors_h = 0; static File *f_init = 0; static File *f_mlout = 0; static File *f_mliout = 0; static File *f_mlbody = 0; static File *f_mlibody = 0; static File *f_enumtypes_type = 0; static File *f_enumtypes_value = 0; static File *f_class_ctors = 0; static File *f_class_ctors_end = 0; static File *f_enum_to_int = 0; static File *f_int_to_enum = 0; class OCAML : public Language { public: String *Swig_class_name(Node *n) { String *name; name = Copy(Getattr(n, "sym:name")); return name; } void PrintIncludeArg() { Printv(stdout,SWIG_LIB,SWIG_FILE_DELIMETER,ocaml_path, "\n",NIL); } /* ------------------------------------------------------------ * main() * ------------------------------------------------------------ */ virtual void main (int argc, char *argv[]) { int i; prefix = 0; SWIG_library_directory(ocaml_path); // Look for certain command line options for (i = 1; i < argc; i++) { if (argv[i]) { if (strcmp (argv[i], "-help") == 0) { fputs (usage, stderr); SWIG_exit (0); } else if (strcmp (argv[i], "-where") == 0) { PrintIncludeArg(); SWIG_exit (0); } else if (strcmp (argv[i], "-prefix") == 0) { if (argv[i + 1]) { prefix = new char[strlen(argv[i + 1]) + 2]; strcpy(prefix, argv[i + 1]); Swig_mark_arg (i); Swig_mark_arg (i + 1); i++; } else { Swig_arg_error(); } } else if (strcmp (argv[i], "-suffix") == 0) { if (argv[i + 1]) { SWIG_config_cppext( argv[i+1] ); Swig_mark_arg (i); Swig_mark_arg (i+1); i++; } else Swig_arg_error(); } } } // If a prefix has been specified make sure it ends in a '_' if (prefix) { if (prefix[strlen (prefix)] != '_') { prefix[strlen (prefix) + 1] = 0; prefix[strlen (prefix)] = '_'; } } else prefix = (char*)"swig_"; // Add a symbol for this module Preprocessor_define ("SWIGOCAML 1",0); // Set name of typemaps SWIG_typemap_lang("ocaml"); // Read in default typemaps */ SWIG_config_file("ocaml.i"); allow_overloading(); } /* Swig_director_declaration() * * Generate the full director class declaration, complete with base classes. * e.g. "class SwigDirector_myclass : public myclass, public Swig::Director {" * */ String *Swig_director_declaration(Node *n) { String* classname = Swig_class_name(n); String *directorname = NewStringf("SwigDirector_%s", classname); String *base = Getattr(n, "classtype"); String *declaration = Swig_class_declaration(n, directorname); Printf(declaration, " : public %s, public Swig::Director {\n", base); Delete(classname); Delete(directorname); return declaration; } /* ------------------------------------------------------------ * top() * * Recognize the %module, and capture the module name. * Create the default enum cases. * Set up the named outputs: * * init * ml * mli * wrapper * header * runtime * directors * directors_h * ------------------------------------------------------------ */ virtual int top(Node *n) { /* Set comparison with none for ConstructorToFunction */ setSubclassInstanceCheck(NewString("caml_list_nth(args,0) != Val_unit")); /* check if directors are enabled for this module. note: this * is a "master" switch, without which no director code will be * emitted. %feature("director") statements are also required * to enable directors for individual classes or methods. * * use %module(directors="1") modulename at the start of the * interface file to enable director generation. */ { Node *module = Getattr(n, "module"); if (module) { Node *options = Getattr(module, "options"); if (options) { if (Getattr(options, "directors")) { allow_directors(); } if (Getattr(options, "dirprot")) { allow_dirprot(); } if (Getattr(options, "sizeof")) { generate_sizeof = 1; } } } } /* Initialize all of the output files */ String *outfile = Getattr(n,"outfile"); f_runtime = NewFile(outfile,"w"); if (!f_runtime) { Printf(stderr,"*** Can't open '%s'\n", outfile); SWIG_exit(EXIT_FAILURE); } f_init = NewString(""); f_header = NewString(""); f_wrappers = NewString(""); f_directors = NewString(""); f_directors_h = NewString(""); f_enumtypes_type = NewString(""); f_enumtypes_value = NewString(""); init_func_def = NewString(""); f_mlbody = NewString(""); f_mlibody = NewString(""); f_class_ctors = NewString(""); f_class_ctors_end = NewString(""); f_enum_to_int = NewString(""); f_int_to_enum = NewString(""); f_classtemplate = NewString(""); module = Getattr(n,"name"); seen_constructors = NewHash(); seen_enums = NewHash(); seen_enumvalues = NewHash(); /* Register file targets with the SWIG file handler */ Swig_register_filebyname("init",init_func_def); Swig_register_filebyname("header",f_header); Swig_register_filebyname("wrapper",f_wrappers); Swig_register_filebyname("runtime",f_runtime); Swig_register_filebyname("mli",f_mlibody); Swig_register_filebyname("ml",f_mlbody); Swig_register_filebyname("director",f_directors); Swig_register_filebyname("director_h",f_directors_h); Swig_register_filebyname("classtemplate",f_classtemplate); Swig_register_filebyname("class_ctors",f_class_ctors); Swig_name_register("set","%v__set__"); Swig_name_register("get","%v__get__"); Printf( f_runtime, "/* -*- buffer-read-only: t -*- vi: set ro: */\n" ); Printf( f_runtime, "#define SWIG_MODULE \"%s\"\n", module ); /* Module name */ Printf( f_mlbody, "let module_name = \"%s\"\n", module ); Printf( f_mlibody, "val module_name : string\n" ); Printf( f_enum_to_int, "let enum_to_int x v =\n" " match v with C_enum y -> (\n" " match (x : c_enum_type) with\n" " `unknown -> " " (match (y : c_enum_tag) with\n" " `int (x : int) -> C_int x\n" " | _ -> raise (LabelNotFromThisEnum v))\n" ); Printf( f_int_to_enum, "let int_to_enum x y =\n" " match (x : c_enum_type) with\n" " `unknown -> C_enum (`int y)\n" ); Swig_banner (f_runtime); if( directorsEnabled() ) { Printf( f_runtime, "#define SWIG_DIRECTORS\n"); Swig_insert_file("director.swg", f_directors_h); } if (NoInclude) { Printf(f_runtime, "#define SWIG_NOINCLUDE\n"); } /* Produce the enum_to_int and int_to_enum functions */ Printf(f_enumtypes_type,"type c_enum_type = [ \n `unknown\n" ); Printf(f_enumtypes_value, "type c_enum_tag = [\n" " `SWIGFake\n" "| `int of int\n" ); String *mlfile = NewString(""); String *mlifile = NewString(""); Printv(mlfile,module,".ml",NIL); Printv(mlifile,module,".mli",NIL); String *mlfilen = NewStringf("%s%s", SWIG_output_directory(),mlfile); if ((f_mlout = NewFile(mlfilen,"w")) == 0) { Printf(stderr,"Unable to open %s\n", mlfilen); SWIG_exit (EXIT_FAILURE); } String *mlifilen = NewStringf("%s%s", SWIG_output_directory(),mlifile); if ((f_mliout = NewFile(mlifilen,"w")) == 0) { Printf(stderr,"Unable to open %s\n", mlifilen); SWIG_exit (EXIT_FAILURE); } Language::top(n); Printf( f_enum_to_int, ") | _ -> (C_int (get_int v))\n" "let _ = Callback.register \"%s_enum_to_int\" enum_to_int\n", module ); Printf( f_mlibody, "val enum_to_int : c_enum_type -> c_obj -> c_obj\n" ); Printf( f_int_to_enum, "let _ = Callback.register \"%s_int_to_enum\" int_to_enum\n", module ); Printf( f_mlibody, "val int_to_enum : c_enum_type -> int -> c_obj\n" ); Printf( f_init, "SWIGEXT void f_%s_init() {\n" "%s" "}\n", module, init_func_def ); Printf( f_mlbody, "external f_init : unit -> unit = \"f_%s_init\" ;;\n" "let _ = f_init ()\n", module, module ); Printf( f_enumtypes_type, "]\n" ); Printf( f_enumtypes_value, "]\n" ); SwigType_emit_type_table (f_runtime, f_wrappers); /* Close all of the files */ Dump(f_directors_h,f_header); Dump(f_header,f_runtime); Dump(f_directors,f_wrappers); Dump(f_wrappers,f_runtime); Wrapper_pretty_print(f_init,f_runtime); Delete(f_header); Delete(f_wrappers); Delete(f_init); Close(f_runtime); Delete(f_runtime); Dump(f_enumtypes_type,f_mlout); Dump(f_enumtypes_value,f_mlout); Dump(f_mlbody,f_mlout); Dump(f_enum_to_int,f_mlout); Dump(f_int_to_enum,f_mlout); Delete(f_int_to_enum); Delete(f_enum_to_int); Dump(f_class_ctors,f_mlout); Dump(f_class_ctors_end,f_mlout); Close(f_mlout); Delete(f_mlout); Dump(f_enumtypes_type,f_mliout); Dump(f_enumtypes_value,f_mliout); Dump(f_mlibody,f_mliout); Close(f_mliout); Delete(f_mliout); return SWIG_OK; } /* Produce an error for the given type */ void throw_unhandled_ocaml_type_error (SwigType *d, const char *types) { Swig_warning(WARN_TYPEMAP_UNDEF, input_file, line_number, "Unable to handle type %s (%s).\n", SwigType_str(d,0), types ); } /* Return true iff T is a pointer type */ int is_a_pointer (SwigType *t) { return SwigType_ispointer(SwigType_typedef_resolve_all(t)); } /* * Delete one reference from a given type. */ void oc_SwigType_del_reference(SwigType *t) { char *c = Char(t); if (strncmp(c,"q(",2) == 0) { Delete(SwigType_pop(t)); c = Char(t); } if (strncmp(c,"r.",2)) { printf("Fatal error. SwigType_del_pointer applied to non-pointer.\n"); abort(); } Replace(t,"r.","", DOH_REPLACE_ANY | DOH_REPLACE_FIRST); } void oc_SwigType_del_array(SwigType *t) { char *c = Char(t); if (strncmp(c,"q(",2) == 0) { Delete(SwigType_pop(t)); c = Char(t); } if (strncmp(c,"a(",2) == 0) { Delete(SwigType_pop(t)); } } /* * Return true iff T is a reference type */ int is_a_reference (SwigType *t) { return SwigType_isreference(SwigType_typedef_resolve_all(t)); } int is_an_array (SwigType *t) { return SwigType_isarray(SwigType_typedef_resolve_all(t)); } /* ------------------------------------------------------------ * functionWrapper() * Create a function declaration and register it with the interpreter. * ------------------------------------------------------------ */ virtual int functionWrapper(Node *n) { char *iname = GetChar(n,"sym:name"); SwigType *d = Getattr(n,"type"); String *return_type_normalized = normalizeTemplatedClassName(d); ParmList *l = Getattr(n,"parms"); Parm *p; Wrapper *f = NewWrapper(); String *proc_name = NewString(""); String *source = NewString(""); String *target = NewString(""); String *arg = NewString(""); String *cleanup = NewString(""); String *outarg = NewString(""); String *build = NewString(""); String *tm; int argout_set = 0; int i = 0; int numargs; int numreq; int newobj = Getattr(n,"feature:new") ? 1 : 0; String *nodeType = Getattr(n, "nodeType"); int constructor = !Cmp(nodeType, "constructor"); String *storage = Getattr(n,"storage"); int isVirtual = !Cmp(storage,"virtual"); String *overname = 0; bool isOverloaded = Getattr(n,"sym:overloaded") ? true : false; // Make a wrapper name for this String *wname = Swig_name_wrapper(iname); if (isOverloaded) { overname = Getattr(n,"sym:overname"); } else { if (!addSymbol(iname,n)) return SWIG_ERROR; } if (overname) { Append(wname, overname); } Setattr(n,"wrap:name",wname); // Build the name for Scheme. Printv(proc_name,"_",iname,NIL); String *mangled_name = mangleNameForCaml(proc_name); if( classmode && in_constructor ) { // Emit constructor for object String *mangled_name_nounder = NewString((char *)(Char(mangled_name))+1); Printf( f_class_ctors_end, "let %s clst = _%s clst\n", mangled_name_nounder, mangled_name_nounder ); Printf(f_mlibody, "val %s : c_obj -> c_obj\n", mangled_name_nounder ); Delete(mangled_name_nounder); } else if( classmode && in_destructor ) { Printf(f_class_ctors, " \"~\", %s ;\n", mangled_name ); } else if( classmode && !in_constructor && !in_destructor && !static_member_function ) { String *opname = Copy(Getattr(n,"name")); Replaceall(opname,"operator ",""); if( strstr( Char(mangled_name), "__get__" ) ) { String *set_name = Copy(mangled_name); if( !Getattr(n,"feature:immutable") ) { Replaceall(set_name,"__get__","__set__"); Printf(f_class_ctors, " \"%s\", (fun args -> " "if args = (C_list [ raw_ptr ]) then %s args else %s args) ;\n", opname, mangled_name, set_name ); Delete(set_name); } else { Printf(f_class_ctors, " \"%s\", (fun args -> " "if args = (C_list [ raw_ptr ]) then %s args else C_void) ;\n", opname, mangled_name ); } } else if( strstr( Char(mangled_name), "__set__" ) ) { ; /* Nothing ... handled by the case above */ } else { Printf(f_class_ctors, " \"%s\", %s ;\n", opname, mangled_name); } Delete(opname); } if( classmode && in_constructor ) { Setattr(seen_constructors,mangled_name,"true"); } // writing the function wrapper function Printv(f->def, "SWIGEXT CAML_VALUE ", wname, " (", NIL); Printv(f->def, "CAML_VALUE args", NIL); Printv(f->def, ")\n{", NIL); /* Define the scheme name in C. This define is used by several macros. */ //Printv(f->def, "#define FUNC_NAME \"", mangled_name, "\"", NIL); // adds local variables Wrapper_add_local(f, "args", "CAMLparam1(args)"); Wrapper_add_local(f, "ret" , "SWIG_CAMLlocal2(swig_result,rv)"); Wrapper_add_local(f, "_v" , "int _v = 0"); if( isOverloaded ) { Wrapper_add_local(f, "i" , "int i"); Wrapper_add_local(f, "argc", "int argc = caml_list_length(args)"); Wrapper_add_local(f, "argv", "CAML_VALUE *argv"); Printv( f->code, "argv = (CAML_VALUE *)malloc( argc * sizeof( CAML_VALUE ) );\n" "for( i = 0; i < argc; i++ ) {\n" " argv[i] = caml_list_nth(args,i);\n" "}\n", NIL ); } // Declare return variable and arguments // number of parameters // they are called arg0, arg1, ... // the return value is called result d = SwigType_typedef_qualified(d); emit_args(d, l, f); /* Attach the standard typemaps */ emit_attach_parmmaps(l,f); Setattr(n,"wrap:parms",l); numargs = emit_num_arguments(l); numreq = emit_num_required(l); Printf(f->code,"swig_result = Val_unit;\n" ); // Now write code to extract the parameters (this is super ugly) for (i = 0, p = l; i < numargs; i++) { /* Skip ignored arguments */ while (checkAttribute(p,"tmap:in:numinputs","0")) { p = Getattr(p,"tmap:in:next"); } SwigType *pt = Getattr(p,"type"); String *ln = Getattr(p,"lname"); pt = SwigType_typedef_qualified(pt); // Produce names of source and target Clear(source); Clear(target); Clear(arg); Printf(source, "caml_list_nth(args,%d)", i); Printf(target, "%s",ln); Printv(arg, Getattr(p,"name"),NIL); if (i >= numreq) { Printf(f->code,"if (caml_list_length(args) > %d) {\n",i); } // Handle parameter types. if ((tm = Getattr(p,"tmap:in"))) { Replaceall(tm,"$source",source); Replaceall(tm,"$target",target); Replaceall(tm,"$input",source); Setattr(p,"emit:input",source); Printv(f->code, tm, "\n", NIL); p = Getattr(p,"tmap:in:next"); } else { // no typemap found // check if typedef and resolve throw_unhandled_ocaml_type_error (pt,"in"); p = nextSibling(p); } if (i >= numreq) { Printf(f->code,"}\n"); } } /* Insert constraint checking code */ for (p = l; p;) { if ((tm = Getattr(p,"tmap:check"))) { Replaceall(tm,"$target",Getattr(p,"lname")); Printv(f->code,tm,"\n",NIL); p = Getattr(p,"tmap:check:next"); } else { p = nextSibling(p); } } // Pass output arguments back to the caller. for (p = l; p;) { if ((tm = Getattr(p,"tmap:argout"))) { Replaceall(tm,"$source",Getattr(p,"emit:input")); /* Deprecated */ Replaceall(tm,"$target",Getattr(p,"lname")); /* Deprecated */ Replaceall(tm,"$arg",Getattr(p,"emit:input")); Replaceall(tm,"$input",Getattr(p,"emit:input")); Replaceall(tm,"$ntype", normalizeTemplatedClassName(Getattr(p,"type"))); Printv(outarg,tm,"\n",NIL); p = Getattr(p,"tmap:argout:next"); argout_set = 1; } else { p = nextSibling(p); } } // Free up any memory allocated for the arguments. /* Insert cleanup code */ for (p = l; p;) { if ((tm = Getattr(p,"tmap:freearg"))) { Replaceall(tm,"$target",Getattr(p,"lname")); Printv(cleanup,tm,"\n",NIL); p = Getattr(p,"tmap:freearg:next"); } else { p = nextSibling(p); } } /* if the object is a director, and the method call originated from its * underlying python object, resolve the call by going up the c++ * inheritance chain. otherwise try to resolve the method in python. * without this check an infinite loop is set up between the director and * shadow class method calls. */ // NOTE: this code should only be inserted if this class is the // base class of a director class. however, in general we haven't // yet analyzed all classes derived from this one to see if they are // directors. furthermore, this class may be used as the base of // a director class defined in a completely different module at a // later time, so this test must be included whether or not directorbase // is true. we do skip this code if directors have not been enabled // at the command line to preserve source-level compatibility with // non-polymorphic swig. also, if this wrapper is for a smart-pointer // method, there is no need to perform the test since the calling object // (the smart-pointer) and the director object (the "pointee") are // distinct. if (CPlusPlus && directorsEnabled()) { if (!is_smart_pointer()) { if (/*directorbase &&*/ !constructor && isVirtual) { Wrapper_add_local(f, "director", "Swig::Director *director = 0"); Printf(f->code, "director = dynamic_cast(arg1);\n"); Printf(f->code, "if (director && !director->swig_get_up(false))" "director->swig_set_up();\n"); } } } // Now write code to make the function call emit_action(n,f); // Now have return value, figure out what to do with it. if ((tm = Swig_typemap_lookup_new("out",n,"result",0))) { Replaceall(tm,"$source","swig_result"); Replaceall(tm,"$target","rv"); Replaceall(tm,"$result","rv"); Replaceall(tm,"$ntype",return_type_normalized); Printv(f->code, tm, "\n",NIL); } else { throw_unhandled_ocaml_type_error (d, "out"); } // Dump the argument output code Printv(f->code, Char(outarg),NIL); // Dump the argument cleanup code Printv(f->code, Char(cleanup),NIL); // Look for any remaining cleanup if (Getattr(n,"feature:new")) { if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) { Replaceall(tm,"$source","swig_result"); Printv(f->code, tm, "\n",NIL); } } // Free any memory allocated by the function being wrapped.. if ((tm = Swig_typemap_lookup_new("swig_result",n,"result",0))) { Replaceall(tm,"$source","result"); Printv(f->code, tm, "\n",NIL); } // Wrap things up (in a manner of speaking) Printv(f->code, tab4, "swig_result = caml_list_append(swig_result,rv);\n", NIL); if( isOverloaded ) Printv(f->code, "free(argv);\n", NIL); Printv(f->code, tab4, "CAMLreturn(swig_result);\n", NIL ); Printv(f->code, "}\n",NIL); Wrapper_print(f, f_wrappers); if( isOverloaded ) { if( !Getattr(n,"sym:nextSibling") ) { int maxargs; Wrapper *df = NewWrapper(); String *dname = Swig_name_wrapper(iname); String *dispatch = Swig_overload_dispatch(n, "free(argv);\n" "CAMLreturn(%s(args));\n", &maxargs); Wrapper_add_local(df, "_v", "int _v = 0"); Wrapper_add_local(df, "argv", "CAML_VALUE *argv"); Printv(df->def, "SWIGEXT CAML_VALUE ",dname,"(CAML_VALUE args) {\n" " CAMLparam1(args);\n" " int i;\n" " int argc = caml_list_length(args);\n",NIL); Printv( df->code, "argv = (CAML_VALUE *)malloc( argc * sizeof( CAML_VALUE ) );\n" "for( i = 0; i < argc; i++ ) {\n" " argv[i] = caml_list_nth(args,i);\n" "}\n", NIL ); Printv(df->code,dispatch,"\n",NIL); Printf(df->code,"failwith(\"No matching function for overloaded '%s'\");\n", iname); Printv(df->code,"}\n",NIL); Wrapper_print(df,f_wrappers); Printf(f_mlbody, "external %s_f : c_obj list -> c_obj list = \"%s\" ;;\n" "let %s = fnhelper %s %s_f\n", mangled_name, dname, mangled_name, newobj ? "true" : "false", mangled_name ); if( !classmode || in_constructor || in_destructor || static_member_function ) Printf(f_mlibody, "(* overload *)\n" "val %s : c_obj -> c_obj\n", mangled_name ); DelWrapper(df); Delete(dispatch); Delete(dname); } } else { Printf(f_mlbody, "external %s_f : c_obj list -> c_obj list = \"%s\" ;;\n" "let %s = fnhelper %s %s_f\n", mangled_name, wname, mangled_name, newobj ? "true" : "false", mangled_name ); if( !classmode || in_constructor || in_destructor || static_member_function ) Printf(f_mlibody, "(* Non-overload *)\n" "val %s : c_obj -> c_obj\n", mangled_name ); } Delete(proc_name); Delete(source); Delete(target); Delete(arg); Delete(outarg); Delete(cleanup); Delete(build); DelWrapper(f); return SWIG_OK; } /* ------------------------------------------------------------ * variableWrapper() * * Create a link to a C variable. * This creates a single function _wrap_swig_var_varname(). * This function takes a single optional argument. If supplied, it means * we are setting this variable to some value. If omitted, it means we are * simply evaluating this variable. In the set case we return C_void. * * symname is the name of the variable with respect to C. This * may need to differ from the original name in the case of enums. * enumvname is the name of the variable with respect to ocaml. This * will vary if the variable has been renamed. * ------------------------------------------------------------ */ virtual int variableWrapper(Node *n) { char *name = GetChar(n,"feature:symname"); String *iname = Getattr(n,"feature:enumvname"); String *mname = mangleNameForCaml(iname); SwigType *t = Getattr(n,"type"); String *proc_name = NewString(""); char var_name[256]; String *tm; String *tm2 = NewString("");; String *argnum = NewString("0"); String *arg = NewString("SWIG_Field(args,0)"); Wrapper *f; if( !name ) { name = GetChar(n,"name"); } if( !iname ) { iname = Getattr(n,"sym:name"); mname = mangleNameForCaml(NewString(iname)); } if (!iname || !addSymbol(iname,n)) return SWIG_ERROR; f = NewWrapper(); // evaluation function names strcpy(var_name, Char(Swig_name_wrapper(iname))); // Build the name for scheme. Printv(proc_name, iname, NIL); Printf (f->def, "SWIGEXT CAML_VALUE %s(CAML_VALUE args) {\n", var_name); // Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL); Wrapper_add_local (f, "swig_result", "CAML_VALUE swig_result"); if (!Getattr(n,"feature:immutable")) { /* Check for a setting of the variable value */ Printf (f->code, "if (args != Val_int(0)) {\n"); if ((tm = Swig_typemap_lookup_new("varin",n,name,0))) { Replaceall(tm,"$source","args"); Replaceall(tm,"$target",name); Replaceall(tm,"$input","args"); Printv(f->code, tm, "\n",NIL); } else if ((tm = Swig_typemap_lookup_new("in",n,name,0))) { Replaceall(tm,"$source","args"); Replaceall(tm,"$target",name); Replaceall(tm,"$input","args"); Printv(f->code, tm, "\n",NIL); } else { throw_unhandled_ocaml_type_error (t, "varin/in"); } Printf (f->code, "}\n"); } // Now return the value of the variable (regardless // of evaluating or setting) if ((tm = Swig_typemap_lookup_new("varout",n,name,0))) { Replaceall(tm,"$source",name); Replaceall(tm,"$target","swig_result"); Replaceall(tm,"$result","swig_result"); Printf (f->code, "%s\n", tm); } else if ((tm = Swig_typemap_lookup_new("out",n,name,0))) { Replaceall(tm,"$source",name); Replaceall(tm,"$target","swig_result"); Replaceall(tm,"$result","swig_result"); Printf (f->code, "%s\n", tm); } else { throw_unhandled_ocaml_type_error (t, "varout/out"); } Printf (f->code, "\nreturn swig_result;\n"); Printf (f->code, "}\n"); Wrapper_print (f, f_wrappers); // Now add symbol to the Ocaml interpreter if( Getattr( n, "feature:immutable" ) ) { Printf( f_mlbody, "external __%s : c_obj -> c_obj = \"%s\" \n" "let _%s = __%s C_void\n", mname, var_name, mname, mname ); Printf( f_mlibody, "val _%s : c_obj\n", iname ); if( const_enum ) { Printf( f_enum_to_int, " | `%s -> _%s\n", mname, mname ); Printf( f_int_to_enum, " if y = (get_int _%s) then `%s else\n", mname, mname ); } } else { Printf( f_mlbody, "external _%s : c_obj -> c_obj = \"%s\"\n", mname, var_name ); Printf( f_mlibody, "external _%s : c_obj -> c_obj = \"%s\"\n", mname, var_name ); } Delete(proc_name); Delete(argnum); Delete(arg); Delete(tm2); DelWrapper(f); return SWIG_OK; } /* ------------------------------------------------------------ * staticmemberfunctionHandler -- * Overridden to set static_member_function * ------------------------------------------------------------ */ virtual int staticmemberfunctionHandler( Node *n ) { int rv; static_member_function = 1; rv = Language::staticmemberfunctionHandler( n ); static_member_function = 0; return SWIG_OK; } /* ------------------------------------------------------------ * constantWrapper() * * The one trick here is that we have to make sure we rename the * constant to something useful that doesn't collide with the * original if any exists. * ------------------------------------------------------------ */ virtual int constantWrapper(Node *n) { String *name = Getattr(n,"feature:symname"); SwigType *type = Getattr(n,"type"); String *value = Getattr(n,"value"); String *qvalue = Getattr(n,"qualified:value"); String *rvalue = NewString(""); String *temp = 0; if( qvalue ) value = qvalue; if( !name ) { name = mangleNameForCaml(Getattr(n,"name")); Insert(name,0,"_swig_wrap_"); Setattr(n,"feature:symname",name); } // See if there's a typemap Printv(rvalue, value,NIL); if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 1)) { temp = Copy(rvalue); Clear(rvalue); Printv(rvalue, "\"", temp, "\"",NIL); Delete(temp); } if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 0)) { temp = Copy(rvalue); Clear(rvalue); Printv(rvalue, "'", temp, "'",NIL); Delete(temp); } // Create variable and assign it a value Printf (f_header, "static %s = ", SwigType_lstr(type,name)); if ((SwigType_type(type) == T_STRING)) { Printf (f_header, "\"%s\";\n", value); } else if (SwigType_type(type) == T_CHAR) { Printf (f_header, "\'%s\';\n", value); } else { Printf (f_header, "%s;\n", value); } Setattr(n,"feature:immutable","1"); variableWrapper(n); return SWIG_OK; } int constructorHandler(Node *n) { int ret; in_constructor = 1; ret = Language::constructorHandler(n); in_constructor = 0; return ret; } /* destructorHandler: * Turn on destructor flag to inform decisions in functionWrapper */ int destructorHandler(Node *n) { int ret; in_destructor = 1; ret = Language::destructorHandler(n); in_destructor = 0; return ret; } /* copyconstructorHandler: * Turn on constructor and copyconstructor flags for functionWrapper */ int copyconstructorHandler(Node *n) { int ret; in_copyconst = 1; in_constructor = 1; ret = Language::copyconstructorHandler(n); in_constructor = 0; in_copyconst = 0; return ret; } /** * A simple, somewhat general purpose function for writing to multiple * streams from a source template. This allows the user to define the * class definition in ways different from the one I have here if they * want to. It will also make the class definition system easier to * fiddle with when I want to change methods, etc. */ void Multiwrite( String *s ) { char *find_marker = strstr(Char(s),"(*Stream:"); while( find_marker ) { char *next = strstr(find_marker,"*)"); find_marker += strlen("(*Stream:"); if( next ) { int num_chars = next - find_marker; String *stream_name = NewString(find_marker); Delslice(stream_name,num_chars,Len(stream_name)); File *fout = Swig_filebyname(stream_name); if( fout ) { next += strlen("*)"); char *following = strstr(next,"(*Stream:"); find_marker = following; if( !following ) following = next + strlen(next); String *chunk = NewString(next); Delslice(chunk,following-next,Len(chunk)); Printv(fout,chunk,NIL); } } } } bool isSimpleType( String *name ) { char *ch = Char(name); return !(strchr(ch,'(') || strchr(ch,'<') || strchr(ch,')') || strchr(ch,'>')); } /* classHandler * * Create a "class" definition for ocaml. I thought quite a bit about * how I should do this part of it, and arrived here, using a function * invocation to select a method, and dispatch. This can obviously be * done better, but I can't see how, given that I want to support * overloaded methods, out parameters, and operators. * * I needed a system that would do this: * * a Be able to call these methods: * int foo( int x ); * float foo( int x, int &out ); * * b Be typeable, even in the presence of mutually dependent classes. * * c Support some form of operator invocation. * * (c) I chose strings for the method names so that "+=" would be a * valid method name, and the somewhat natural << (invoke x) "+=" y >> * would work. * * (a) (b) Since the c_obj type exists, it's easy to return C_int in one * case and C_list [ C_float ; C_int ] in the other. This makes tricky * problems with out parameters disappear; they're simply appended to the * return list. * * (b) Since every item that comes from C++ is the same type, there is no * problem with the following: * * class Foo; * class Bar { Foo *toFoo(); } * class Foo { Bar *toBar(); } * * Since the Objective caml types of Foo and Bar are the same. Now that * I correctly incorporate SWIG's typechecking, this isn't a big deal. * * The class is in the form of a function returning a c_obj. The c_obj * is a C_obj containing a function which invokes a method on the * underlying object given its type. * * The name emitted here is normalized before being sent to * Callback.register, because we need this string to look up properly * when the typemap passes the descriptor string. I've been considering * some, possibly more forgiving method that would do some transformations * on the $descriptor in order to find a potential match. This is for * later. * * Important things to note: * * We rely on exception handling (BadMethodName) in order to call an * ancestor. This can be improved. * * The method used to get :classof could be improved to look at the type * info that the base pointer contains. It's really an error to have a * SWIG-generated object that does not contain type info, since the * existence of the object means that SWIG knows the type. * * :parents could use :classof to tell what class it is and make a better * decision. This could be nice, (i.e. provide a run-time graph of C++ * classes represented);. * * I can't think of a more elegant way of converting a C_obj fun to a * pointer than "operator &"... * * Added a 'sizeof' that will allow you to do the expected thing. * This should help users to fill buffer structs and the like (as is * typical in windows-styled code). It's only enabled if you give * %feature(sizeof) and then, only for simple types. * * Overall, carrying the list of methods and base classes has worked well. * It allows me to give the Ocaml user introspection over their objects. */ int classHandler( Node *n ) { String *name = Getattr(n,"name"); String *mangled_sym_name = mangleNameForCaml(name); String *this_class_def = NewString( f_classtemplate ); String *name_normalized = normalizeTemplatedClassName(name); String *old_class_ctors = f_class_ctors; String *base_classes = NewString(""); f_class_ctors = NewString(""); bool sizeof_feature = generate_sizeof && isSimpleType(name); if( !name ) return SWIG_OK; classname = mangled_sym_name; classmode = true; int rv = Language::classHandler(n); classmode = false; if( sizeof_feature ) { Printf( f_wrappers, "SWIGEXT CAML_VALUE _wrap_%s_sizeof( CAML_VALUE args ) {\n" " CAMLparam1(args);\n" " CAMLreturn(Val_int(sizeof(%s)));\n" "}\n", mangled_sym_name, name_normalized ); Printf( f_mlbody, "external __%s_sizeof : unit -> int = " "\"_wrap_%s_sizeof\"\n", classname, mangled_sym_name ); } /* Insert sizeof operator for concrete classes */ if( sizeof_feature ) { Printv(f_class_ctors, "\"sizeof\" , (fun args -> C_int (__", classname, "_sizeof ())) ;\n", NIL); } /* Handle up-casts in a nice way */ List *baselist = Getattr(n,"bases"); if (baselist && Len(baselist)) { Iterator b; b = First(baselist); while (b.item) { String *bname = Getattr(b.item, "ocaml:ctor"); if (bname) { Printv(f_class_ctors, " \"::",bname,"\", (fun args -> " "create_",bname,"_from_ptr raw_ptr) ;\n",NIL); Printv( base_classes, "create_", bname, "_from_ptr ;\n", NIL ); } b = Next(b); } } Replaceall(this_class_def,"$classname",classname); Replaceall(this_class_def,"$normalized",name_normalized); Replaceall(this_class_def,"$realname",name); Replaceall(this_class_def,"$baselist",base_classes); Replaceall(this_class_def,"$classbody",f_class_ctors); Delete(f_class_ctors); f_class_ctors = old_class_ctors; // Actually write out the class definition Multiwrite( this_class_def ); Setattr(n,"ocaml:ctor",classname); return rv; } String *normalizeTemplatedClassName( String *name ) { String *name_normalized = SwigType_typedef_resolve_all(name); bool took_action; do { took_action = false; if( is_a_pointer(name_normalized) ) { SwigType_del_pointer( name_normalized ); took_action = true; } if( is_a_reference(name_normalized) ) { oc_SwigType_del_reference( name_normalized ); took_action = true; } if( is_an_array(name_normalized) ) { oc_SwigType_del_array( name_normalized ); took_action = true; } } while( took_action ); return SwigType_str(name_normalized,0); } /* * Produce the symbol name that ocaml will use when referring to the * target item. I wonder if there's a better way to do this: * * I shudder to think about doing it with a hash lookup, but that would * make a couple of things easier: */ String *mangleNameForCaml( String *s ) { String *out = Copy(s); Replaceall(out," ","_xx"); Replaceall(out,"::","_xx"); Replaceall(out,",","_x"); Replaceall(out,"+","_xx_plus"); Replaceall(out,"-","_xx_minus"); Replaceall(out,"<","_xx_ldbrace"); Replaceall(out,">","_xx_rdbrace"); Replaceall(out,"!","_xx_not"); Replaceall(out,"%","_xx_mod"); Replaceall(out,"^","_xx_xor"); Replaceall(out,"*","_xx_star"); Replaceall(out,"&","_xx_amp"); Replaceall(out,"|","_xx_or"); Replaceall(out,"(","_xx_lparen"); Replaceall(out,")","_xx_rparen"); Replaceall(out,"[","_xx_lbrace"); Replaceall(out,"]","_xx_rbrace"); Replaceall(out,"~","_xx_bnot"); Replaceall(out,"=","_xx_equals"); Replaceall(out,"/","_xx_slash"); Replaceall(out,".","_xx_dot"); return out; } String *fully_qualify_enum_name( Node *n, String *name ) { Node *parent = 0; String *qualification = NewString(""); String *fully_qualified_name = NewString(""); String *parent_type = 0; String *normalized_name; parent = parentNode(n); while( parent ) { parent_type = nodeType(parent); if( Getattr(parent,"name") ) { String *parent_copy = NewStringf("%s::",Getattr(parent,"name")); if( !Cmp(parent_type,"class") || !Cmp(parent_type,"namespace") ) Insert(qualification,0,parent_copy); Delete(parent_copy); } if( !Cmp( parent_type, "class" ) ) break; parent = parentNode(parent); } Printf( fully_qualified_name, "%s%s", qualification, name ); normalized_name = normalizeTemplatedClassName(fully_qualified_name); if( !strncmp(Char(normalized_name),"enum ",5) ) { Insert(normalized_name,5,qualification); } return normalized_name; } /* Benedikt Grundmann inspired --> Enum wrap styles */ int enumvalueDeclaration(Node *n) { String *name = Getattr(n,"name"); String *qvalue = 0; if( name_qualifier ) { qvalue = Copy(name_qualifier); Printv( qvalue, name, NIL ); } if( const_enum && name && !Getattr(seen_enumvalues,name) ) { Setattr(seen_enumvalues,name,"true"); Setattr(n,"feature:immutable","1"); Setattr(n,"feature:enumvalue","1"); if( qvalue ) Setattr(n,"qualified:value",qvalue); String *evname = SwigType_manglestr(qvalue); Insert( evname, 0, "SWIG_ENUM_" ); Setattr(n,"feature:enumvname",name); Setattr(n,"feature:symname",evname); Delete( evname ); Printf( f_enumtypes_value, "| `%s\n", name ); return Language::enumvalueDeclaration(n); } else return SWIG_OK; } /* ------------------------------------------------------------------- * This function is a bit uglier than it deserves. * * I used to direct lookup the name of the enum. Now that certain fixes * have been made in other places, the names of enums are now fully * qualified, which is a good thing, overall, but requires me to do * some legwork. * * The other thing that uglifies this function is the varying way that * typedef enum and enum are handled. I need to produce consistent names, * which means looking up and registering by typedef and enum name. */ int enumDeclaration(Node *n) { String *name = Getattr(n,"name"); String *fully_qualified_name = fully_qualify_enum_name(n,name); bool seen_enum = false; if( name_qualifier ) Delete(name_qualifier); name_qualifier = fully_qualify_enum_name(n,NewString("")); seen_enum = name ? (Getattr(seen_enums,fully_qualified_name) ? true : false) : false; if( name && !seen_enum ) { const_enum = true; Printf( f_enum_to_int, "| `%s -> (match (y : c_enum_tag) with\n", name ); Printf( f_int_to_enum, "| `%s -> C_enum (\n", name ); /* * * * A note about enum name resolution * * * * * This code should now work, but I think we can do a bit better. * The problem I'm having is that swig isn't very precise about * typedef name resolution. My opinion is that SwigType_typedef * resolve_all should *always* return the enum tag if one exists, * rather than the admittedly friendlier enclosing typedef. * * This would make one of the cases below unnecessary. * * * */ Printf( f_mlbody, "let _ = Callback.register \"%s_marker\" (`%s)\n", fully_qualified_name, name ); if( !strncmp(Char(fully_qualified_name),"enum ",5) ) { String *fq_noenum = NewString(Char(fully_qualified_name) + 5); Printf( f_mlbody, "let _ = Callback.register \"%s_marker\" (`%s)\n", fq_noenum, name ); } Printf( f_enumtypes_type,"| `%s\n", name ); Insert(fully_qualified_name,0,"enum "); Setattr(seen_enums,fully_qualified_name,n); } int ret = Language::enumDeclaration(n); if( const_enum ) { Printf( f_int_to_enum, "`int y)\n", name ); Printf( f_enum_to_int, "| `int (x : int) -> C_int x\n" "| _ -> raise (Failure \"Unknown enum tag\"))\n" ); } const_enum = false; return ret; } /*************************************************************************** * BEGIN C++ Director Class modifications ***************************************************************************/ /* * Modified polymorphism code for Ocaml language module. * Original: * C++/Python polymorphism demo code, copyright (C) 2002 Mark Rose * * * TODO * * Move some boilerplate code generation to Swig_...() functions. * */ /* --------------------------------------------------------------- * classDirectorMethod() * * Emit a virtual director method to pass a method call on to the * underlying Python object. * * --------------------------------------------------------------- */ int classDirectorMethod(Node *n, Node *parent, String *super) { int is_void = 0; int is_pointer = 0; String *storage; String *value; String *decl; String *type; String *name; String *classname; String *declaration; ParmList *l; Wrapper *w; String *tm; String *wrap_args; String *return_type; int status = SWIG_OK; int idx; bool pure_virtual = false; storage = Getattr(n, "storage"); value = Getattr(n, "value"); classname = Getattr(parent, "sym:name"); type = Getattr(n, "type"); name = Getattr(n, "name"); if (Cmp(storage,"virtual") == 0) { if (Cmp(value,"0") == 0) { pure_virtual = true; } } w = NewWrapper(); declaration = NewString(""); Wrapper_add_local(w,"swig_result", "CAMLparam0();\n" "SWIG_CAMLlocal2(swig_result,args)"); /* determine if the method returns a pointer */ decl = Getattr(n, "decl"); is_pointer = SwigType_ispointer_return(decl); is_void = (!Cmp(type, "void") && !is_pointer); /* form complete return type */ return_type = Copy(type); { SwigType *t = Copy(decl); SwigType *f = 0; f = SwigType_pop_function(t); SwigType_push(return_type, t); Delete(f); Delete(t); } /* virtual method definition */ l = Getattr(n, "parms"); String *target; String *pclassname = NewStringf("SwigDirector_%s", classname); String *qualified_name = NewStringf("%s::%s", pclassname, name); target = Swig_method_decl(decl, qualified_name, l, 0, 0); String *rtype = SwigType_str(type, 0); Printf(w->def, "%s %s {", rtype, target); Delete(qualified_name); Delete(target); /* header declaration */ target = Swig_method_decl(decl, name, l, 0, 1); Printf(declaration, " virtual %s %s;\n", rtype, target); Delete(target); /* attach typemaps to arguments (C/C++ -> Ocaml) */ String *arglist = NewString(""); Swig_typemap_attach_parms("in", l, w); Swig_typemap_attach_parms("directorin", l, w); Swig_typemap_attach_parms("directorout", l, w); Swig_typemap_attach_parms("directorargout", l, w); Parm* p; int num_arguments = emit_num_arguments(l); int i; char source[256]; wrap_args = NewString(""); int outputs = 0; if (!is_void) outputs++; /* build argument list and type conversion string */ for (i=0, idx=0, p = l; i < num_arguments; i++) { while (Getattr(p, "tmap:ignore")) { p = Getattr(p, "tmap:ignore:next"); } if (Getattr(p, "tmap:directorargout") != 0) outputs++; String* pname = Getattr(p, "name"); String* ptype = Getattr(p, "type"); Putc(',',arglist); if ((tm = Getattr(p, "tmap:directorin")) != 0) { Replaceall(tm, "$input", pname); Replaceall(tm, "$owner", "0"); if (Len(tm) == 0) Append(tm, pname); Printv(wrap_args, tm, "\n", NIL); p = Getattr(p, "tmap:directorin:next"); continue; } else if (Cmp(ptype, "void")) { /* special handling for pointers to other C++ director classes. * ideally this would be left to a typemap, but there is currently no * way to selectively apply the dynamic_cast<> to classes that have * directors. in other words, the type "SwigDirector_$1_lname" only exists * for classes with directors. we avoid the problem here by checking * module.wrap::directormap, but it's not clear how to get a typemap to * do something similar. perhaps a new default typemap (in addition * to SWIGTYPE) called DIRECTORTYPE? */ if (SwigType_ispointer(ptype) || SwigType_isreference(ptype)) { Node *module = Getattr(parent, "module"); Node *target = Swig_directormap(module, ptype); sprintf(source, "obj%d", idx++); String *nonconst = 0; /* strip pointer/reference --- should move to Swig/stype.c */ String *nptype = NewString(Char(ptype)+2); /* name as pointer */ String *ppname = Copy(pname); if (SwigType_isreference(ptype)) { Insert(ppname,0,"&"); } /* if necessary, cast away const since Python doesn't support it! */ if (SwigType_isconst(nptype)) { nonconst = NewStringf("nc_tmp_%s", pname); String *nonconst_i = NewStringf("= const_cast<%s>(%s)", SwigType_lstr(ptype, 0), ppname); Wrapper_add_localv(w, nonconst, SwigType_lstr(ptype, 0), nonconst, nonconst_i, NIL); Delete(nonconst_i); Swig_warning(WARN_LANG_DISCARD_CONST, input_file, line_number, "Target language argument '%s' discards const in director method %s::%s.\n", SwigType_str(ptype, pname), classname, name); } else { nonconst = Copy(ppname); } Delete(nptype); Delete(ppname); String *mangle = SwigType_manglestr(ptype); if (target) { String *director = NewStringf("director_%s", mangle); Wrapper_add_localv(w, director, "Swig::Director *", director, "= 0", NIL); Wrapper_add_localv(w, source, "CAML_VALUE", source, "= Val_unit", NIL); Printf(wrap_args, "%s = dynamic_cast(%s);\n", director, nonconst); Printf(wrap_args, "if (!%s) {\n", director); Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle); Printf(wrap_args, "} else {\n"); Printf(wrap_args, "%s = %s->swig_get_self();\n", source, director); Printf(wrap_args, "}\n"); Delete(director); Printv(arglist, source, NIL); } else { Wrapper_add_localv(w, source, "CAML_VALUE", source, "= Val_unit", NIL); Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle); //Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE_p_%s, 0);\n", // source, nonconst, base); Printv(arglist, source, NIL); } Delete(mangle); Delete(nonconst); } else { Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0), classname, name); status = SWIG_NOWRAP; break; } } p = nextSibling(p); } /* declare method return value * if the return value is a reference or const reference, a specialized typemap must * handle it, including declaration of c_result ($result). */ if (!is_void) { Wrapper_add_localv(w, "c_result", SwigType_lstr(return_type, "c_result"), NIL); } Printv(w->code, "swig_result = Val_unit;\n",0); Printf(w->code,"args = Val_unit;\n"); /* direct call to superclass if _up is set */ if( pure_virtual ) { Printf(w->code, "if (swig_get_up()) {\n"); Printf(w->code, " throw Swig::DirectorPureVirtualException();\n"); Printf(w->code, "}\n"); } else { Printf(w->code, "if (swig_get_up()) {\n"); Printf(w->code, "CAMLreturn(%s);\n", Swig_method_call(super,l)); Printf(w->code, "}\n"); } /* wrap complex arguments to values */ Printv(w->code, wrap_args, NIL); /* pass the method call on to the Python object */ Printv(w->code, "swig_result = caml_swig_alloc(1,C_list);\n" "SWIG_Store_field(swig_result,0,args);\n" "args = swig_result;\n" "swig_result = Val_unit;\n",0); Printf(w->code, "swig_result = " "callback3(*caml_named_value(\"swig_runmethod\")," "swig_get_self(),copy_string(\"%s\"),args);\n", Getattr(n,"name")); /* exception handling */ tm = Swig_typemap_lookup_new("director:except", n, "result", 0); if (!tm) { tm = Getattr(n, "feature:director:except"); } if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) { Printf(w->code, "if (result == NULL) {\n"); Printf(w->code, " CAML_VALUE error = *caml_named_value(\"director_except\");\n"); Replaceall(tm, "$error", "error"); Printv(w->code, Str(tm), "\n", NIL); Printf(w->code, "}\n"); } /* * Python method may return a simple object, or a tuple. * for in/out aruments, we have to extract the appropriate values from the * argument list, then marshal everything back to C/C++ (return value and * output arguments). */ /* marshal return value and other outputs (if any) from value to C/C++ * type */ String* cleanup = NewString(""); String* outarg = NewString(""); idx = 0; /* this seems really silly. the node's type excludes * qualifier/pointer/reference markers, which have to be retrieved * from the decl field to construct return_type. but the typemap * lookup routine uses the node's type, so we have to swap in and * out the correct type. it's not just me, similar silliness also * occurs in Language::cDeclaration(). */ Setattr(n, "type", return_type); tm = Swig_typemap_lookup_new("directorout", n, "c_result", w); Setattr(n, "type", type); if (tm == 0) { String *name = NewString("c_result"); tm = Swig_typemap_search("directorout", return_type, name, NULL); Delete(name); } if (tm != 0) { Replaceall(tm, "$input", "swig_result"); /* TODO check this */ if (Getattr(n,"wrap:disown")) { Replaceall(tm,"$disown","SWIG_POINTER_DISOWN"); } else { Replaceall(tm,"$disown","0"); } Replaceall(tm, "$result", "c_result"); Printv(w->code, tm, "\n", NIL); } /* marshal outputs */ for (p = l; p; ) { if ((tm = Getattr(p, "tmap:directorargout")) != 0) { Replaceall(tm, "$input", "swig_result"); Replaceall(tm, "$result", Getattr(p, "name")); Printv(w->code, tm, "\n", NIL); p = Getattr(p, "tmap:directorargout:next"); } else { p = nextSibling(p); } } /* any existing helper functions to handle this? */ if (!is_void) { if (!SwigType_isreference(return_type)) { Printf(w->code, "CAMLreturn(c_result);\n"); } else { Printf(w->code, "CAMLreturn(*c_result);\n"); } } Printf(w->code, "}\n"); /* emit the director method */ if (status == SWIG_OK) { Wrapper_print(w, f_directors); Printv(f_directors_h, declaration, NIL); } /* clean up */ Delete(wrap_args); Delete(arglist); Delete(rtype); Delete(return_type); Delete(pclassname); Delete(cleanup); Delete(outarg); DelWrapper(w); return status; } /* ------------------------------------------------------------ * classDirectorConstructor() * ------------------------------------------------------------ */ int classDirectorConstructor(Node *n) { Node *parent = Getattr(n, "parentNode"); String *sub = NewString(""); String *decl = Getattr(n, "decl"); String *supername = Swig_class_name(parent); String *classname = NewString(""); Printf(classname, "SwigDirector_%s", supername); /* insert self and disown parameters */ Parm *p, *q, *ip; ParmList *superparms = Getattr(n, "parms"); ParmList *parms = CopyParmList(superparms); String *type = NewString("CAML_VALUE"); p = NewParm(type, NewString("self")); q = Copy(p); set_nextSibling(q, superparms); set_nextSibling(p, parms); parms = p; for (ip = parms; nextSibling(ip); ) ip = nextSibling(ip); p = NewParm(NewString("bool"), NewString("disown")); Setattr(p, "arg:byname", "1"); Setattr(n, "director:postfix_args", p); Setattr(p, "value", "0"); set_nextSibling(ip, p); /* constructor */ { Wrapper *w = NewWrapper(); String *call; String *basetype = Getattr(parent, "classtype"); String *target = Swig_method_decl(decl, classname, parms, 0, 0); call = Swig_csuperclass_call(0, basetype, superparms); Printf( w->def, "%s::%s: %s, Swig::Director(self, disown) { }", classname, target, call ); Delete(target); Wrapper_print(w, f_directors); Delete(call); DelWrapper(w); } /* constructor header */ { String *target = Swig_method_decl(decl, classname, parms, 0, 1); Printf(f_directors_h, " %s;\n", target); Delete(target); } Setattr(n,"parms",q); Language::classDirectorConstructor(n); Delete(sub); Delete(classname); Delete(supername); //Delete(parms); return SWIG_OK; } /* ------------------------------------------------------------ * classDirectorDefaultConstructor() * ------------------------------------------------------------ */ int classDirectorDefaultConstructor(Node *n) { String *classname; classname = Swig_class_name(n); /* insert self and disown parameters */ Parm *p, *q, *ip; ParmList *superparms = Getattr(n, "parms"); ParmList *parms = CopyParmList(superparms); String *type = NewString("CAML_VALUE"); p = NewParm(type, NewString("self")); q = Copy(p); set_nextSibling(p, parms); parms = p; for (ip = parms; nextSibling(ip); ) ip = nextSibling(ip); p = NewParm(NewString("bool"), NewString("disown")); Setattr(p, "arg:byname", "1"); Setattr(n, "director:postfix_args", p); Setattr(p, "value", "0"); set_nextSibling(ip, p); { Wrapper *w = NewWrapper(); Printf(w->def, "SwigDirector_%s::SwigDirector_%s(CAML_VALUE self, bool disown) : Swig::Director(self, disown) { }", classname, classname); Wrapper_print(w, f_directors); DelWrapper(w); } Printf(f_directors_h, " SwigDirector_%s(CAML_VALUE self, bool disown = true);\n", classname); Delete(classname); Setattr(n,"parms",q); return Language::classDirectorDefaultConstructor(n); } int classDirectorInit( Node *n ) { String *declaration = Swig_director_declaration(n); Printf( f_directors_h, "\n" "%s\n" "public:\n", declaration ); Delete( declaration ); return Language::classDirectorInit( n ); } int classDirectorEnd( Node *n ) { Printf( f_directors_h, "};\n\n" ); return Language::classDirectorEnd( n ); } /* --------------------------------------------------------------------- * typedefHandler * * This is here in order to maintain the correct association between * typedef names and enum names. * * Since I implement enums as polymorphic variant tags, I need to call * back into ocaml to evaluate them. This requires a string that can * be generated in the typemaps, and also at SWIG time to be the same * string. The problem that arises is that SWIG variously generates * enum e_name_tag * e_name_tag * e_typedef_name * for * typedef enum e_name_tag { ... } e_typedef_name; * * Since I need these strings to be consistent, I must maintain a correct * association list between typedef and enum names. * --------------------------------------------------------------------- */ int typedefHandler( Node *n ) { String *type = Getattr(n,"type"); Node *enum_node = type ? Getattr(seen_enums,type) : 0; if( enum_node ) { String *name = Getattr(enum_node,"name"); Printf( f_mlbody, "let _ = Callback.register \"%s_marker\" (`%s)\n", Getattr(n,"name"), name ); } return SWIG_OK; } }; /* ------------------------------------------------------------------------- * swig_ocaml() - Instantiate module * ------------------------------------------------------------------------- */ static Language * new_swig_ocaml() { return new OCAML(); } extern "C" Language * swig_ocaml(void) { return new_swig_ocaml(); } cableswig-0.1.0+git20150808.orig/SWIG/Source/Modules/contract.cxx0000644000175000000620000002331112561312227023007 0ustar stevestaff/* ----------------------------------------------------------------------------- * contract.cxx * * Support for Wrap by Contract in SWIG * * Author(s) : Songyan Feng (Tiger) (songyanf@cs.uchicago.edu) * David Beazley (beazley@cs.uchicago.edu) * * Department of Computer Science * University of Chicago * * Copyright (C) 1999-2003. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_contract_cxx[] = "/cvsroot/SWIG/Source/Modules/contract.cxx,v 1.13 2003/12/28 21:47:58 cheetah Exp"; #include "swigmod.h" /* Contract structure. This holds rules about the different kinds of contract sections and their combination rules */ struct contract { const char *section; const char *combiner; }; /* Contract rules. This table defines what contract sections are recognized as well as how contracts are to combined via inheritance */ static contract Rules[] = { {"require:", "&&"}, {"ensure:", "||"}, { NULL, NULL} }; /************************************************************************ * class Contracts: * * This class defines the functions that need to be used in * "wrap by contract" module. *************************************************************************/ class Contracts : public Dispatcher { String *make_expression(String *s, Node *n); void substitute_parms(String *s, ParmList *p, int method); public: Hash *ContractSplit(Node *n); int emit_contract(Node *n, int method); int cDeclaration(Node *n); int constructorDeclaration(Node *n); int externDeclaration(Node *n); int extendDirective(Node *n); int importDirective(Node *n); int includeDirective(Node *n); int classDeclaration(Node *n); virtual int top(Node *n); }; static int Contract_Mode = 0; /* contract option */ static int InClass = 0; /* Parsing C++ or not */ static int InConstructor = 0; static Node *CurrentClass = 0; /* Set the contract mode, default is 0 (not open) */ /* Normally set in main.cxx, when get the "-contracts" option */ void Swig_contract_mode_set(int flag) { Contract_Mode = flag; } /* Get the contract mode */ int Swig_contract_mode_get() { return Contract_Mode; } /* Apply contracts */ void Swig_contracts(Node *n) { Contracts *a = new Contracts; a->top(n); delete a; } /* Split the whole contract into preassertion, postassertion and others */ Hash *Contracts::ContractSplit(Node *n) { String *contract = Getattr(n, "feature:contract"); Hash *result; if (!contract) return NULL; result = NewHash(); String *current_section = NewString(""); const char *current_section_name = Rules[0].section; List *l = SplitLines(contract); Iterator i; for (i = First(l); i.item; i = Next(i)) { int found = 0; if (Strstr(i.item,"{")) continue; if (Strstr(i.item,"}")) continue; for (int j = 0; Rules[j].section; j++) { if (Strstr(i.item,Rules[j].section)) { if (Len(current_section)) { Setattr(result,current_section_name,current_section); current_section = Getattr(result,Rules[j].section); if (!current_section) current_section = NewString(""); } current_section_name = Rules[j].section; found = 1; break; } } if (!found) Append(current_section, i.item); } if (Len(current_section)) Setattr(result, current_section_name, current_section); return result; } /* This function looks in base classes and collects contracts found */ void inherit_contracts(Node *c, Node *n, Hash *contracts, Hash *messages) { Node *b, *temp; String *name, *type, *local_decl, *base_decl; List *bases; int found = 0; bases = Getattr(c,"bases"); if (!bases) return; name = Getattr(n, "name"); type = Getattr(n, "type"); local_decl = Getattr(n, "decl"); if (local_decl) { local_decl = SwigType_typedef_resolve_all(local_decl); } else { return; } /* Width first search */ for (int i = 0; i < Len(bases); i++) { b = Getitem(bases,i); temp = firstChild (b); while (temp) { base_decl = Getattr(temp, "decl"); if (base_decl) { base_decl = SwigType_typedef_resolve_all(base_decl); if ( (checkAttribute(temp, "storage", "virtual")) && (checkAttribute(temp, "name", name)) && (checkAttribute(temp, "type", type)) && (!Strcmp(local_decl, base_decl)) ) { /* Yes, match found. */ Hash *icontracts = Getattr(temp,"contract:rules"); Hash *imessages = Getattr(temp,"contract:messages"); found = 1; if (icontracts && imessages) { /* Add inherited contracts and messages to the contract rules above */ int j = 0; for (j = 0; Rules[j].section; j++) { String *t = Getattr(contracts, Rules[j].section); String *s = Getattr(icontracts, Rules[j].section); if (s) { if (t) { Insert(t,0,"("); Printf(t,") %s (%s)", Rules[j].combiner, s); String *m = Getattr(messages, Rules[j].section); Printf(m," %s [%s from %s]", Rules[j].combiner, Getattr(imessages,Rules[j].section), Getattr(b,"name")); } else { Setattr(contracts, Rules[j].section, NewString(s)); Setattr(messages,Rules[j].section,NewStringf("[%s from %s]", Getattr(imessages,Rules[j].section), Getattr(b,"name"))); } } } } } Delete(base_decl); } temp = nextSibling(temp); } } Delete(local_decl); if (!found) { for (int j = 0; j < Len(bases); j++) { b = Getitem(bases,j); inherit_contracts(b,n,contracts,messages); } } } /* This function cleans up the assertion string by removing some extraneous characters. Splitting the assertion into pieces */ String *Contracts::make_expression(String *s, Node *n) { String *str_assert, *expr = 0; List *list_assert; str_assert = NewString(s); /* Omit all useless characters and split by ; */ Replaceall(str_assert, "\n", ""); Replaceall(str_assert, "{", ""); Replaceall(str_assert, "}", ""); Replace(str_assert, " ", "", DOH_REPLACE_ANY | DOH_REPLACE_NOQUOTE); Replace(str_assert, "\t", "", DOH_REPLACE_ANY | DOH_REPLACE_NOQUOTE); list_assert = Split(str_assert, ';', -1); Delete(str_assert); /* build up new assertion */ str_assert = NewString(""); Iterator ei; for (ei = First(list_assert); ei.item; ei = Next(ei)) { expr = ei.item; if (Len(expr)) { Replaceid(expr, Getattr(n,"name"), "result"); if (Len(str_assert)) Append(str_assert, "&&"); Printf(str_assert, "(%s)", expr); } } Delete(list_assert); return str_assert; } /* This function substitutes parameter names for argument names in the contract specification. Note: it is assumed that the wrapper code uses arg1--argn for arguments. */ void Contracts::substitute_parms(String *s, ParmList *p, int method) { int argnum = 1; char argname[32]; if (method) { Replaceid(s,"self","arg0"); argnum++; } while (p) { sprintf(argname,"arg%d",argnum); String *name = Getattr(p,"name"); if (name) { Replaceid(s,name,argname); } argnum++; p = nextSibling(p); } } int Contracts::emit_contract(Node *n, int method) { Hash *contracts; Hash *messages; String *c; ParmList *cparms; if (!Getattr(n, "feature:contract")) return SWIG_ERROR; /* Get contract parameters */ cparms = Getmeta(Getattr(n, "feature:contract"), "parms"); /* Split contract into preassert & postassert */ contracts = ContractSplit(n); if (!contracts) return SWIG_ERROR; /* This messages hash is used to hold the error messages that will be displayed on failed contract. */ messages = NewHash(); /* Take the different contract expressions and clean them up a bit */ Iterator i; for (i = First(contracts); i.item; i = Next(i)) { String *e = make_expression(i.item, n); substitute_parms(e, cparms, method); Setattr(contracts,i.key,e); /* Make a string containing error messages */ Setattr(messages,i.key, NewString(e)); } /* If we're in a class. We need to inherit other assertions. */ if (InClass) { inherit_contracts(CurrentClass, n, contracts, messages); } /* Save information */ Setattr(n,"contract:rules", contracts); Setattr(n,"contract:messages", messages); /* Okay. Generate the contract runtime code. */ if ((c = Getattr(contracts,"require:"))) { Setattr(n,"contract:preassert", NewStringf("SWIG_contract_assert(%s, \"Contract violation: require: %s\");\n", c, Getattr(messages,"require:"))); } if ((c = Getattr(contracts,"ensure:"))) { Setattr(n,"contract:postassert", NewStringf("SWIG_contract_assert(%s, \"Contract violation: ensure: %s\");\n", c, Getattr(messages,"ensure:"))); } return SWIG_OK; } int Contracts::cDeclaration(Node *n) { int ret = SWIG_OK; String *decl = Getattr(n,"decl"); /* Not a function. Don't even bother with it (for now) */ if (!SwigType_isfunction(decl)) return SWIG_OK; if (Getattr(n, "feature:contract")) ret = emit_contract(n, (InClass && !checkAttribute(n,"storage","static"))); return ret; } int Contracts::constructorDeclaration(Node *n){ int ret = SWIG_OK; InConstructor = 1; if (Getattr(n, "feature:contract")) ret = emit_contract(n,0); InConstructor = 0; return ret; } int Contracts::externDeclaration(Node *n) { return emit_children(n); } int Contracts::extendDirective(Node *n) { return emit_children(n); } int Contracts::importDirective(Node *n) { return emit_children(n); } int Contracts::includeDirective(Node *n) { return emit_children(n); } int Contracts::classDeclaration(Node *n) { int ret = SWIG_OK; InClass = 1; CurrentClass = n; emit_children(n); InClass = 0; CurrentClass = 0; return ret; } int Contracts::top(Node *n) { emit_children(n); return SWIG_OK; } cableswig-0.1.0+git20150808.orig/SWIG/Source/Modules/chicken.cxx0000644000175000000620000015567312561312227022617 0ustar stevestaff/******************************************************************** * CHICKEN module for SWIG * * Author : Jonah Beckford * * Modified from mzscheme.cxx, guile.cxx and python.cxx : David * Beazley * * Please read the file LICENSE for the copyright and terms by which * SWIG can be used and distributed. * ********************************************************************/ char cvsroot_chicken_cxx[] = "/cvsroot/SWIG/Source/Modules/chicken.cxx,v 1.13 2004/01/22 22:42:14 cheetah Exp"; /*********************************************************************** * /cvsroot/SWIG/Source/Modules/chicken.cxx,v 1.13 2004/01/22 22:42:14 cheetah Exp * * chicken.cxx * * Definitions for adding functions to CHICKEN ***********************************************************************/ #include "swigmod.h" #include static const char *chicken_usage = (char*)"\ \ CHICKEN Options (available with -chicken)\n\ -prefix - Set a prefix to be prepended to all names\n\ Defaults to the name of the module\n\ -noprefix - Don't use a prefix\n\ -mixed - Convert mixed case (ex. aMethodName) into\n\ dash seperated, lower case (ex. a-method-name)\n\ -noclos - Don't generate clos TinyCLOS code\n\ -nogeneric - Don't generate (make-generic) definitions\n\ -ldflags - Print runtime libraries to link with\n\ \n" ; #define SCMCLOS_MEMBER 0x2 #define SCMCLOS_STATIC_MEMBER 0x4 static String *prefix=0; static int noprefix=0; static String *module=0; static String *realmodule=0; static char *chicken_path=(char*)"chicken"; static int clos = 1; static int generic = 1; static int mixed = 0; static int num_methods = 0; static File *f_runtime = 0; static File *f_header = 0; static File *f_wrappers = 0; static File *f_init_helper = 0; static File *f_sym_size = 0; static File *f_init = 0; static File *f_scm = 0; static File *f_scm_stubs = 0; static File *f_clos = 0; static File *f_generic = 0; static String *clos_indent = 0; /* C++ Support + Clos Classes */ static int in_class = 0; static int classic = 0; static int have_constructor; static String *class_name = 0; static String *short_class_name = 0; static String *real_classname; static Hash *known_classes = 0; class CHICKEN : public Language { public: virtual void main(int argc, char *argv[]); virtual int top(Node *n); virtual int importDirective(Node *n); virtual int insertDirective(Node *n); virtual int functionWrapper(Node *n); /* ------------------------------------------------------------ * variableWrapper() * * Create a link to a C variable. This creates a single function * _wrap_swig_var_varname(). This function takes a single optional * argument. If supplied, it means we are setting this variable to * some value. If omitted, it means we are simply evaluating this * variable. Either way, we return the variables value. * ------------------------------------------------------------ */ virtual int variableWrapper(Node *n); virtual int constantWrapper(Node *n); virtual int classDeclaration(Node *n); virtual int classHandler(Node *n); virtual int memberfunctionHandler(Node *n); virtual int membervariableHandler(Node *n); virtual int memberconstantHandler(Node *n); virtual int staticmemberfunctionHandler(Node *n); virtual int staticmembervariableHandler(Node *n); virtual int destructorHandler(Node *n); virtual int constructorHandler(Node *n); virtual int validIdentifier(String *s); protected: void addMethod(String *, String *scheme_name, String *function); void throwUnhandledChickenTypeError(SwigType *d); /* Return true iff T is a pointer type */ int isPointer(SwigType *t); void dispatchFunction(Node *n); /* Output CHICKEN code into the clos file */ String* chickenCode(String *code, const String *indent); void namify(String *scmname); /* search for a typemap("TYPEMAP") SEARCHCLASS */ String* singleSearch(const char *typemap, char *argname, SwigType *searchClass); /* do a recursive search for a typemap("TYPEMAP") SEARCHCLASS. example: typename can be "in" or "out"; argname can be "result" for output typemaps or Getattr(parm, "name") for an input parameter, and 'n' may be a class definition or anything else. */ String* recurseSearch(const char *typemap, char *argname, Node *n); void selectOutOneOrMany(String *tm, int is_many); }; /* ----------------------------------------------------------------------- * swig_chicken() - Instantiate module * ----------------------------------------------------------------------- */ static Language * new_swig_chicken() { return new CHICKEN(); } extern "C" Language * swig_chicken(void) { return new_swig_chicken(); } void CHICKEN::main(int argc, char *argv[]) { int i; SWIG_library_directory(chicken_path); // Look for certain command line options for (i = 1; i < argc; i++) { if (argv[i]) { if (strcmp(argv[i], "-help") == 0) { fputs(chicken_usage, stderr); SWIG_exit(0); } else if (strcmp(argv[i], "-prefix") == 0) { if (argv[i + 1]) { prefix = NewString(argv [i + 1]); Swig_mark_arg(i); Swig_mark_arg(i + 1); i++; } else { Swig_arg_error(); } } else if (strcmp(argv[i],"-noprefix") == 0) { noprefix = 1; Swig_mark_arg(i); } else if (strcmp(argv[i],"-mixed") == 0) { mixed = 1; Swig_mark_arg(i); } else if (strcmp(argv[i],"-noclos") == 0) { clos = 0; Swig_mark_arg(i); } else if (strcmp(argv[i],"-nogeneric") == 0) { generic = 0; Swig_mark_arg(i); } else if (strcmp(argv[i], "-ldflags") == 0) { printf("%s\n", SWIG_CHICKEN_RUNTIME); SWIG_exit(EXIT_SUCCESS); } } } // Add a symbol for this module Preprocessor_define("SWIGCHICKEN 1",0); // Set name of typemaps SWIG_typemap_lang("chicken"); // Read in default typemaps */ SWIG_config_file("chicken.swg"); allow_overloading(); } int CHICKEN::top(Node *n) { String *chicken_filename; String *clos_filename; String *generic_filename; if (!CPlusPlus) { clos = 0; generic = 0; } known_classes = NewHash(); /* Initialize all of the output files */ String *outfile = Getattr(n,"outfile"); f_runtime = NewFile(outfile,"w"); if (!f_runtime) { Printf(stderr,"*** Can't open '%s'\n", outfile); SWIG_exit(EXIT_FAILURE); } f_sym_size = NewString(""); f_init_helper = NewString("\n"); f_init = NewString(""); f_header = NewString(""); f_wrappers = NewString(""); chicken_filename = NewString(""); clos_filename = NewString(""); generic_filename = NewString(""); /* Register file targets with the SWIG file handler */ Swig_register_filebyname("header",f_header); Swig_register_filebyname("wrapper",f_wrappers); Swig_register_filebyname("runtime",f_runtime); Swig_register_filebyname("init_helper",f_init_helper); Swig_register_filebyname("init",f_init); Printf(f_runtime, "/* -*- buffer-read-only: t -*- vi: set ro: */\n"); Swig_banner(f_runtime); if (NoInclude) { Printf(f_runtime, "#define SWIG_NOINCLUDE\n"); } /* Set module name */ realmodule = Copy(Getattr(n,"name")); module = Copy(realmodule); namify(module); /* Set prefix. If a prefix has been specified make sure it ends in a '-' */ if (noprefix) { prefix = NewString(""); } else { if (!prefix) { prefix = Copy(module); } if (Len(prefix) && ((Char(prefix)) [Len(prefix) - 1] != ':')) { Append(prefix, ":"); } } Printf(chicken_filename,"%s%s.scm", SWIG_output_directory(), module); if ((f_scm = NewFile(chicken_filename,"w")) == 0) { Printf(stderr,"Unable to open %s\n", chicken_filename); SWIG_exit(EXIT_FAILURE); } f_scm_stubs = NewString(""); Swig_register_filebyname("chicken",f_scm); Printv(f_scm, ";; -*- buffer-read-only: t -*- vi: set ro:\n", ";; This file was created automatically by SWIG.\n", ";; Don't modify this file, modify the SWIG interface instead.\n", NIL); Printv(f_scm,"(cond-expand ((or chicken-compile-shared shared)) (else (declare (unit ", module, "))))\n\n", NIL); #ifdef JONAH_IS_CRAZY Printv(f_scm,"(declare \n", tab4, "(foreign-declare \"void* ", realmodule, "_swig_get_type(char*);\"))\n", NIL); #endif #ifndef INIT_BINDING Printv(f_scm,"(declare \n", tab4, "(hide swig-init)\n", tab4, "(foreign-declare \"C_extern void ", realmodule, "_swig_init(int,C_word,C_word) C_noret;\"))\n", NIL); Printv(f_scm,"(define swig-init (##core#primitive \"", realmodule, "_swig_init\"))\n", NIL); Printv(f_scm,"(swig-init)\n\n", NIL); #endif #ifdef JONAH_IS_CRAZY Printv(f_scm,"(define-record swig-",prefix,"tag class name ptr str)\n", "(define-record-printer (swig-",prefix,"tag tag out)\n", tab4, "(fprintf out \"#(~A)\" (swig-",prefix, "tag-str tag)\n", tab8, "(swig-",prefix,"tag-ptr tag)))\n", NIL); #endif // Include some information in the code Printf(f_header,"\n/*-----------------------------------------------\n @(target):= %s.so\n\ ------------------------------------------------*/\n", module); if (generic) { Printf(generic_filename,"%s%s-generic.scm", SWIG_output_directory(), module); if ((f_generic = NewFile(generic_filename,"w")) == 0) { Printf(stderr,"Unable to open %s\n", generic_filename); SWIG_exit (EXIT_FAILURE); } Swig_register_filebyname("generic",f_generic); Printv(f_generic, ";; -*- buffer-read-only: t -*- vi: set ro:\n", ";; This file was created automatically by SWIG.\n", ";; Don't modify this file, modify the SWIG interface instead.\n", NIL); } if (clos) { Printf(clos_filename,"%s%s-clos.scm", SWIG_output_directory(), module); if ((f_clos = NewFile(clos_filename,"w")) == 0) { Printf(stderr,"Unable to open %s\n", clos_filename); SWIG_exit (EXIT_FAILURE); } Swig_register_filebyname("clos",f_clos); Printv(f_clos, ";; -*- buffer-read-only: t -*- vi: set ro:\n", ";; This file was created automatically by SWIG.\n", ";; Don't modify this file, modify the SWIG interface instead.\n", NIL); Printf (f_clos, "(declare (uses extras))\n"); } Printf(f_header,"#define SWIG_name \"%s\"\n", realmodule); Printf(f_wrappers,"#ifdef __cplusplus\n"); Printf(f_wrappers,"extern \"C\" {\n"); Printf(f_wrappers,"#endif\n\n"); #ifdef JONAH_IS_CRAZY Printv(f_init_helper, "#ifdef __cplusplus\n", "extern \"C\"\n", "#endif\n", "SWIGEXPORT(void *) ", realmodule, "_swig_get_type (char *type) {\n", "int i;\n", "for (i = 0; swig_types_initial[i]; i++) {\n", "if (strcmp (type, swig_types[i]->name) == 0) ", "return swig_types[i];\n", "}\n", "return NULL;\n", "}\n\n", NIL); #endif Printf(f_init_helper, "static void swig_init_helper (C_word continuation) C_noret;\n"); Printf(f_init_helper, "static void swig_init_helper (C_word continuation) {\n"); Printf(f_init_helper, "C_word sym;\n"); Printf(f_init_helper, "C_word tmp;\n"); Printf(f_init_helper, "C_word *a = C_alloc (2*$nummethods$symsize);\n"); #ifdef INIT_BINDING { String *tmp = NewString(""); String *tmp2 = NewString("swig-init"); Printv(tmp, realmodule, "_swig_init", NIL); addMethod(tmp, tmp2, tmp); Delete(tmp); Delete(tmp2); } #endif /* emit code */ Language::top(n); /* Close language module */ SwigType_emit_type_table(f_runtime, f_wrappers); Printf(f_wrappers,"#ifdef __cplusplus\n"); Printf(f_wrappers,"}\n"); Printf(f_wrappers,"#endif\n"); Printf(f_init_helper, "C_kontinue (continuation, C_SCHEME_TRUE);\n"); Printf(f_init_helper, "}\n"); char buftmp[20]; sprintf(buftmp, "%d", num_methods); Replaceall(f_init_helper, "$nummethods", buftmp); Replaceall(f_init_helper, "$symsize", f_sym_size); Delete(chicken_filename); Delete(clos_filename); Delete(generic_filename); Printv(f_scm, f_scm_stubs, "\n",NIL); Close(f_scm); Delete(f_scm); if (clos) { Close(f_clos); Delete(f_clos); } if (generic) { Close(f_generic); Delete(f_generic); } Delete(prefix); Delete(known_classes); /* Close all of the files */ Dump(f_header,f_runtime); Dump(f_wrappers,f_runtime); Wrapper_pretty_print(f_init_helper,f_runtime); Wrapper_pretty_print(f_init,f_runtime); Delete(f_header); Delete(f_wrappers); Delete(f_sym_size); Delete(f_init_helper); Delete(f_init); Close(f_runtime); Delete(f_runtime); return SWIG_OK; } int CHICKEN::importDirective(Node *n) { String *modname = Getattr(n,"module"); if (modname) { Printf(f_scm,"(declare (uses %s))\n", modname); } return Language::importDirective(n); } int CHICKEN::insertDirective(Node *n) { String *code = Getattr(n,"code"); Replaceall(code, "$module", module); Replaceall(code, "$realmodule", realmodule); return Language::insertDirective(n); } int CHICKEN::functionWrapper(Node *n) { String *name = Getattr(n,"name"); String *iname = Getattr(n,"sym:name"); SwigType *d = Getattr(n,"type"); ParmList *l = Getattr(n,"parms"); Parm *p; int i; String *wname; char source[64]; Wrapper *f; String *mangle = NewString(""); String *known_alloca; String *known_alloca_plus; String *get_pointers; String *cleanup; String *outarg; String *tm; String *am; String *overname = 0; String *declfunc = 0; String *scmname; String *closparam; String *closargs; String *closwrapargs; int num_required; int num_arguments; Printf(mangle, "\"%s\"", SwigType_manglestr(d)); if (Getattr(n,"sym:overloaded")) { overname = Getattr(n,"sym:overname"); } else { if (!addSymbol(iname,n)) return SWIG_ERROR; } f = NewWrapper(); wname = NewString(""); known_alloca = NewString(""); known_alloca_plus = NewString(""); get_pointers = NewString(""); cleanup = NewString(""); outarg = NewString(""); declfunc = NewString(""); closargs = NewString(""); closwrapargs = NewString(""); scmname = NewString(iname); namify(scmname); /* Local vars */ Wrapper_add_local(f,"resultobj", "C_word resultobj"); /* Write code to extract function parameters. */ emit_args(d, l, f); /* Attach the standard typemaps */ emit_attach_parmmaps(l,f); Setattr(n,"wrap:parms",l); /* Get number of required and total arguments */ num_arguments = emit_num_arguments(l); num_required = emit_num_required(l); Append(wname, realmodule); Append(wname, Swig_name_wrapper(iname)); if (overname) { Append(wname, overname); } // Check for interrupts Printv (f->code, "C_trace(\"",scmname,"\");\n", NIL); Printv(f->def, #ifndef BINDING "static ", #endif "void ", wname, " (int argc, C_word closure, C_word continuation", NIL); Printv(declfunc, "void ", wname, "(int,C_word,C_word", NIL); /* Calculate fixed alloca code */ int result_list_len = 0; int has_void_return = 0; int will_alloca = 0; for (p = l; p;) { if ((tm = Getattr(p,"tmap:argout:chicken_words"))) { Replaceall(tm,"$typename", mangle); if (strcmp(Char(tm), "void") == 0) continue; if (strcmp(Char(tm), "0") != 0) will_alloca = 1; if (result_list_len) { Printf(known_alloca_plus, " + "); } else { Printf(known_alloca, "%s /*%s*/", tm, Getattr(p,"lname")); } Printf(known_alloca_plus, "3+%s /*%s*/", tm, Getattr(p,"lname")); result_list_len++; p = Getattr(p,"tmap:argout:next"); } else { p = nextSibling(p); } } if ((tm = Swig_typemap_lookup_new("out",n,"result",0))) { if ((am = Getattr(n,"tmap:out:chicken_words"))) { Replaceall(am,"$typename", mangle); if (strcmp(Char(am), "void") == 0) { has_void_return = 1; } else { if (strcmp(Char(am), "0") != 0) will_alloca = 1; if (result_list_len) { Printf(known_alloca_plus, " + "); } else { Printf(known_alloca, "%s /*result*/", am); } Printf(known_alloca_plus, "3+%s /*result*/", am); result_list_len++; } } } /* Generate known_space code */ if (result_list_len > 1 || (will_alloca && result_list_len == 1)) { if (result_list_len == 1) { Wrapper_add_local(f,"known_space", "C_word *known_space"); Printf(f->code, " known_space = C_alloc (%s);\n", known_alloca); } else { Wrapper_add_local(f,"known_space", "C_word *known_space"); Printf(f->code, " /* allocate space for fixed-size scheme objects " "used for output */\n"); Printf(f->code, " known_space = C_alloc (%s); " "/* The '3' in 3+... is to alloc a C_pair " "in the Scheme list 'resultobj' */ \n", known_alloca_plus); } } /* Generate code for argument marshalling */ for (i = 0, p=l; i < num_arguments; i++) { while (checkAttribute(p,"tmap:in:numinputs","0")) { p = Getattr(p,"tmap:in:next"); } SwigType *pt = Getattr(p,"type"); String *pn = Getattr(p,"name"); String *ln = Getattr(p,"lname"); SwigType *pb = SwigType_base(pt); sprintf(source,"scm%d",i+1); Printf(f->def, ", C_word scm%d", i+1); Printf(declfunc,",C_word"); closparam = NewString(""); Printf(closparam, "%%%d", i+1); Printv(closargs, " ", closparam, NIL); /* Look for an clos input conversion */ int gotwrap = 0; Node *search; String *tm = 0; if ((search = Getattr(known_classes, pb)) || (tm = singleSearch("clos_in", Char(pn), pb))) { /* search for typemap("clos_in") CLASS_OR_BASE_CLASS */ if (tm || (tm = recurseSearch("clos_in", Char(pn), search))) { String *cn = NewString(""); Printv(cn, "<", prefix, pb, ">", NIL); namify(cn); Replaceall(tm, "$class", cn); Replaceall(tm, "$input", closparam); Printv(closwrapargs, " ", tm, NIL); gotwrap = 1; Delete(cn); } else { Swig_warning(WARN_TYPEMAP_UNDEF, input_file, line_number, "Unable to find \"%%typemap(clos_in) %s *\" " "or typemaps for any superclasses.\n", SwigType_str(pb,0)); } } if (!gotwrap) { Printv(closwrapargs, " ", closparam, NIL); } Delete(closparam); /* Look for an input typemap */ if ((tm = Getattr(p,"tmap:in"))) { String *parse = Getattr(p,"tmap:in:parse"); if (!parse) { Replaceall(tm,"$source",source); Replaceall(tm,"$target",ln); Replaceall(tm,"$input", source); Setattr(p,"emit:input", source); /* Save the location of the object */ if (Getattr(p,"wrap:disown") || (Getattr(p,"tmap:in:disown"))) { Replaceall(tm,"$disown","SWIG_POINTER_DISOWN"); } else { Replaceall(tm,"$disown","0"); } if (i >= num_required) Printv(get_pointers, "if (", source, ") {\n", NIL); Printv(get_pointers,tm,"\n", NIL); if (i >= num_required) Printv(get_pointers, "}\n", NIL); } else { } p = Getattr(p,"tmap:in:next"); continue; } else { Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt,0)); break; } p = nextSibling(p); } /* finish argument marshalling */ Printf(f->def, ") {"); Printf(declfunc, ")"); /* Now piece together the first part of the wrapper function */ Printv(f->code, get_pointers, NIL); /* Insert constraint checking code */ for (p = l; p;) { if ((tm = Getattr(p,"tmap:check"))) { Replaceall(tm,"$target",Getattr(p,"lname")); Printv(f->code,tm,"\n",NIL); p = Getattr(p,"tmap:check:next"); } else { p = nextSibling(p); } } /* Insert cleanup code */ for (p = l; p;) { if ((tm = Getattr(p,"tmap:freearg"))) { Replaceall(tm,"$source",Getattr(p,"lname")); Printv(cleanup,tm,"\n",NIL); p = Getattr(p,"tmap:freearg:next"); } else { p = nextSibling(p); } } /* Want outputs done in reverse order */ List *l_out = NewList(); /* Return the function value */ if (has_void_return && result_list_len == 1) { /* do absolutely nothing since result will be initted elsewhere by one argout */ } else if ((tm = Swig_typemap_lookup_new("out",n,"result",0))) { Replaceall(tm,"$source", "result"); Replaceall(tm,"$target", "resultobj"); Replaceall(tm,"$result", "resultobj"); if (Getattr(n,"feature:new")) { Replaceall(tm,"$owner","1"); } else { Replaceall(tm,"$owner","0"); } selectOutOneOrMany(tm, result_list_len > 1); Append(l_out, tm); } else { Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d,0), name); } /* Insert argument output code */ for (p = l; p;) { if ((tm = Getattr(p,"tmap:argout"))) { Replaceall(tm,"$source",Getattr(p,"lname")); Replaceall(tm,"$target","resultobj"); Replaceall(tm,"$arg",Getattr(p,"emit:input")); Replaceall(tm,"$input",Getattr(p,"emit:input")); selectOutOneOrMany(tm, result_list_len > 1); Append(l_out, tm); p = Getattr(p,"tmap:argout:next"); } else { p = nextSibling(p); } } /* Emit the function call */ emit_action(n,f); /* Output argument output code */ int i_out; if (result_list_len > 1) { Printv(f->code, "resultobj = C_SCHEME_UNDEFINED;\n", NIL); } for (i_out = Len(l_out); i_out > 0; ) { Printv(f->code, (String *) Getitem(l_out, --i_out), "\n", NIL); } /* Output cleanup code */ Printv(f->code,cleanup,NIL); /* Look to see if there is any newfree cleanup code */ if (Getattr(n,"feature:new")) { if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) { Replaceall(tm,"$source","result"); Printf(f->code,"%s\n",tm); } } /* See if there is any return cleanup code */ if ((tm = Swig_typemap_lookup_new("ret", n, "result", 0))) { Replaceall(tm,"$source","result"); Printf(f->code,"%s\n",tm); } Printf(f->code," C_kontinue (continuation, resultobj);\n"); /* Error handling code */ #ifdef USE_FAIL Printf(f->code,"fail:\n"); Printv(f->code,cleanup,NIL); Printf(f->code,"swig_panic (\"failure in " "'$symname' SWIG function wrapper\");\n"); #endif Printf(f->code,"}\n"); /* Substitute the cleanup code */ Replaceall(f->code,"$cleanup",cleanup); /* Substitute the function name */ Replaceall(f->code,"$symname",iname); Replaceall(f->code,"$result","resultobj"); /* Dump the function out */ Printv(f_wrappers, #ifndef BINDING "static ", #endif declfunc, " C_noret;\n", NIL); Wrapper_print(f,f_wrappers); Setattr(n,"wrap:name", wname); /* Now register the function with the interpreter. */ if (!Getattr(n,"sym:overloaded")) { addMethod(iname, scmname, wname); /* Create a binding for this function */ #ifdef BINDING Printv(f_scm, "(declare (foreign-declare \"C_extern ", declfunc, " C_noret;\"))\n", NIL); Printv(f_scm, "(define ", prefix, scmname, " (##core#primitive \"", realmodule, "_wrap_", iname, "\"))\n\n", NIL); #endif } else { if (!Getattr(n,"sym:nextSibling")) { dispatchFunction(n); } } /* Look for typemap(clos_out) */ closparam = NewString(""); Printv(closparam, "(", prefix, scmname, closwrapargs, ")", NIL); Node *search; String *pb = SwigType_base(d); tm = 0; if ((search = Getattr(known_classes, pb)) || (tm = singleSearch("clos_out", Char(closparam), pb))) { /* search for typemap("clos_out") CLASS_OR_BASE_CLASS */ if (tm || (tm = recurseSearch("clos_out", Char(closparam), search))) { String *cn = NewString(""); Printv(cn, "<", prefix, pb, ">", NIL); namify(cn); Replaceall(tm, "$class", cn); Delete(closparam); Delete(cn); closparam = Copy(tm); } else { Swig_warning(WARN_TYPEMAP_UNDEF, input_file, line_number, "Unable to find \"%%typemap(clos_out) %s *\" " "or typemaps for any superclasses.\n", SwigType_str(pb,0)); } } /* Dump clos code if enabled and not in a non-static member function */ if (!Getattr(n,"sym:overloaded")) { if (clos && (!(clos & SCMCLOS_MEMBER) || (clos & SCMCLOS_STATIC_MEMBER))) { Printv(f_clos, "(define (+", prefix, scmname, "+", closargs, ")\n", tab4, closparam, ")\n", NIL); } } Delete(closparam); Delete(wname); Delete(l_out); Delete(known_alloca); Delete(known_alloca_plus); Delete(get_pointers); Delete(cleanup); Delete(outarg); Delete(declfunc); Delete(mangle); Delete(closwrapargs); Delete(closargs); DelWrapper(f); return SWIG_OK; } int CHICKEN::variableWrapper(Node *n) { char *name = GetChar(n,"name"); char *iname = GetChar(n,"sym:name"); SwigType *t = Getattr(n,"type"); SwigType *pb = SwigType_base(t); ParmList *l = Getattr(n,"parms"); String *proc_name = NewString(""); char var_name[256]; String *wname = NewString(""); String *mangle = NewString(""); String *tm; String *am; String *tm2 = NewString("");; String *argnum = NewString("0"); String *arg = NewString("argv[0]"); String *known_alloca = NewString(""); Wrapper *f; String *overname = 0; String *scmname; String *closparam; String *closargs; String *closwrapargs; int num_required; int num_arguments; scmname = NewString(iname); namify(scmname); Printf(mangle, "\"%s\"", SwigType_manglestr(t)); if (Getattr(n,"sym:overloaded")) { overname = Getattr(n,"sym:overname"); } else { if (!addSymbol(iname,n)) return SWIG_ERROR; } f = NewWrapper(); /* Attach the standard typemaps */ emit_attach_parmmaps(l,f); Setattr(n,"wrap:parms",l); /* Get number of required and total arguments */ num_arguments = emit_num_arguments(l); num_required = emit_num_required(l); // evaluation function names Append(wname, realmodule); Append(wname, Swig_name_wrapper(iname)); if (overname) { Append(wname, overname); } strcpy(var_name, Char(Swig_name_wrapper(iname))); // Build the name for scheme. Printv(proc_name, iname,NIL); namify(proc_name); // Check for interrupts Printv (f->code, "C_trace(\"",scmname,"\");\n", NIL); closargs = NewString(""); closwrapargs = NewString(""); if (1 || (SwigType_type(t) != T_USER) || (isPointer(t))) { closparam = NewString("(car %value)"); Printv(closargs, " . %value", NIL); Printv(f->def, #ifndef BINDING "static ", #endif "void ",wname,"(int, C_word, C_word, C_word) C_noret;\n", NIL); Printv(f->def, #ifndef BINDING "static " #endif "void ",wname,"(int argc, C_word closure, " "C_word continuation, C_word value) {\n", NIL); Wrapper_add_local(f, "resultobj", "C_word resultobj"); /* Check for a setting of the variable value */ if (!Getattr(n,"feature:immutable")) { Printf(f->code, "if (argc > 2) {\n"); if ((tm = Swig_typemap_lookup_new("varin",n,name,0))) { Replaceall(tm,"$source","value"); Replaceall(tm,"$target",name); Replaceall(tm,"$input","value"); Printv(f->code, tm, "\n",NIL); } else { Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t,0)); } Printf(f->code, "}\n"); } /* Look for an clos input conversion */ int gotwrap = 0; Node *search; String *tm = 0; if ((search = Getattr(known_classes, pb)) || (tm = singleSearch("clos_in", Char(name), pb))) { /* search for typemap("clos_in") CLASS_OR_BASE_CLASS */ if (tm || (tm = recurseSearch("clos_in", Char(name), search))) { String *cn = NewString(""); Printv(cn, "<", prefix, pb, ">", NIL); namify(cn); Replaceall(tm, "$class", cn); Replaceall(tm, "$input", closparam); Printv(closwrapargs, " ", tm, NIL); gotwrap = 1; Delete(cn); } else { Swig_warning(WARN_TYPEMAP_UNDEF, input_file, line_number, "Unable to find \"%%typemap(clos_in) %s *\" " "or typemaps for any superclasses.\n", SwigType_str(pb,0)); } } if (!gotwrap) { Printv(closwrapargs, " ", closparam, NIL); } Delete(closparam); // Now return the value of the variable - regardless // of evaluating or setting. if ((tm = Swig_typemap_lookup_new("varout",n,name,0))) { /* Calculate fixed alloca code */ if ((am = Getattr(n,"tmap:varout:chicken_words"))) { Replaceall(am,"$typename", mangle); if (strcmp(Char(am), "0") != 0) { Wrapper_add_local(f,"known_space", "C_word *known_space"); Printf(f->code, " known_space = C_alloc (%s);\n", am); } } selectOutOneOrMany(tm, 0); Replaceall(tm,"$source",name); Replaceall(tm,"$varname",name); Replaceall(tm,"$target","resultobj"); Replaceall(tm,"$result","resultobj"); Printf(f->code, "%s\n", tm); } else { Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t,0)); } Printf(f->code,"\nC_kontinue (continuation, resultobj);\n"); /* Error handling code */ #ifdef USE_FAIL Printf(f->code,"fail:\n"); Printf(f->code,"swig_panic (\"failure in " "'%s' SWIG wrapper\");\n", proc_name); #endif Printf(f->code,"}\n"); Wrapper_print(f, f_wrappers); /* Now register the variable with the interpreter. */ addMethod(iname, scmname, wname); /* Look for typemap(clos_out) */ closparam = NewString(""); Printv(closparam, "(if (= (length %value) 0)\n", tab4, "(", prefix, scmname, ")\n", tab4, "(", prefix, scmname, closwrapargs, "))", NIL); tm = 0; if ((search = Getattr(known_classes, pb)) || (tm = singleSearch("clos_out", Char(closparam), pb))) { /* search for typemap("clos_out") CLASS_OR_BASE_CLASS */ if (tm || (tm = recurseSearch("clos_out", Char(closparam), search))) { String *cn = NewString(""); Printv(cn, "<", prefix, pb, ">", NIL); namify(cn); Replaceall(tm, "$class", cn); Delete(closparam); Delete(cn); closparam = Copy(tm); } else { Swig_warning(WARN_TYPEMAP_UNDEF, input_file, line_number, "Unable to find \"%%typemap(clos_out) %s *\" " "or typemaps for any superclasses.\n", SwigType_str(pb,0)); } } /* Create a binding for this variable */ #ifdef BINDING Printv(f_scm, "(declare (foreign-declare \"C_extern ", wname, "(int,C_word,C_word,C_word)" " C_noret;\"))\n", NIL); Printv(f_scm, "(define ", prefix, scmname, " (##core#primitive \"", realmodule, "_wrap_", iname, "\"))\n\n", NIL); #endif /* Create a clos for this variable (if enabled and not in a non-static member variable) */ if (clos && (!(clos & SCMCLOS_MEMBER) || (clos & SCMCLOS_STATIC_MEMBER))) { Printv(f_clos, "(define (+", prefix, scmname, "+", closargs, ")\n", tab4, closparam, ")\n", NIL); } Delete(closparam); } else { Swig_warning(WARN_TYPEMAP_VAR_UNDEF, input_file, line_number, "Unsupported variable type %s (ignored).\n", SwigType_str(t,0)); } Delete(wname); Delete(known_alloca); Delete(proc_name); Delete(argnum); Delete(arg); Delete(tm2); Delete(mangle); Delete(closwrapargs); Delete(closargs); DelWrapper(f); return SWIG_OK; } /* ------------------------------------------------------------ * constantWrapper() * ------------------------------------------------------------ */ int CHICKEN::constantWrapper(Node *n) { char *name = GetChar(n,"name"); char *iname = GetChar(n,"sym:name"); SwigType *t = Getattr(n,"type"); ParmList *l = Getattr(n,"parms"); String *value = Getattr(n,"value"); String *proc_name = NewString(""); char var_name[256]; String *wname = NewString(""); String *mangle = NewString(""); String *tm; String *am; String *tm2 = NewString(""); String *source = NewString(""); String *argnum = NewString("0"); String *arg = NewString("argv[0]"); String *known_alloca = NewString(""); Wrapper *f; String *overname = 0; String *scmname; int num_required; int num_arguments; scmname = NewString(iname); namify(scmname); Printf(mangle, "\"%s\"", SwigType_manglestr(t)); Printf(source, "swig_const_%s", name); Replaceall(source, "::", "__"); if (Getattr(n,"sym:overloaded")) { overname = Getattr(n,"sym:overname"); } else { if (!addSymbol(iname,n)) return SWIG_ERROR; } Append(wname, realmodule); Append(wname, Swig_name_wrapper(iname)); if (overname) { Append(wname, overname); } /* Special hook for member pointer */ if (SwigType_type(t) == T_MPOINTER) { Printf(f_header, "static %s = %s;\n", SwigType_str(t,wname), value); value = wname; } if ((tm = Swig_typemap_lookup_new("constcode", n, name, 0))) { Replaceall(tm,"$source",value); Replaceall(tm,"$target",source); Replaceall(tm,"$result",source); Replaceall(tm,"$value",value); Printf(f_header, "%s\n", tm); } else { Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n"); return SWIG_NOWRAP; } f = NewWrapper(); /* Attach the standard typemaps */ emit_attach_parmmaps(l,f); Setattr(n,"wrap:parms",l); /* Get number of required and total arguments */ num_arguments = emit_num_arguments(l); num_required = emit_num_required(l); // evaluation function names strcpy(var_name, Char(Swig_name_wrapper(iname))); // Build the name for scheme. Printv(proc_name, iname,NIL); namify(proc_name); // Check for interrupts Printv (f->code, "C_trace(\"",scmname,"\");\n", NIL); if (1 || (SwigType_type(t) != T_USER) || (isPointer(t))) { Printv(f->def, #ifndef BINDING "static ", #endif "void ",wname,"(int, C_word, C_word) C_noret;\n", NIL); Printv(f->def, #ifndef BINDING "static ", #endif "void ",wname,"(int argc, C_word closure, " "C_word continuation) {\n", NIL); Wrapper_add_local(f, "resultobj", "C_word resultobj"); // Return the value of the variable if ((tm = Swig_typemap_lookup_new("varout",n,name,0))) { /* Calculate fixed alloca code */ if ((am = Getattr(n,"tmap:varout:chicken_words"))) { Replaceall(am,"$typename", mangle); if (strcmp(Char(am), "0") != 0) { Wrapper_add_local(f,"known_space", "C_word *known_space"); Printf(f->code, " known_space = C_alloc (%s);\n", am); } } selectOutOneOrMany(tm, 0); Replaceall(tm,"$source",source); Replaceall(tm,"$varname",source); Replaceall(tm,"$target","resultobj"); Replaceall(tm,"$result","resultobj"); Printf(f->code, "%s\n", tm); } else { Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t,0)); } Printf(f->code,"\nC_kontinue (continuation, resultobj);\n"); /* Error handling code */ #ifdef USE_FAIL Printf(f->code,"fail:\n"); Printf(f->code,"swig_panic (\"failure in " "'%s' SWIG wrapper\");\n", proc_name); #endif Printf(f->code,"}\n"); Wrapper_print(f, f_wrappers); /* Now register the variable with the interpreter. */ addMethod(iname, scmname, wname); /* Create a binding for this variable */ #ifdef BINDING Printv(f_scm, "(declare (foreign-declare \"C_extern ", wname, "(int argc, C_word closure, C_word continuation, " "C_word value)" " C_noret;\"))\n", NIL); Printv(f_scm, "(define ", prefix, scmname, " (##core#primitive \"", realmodule, "_wrap_", iname, "\"))\n\n", NIL); #endif } else { Swig_warning(WARN_TYPEMAP_VAR_UNDEF, input_file, line_number, "Unsupported variable type %s (ignored).\n", SwigType_str(t,0)); } Delete(wname); Delete(known_alloca); Delete(proc_name); Delete(argnum); Delete(arg); Delete(tm2); Delete(mangle); Delete(source); DelWrapper(f); return SWIG_OK; } int CHICKEN::classDeclaration(Node *n) { String *importname; Node *mod; if (clos) { mod = Getattr(n,"module"); if (mod) { String *iname = Getattr(n, "sym:name"); importname = NewString(prefix); Printv(importname, iname, NIL); Setattr(n,"chicken:proxy",importname); Setattr(known_classes, iname, n); } } return Language::classDeclaration(n); } int CHICKEN::classHandler(Node *n) { int oldclassic = classic; /* Create new strings for building up a wrapper function */ have_constructor = 0; if (Getattr(n,"cplus:exceptionclass")) { classic = 1; } clos_indent = (String *) tab4; class_name = NewString(""); short_class_name = NewString(""); Printv(class_name, "<", prefix, Getattr(n,"sym:name"), ">", NIL); namify(class_name); Printv(short_class_name, Getattr(n,"sym:name"), NIL); namify(short_class_name); real_classname = Getattr(n,"name"); if (!addSymbol(class_name,n)) return SWIG_ERROR; #ifdef JONAH_IS_CRAZY Printv(f_scm,"(set! swig-",prefix,"tag:",Getattr(n,"sym:name"),"\n", tab4,"(make-swig-",prefix,"tag ", "1000 \"_p_",Getattr(n,"sym:name"),"\"\n", tab8,"((foreign-lambda* c-pointer ()\n", tab8, tab4, "\"return (",realmodule, "_swig_get_type (\\\"_p_",Getattr(n,"sym:name"),"\\\"));\"))\n", tab8, "\"",Getattr(n,"sym:name")," *\"))\n", NIL); #endif if (clos) { /* Handle inheritance */ String *base_class = NewString("<"); List *baselist = Getattr(n,"bases"); if (baselist && Len(baselist)) { Iterator base = First(baselist); while (base.item) { String *bname = Copy(Getattr(base.item, "chicken:proxy")); if (!bname) { base = Next(base); continue; } namify(bname); Printv(base_class,bname,NIL); Delete(bname); base = Next(base); if (base.item) { Printf(base_class, "> <"); } } } Printf(base_class, ">"); Printv(f_clos,"\n(define-class ", class_name, " ", NIL); if (Len(base_class) > 2) { Printv(f_clos,"(", base_class, ") ())\n", NIL); } else { Printv(f_clos,"() (this))\n", NIL); } } /* Emit all of the members */ in_class = 1; Language::classHandler(n); in_class = 0; if (clos) { char apply[] = "apply "; if (have_constructor) { Printv(f_clos, "(define-method (initialize (obj ", class_name, ") initargs)\n", tab4, "(call-next-method)\n", tab4, "(if (and (list? initargs) (= (length initargs) 2) (eq? (car initargs) (quote this)))\n", tab8, "(slot-set! obj (quote this) (cadr initargs))\n", tab8, "(begin\n", tab8, tab4, "(slot-set! obj (quote this) (", apply, prefix, "new-", short_class_name, "\n", tab8, tab8, " (map (lambda (arg) (if (instance? arg) (slot-ref arg (quote this)) arg)) initargs)))\n", tab8, tab4, "(set-finalizer! obj\n", tab8, tab8, "(lambda (deadobj) (", prefix, "delete-", short_class_name, " (slot-ref deadobj (quote this))))))))\n", NIL); } else { Printv(f_clos, "(define-method (initialize (obj ", class_name, ") initargs)\n", tab4, "(call-next-method)\n", tab4, "(if (and (list? initargs) (= (length initargs) 2) (eq? (car initargs) (quote this)))\n", tab8, "(slot-set! obj (quote this) (cadr initargs))\n", tab8, "(slot-set! obj (quote this) #f)))\n", NIL); } } Delete(class_name); Delete(short_class_name); class_name = 0; short_class_name = 0; classic = oldclassic; return SWIG_OK; } int CHICKEN::memberfunctionHandler(Node *n) { String *iname = Getattr(n,"sym:name"); SwigType *d = Getattr(n,"type"); ParmList *l = Getattr(n,"parms"); int oldclos; String *scmname; String *args; String *wrapargs; String *closparam; int i; Parm *p; String *tm; scmname = NewString(iname); namify(scmname); /* input arguments */ args = NewString(""); wrapargs = NewString(""); for (i=0, p=l; p; i++) { while (checkAttribute(p,"tmap:in:numinputs","0")) { p = Getattr(p,"tmap:in:next"); } SwigType *pt = Getattr(p,"type"); String *pn = Getattr(p,"name"); SwigType *pb = SwigType_base(pt); if (strcmp("void", Char(pt)) != 0) { String *arg = NewString(""); /* make name of argument */ if (pn && Len(pn)) { Printf(arg, "%%%s", pn); } else { Printf(arg, "%%%d", i+1); } Printv(args, " ", arg, NIL); /* do input conversion */ int gotwrap = 0; Node *search; String *tm = 0; if ((search = Getattr(known_classes, pb)) || (tm = singleSearch("clos_in", Char(pn), pb))) { /* search for typemap("clos_in") CLASS_OR_BASE_CLASS */ if (tm || (tm = recurseSearch("clos_in", Char(pn), search))) { String *cn = NewString(""); Printv(cn, "<", prefix, pb, ">", NIL); namify(cn); Replaceall(tm, "$class", cn); Replaceall(tm, "$input", arg); Printv(wrapargs, " ", tm, NIL); gotwrap = 1; Delete(cn); } else { Swig_warning(WARN_TYPEMAP_UNDEF, input_file, line_number, "Unable to find \"%%typemap(clos_in) %s *\" " "or typemaps for any superclasses.\n", SwigType_str(pb,0)); } } if (!gotwrap) { Printv(wrapargs, " ", arg, NIL); } Delete(arg); } p = nextSibling(p); } /* Create the default member function */ oldclos = clos; /* Disable clos'ing when wrapping member functions */ if (clos) clos = clos | SCMCLOS_MEMBER; Language::memberfunctionHandler(n); clos = oldclos; /* return value */ closparam = NewString(""); if (Getattr(n,"sym:overloaded")) { Printv(closparam, "(apply ", prefix, short_class_name, "-", scmname, "\n", tab8, "(cons (slot-ref obj (quote this))\n", tab8, tab4, "(map (lambda (arg) (if (instance? arg) (slot-ref arg (quote this)) arg)) args)))", NIL); } else { Printv(closparam, "(", prefix, short_class_name, "-", scmname, " (slot-ref obj (quote this))", wrapargs, ")", NIL); } Node *search; String *pb = SwigType_base(d); tm = 0; if ((search = Getattr(known_classes, pb)) || (tm = singleSearch("clos_out", Char(closparam), pb))) { /* search for typemap("clos_out") CLASS_OR_BASE_CLASS */ if (tm || (tm = recurseSearch("clos_out", Char(closparam), search))) { String *cn = NewString(""); Printv(cn, "<", prefix, pb, ">", NIL); namify(cn); Replaceall(tm, "$class", cn); Delete(closparam); Delete(cn); closparam = Copy(tm); } else { Swig_warning(WARN_TYPEMAP_UNDEF, input_file, line_number, "Unable to find \"%%typemap(clos_out) %s *\" " "or typemaps for any superclasses.\n", SwigType_str(pb,0)); } } /* print */ if (!Getattr(n,"sym:nextSibling")) { if (clos) { if (Getattr(n,"feature:clos")) { String *scmcode = chickenCode(Getattr(n,"feature:clos"),tab4); Printv(f_clos,scmcode,"\n",NIL); } else if (Getattr(n,"sym:overloaded")) { Printv(f_clos, "(define-method (-", iname, "- (obj ", class_name, ") . args)\n", tab4, closparam, ")\n", NIL); } else { Printv(f_clos, "(define-method (-", iname, "- (obj ", class_name, ")", args, ")\n", tab4, closparam, ")\n", NIL); } } if (generic) { Printv(f_generic, "(define -", iname, "- (make-generic \"", iname, "\")) ;; class ", class_name, "\n", NIL); } } Delete(closparam); Delete(wrapargs); Delete(args); Delete(scmname); return SWIG_OK; } int CHICKEN::membervariableHandler(Node *n) { String *iname = Getattr(n,"sym:name"); int oldclos = clos; if (clos) clos = clos | SCMCLOS_MEMBER; Language::membervariableHandler(n); clos = oldclos; if (clos) { int immutable = 0; if (!Getattr(n,"feature:immutable")) { Printv(f_clos, "(define-method (-set-", iname, "!- (obj ", class_name, ") %value)\n", tab4, "(", prefix, real_classname, "-", iname, "-set (slot-ref obj (quote this)) %value))\n", NIL); if (generic) { Printv(f_generic, "(define -set-", iname, "!- (make-generic \"set-", iname, "!\")) ;; class ", class_name, "\n", NIL); } } else { immutable = 1; } Printv(f_clos, "(define-method (-get-", iname, "- (obj ", class_name, "))\n", tab4, "(", prefix, real_classname, "-", iname, "-get (slot-ref obj (quote this))))\n", NIL); if (generic) { Printv(f_generic, "(define -get-", iname, "- (make-generic \"get-", iname, "\")) ;; class ", class_name, "\n", NIL); } } return SWIG_OK; } int CHICKEN::memberconstantHandler(Node *n) { int oldclos = clos; if (clos) clos = clos | SCMCLOS_MEMBER; Language::memberconstantHandler(n); clos = oldclos; return SWIG_OK; } int CHICKEN::staticmemberfunctionHandler(Node *n) { int oldclos = clos; if (clos) clos = clos | SCMCLOS_STATIC_MEMBER; Language::staticmemberfunctionHandler(n); clos = oldclos; return SWIG_OK; } int CHICKEN::staticmembervariableHandler(Node *n) { int oldclos = clos; if (clos) clos = clos | SCMCLOS_STATIC_MEMBER; Language::staticmembervariableHandler(n); clos = oldclos; return SWIG_OK; } int CHICKEN::destructorHandler(Node *n) { int oldclos = clos; if (clos) clos = clos | SCMCLOS_MEMBER; Language::destructorHandler(n); clos = oldclos; return SWIG_OK; } int CHICKEN::constructorHandler(Node *n) { int oldclos = clos; if (clos) clos = clos | SCMCLOS_MEMBER; Language::constructorHandler(n); clos = oldclos; if (clos) { have_constructor = 1; } return SWIG_OK; } void CHICKEN::dispatchFunction(Node *n) { /* Last node in overloaded chain */ int maxargs; String *tmp = NewString(""); String *dispatch = Swig_overload_dispatch(n,"%s (2+argc,closure," "continuation$commaargs);", &maxargs); /* Generate a dispatch wrapper for all overloaded functions */ Wrapper *f = NewWrapper(); String *iname = Getattr(n,"sym:name"); String *wname = NewString(""); String *scmname = NewString(iname); namify(scmname); Append(wname, realmodule); Append(wname, Swig_name_wrapper(iname)); #ifndef BINDING Printv(f->def, "static void real_", wname, "(int, C_word, C_word, C_word) C_noret;\n", NIL); #endif Printv(f->def, #ifdef BINDING "void ", #else "static void real_", #endif wname, "(int, C_word closure, C_word continuation, C_word args) {", NIL); Wrapper_add_local(f,"argc","int argc"); Printf(tmp,"C_word argv[%d]", maxargs+1); Wrapper_add_local(f,"argv",tmp); Wrapper_add_local(f,"ii","int ii"); Wrapper_add_local(f,"t","C_word t = args"); Printf(f->code,"if (!C_swig_is_list (args)) {\n"); Printf(f->code," swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, " "\"Argument #1 must be a list of overloaded arguments\");\n"); Printf(f->code,"}\n"); Printf(f->code,"argc = C_unfix (C_i_length (args));\n"); Printf(f->code,"for (ii = 0; (ii < argc) && (ii < %d); ii++, t = C_block_item (t, 1)) {\n",maxargs); Printf(f->code,"argv[ii] = C_block_item (t, 0);\n"); Printf(f->code,"}\n"); Printv(f->code,dispatch,"\n",NIL); Printf(f->code,"swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE," "\"No matching function for overloaded '%s'\");\n", iname); Printv(f->code,"}\n",NIL); Wrapper_print(f,f_wrappers); addMethod(iname,scmname, wname); /* Create a binding for this function */ #ifdef BINDING Printv(f_scm, "(declare (foreign-declare \"C_extern ", realmodule, wname, "(int, C_word, C_word, C_word) C_noret;\"))\n", NIL); Printv(f_scm, "(define swig-", prefix, scmname, "-prim (##core#primitive \"", realmodule, "_wrap_", iname, "\"))\n", NIL); Printv(f_scm, "(define (", prefix, scmname, " . args) (swig-", prefix, scmname, "-prim args))\n\n", NIL); #else DelWrapper(f); f = NewWrapper(); /* varargs */ Printv(f->def, "void ", wname, "(int, C_word, C_word, ...) C_noret;\n", NIL); Printv(f->def, "void ", wname, "(int c, C_word t0, C_word t1, ...) {", NIL); Printv(f->code, "C_word t2;\n", "va_list v;\n", "C_word *a, c2 = c;\n", "C_save_rest (t1, c2, 2);\n", "a = C_alloc((c-2)*3);\n", "t2 = C_restore_rest (a, C_rest_count (0));\n", "real_", wname, " (3, t0, t1, t2);\n", NIL); Printv(f->code,"}\n",NIL); Wrapper_print(f,f_wrappers); #endif /* Create a clos for this function (if enabled and not in a non-static member function) */ if (clos && (!(clos & SCMCLOS_MEMBER) || (clos & SCMCLOS_STATIC_MEMBER))) { Printv(f_clos, "(define (+", prefix, scmname, "+ . args)\n", tab4, "(apply ", prefix, scmname, " args))\n", NIL); } DelWrapper(f); Delete(dispatch); Delete(tmp); Delete(wname); } void CHICKEN::throwUnhandledChickenTypeError(SwigType *d) { Swig_warning(WARN_TYPEMAP_UNDEF, input_file, line_number, "Unable to handle type %s.\n", SwigType_str(d,0)); } int CHICKEN::isPointer(SwigType *t) { return SwigType_ispointer(SwigType_typedef_resolve_all(t)); } void CHICKEN::addMethod(String *, String *scheme_name, String *function) { #ifndef BINDING /* unless Chicken is run in case-sensitive mode, all symbols need to be lowercase. Also, the symbols need the prefix. */ String *sym = NewString(prefix); Append(sym, scheme_name); char *s = Char(sym); const int L = Len(sym); for (int i=0; i < L; i++, s++) { *s = tolower(*s); } /* add symbol to Chicken internal symbol table */ Printf(f_sym_size, "+C_SIZEOF_INTERNED_SYMBOL(%d)", Len(sym)); Printf(f_init_helper, "sym = C_intern (&a, %d, \"%s\");\n", Len(sym), sym); Printv(f_init_helper, "C_mutate ((C_word*)sym+1, (*a=C_CLOSURE_TYPE|1, a[1]=(C_word)", function, ", tmp=(C_word)a, a+=2, tmp));\n", NIL); num_methods++; Delete(sym); #endif } int CHICKEN::validIdentifier(String *s) { char *c = Char(s); /* Check whether we have an R5RS identifier.*/ /* --> * | */ /* --> | */ if (!(isalpha(*c) || (*c == '!') || (*c == '$') || (*c == '%') || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':') || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?') || (*c == '^') || (*c == '_') || (*c == '~'))) { /* --> + | - | ... */ if ((strcmp(c, "+") == 0) || strcmp(c, "-") == 0 || strcmp(c, "...") == 0) return 1; else return 0; } /* --> | | */ while (*c) { if (!(isalnum(*c) || (*c == '!') || (*c == '$') || (*c == '%') || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':') || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?') || (*c == '^') || (*c == '_') || (*c == '~') || (*c == '+') || (*c == '-') || (*c == '.') || (*c == '@'))) return 0; c++; } return 1; } String * CHICKEN::chickenCode(String *code, const String *indent) { String *out = NewString(""); String *temp; if (!indent) indent = ""; temp = NewString(code); /* Split the input text into lines */ List *clist = DohSplit(temp,'\n',-1); Delete(temp); int initial = 0; Iterator s; /* Get the initial indentation */ for (s = First(clist); s.item; s = Next(s)) { if (Len(s.item)) { char *c = Char(s.item); while (*c) { if (!isspace(*c)) break; initial++; c++; } if (*c && !isspace(*c)) break; else { initial = 0; } } } while (s.item) { if (Len(s.item) > initial) { char *c = Char(s.item); c += initial; Printv(out,indent,c,"\n",NIL); } else { Printv(out,"\n",NIL); } s = Next(s); } Delete(clist); return out; } String * CHICKEN::singleSearch(const char *typemap, char *argname, SwigType *searchClass) { String *tm; char *source = (char*)"$input"; char *target = (char*)"$1"; /* search for search-class typemap */ SwigType *type = Copy(searchClass); SwigType_add_pointer(type); tm = Swig_typemap_lookup(typemap, type, argname, argname, source, target, 0); Delete(type); return tm; } String * CHICKEN::recurseSearch(const char *typemap, char *argname, Node *n) { String *tm; tm = singleSearch(typemap, argname, Getattr(n, "name")); if (tm) { return tm; } /* recurse through base classes */ List *baselist = Getattr(n,"bases"); if (baselist && Len(baselist)) { Iterator base = First(baselist); while (base.item) { tm = recurseSearch(typemap, argname, base.item); if (tm) break; base = Next(base); } } return tm; } void CHICKEN::namify(String *scmname) { Replaceall(scmname,"_to_", "->"); Replaceall(scmname,"_", "-"); /* Convert mixed-case to lower case with dashes */ if (mixed) { int changedcase; int i; /* insert "-" in all places with switches in case, and lowercase any upcase chars */ do { char *s = Char(scmname); const int l = Len(scmname); int case_is_set = 0; int was_uppercase = 0; int pseudo_first = 0; changedcase = 0; for (i=0; i < l; ++i, ++s) { int is_uppercase = -1; /* -1 = neither, 0 = lower, 1 = upper */ if (isalpha(*s) && !isdigit(*s)) { is_uppercase = ((*s) >= 'A' && (*s) <= 'Z') ? 1 : 0; } if (i == 0 || !isalpha(*s) || isdigit(*s)) { case_is_set = 0; pseudo_first = 1; } if (case_is_set) { if (is_uppercase >= 0 && was_uppercase != is_uppercase) { *s = tolower(*s); Insert(scmname, i, "-"); changedcase = 1; break; } } else if (is_uppercase >= 0) { /* use currentcase, or lowercase if first char */ if (pseudo_first) { pseudo_first = 0; /* only if first two chars are upper case will we say that the first char is upper case (like JavaBean property naming rules) */ was_uppercase = 0; const char *t = s + 1; if (l >= i+2 && isalpha(*t) && !isdigit(*t) && ((*t) >= 'A' && (*t) <= 'Z')) { was_uppercase = 1; } } else { was_uppercase = is_uppercase; } case_is_set = 1; } if (is_uppercase == 1) { *s = tolower(*s); } } } while (changedcase); } } void CHICKEN::selectOutOneOrMany(String *tm, int is_many) { char *s = Char(tm); const char IFMANY[] = "/*if MANY*/"; const char IFONE[] = "/*if ONE*/"; const char ELSE[] = "/*else*/"; const char ENDIF[] = "/*endif*/"; enum { NONE, ONE, MANY } mode = NONE; while (s) { int displayline = 1; /* set nextline */ char * nextline = strstr(s, "\n"); if (nextline) nextline += strlen("\n"); /* set displayline if necessary */ if (is_many && mode == ONE) displayline = 0; if (!is_many && mode == MANY) displayline = 0; /* which control line are we on? */ if (strncmp(s, IFMANY, sizeof(IFMANY) - 1) == 0) { mode = MANY; displayline = 0; } else if (strncmp(s, IFONE, sizeof(IFONE) - 1) == 0) { mode = ONE; displayline = 0; } else if (strncmp(s, ELSE, sizeof(ELSE) - 1) == 0) { if (mode == ONE) mode = MANY; else if (mode == MANY) mode = ONE; displayline = 0; } else if (strncmp (s, ENDIF, sizeof(ENDIF) - 1) == 0) { mode = NONE; displayline = 0; } /* display line */ if (displayline) { /* advance to next line */ s = nextline; } /* or don't display line */ else { if (!nextline) { memset(s, ' ', strlen(s)); /* truncate this (last) line */ s = 0; } else { memset(s, ' ', nextline - s); /* remove this line */ s = nextline; } } }; }; cableswig-0.1.0+git20150808.orig/SWIG/Source/Modules/allocate.cxx0000644000175000000620000004671412561312227022772 0ustar stevestaff/* ----------------------------------------------------------------------------- * allocate.cxx * * This module tries to figure out which classes and structures support * default constructors and destructors in C++. There are several rules that * define this behavior including pure abstract methods, private sections, * and non-default constructors in base classes. See the ARM or * Doc/Manual/SWIGPlus.html for details. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1998-2002. The University of Chicago * Copyright (C) 1995-1998. The University of Utah and The Regents of the * University of California. * * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_allocate_cxx[] = "/cvsroot/SWIG/Source/Modules/allocate.cxx,v 1.22 2004/01/15 22:46:05 cheetah Exp"; #include "swigmod.h" static int virtual_elimination_mode = 0; /* set to 0 on default */ /* Set virtual_elimination_mode */ void Wrapper_virtual_elimination_mode_set(int flag) { virtual_elimination_mode = flag; } /* Helper function to assist with abstract class checking. This is a major hack. Sorry. */ extern "C" { static String *search_decl = 0; /* Declarator being searched */ static int check_implemented(Node *n) { String *local_decl; if (!n) return 0; while (n) { if (Strcmp(nodeType(n), "cdecl") == 0) { local_decl = Getattr(n,"decl"); if (SwigType_isfunction(local_decl)) { SwigType *decl1 = SwigType_typedef_resolve_all(local_decl); SwigType *decl2 = SwigType_pop_function(decl1); if (Strcmp(decl2, search_decl) == 0) { if (!Getattr(n,"abstract")) { Delete(decl1); Delete(decl2); return 1; } } Delete(decl1); Delete(decl2); } } n = Getattr(n,"csym:nextSibling"); } return 0; } } class Allocate : public Dispatcher { Node *inclass; enum AccessMode { PUBLIC, PRIVATE, PROTECTED }; AccessMode cplus_mode; int extendmode; /* Checks if a virtual function is the same as inherited from the bases */ int function_is_defined_in_bases(Node *c, Node *bases) { Node *b, *temp; String *name, *type, *local_decl, *base_decl; SwigType *base_type, *local_type; if (!bases) return 0; name = Getattr(c, "name"); type = Getattr(c, "type"); local_decl = Getattr(c, "decl"); if (local_decl) { local_decl = SwigType_typedef_resolve_all(local_decl); } else { return 0; } local_type = SwigType_typedef_resolve_all(type); /* Width first search */ for (int i = 0; i < Len(bases); i++) { b = Getitem(bases,i); temp = firstChild (b); while (temp) { base_decl = Getattr(temp, "decl"); base_type = Getattr(temp, "type"); if (base_decl && base_type) { base_decl = SwigType_typedef_resolve_all(base_decl); base_type = SwigType_typedef_resolve_all(base_type); if ( (checkAttribute(temp, "storage", "virtual")) && (checkAttribute(temp, "name", name)) && (!Strcmp(local_type, base_type) || SwigType_issubtype(local_type, base_type)) && (!Strcmp(local_decl, base_decl)) ) { // Indicate a virtual method in the derived class, that // is, not the virtual method definition in a base class Setattr(c, "storage", "virtual"); Setattr(c, "virtual:derived", "1"); if (Strcmp(local_type, base_type) == 0) { // if the types are the same, then we can attemp // to eliminate the derived virtual method. if (virtual_elimination_mode) Setattr(c,"feature:ignore", "1"); } else { // if the types are different, we record the original // virtual base type in case some language needs it. Setattr(c, "virtual:type", Getattr(temp, "type")); } Delete(base_decl); Delete(base_type); Delete(local_decl); Delete(local_type); return 1; } Delete(base_decl); Delete(base_type); } temp = nextSibling(temp); } } Delete(local_decl); Delete(local_type); for (int j = 0; j < Len(bases); j++) { b = Getitem(bases,j); if (function_is_defined_in_bases(c, Getattr(b, "bases"))) return 1; } return 0; } // function not used /* Checks if a class has the same virtual functions as the bases have */ int class_is_defined_in_bases(Node *n) { Node *c, *bases; /* bases is the closest ancestors of class n */ int defined = 0; bases = Getattr(n, "bases"); if (!bases) return 0; c = firstChild(n); /* c is the members of class n */ while (c) { if (checkAttribute(c, "storage", "virtual")) { if (function_is_defined_in_bases(c, bases)) defined = 1; } c = nextSibling(c); } if (defined) return 1; else return 0; } /* Checks if a class member is the same as inherited from the class bases */ int class_member_is_defined_in_bases(Node *member, Node *classnode) { Node *bases; /* bases is the closest ancestors of classnode */ int defined = 0; bases = Getattr(classnode, "bases"); if (!bases) return 0; //if (checkAttribute(member, "storage", "virtual")) { int old_mode = virtual_elimination_mode; if (is_member_director(classnode, member)) virtual_elimination_mode = 0; if (function_is_defined_in_bases(member, bases)) defined = 1; virtual_elimination_mode = old_mode; } if (defined) return 1; else return 0; } /* Checks to see if a class is abstract through inheritance, and saves the first node that seems to be abstract. */ int is_abstract_inherit(Node *n, Node *base = 0, int first = 0) { if (!first && (base == n)) return 0; if (!base) { /* Root node */ Symtab *stab = Getattr(n,"symtab"); /* Get symbol table for node */ Symtab *oldtab = Swig_symbol_setscope(stab); int ret = is_abstract_inherit(n,n,1); Swig_symbol_setscope(oldtab); return ret; } List *abstract = Getattr(base,"abstract"); if (abstract) { for (int i = 0; i < Len(abstract); i++) { Node *nn = Getitem(abstract,i); String *name = Getattr(nn,"name"); String *base_decl = Getattr(nn,"decl"); if (base_decl) base_decl = SwigType_typedef_resolve_all(base_decl); if (Strstr(name,"~")) continue; /* Don't care about destructors */ /* int implemented = 0; Node *dn = Swig_symbol_clookup_local(name,0); if (!dn) { Printf(stdout,"node: %x '%s'. base: %x '%s'. member '%s'\n", n, Getattr(n,"name"), base, Getattr(base,"name"), name); } assert(dn != 0); // Assertion of doom */ if (SwigType_isfunction(base_decl)) { search_decl = SwigType_pop_function(base_decl); } Node *dn = Swig_symbol_clookup_local_check(name,0,check_implemented); Delete(search_decl); Delete(base_decl); /* while (dn && !implemented) { String *local_decl = Getattr(dn,"decl"); if (local_decl) local_decl = SwigType_typedef_resolve_all(local_decl); if (local_decl && !Strcmp(local_decl, base_decl)) { if (Getattr(dn,"abstract")) return 1; implemented++; } Delete(local_decl); dn = Getattr(dn,"csym:nextSibling"); } */ /* if (!implemented && (Getattr(nn,"abstract"))) { return 1; } */ if (!dn) { Setattr(n,"abstract:firstnode",nn); return 1; } /* if (dn && (Getattr(dn,"abstract"))) { return 1; } */ } } List *bases = Getattr(base,"bases"); if (!bases) return 0; for (int i = 0; i < Len(bases); i++) { if (is_abstract_inherit(n,Getitem(bases,i))) { return 1; } } return 0; } /* Grab methods used by smart pointers */ List *smart_pointer_methods(Node *cls, List *methods, int isconst) { if (!methods) { methods = NewList(); } Node *c = firstChild(cls); String *kind = Getattr(cls,"kind"); int mode; if (Strcmp(kind,"class") == 0) mode = PRIVATE; else mode = PUBLIC; while (c) { if (Getattr(c,"error") || Getattr(c,"feature:ignore")) { c = nextSibling(c); continue; } if (Strcmp(nodeType(c),"cdecl") == 0) { if (!Getattr(c,"feature:ignore")) { String *storage = Getattr(c,"storage"); if (!((Cmp(storage,"static") == 0) || (Cmp(storage,"typedef") == 0))) { String *name = Getattr(c,"name"); String *symname = Getattr(c,"sym:name"); Node *e = Swig_symbol_clookup_local(name,0); if (e && is_public(e) && !Getattr(e,"feature:ignore") && (Cmp(symname, Getattr(e,"sym:name")) == 0)) { Swig_warning(WARN_LANG_DEREF_SHADOW,Getfile(e),Getline(e),"Declaration of '%s' shadows declaration accessible via operator->(),\n", name); Swig_warning(WARN_LANG_DEREF_SHADOW,Getfile(c),Getline(c),"previous declaration of '%s'.\n", name); } else { /* Make sure node with same name doesn't already exist */ int k; int match = 0; for (k = 0; k < Len(methods); k++) { e = Getitem(methods,k); if (Cmp(symname,Getattr(e,"sym:name")) == 0) { match = 1; break; } if ((!symname || (!Getattr(e,"sym:name"))) && (Cmp(name,Getattr(e,"name")) == 0)) { match = 1; break; } } if (!match) { Node *cc = c; while (cc) { /* If constant, we have to be careful */ if (isconst) { SwigType *decl = Getattr(cc,"decl"); if (decl) { if (SwigType_isfunction(decl)) { /* If method, we only add if it's a const method */ if (SwigType_isconst(decl)) { Append(methods,cc); } } else { Append(methods,cc); } } else { Append(methods,cc); } } else { Append(methods,cc); } cc = Getattr(cc,"sym:nextSibling"); } } } } } } if (Strcmp(nodeType(c),"access") == 0) { kind = Getattr(c,"kind"); if (Strcmp(kind,"public") == 0) mode = PUBLIC; else mode = PRIVATE; } c = nextSibling(c); } /* Look for methods in base classes */ { Node *bases = Getattr(cls,"bases"); int k; for (k = 0; k < Len(bases); k++) { smart_pointer_methods(Getitem(bases,k),methods,isconst); } } /* Remove protected/private members */ { for (int i = 0; i < Len(methods); ) { Node *n = Getitem(methods,i); if (!is_public(n)) { Delitem(methods,i); continue; } i++; } } return methods; } void mark_exception_classes(ParmList *p) { while(p) { SwigType *ty = Getattr(p,"type"); SwigType *t = SwigType_typedef_resolve_all(ty); Node *c = Swig_symbol_clookup(t,0); if (c) { Setattr(c,"cplus:exceptionclass","1"); } p = nextSibling(p); } } public: virtual int top(Node *n) { cplus_mode = PUBLIC; inclass = 0; extendmode = 0; emit_children(n); return SWIG_OK; } virtual int importDirective(Node *n) { return emit_children(n); } virtual int includeDirective(Node *n) { return emit_children(n); } virtual int externDeclaration(Node *n) { return emit_children(n); } virtual int namespaceDeclaration(Node *n) { return emit_children(n); } virtual int extendDirective(Node *n) { extendmode = 1; emit_children(n); extendmode = 0; return SWIG_OK; } virtual int classDeclaration(Node *n) { Symtab *symtab = Swig_symbol_current(); Swig_symbol_setscope(Getattr(n,"symtab")); if (!CPlusPlus) { /* Always have default constructors/destructors in C */ Setattr(n,"allocate:default_constructor","1"); Setattr(n,"allocate:default_destructor","1"); } if (Getattr(n,"allocate:visit")) return SWIG_OK; Setattr(n,"allocate:visit","1"); /* Always visit base classes first */ { List *bases = Getattr(n,"bases"); if (bases) { for (int i = 0; i < Len(bases); i++) { Node *b = Getitem(bases,i); classDeclaration(b); } } } inclass = n; String *kind = Getattr(n,"kind"); if (Strcmp(kind,"class") == 0) { cplus_mode = PRIVATE; } else { cplus_mode = PUBLIC; } emit_children(n); /* Check if the class is abstract via inheritance. This might occur if a class didn't have any pure virtual methods of its own, but it didn't implement all of the pure methods in a base class */ if (is_abstract_inherit(n)) { if ((!Getattr(n,"abstract")) && ((Getattr(n,"allocate:public_constructor") || (!Getattr(n,"feature:nodefault") && !Getattr(n,"allocate:has_constructor"))))) { if (!Getattr(n,"feature:notabstract")) { Node *na = Getattr(n,"abstract:firstnode"); Swig_warning(WARN_TYPE_ABSTRACT, Getfile(n), Getline(n), "Class '%s' might be abstract, " "no constructors generated,\n", SwigType_namestr(Getattr(n,"name"))); Swig_warning(WARN_TYPE_ABSTRACT, Getfile(na), Getline(na), " method '%s' might not be implemented.", SwigType_namestr(Getattr(na,"name"))); Setattr(n,"abstract",NewList()); } } } if (!Getattr(n,"allocate:has_constructor")) { /* No constructor is defined. We need to check a few things */ /* If class is abstract. No default constructor. Sorry */ if (Getattr(n,"abstract")) { Delattr(n,"allocate:default_constructor"); } if (!Getattr(n,"allocate:default_constructor")) { /* Check base classes */ List *bases = Getattr(n,"bases"); int allows_default = 1; for (int i = 0; i < Len(bases); i++) { Node *n = Getitem(bases,i); /* If base class does not allow default constructor, we don't allow it either */ if (!Getattr(n,"allocate:default_constructor") && (!Getattr(n,"allocate:default_base_constructor"))) { allows_default = 0; } } if (allows_default) { Setattr(n,"allocate:default_constructor","1"); } } } if (!Getattr(n,"allocate:has_destructor")) { /* No destructor was defined. We need to check a few things here too */ List *bases = Getattr(n,"bases"); int allows_destruct = 1; for (int i = 0; i < Len(bases); i++) { Node *n = Getitem(bases,i); /* If base class does not allow default destructor, we don't allow it either */ if (!Getattr(n,"allocate:default_destructor") && (!Getattr(n,"allocate:default_base_destructor"))) { allows_destruct = 0; } } if (allows_destruct) { Setattr(n,"allocate:default_destructor","1"); } } /* Check if base classes allow smart pointers, but might be hidden */ if (!Getattr(n,"allocate:smartpointer")) { Node *sp = Swig_symbol_clookup((char*)"operator ->",0); if (sp) { /* Look for parent */ Node *p = parentNode(sp); if (Strcmp(nodeType(p),"extend") == 0) { p = parentNode(p); } if (Strcmp(nodeType(p),"class") == 0) { if (Getattr(p,"feature:ignore")) { Setattr(n,"allocate:smartpointer",Getattr(p,"allocate:smartpointer")); } } } } /* Only care about default behavior. Remove temporary values */ Setattr(n,"allocate:visit","1"); inclass = 0; Swig_symbol_setscope(symtab); return SWIG_OK; } virtual int accessDeclaration(Node *n) { String *kind = Getattr(n,"kind"); if (Cmp(kind,"public") == 0) { cplus_mode = PUBLIC; } else if (Cmp(kind,"private") == 0) { cplus_mode = PRIVATE; } else if (Cmp(kind,"protected") == 0) { cplus_mode = PROTECTED; } return SWIG_OK; } virtual int cDeclaration(Node *n) { mark_exception_classes(Getattr(n,"throws")); if (inclass) { /* check whether the member node n is defined in class node inclass's bases */ // if (checkAttribute(n, "storage", "virtual")) class_member_is_defined_in_bases(n, inclass); /* Check to see if this is a static member or not. If so, we add an attribute cplus:staticbase that saves the current class */ if (checkAttribute(n,"storage","static")) { Setattr(n,"cplus:staticbase", inclass); } String *name = Getattr(n,"name"); if (cplus_mode != PUBLIC) { /* Look for a private assignment operator */ if (Strcmp(name,"operator =") == 0) { Setattr(inclass,"allocate:noassign","1"); } } else { /* Look for smart pointer operator */ if ((Strcmp(name,"operator ->") == 0) && (!Getattr(n,"feature:ignore"))) { /* Look for version with no parameters */ Node *sn = n; while (sn) { if (!Getattr(sn,"parms")) { SwigType *type = SwigType_typedef_resolve_all(Getattr(sn,"type")); SwigType_push(type,Getattr(sn,"decl")); Delete(SwigType_pop_function(type)); SwigType *base = SwigType_base(type); Node *sc = Swig_symbol_clookup(base, 0); if ((sc) && (Strcmp(nodeType(sc),"class") == 0)) { if (SwigType_check_decl(type,"p.")) { /* Need to check if type is a const pointer */ int isconst = 0; SwigType_pop(type); if (SwigType_isconst(type)) { isconst = 1; Setattr(inclass,"allocate:smartpointerconst","1"); } List *methods = smart_pointer_methods(sc,0,isconst); Setattr(inclass,"allocate:smartpointer",methods); Setattr(inclass,"allocate:smartpointerbase",base); break; } else { /* Hmmm. The return value is not a pointer. If the type is a value or reference. We're going to chase it to see if another operator->() can be found */ if ((SwigType_check_decl(type,"")) || (SwigType_check_decl(type,"r."))) { Node *nn = Swig_symbol_clookup((char*)"operator ->", Getattr(sc,"symtab")); if (nn) { sn = nn; continue; } else { break; } } else { break; } } } else { break; } } else { break; } } } } } return SWIG_OK; } virtual int constructorDeclaration(Node *n) { if (!inclass) return SWIG_OK; Parm *parms = Getattr(n,"parms"); mark_exception_classes(Getattr(n,"throws")); if (!extendmode) { if (!ParmList_numrequired(parms)) { /* Class does define a default constructor */ /* However, we had better see where it is defined */ if (cplus_mode == PUBLIC) { Setattr(inclass,"allocate:default_constructor","1"); } else if (cplus_mode == PROTECTED) { Setattr(inclass,"allocate:default_base_constructor","1"); } } /* Class defines some kind of constructor. May or may not be public */ Setattr(inclass,"allocate:has_constructor","1"); if (cplus_mode == PUBLIC) { Setattr(inclass,"allocate:public_constructor","1"); } } /* See if this is a copy constructor */ if (parms && (ParmList_numrequired(parms) == 1)) { /* Look for a few cases. X(const X &), X(X &), X(X *) */ String *cc = NewStringf("r.q(const).%s", Getattr(inclass,"name")); if (Strcmp(cc,Getattr(parms,"type")) == 0) { Setattr(n,"copy_constructor","1"); } Delete(cc); cc = NewStringf("r.%s", Getattr(inclass,"name")); if (Strcmp(cc,Getattr(parms,"type")) == 0) { Setattr(n,"copy_constructor","1"); } Delete(cc); cc = NewStringf("p.%s", Getattr(inclass,"name")); String *ty = SwigType_strip_qualifiers(Getattr(parms,"type")); if (Strcmp(cc,ty) == 0) { Setattr(n,"copy_constructor","1"); } Delete(cc); Delete(ty); } return SWIG_OK; } virtual int destructorDeclaration(Node *n) { (void)n; if (!inclass) return SWIG_OK; if (!extendmode) { Setattr(inclass,"allocate:has_destructor","1"); if (cplus_mode == PUBLIC) { Setattr(inclass,"allocate:default_destructor","1"); } else if (cplus_mode == PROTECTED) { Setattr(inclass,"allocate:default_base_destructor","1"); } } return SWIG_OK; } }; void Swig_default_allocators(Node *n) { if (!n) return; Allocate *a = new Allocate; a->top(n); delete a; } cableswig-0.1.0+git20150808.orig/SWIG/Source/Modules/emit.cxx0000644000175000000620000003037212561312227022135 0ustar stevestaff/* ----------------------------------------------------------------------------- * emit.cxx * * Useful functions for emitting various pieces of code. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1998-2000. The University of Chicago * Copyright (C) 1995-1998. The University of Utah and The Regents of the * University of California. * * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ #include "swigmod.h" char cvsroot_emit_cxx[] = "/cvsroot/SWIG/Source/Modules/emit.cxx,v 1.27 2004/01/19 21:34:58 cheetah Exp"; /* ----------------------------------------------------------------------------- * emit_args() * * Creates a list of variable declarations for both the return value * and function parameters. * * The return value is always called result and arguments arg0, arg1, arg2, etc... * Returns the number of parameters associated with a function. * ----------------------------------------------------------------------------- */ void emit_args(SwigType *rt, ParmList *l, Wrapper *f) { Parm *p; String *tm; /* Emit function arguments */ Swig_cargs(f, l); /* Handle return type */ if (rt && (SwigType_type(rt) != T_VOID)) { if (!CPlusPlus || (CPlusPlus && !SwigType_isclass(rt))) { Wrapper_add_local(f,"result", SwigType_lstr(rt,"result")); } else { SwigType *vt = 0; vt = cplus_value_type(rt); if (!vt) { Wrapper_add_local(f,"result", SwigType_lstr(rt,"result")); } else { Wrapper_add_local(f,"result", SwigType_lstr(vt,"result")); Delete(vt); } } } /* Attach typemaps to parameters */ /* Swig_typemap_attach_parms("ignore",l,f); */ Swig_typemap_attach_parms("default",l,f); Swig_typemap_attach_parms("arginit",l,f); /* Apply the arginit and default */ p = l; while (p) { tm = Getattr(p,"tmap:arginit"); if (tm) { Replace(tm,"$target", Getattr(p,"lname"), DOH_REPLACE_ANY); Printv(f->code,tm,"\n",NIL); p = Getattr(p,"tmap:arginit:next"); } else { p = nextSibling(p); } } /* Apply the default typemap */ p = l; while (p) { tm = Getattr(p,"tmap:default"); if (tm) { Replace(tm,"$target", Getattr(p,"lname"), DOH_REPLACE_ANY); Printv(f->code,tm,"\n",NIL); p = Getattr(p,"tmap:default:next"); } else { p = nextSibling(p); } } return; } /* ----------------------------------------------------------------------------- * emit_attach_parmmaps() * * Attach the standard parameter related typemaps. * ----------------------------------------------------------------------------- */ void emit_attach_parmmaps(ParmList *l, Wrapper *f) { Swig_typemap_attach_parms("in",l,f); Swig_typemap_attach_parms("typecheck",l,0); Swig_typemap_attach_parms("argout",l,f); Swig_typemap_attach_parms("check",l,f); Swig_typemap_attach_parms("freearg",l,f); { /* This is compatibility code to deal with the deprecated "ignore" typemap */ Parm *p = l; Parm *np; String *tm; while (p) { tm = Getattr(p,"tmap:in"); if (tm && checkAttribute(p,"tmap:in:numinputs","0")) { Replaceall(tm,"$target", Getattr(p,"lname")); Printv(f->code,tm,"\n",NIL); np = Getattr(p,"tmap:in:next"); while (p && (p != np)) { Setattr(p,"ignore","1"); p = nextSibling(p); } } else if (tm) { p = Getattr(p,"tmap:in:next"); } else { p = nextSibling(p); } } } /* Perform a sanity check on "in" and "freearg" typemaps. These must exactly match to avoid chaos. If a mismatch occurs, we nuke the freearg typemap */ { Parm *p = l; Parm *npin, *npfreearg; while (p) { npin = Getattr(p,"tmap:in:next"); /* if (Getattr(p,"tmap:ignore")) { npin = Getattr(p,"tmap:ignore:next"); } else if (Getattr(p,"tmap:in")) { npin = Getattr(p,"tmap:in:next"); } */ if (Getattr(p,"tmap:freearg")) { npfreearg = Getattr(p,"tmap:freearg:next"); if (npin != npfreearg) { while (p != npin) { Delattr(p,"tmap:freearg"); Delattr(p,"tmap:freearg:next"); p = nextSibling(p); } } } p = npin; } } /* Check for variable length arguments with no input typemap. If no input is defined, we set this to ignore and print a message. */ { Parm *p = l; Parm *lp = 0; while (p) { if (!checkAttribute(p,"tmap:in:numinputs","0")) { lp = p; p = Getattr(p,"tmap:in:next"); continue; } if (SwigType_isvarargs(Getattr(p,"type"))) { Swig_warning(WARN_LANG_VARARGS,input_file,line_number,"Variable length arguments discarded.\n"); Setattr(p,"tmap:in",""); } lp = 0; p = nextSibling(p); } /* Check if last input argument is variable length argument */ if (lp) { p = lp; while (p) { if (SwigType_isvarargs(Getattr(p,"type"))) { Setattr(l,"emit:varargs",lp); break; } p = nextSibling(p); } } } } /* ----------------------------------------------------------------------------- * emit_num_arguments() ** new in 1.3.10 * * Calculate the total number of arguments. This function is safe for use * with multi-valued typemaps which may change the number of arguments in * strange ways. * ----------------------------------------------------------------------------- */ int emit_num_arguments(ParmList *parms) { Parm *p = parms; int nargs = 0; while (p) { if (Getattr(p,"tmap:in")) { nargs += GetInt(p,"tmap:in:numinputs"); p = Getattr(p,"tmap:in:next"); } else { p = nextSibling(p); } } /* DB 04/02/2003: Not sure this is necessary with tmap:in:numinputs */ /* if (parms && (p = Getattr(parms,"emit:varargs"))) { if (!nextSibling(p)) { nargs--; } } */ return nargs; } /* ----------------------------------------------------------------------------- * emit_num_required() ** new in 1.3.10 * * Computes the number of required arguments. This is function is safe for * use with multi-valued typemaps and knows how to skip over everything * properly. * ----------------------------------------------------------------------------- */ int emit_num_required(ParmList *parms) { Parm *p = parms; int nargs = 0; while (p) { if (Getattr(p,"tmap:in") && checkAttribute(p,"tmap:in:numinputs","0")) { p = Getattr(p,"tmap:in:next"); } else { if (Getattr(p,"value")) break; if (Getattr(p,"tmap:default")) break; nargs+= GetInt(p,"tmap:in:numinputs"); if (Getattr(p,"tmap:in")) { p = Getattr(p,"tmap:in:next"); } else { p = nextSibling(p); } } } /* Print message for non-default arguments */ while (p) { if (Getattr(p,"tmap:in") && checkAttribute(p,"tmap:in:numinputs","0")) { p = Getattr(p,"tmap:in:next"); } else { if (!Getattr(p,"value") && (!Getattr(p,"tmap:default"))) { Swig_error(Getfile(p),Getline(p),"Non-optional argument '%s' follows an optional argument.\n",Getattr(p,"name")); } if (Getattr(p,"tmap:in")) { p = Getattr(p,"tmap:in:next"); } else { p = nextSibling(p); } } } /* DB 04/02/2003: Not sure this is necessary with tmap:in:numinputs */ /* if (parms && (p = Getattr(parms,"emit:varargs"))) { if (!nextSibling(p)) { nargs--; } } */ return nargs; } /* ----------------------------------------------------------------------------- * emit_isvarargs() * * Checks if a function is a varargs function * ----------------------------------------------------------------------------- */ int emit_isvarargs(ParmList *p) { if (!p) return 0; if (Getattr(p,"emit:varargs")) return 1; return 0; } /* ----------------------------------------------------------------------------- * void emit_mark_vararg_parms() * * Marks the vararg parameters which are to be ignored. * Vararg parameters are marked as ignored if there is no 'in' varargs (...) * typemap. * ----------------------------------------------------------------------------- */ void emit_mark_varargs(ParmList *l) { Parm *p = l; while (p) { if (SwigType_isvarargs(Getattr(p,"type"))) if (!Getattr(p,"tmap:in")) Setattr(p,"varargs:ignore","1"); p = nextSibling(p); } } #if 0 /* replace_contract_args. This function replaces argument names in contract specifications. Used in conjunction with the %contract directive. */ static void replace_contract_args(Parm *cp, Parm *rp, String *s) { while (cp && rp) { String *n = Getattr(cp,"name"); if (n) { Replace(s,n,Getattr(rp,"lname"), DOH_REPLACE_ID); } cp = nextSibling(cp); rp = nextSibling(rp); } } #endif /* ----------------------------------------------------------------------------- * int emit_action() * * Emits action code for a wrapper and checks for exception handling * ----------------------------------------------------------------------------- */ void emit_action(Node *n, Wrapper *f) { String *tm; String *action; String *wrap; SwigType *rt; ParmList *throws = Getattr(n,"throws"); /* Look for fragments */ { String *f; f = Getattr(n,"feature:fragment"); if (f) { char *c, *tok; String *t = Copy(f); c = Char(t); tok = strtok(c,","); while (tok) { Swig_fragment_emit(tok); tok = strtok(NULL,","); } Delete(t); } } /* Emit wrapper code (if any) */ wrap = Getattr(n,"wrap:code"); if (wrap && Swig_filebyname("header")!=Getattr(n,"wrap:code:done") ) { File *f_code = Swig_filebyname("header"); if (f_code) { Printv(f_code,wrap,NIL); } Setattr(n,"wrap:code:done",f_code); } action = Getattr(n,"feature:action"); if (!action) action = Getattr(n,"wrap:action"); assert(action != 0); if (is_protected(n) && is_member_director(n)) { /* We need to add an extra dynamic_cast to access the director class, where the virtual methods are all public */ Node* parent = Getattr(n,"parentNode"); String* symname = Getattr(parent, "sym:name"); String* dirname = NewStringf("SwigDirector_%s", symname); String* dirdecl = NewStringf("%s *darg = 0", dirname); Wrapper_add_local(f, "darg", dirdecl); Printf(f->code, "darg = dynamic_cast<%s *>(arg1);\n",dirname); Replace(action, "arg1", "darg", DOH_REPLACE_FIRST); Delete(dirname); Delete(dirdecl); } /* Get the return type */ rt = Getattr(n,"type"); /* Emit contract code (if any) */ if (Swig_contract_mode_get()) { /* Preassertion */ tm = Getattr(n, "contract:preassert"); if (Len(tm)) { Printv(f->code,tm,"\n",NIL); } } /* Exception handling code */ /* saves action -> eaction for postcatching exception */ String *eaction = NewString(""); /* If we are in C++ mode and there is a throw specifier. We're going to enclose the block in a try block */ if (throws) { Printf(eaction,"try {\n"); } Printv(eaction, action, NIL); if (throws) { Printf(eaction,"}\n"); for (Parm *ep = throws; ep; ep = nextSibling(ep)) { String *em = Swig_typemap_lookup_new("throws",ep,"_e",0); if (em) { Printf(eaction,"catch(%s) {\n", SwigType_str(Getattr(ep,"type"),"&_e")); Printv(eaction,em,"\n",NIL); Printf(eaction,"}\n"); } else { Swig_warning(WARN_TYPEMAP_THROW, Getfile(n), Getline(n), "No 'throw' typemap defined for exception type '%s'\n", SwigType_str(Getattr(ep,"type"),0)); Printf(eaction,"catch(...) { throw; }\n"); } } } /* Look for except typemap (Deprecated) */ tm = Swig_typemap_lookup_new("except",n,"result",0); /* Look for except feature */ if (!tm) { tm = Getattr(n,"feature:except"); if (tm) tm = Copy(tm); } if ((tm) && Len(tm) && (Strcmp(tm,"1") != 0)) { Replaceall(tm,"$name",Getattr(n,"name")); Replaceall(tm,"$symname", Getattr(n,"sym:name")); Replaceall(tm,"$function", eaction); Replaceall(tm,"$action", eaction); Printv(f->code,tm,"\n", NIL); Delete(tm); } else { Printv(f->code,eaction,"\n",NIL); } Delete(eaction); /* Emit contract code (if any) */ if (Swig_contract_mode_get()) { /* Postassertion */ tm = Getattr(n, "contract:postassert"); if (Len(tm)) { Printv(f->code,tm,"\n",NIL); } } } cableswig-0.1.0+git20150808.orig/SWIG/Source/Modules/java.cxx0000644000175000000620000035516312561312227022130 0ustar stevestaff/* ----------------------------------------------------------------------------- * java.cxx * * Java wrapper module. * * Author(s) : William Fulton * Harco de Hilster * * Copyright (C) 1999-2002. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_java_cxx[] = "/cvsroot/SWIG/Source/Modules/java.cxx,v 1.54 2004/02/12 21:48:37 cheetah Exp"; #include // for INT_MAX #include "swigmod.h" #include /* Hash type used for JNI upcall data */ typedef DOH UpcallData; class JAVA : public Language { static const char *usage; const String *empty_string; const String *public_string; const String *protected_string; Hash *swig_types_hash; File *f_runtime; File *f_runtime_h; File *f_header; File *f_wrappers; File *f_init; File *f_directors; File *f_directors_h; bool proxy_flag; // Flag for generating proxy classes bool have_default_constructor_flag; bool native_function_flag; // Flag for when wrapping a native function bool enum_constant_flag; // Flag for when wrapping an enum or constant bool static_flag; // Flag for when wrapping a static functions or member variables bool variable_wrapper_flag; // Flag for when wrapping a nonstatic member variable bool wrapping_member_flag; // Flag for when wrapping a member variable/enum/const bool global_variable_flag; // Flag for when wrapping a global variable bool member_func_flag; // flag set when wrapping a member function String *module; // module name String *imclass_name; // intermediary class name String *module_class_name; // module class name String *imclass_class_code; // intermediary class code String *proxy_class_def; String *proxy_class_code; String *module_class_code; String *proxy_class_name; String *variable_name; //Name of a variable being wrapped String *proxy_class_constants_code; String *module_class_constants_code; String *package; // Package name String *jnipackage; // Package name used in the JNI code String *package_path; // Package name used internally by JNI (slashes) String *imclass_imports; //intermediary class imports from %pragma String *module_imports; //module imports from %pragma String *imclass_baseclass; //inheritance for intermediary class class from %pragma String *module_baseclass; //inheritance for module class from %pragma String *imclass_interfaces; //interfaces for intermediary class class from %pragma String *module_interfaces; //interfaces for module class from %pragma String *imclass_class_modifiers; //class modifiers for intermediary class overriden by %pragma String *module_class_modifiers; //class modifiers for module class overriden by %pragma String *upcasts_code; //C++ casts for inheritance hierarchies C++ code String *imclass_cppcasts_code; //C++ casts up inheritance hierarchies intermediary class code String *imclass_directors; // Intermediate class director Java code String *destructor_call; //C++ destructor call if any // Director method stuff: List *dmethods_seq; Hash *dmethods_table; int n_dmethods; int n_directors; bool emitted_connect; int first_class_dmethod; int curr_class_dmethod; enum type_additions {none, pointer, reference}; public: /* ----------------------------------------------------------------------------- * JAVA() * ----------------------------------------------------------------------------- */ JAVA() : empty_string(NewString("")), public_string(NewString("public")), protected_string(NewString("protected")), swig_types_hash(NULL), f_runtime(NULL), f_runtime_h(NULL), f_header(NULL), f_wrappers(NULL), f_init(NULL), f_directors(NULL), f_directors_h(NULL), proxy_flag(true), have_default_constructor_flag(false), native_function_flag(false), enum_constant_flag(false), static_flag(false), variable_wrapper_flag(false), wrapping_member_flag(false), global_variable_flag(false), member_func_flag(false), imclass_name(NULL), module_class_name(NULL), imclass_class_code(NULL), proxy_class_def(NULL), proxy_class_code(NULL), module_class_code(NULL), proxy_class_name(NULL), variable_name(NULL), proxy_class_constants_code(NULL), module_class_constants_code(NULL), package(NULL), jnipackage(NULL), package_path(NULL), imclass_imports(NULL), module_imports(NULL), imclass_baseclass(NULL), module_baseclass(NULL), imclass_interfaces(NULL), module_interfaces(NULL), imclass_class_modifiers(NULL), module_class_modifiers(NULL), upcasts_code(NULL), imclass_cppcasts_code(NULL), imclass_directors(NULL), destructor_call(NULL), dmethods_seq(NULL), dmethods_table(NULL), n_dmethods(0), n_directors(0), emitted_connect(false) { } /* ----------------------------------------------------------------------------- * getProxyName() * * Test to see if a type corresponds to something wrapped with a proxy class * Return NULL if not otherwise the proxy class name * ----------------------------------------------------------------------------- */ String *getProxyName(SwigType *t) { if (proxy_flag) { Node *n = classLookup(t); if (n) { return Getattr(n,"sym:name"); } } return NULL; } /* ----------------------------------------------------------------------------- * makeValidJniName() * ----------------------------------------------------------------------------- */ String *makeValidJniName(const String *name) { String *valid_jni_name = NewString(name); Replaceall(valid_jni_name,"_","_1"); return valid_jni_name; } /* ----------------------------------------------------------------------------- * directorClassName() * ----------------------------------------------------------------------------- */ String *directorClassName(Node *n) { String *dirclassname; const char *attrib = "director:classname"; if ((dirclassname = Getattr(n, attrib)) == NULL) { String *classname = Getattr(n, "sym:name"); dirclassname = NewStringf("SwigDirector_%s", classname); Setattr(n, attrib, dirclassname); } return dirclassname; } /* ------------------------------------------------------------ * main() * ------------------------------------------------------------ */ virtual void main(int argc, char *argv[]) { SWIG_library_directory("java"); // Look for certain command line options for (int i = 1; i < argc; i++) { if (argv[i]) { if (strcmp(argv[i],"-package") == 0) { if (argv[i+1]) { package = NewString(""); Printf(package, argv[i+1]); Swig_mark_arg(i); Swig_mark_arg(i+1); i++; } else { Swig_arg_error(); } } else if ((strcmp(argv[i],"-shadow") == 0) || ((strcmp(argv[i],"-proxy") == 0))) { Printf(stderr,"Deprecated command line option: %s. Proxy classes are now generated by default.\n", argv[i]); Swig_mark_arg(i); proxy_flag = true; } else if ((strcmp(argv[i],"-noproxy") == 0)) { Swig_mark_arg(i); proxy_flag = false; } else if (strcmp(argv[i],"-jnic") == 0) { Swig_mark_arg(i); Printf(stderr,"Deprecated command line option: -jnic. C JNI calling convention now used when -c++ not specified.\n"); } else if (strcmp(argv[i],"-nofinalize") == 0) { Swig_mark_arg(i); Printf(stderr,"Deprecated command line option: -nofinalize. Use the new javafinalize typemap instead.\n"); } else if (strcmp(argv[i],"-jnicpp") == 0) { Swig_mark_arg(i); Printf(stderr,"Deprecated command line option: -jnicpp. C++ JNI calling convention now used when -c++ specified.\n"); } else if (strcmp(argv[i],"-help") == 0) { Printf(stderr,"%s\n", usage); } } } // Add a symbol to the parser for conditional compilation Preprocessor_define("SWIGJAVA 1",0); // Add typemap definitions SWIG_typemap_lang("java"); SWIG_config_file("java.swg"); allow_overloading(); } /* --------------------------------------------------------------------- * top() * --------------------------------------------------------------------- */ virtual int top(Node *n) { // Make the intermediary class and module class names. The // intermediary class name can be set in the module directive. Node* optionsnode = Getattr( Getattr(n,"module"), "options"); if (optionsnode) { if (Getattr(optionsnode,"jniclassname")) imclass_name = Copy(Getattr(optionsnode,"jniclassname")); /* check if directors are enabled for this module. note: this * is a "master" switch, without which no director code will be * emitted. %feature("director") statements are also required * to enable directors for individual classes or methods. * * use %module(directors="1") modulename at the start of the * interface file to enable director generation. */ if (Getattr(optionsnode, "directors")) { allow_directors(); } if (Getattr(optionsnode, "dirprot")) { allow_dirprot(); } } /* Initialize all of the output files */ String *outfile = Getattr(n,"outfile"); String *outfile_h = Getattr(n, "outfile_h"); f_runtime = NewFile(outfile,"w"); if (!f_runtime) { Printf(stderr,"Unable to open %s\n", outfile); SWIG_exit(EXIT_FAILURE); } if (directorsEnabled()) { f_runtime_h = NewFile(outfile_h,"w"); if (!f_runtime_h) { Printf(stderr,"*** Can't open '%s'\n", outfile_h); SWIG_exit(EXIT_FAILURE); } } f_init = NewString(""); f_header = NewString(""); f_wrappers = NewString(""); f_directors_h = NewString(""); f_directors = NewString(""); /* Register file targets with the SWIG file handler */ Swig_register_filebyname("header",f_header); Swig_register_filebyname("wrapper",f_wrappers); Swig_register_filebyname("runtime",f_runtime); Swig_register_filebyname("init",f_init); Swig_register_filebyname("director",f_directors); Swig_register_filebyname("director_h",f_directors_h); swig_types_hash = NewHash(); if (!imclass_name) { imclass_name = NewStringf("%sJNI", Getattr(n,"name")); module_class_name = Copy(Getattr(n,"name")); } else { // Rename the module name if it is the same as intermediary class name - a backwards compatibility solution if (Cmp(imclass_name, Getattr(n,"name")) == 0) module_class_name = NewStringf("%sModule", Getattr(n,"name")); else module_class_name = Copy(Getattr(n,"name")); } module = Copy(Getattr(n,"name")); imclass_class_code = NewString(""); proxy_class_def = NewString(""); proxy_class_code = NewString(""); module_class_constants_code = NewString(""); imclass_baseclass = NewString(""); imclass_interfaces = NewString(""); imclass_class_modifiers = NewString(""); // package access only to the intermediary class by default module_class_code = NewString(""); module_baseclass = NewString(""); module_interfaces = NewString(""); module_imports = NewString(""); module_class_modifiers = NewString("public"); imclass_imports = NewString(""); imclass_cppcasts_code = NewString(""); imclass_directors = NewString(""); upcasts_code = NewString(""); dmethods_seq = NewList(); dmethods_table = NewHash(); n_dmethods = 0; n_directors = 0; emitted_connect = false; if (!package) package = NewString(""); jnipackage = NewString(""); package_path = NewString(""); Swig_banner(f_runtime); // Print the SWIG banner message if (NoInclude) { Printf(f_runtime,"#define SWIG_NOINCLUDE\n"); } if (directorsEnabled()) { Printf(f_runtime,"#define SWIG_DIRECTORS\n"); } /* Emit initial director header and director code: */ if (directorsEnabled()) { Swig_banner(f_directors_h); Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", module); Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", module); Printf(f_directors, "\n\n"); Printf(f_directors, "/* ---------------------------------------------------\n"); Printf(f_directors, " * C++ director class methods\n"); Printf(f_directors, " * --------------------------------------------------- */\n\n"); Printf(f_directors, "#include \"%s\"\n\n", Swig_file_filename(outfile_h)); } String *wrapper_name = NewString(""); if(Len(package)) { String *jniname = makeValidJniName(package); Printv(jnipackage, jniname, NIL); Delete(jniname); Replaceall(jnipackage,".","_"); Append(jnipackage, "_"); Printv(package_path, package, NIL); Replaceall(package_path, ".", "/"); } String *jniname = makeValidJniName(imclass_name); Printf(wrapper_name, "Java_%s%s_%%f", Char(jnipackage), jniname); Delete(jniname); Swig_name_register((char*)"wrapper", Char(wrapper_name)); Swig_name_register((char*)"set", (char*)"set_%v"); Swig_name_register((char*)"get", (char*)"get_%v"); Swig_name_register((char*)"member", (char*)"%c_%m"); Delete(wrapper_name); Printf(f_wrappers,"\n#ifdef __cplusplus\n"); Printf(f_wrappers,"extern \"C\" {\n"); Printf(f_wrappers,"#endif\n\n"); /* Emit code */ Language::top(n); if (directorsEnabled()) { // Insert director runtime into the f_runtime file (make it // occur before %header section. Swig_insert_file("director.swg", f_runtime); } // Generate the intermediary class { String *filen = NewStringf("%s%s.java", SWIG_output_directory(), imclass_name); File *f_im = NewFile(filen,"w"); if(!f_im) { Printf(stderr,"Unable to open %s\n", filen); SWIG_exit(EXIT_FAILURE); } Delete(filen); filen = NULL; // Start writing out the intermediary class if(Len(package) > 0) Printf(f_im, "package %s;\n\n", package); emitBanner(f_im); if(imclass_imports) Printf(f_im, "%s\n", imclass_imports); if (Len(imclass_class_modifiers) > 0) Printf(f_im, "%s ", imclass_class_modifiers); Printf(f_im, "class %s ", imclass_name); if (imclass_baseclass && *Char(imclass_baseclass)) Printf(f_im, "extends %s ", imclass_baseclass); if (Len(imclass_interfaces) > 0) Printv(f_im, "implements ", imclass_interfaces, " ", NIL); Printf(f_im, "{\n"); // Add the intermediary class methods Printv(f_im, imclass_class_code, NIL); Printv(f_im, imclass_cppcasts_code, NIL); if (Len(imclass_directors) > 0) { Printf(f_im, "\n/* Director upcall methods: */\n\n"); Printv(f_im, imclass_directors, NIL); } if (n_dmethods > 0) { Putc('\n', f_im); Printf(f_im, " private final static native void swig_module_init();\n"); Printf(f_im, " static {\n"); Printf(f_im, " swig_module_init();\n"); Printf(f_im, " }\n"); } // Finish off the class Printf(f_im, "}\n"); Close(f_im); } // Generate the Java module class { String *filen = NewStringf("%s%s.java", SWIG_output_directory(), module_class_name); File *f_module = NewFile(filen,"w"); if(!f_module) { Printf(stderr,"Unable to open %s\n", filen); SWIG_exit(EXIT_FAILURE); } Delete(filen); filen = NULL; // Start writing out the module class if(Len(package) > 0) Printf(f_module, "package %s;\n\n", package); emitBanner(f_module); if(module_imports) Printf(f_module, "%s\n", module_imports); if (Len(module_class_modifiers) > 0) Printf(f_module, "%s ", module_class_modifiers); Printf(f_module, "class %s ", module_class_name); if (module_baseclass && *Char(module_baseclass)) Printf(f_module, "extends %s ", module_baseclass); if (Len(module_interfaces) > 0) { if (Len(module_class_constants_code) != 0 ) Printv(f_module, "implements ", Getattr(n, "name"), "Constants, ", module_interfaces, " ", NIL); else Printv(f_module, "implements ", module_interfaces, " ", NIL); } else { if (Len(module_class_constants_code) != 0 ) Printv(f_module, "implements ", Getattr(n, "name"), "Constants ", NIL); } Printf(f_module, "{\n"); // Add the wrapper methods Printv(f_module, module_class_code, NIL); // Finish off the class Printf(f_module, "}\n"); Close(f_module); } // Generate the Java constants interface if (Len(module_class_constants_code) != 0 ) { String *filen = NewStringf("%s%sConstants.java", SWIG_output_directory(), module_class_name); File *f_module = NewFile(filen,"w"); if(!f_module) { Printf(stderr,"Unable to open %s\n", filen); SWIG_exit(EXIT_FAILURE); } Delete(filen); filen = NULL; // Start writing out the Java constants interface if(Len(package) > 0) Printf(f_module, "package %s;\n\n", package); emitBanner(f_module); if(module_imports) Printf(f_module, "%s\n", module_imports); if (Len(module_class_modifiers) > 0) Printf(f_module, "%s ", module_class_modifiers); Printf(f_module, "interface %sConstants {\n", module_class_name); // Write out all the enums constants Printv(f_module, " // enums and constants\n", module_class_constants_code, NIL); // Finish off the Java interface Printf(f_module, "}\n"); Close(f_module); } if(upcasts_code) Printv(f_wrappers,upcasts_code,NIL); emitDirectorUpcalls(); Printf(f_wrappers,"#ifdef __cplusplus\n"); Printf(f_wrappers,"}\n"); Printf(f_wrappers,"#endif\n"); // Output a Java type wrapper class for each SWIG type for (Iterator swig_type = First(swig_types_hash); swig_type.key; swig_type = Next(swig_type)) { emitTypeWrapperClass(swig_type.key, swig_type.item); } /* Close all of the files */ Dump(f_header,f_runtime); if (directorsEnabled()) { Dump(f_directors, f_runtime); Dump(f_directors_h, f_runtime_h); Printf(f_runtime_h, "\n"); Printf(f_runtime_h, "#endif\n"); } Delete(swig_types_hash); swig_types_hash = NULL; Delete(imclass_name); imclass_name = NULL; Delete(imclass_class_code); imclass_class_code = NULL; Delete(proxy_class_def); proxy_class_def = NULL; Delete(proxy_class_code); proxy_class_code = NULL; Delete(module_class_constants_code); module_class_constants_code = NULL; Delete(imclass_baseclass); imclass_baseclass = NULL; Delete(imclass_interfaces); imclass_interfaces = NULL; Delete(imclass_class_modifiers); imclass_class_modifiers = NULL; Delete(module_class_name); module_class_name = NULL; Delete(module_class_code); module_class_code = NULL; Delete(module_baseclass); module_baseclass = NULL; Delete(module_interfaces); module_interfaces = NULL; Delete(module_imports); module_imports = NULL; Delete(module_class_modifiers); module_class_modifiers = NULL; Delete(imclass_imports); imclass_imports = NULL; Delete(imclass_cppcasts_code); imclass_cppcasts_code = NULL; Delete(imclass_directors); imclass_directors = NULL; Delete(upcasts_code); upcasts_code = NULL; Delete(package); package = NULL; Delete(jnipackage); jnipackage = NULL; Delete(package_path); package_path = NULL; Delete(dmethods_seq); dmethods_seq = NULL; Delete(dmethods_table); dmethods_table = NULL; n_dmethods = 0; emitted_connect = false; if (f_runtime_h) { Close(f_runtime_h); Delete(f_runtime_h); f_runtime_h = NULL; } Delete(f_directors); f_directors = NULL; Delete(f_directors_h); f_directors_h = NULL; Dump(f_wrappers,f_runtime); Wrapper_pretty_print(f_init,f_runtime); Delete(f_header); Delete(f_wrappers); Delete(f_init); Close(f_runtime); Delete(f_runtime); return SWIG_OK; } /* ----------------------------------------------------------------------------- * emitBanner() * ----------------------------------------------------------------------------- */ void emitBanner(File *f) { Printf(f, "/* ----------------------------------------------------------------------------\n"); Printf(f, " * This file was automatically generated by SWIG (http://www.swig.org).\n"); Printf(f, " * Version: %s\n", PACKAGE_VERSION); Printf(f, " *\n"); Printf(f, " * Do not make changes to this file unless you know what you are doing--modify\n"); Printf(f, " * the SWIG interface file instead.\n"); Printf(f, " * ----------------------------------------------------------------------------- */\n\n"); } /*----------------------------------------------------------------------- * Add new director upcall signature *----------------------------------------------------------------------*/ UpcallData * addUpcallMethod(String *imclass_method, String *class_method, String *imclass_desc, String *class_desc, String *decl) { UpcallData *udata; String *imclass_methodidx; String *class_methodidx; Hash *new_udata; String *key = NewStringf("%s|%s", imclass_method, decl); /* Do we know about this director class already? */ if ((udata = Getattr(dmethods_table, key)) != NULL) { Delete(key); return Getattr(udata, "methodoff"); } imclass_methodidx = NewStringf("%d", n_dmethods); class_methodidx = NewStringf("%d", n_dmethods - first_class_dmethod); n_dmethods++; new_udata = NewHash(); Append(dmethods_seq, new_udata); Setattr(dmethods_table, key, new_udata); Setattr(new_udata, "method", Copy(class_method)); Setattr(new_udata, "fdesc", Copy(class_desc)); Setattr(new_udata, "imclass_method", Copy(imclass_method)); Setattr(new_udata, "imclass_fdesc", Copy(imclass_desc)); Setattr(new_udata, "imclass_methodidx", imclass_methodidx); Setattr(new_udata, "class_methodidx", class_methodidx); Setattr(new_udata, "decl", Copy(decl)); Delete(key); return new_udata; } /*----------------------------------------------------------------------- * Get director upcall signature *----------------------------------------------------------------------*/ UpcallData * getUpcallMethodData(String *director_class, String *decl) { String *key = NewStringf("%s|%s", director_class, decl); UpcallData *udata = Getattr(dmethods_table, key); Delete(key); return udata; } /* ---------------------------------------------------------------------- * nativeWrapper() * ---------------------------------------------------------------------- */ virtual int nativeWrapper(Node *n) { String *wrapname = Getattr(n,"wrap:name"); if (!addSymbol(wrapname,n)) return SWIG_ERROR; if (Getattr(n,"type")) { Swig_save("nativeWrapper",n,"name",NIL); Setattr(n,"name", wrapname); native_function_flag = true; functionWrapper(n); Swig_restore(n); native_function_flag = false; } else { Printf(stderr,"%s : Line %d. No return type for %%native method %s.\n", input_file, line_number, Getattr(n,"wrap:name")); } return SWIG_OK; } /* ---------------------------------------------------------------------- * functionWrapper() * ---------------------------------------------------------------------- */ virtual int functionWrapper(Node *n) { String *symname = Getattr(n,"sym:name"); SwigType *t = Getattr(n,"type"); ParmList *l = Getattr(n,"parms"); String *tm; Parm *p; int i; String *c_return_type = NewString(""); String *im_return_type = NewString(""); String *cleanup = NewString(""); String *outarg = NewString(""); String *body = NewString(""); int num_arguments = 0; int num_required = 0; int gencomma = 0; bool is_void_return; String *overloaded_name = getOverloadedName(n); String *nondir_args = NewString(""); if (!Getattr(n,"sym:overloaded")) { if (!addSymbol(Getattr(n,"sym:name"),n)) return SWIG_ERROR; } /* * Generate the proxy class getters/setters for public member variables. * Not for enums and constants. */ if(proxy_flag && wrapping_member_flag && !enum_constant_flag) { // Capitalize the first letter in the variable to create a JavaBean type getter/setter function name bool getter_flag = Cmp(symname, Swig_name_set(Swig_name_member(proxy_class_name, variable_name))) != 0; String *getter_setter_name = NewString(""); if(!getter_flag) Printf(getter_setter_name,"set"); else Printf(getter_setter_name,"get"); Putc(toupper((int) *Char(variable_name)), getter_setter_name); Printf(getter_setter_name, "%s", Char(variable_name)+1); Setattr(n,"proxyfuncname", getter_setter_name); Setattr(n,"imfuncname", symname); proxyClassFunctionHandler(n); Delete(getter_setter_name); } /* The rest of this function deals with generating the intermediary class wrapper function (that wraps a c/c++ function) and generating the JNI c code. Each Java wrapper function has a matching JNI c function call. */ // A new wrapper function object Wrapper *f = NewWrapper(); // Make a wrapper name for this function String *jniname = makeValidJniName(overloaded_name); String *wname = Swig_name_wrapper(jniname); Delete(jniname); /* Attach the non-standard typemaps to the parameter list. */ Swig_typemap_attach_parms("jni", l, f); Swig_typemap_attach_parms("jtype", l, f); if ((tm = Swig_typemap_lookup_new("jni",n,"",0))) { Printf(c_return_type,"%s", tm); } else { Swig_warning(WARN_JAVA_TYPEMAP_JNI_UNDEF, input_file, line_number, "No jni typemap defined for %s\n", SwigType_str(t,0)); } if ((tm = Swig_typemap_lookup_new("jtype",n,"",0))) { Printf(im_return_type,"%s", tm); } else { Swig_warning(WARN_JAVA_TYPEMAP_JTYPE_UNDEF, input_file, line_number, "No jtype typemap defined for %s\n", SwigType_str(t,0)); } is_void_return = (Cmp(c_return_type, "void") == 0); if (!is_void_return) Wrapper_add_localv(f,"jresult", c_return_type, "jresult = 0",NIL); Printv(f->def, "JNIEXPORT ", c_return_type, " JNICALL ", wname, "(JNIEnv *jenv, jclass jcls", NIL); // Usually these function parameters are unused - The code below ensures // that compilers do not issue such a warning if configured to do so. Printv(f->code," (void)jenv;\n",NIL); Printv(f->code," (void)jcls;\n",NIL); // Emit all of the local variables for holding arguments. emit_args(t,l,f); /* Attach the standard typemaps */ emit_attach_parmmaps(l,f); // Parameter overloading Setattr(n,"wrap:parms",l); Setattr(n,"wrap:name", wname); // Wrappers not wanted for some methods where the parameters cannot be overloaded in Java if (Getattr(n,"sym:overloaded")) { // Emit warnings for the few cases that can't be overloaded in Java and give up on generating wrapper Swig_overload_check(n); if (Getattr(n, "overload:ignore")) return SWIG_OK; } Printf(imclass_class_code, " public final static native %s %s(", im_return_type, overloaded_name); /* Get number of required and total arguments */ num_arguments = emit_num_arguments(l); num_required = emit_num_required(l); // Now walk the function parameter list and generate code to get arguments for (i = 0, p=l; i < num_arguments; i++) { while (checkAttribute(p,"tmap:in:numinputs","0")) { p = Getattr(p,"tmap:in:next"); } SwigType *pt = Getattr(p,"type"); String *ln = Getattr(p,"lname"); String *im_param_type = NewString(""); String *c_param_type = NewString(""); String *arg = NewString(""); Printf(arg,"j%s", ln); /* Get the JNI C types of the parameter */ if ((tm = Getattr(p,"tmap:jni"))) { Printv(c_param_type, tm, NIL); } else { Swig_warning(WARN_JAVA_TYPEMAP_JNI_UNDEF, input_file, line_number, "No jni typemap defined for %s\n", SwigType_str(pt,0)); } /* Get the intermediary class parameter types of the parameter */ if ((tm = Getattr(p,"tmap:jtype"))) { Printv(im_param_type, tm, NIL); } else { Swig_warning(WARN_JAVA_TYPEMAP_JTYPE_UNDEF, input_file, line_number, "No jtype typemap defined for %s\n", SwigType_str(pt,0)); } /* Add parameter to intermediary class method */ if(gencomma) Printf(imclass_class_code, ", "); Printf(imclass_class_code, "%s %s", im_param_type, arg); // Add parameter to C function Printv(f->def, ", ", c_param_type, " ", arg, NIL); ++gencomma; // Get typemap for this argument if ((tm = Getattr(p,"tmap:in"))) { addThrows(n, "tmap:in", p); Replaceall(tm,"$source",arg); /* deprecated */ Replaceall(tm,"$target",ln); /* deprecated */ Replaceall(tm,"$arg",arg); /* deprecated? */ Replaceall(tm,"$input", arg); Setattr(p,"emit:input", arg); Printf(nondir_args,"%s\n", tm); p = Getattr(p,"tmap:in:next"); } else { Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n",SwigType_str(pt,0)); p = nextSibling(p); } Delete(im_param_type); Delete(c_param_type); Delete(arg); } Printv(f->code, nondir_args, NIL); Delete(nondir_args); /* Insert constraint checking code */ for (p = l; p;) { if ((tm = Getattr(p,"tmap:check"))) { addThrows(n, "tmap:check", p); Replaceall(tm,"$target",Getattr(p,"lname")); /* deprecated */ Replaceall(tm,"$arg",Getattr(p,"emit:input")); /* deprecated? */ Replaceall(tm,"$input",Getattr(p,"emit:input")); Printv(f->code,tm,"\n",NIL); p = Getattr(p,"tmap:check:next"); } else { p = nextSibling(p); } } /* Insert cleanup code */ for (p = l; p;) { if ((tm = Getattr(p,"tmap:freearg"))) { addThrows(n, "tmap:freearg", p); Replaceall(tm,"$source",Getattr(p,"emit:input")); /* deprecated */ Replaceall(tm,"$arg",Getattr(p,"emit:input")); /* deprecated? */ Replaceall(tm,"$input",Getattr(p,"emit:input")); Printv(cleanup,tm,"\n",NIL); p = Getattr(p,"tmap:freearg:next"); } else { p = nextSibling(p); } } /* Insert argument output code */ for (p = l; p;) { if ((tm = Getattr(p,"tmap:argout"))) { addThrows(n, "tmap:argout", p); Replaceall(tm,"$source",Getattr(p,"emit:input")); /* deprecated */ Replaceall(tm,"$target",Getattr(p,"lname")); /* deprecated */ Replaceall(tm,"$arg",Getattr(p,"emit:input")); /* deprecated? */ Replaceall(tm,"$result","jresult"); Replaceall(tm,"$input",Getattr(p,"emit:input")); Printv(outarg,tm,"\n",NIL); p = Getattr(p,"tmap:argout:next"); } else { p = nextSibling(p); } } // Get any Java exception classes in the throws typemap ParmList *throw_parm_list = NULL; if ((throw_parm_list = Getattr(n,"throws"))) { Swig_typemap_attach_parms("throws", throw_parm_list, f); for (p = throw_parm_list; p; p=nextSibling(p)) { if ((tm = Getattr(p,"tmap:throws"))) { addThrows(n, "tmap:throws", p); } } } if (Cmp(nodeType(n), "constant") == 0) { // Wrapping a constant hack Swig_save("functionWrapper",n,"wrap:action",NIL); // below based on Swig_VargetToFunction() SwigType *ty = Swig_wrapped_var_type(Getattr(n,"type")); Setattr(n,"wrap:action", NewStringf("result = (%s) %s;\n", SwigType_lstr(ty,0), Getattr(n, "value"))); } // Now write code to make the function call if(!native_function_flag) emit_action(n,f); if (Cmp(nodeType(n), "constant") == 0) Swig_restore(n); /* Return value if necessary */ if(!native_function_flag) { if ((tm = Swig_typemap_lookup_new("out",n,"result",0))) { addThrows(n, "tmap:out", n); Replaceall(tm,"$source", "result"); /* deprecated */ Replaceall(tm,"$target", "jresult"); /* deprecated */ Replaceall(tm,"$result","jresult"); Printf(f->code,"%s", tm); if (Len(tm)) Printf(f->code,"\n"); } else { Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(t,0), Getattr(n,"name")); } } /* Output argument output code */ Printv(f->code,outarg,NIL); /* Output cleanup code */ Printv(f->code,cleanup,NIL); /* Look to see if there is any newfree cleanup code */ if (Getattr(n,"feature:new")) { if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) { addThrows(n, "tmap:newfree", n); Replaceall(tm,"$source","result"); /* deprecated */ Printf(f->code,"%s\n",tm); } } /* See if there is any return cleanup code */ if(!native_function_flag) { if ((tm = Swig_typemap_lookup_new("ret", n, "result", 0))) { Replaceall(tm,"$source","result"); /* deprecated */ Printf(f->code,"%s\n",tm); } } /* Finish C function and intermediary class function definitions */ Printf(imclass_class_code, ")"); generateThrowsClause(n, imclass_class_code); Printf(imclass_class_code, ";\n"); Printf(f->def,") {"); if(!is_void_return) Printv(f->code, " return jresult;\n", NIL); Printf(f->code, "}\n"); /* Substitute the cleanup code */ Replaceall(f->code,"$cleanup",cleanup); /* Contract macro modification */ Replaceall(f->code, "SWIG_contract_assert(", "SWIG_contract_assert($null, "); if(!is_void_return) Replaceall(f->code,"$null","0"); else Replaceall(f->code,"$null",""); /* Dump the function out */ if(!native_function_flag) Wrapper_print(f,f_wrappers); if(!(proxy_flag && is_wrapping_class()) && !enum_constant_flag) { moduleClassFunctionHandler(n); } Delete(c_return_type); Delete(im_return_type); Delete(cleanup); Delete(outarg); Delete(body); Delete(overloaded_name); DelWrapper(f); return SWIG_OK; } /* ----------------------------------------------------------------------- * variableWrapper() * ----------------------------------------------------------------------- */ virtual int variableWrapper(Node *n) { variable_wrapper_flag = true; Language::variableWrapper(n); /* Default to functions */ variable_wrapper_flag = false; return SWIG_OK; } /* ----------------------------------------------------------------------- * globalvariableHandler() * ------------------------------------------------------------------------ */ virtual int globalvariableHandler(Node *n) { variable_name = Getattr(n,"sym:name"); global_variable_flag = true; int ret = Language::globalvariableHandler(n); global_variable_flag = false; return ret; } /* ----------------------------------------------------------------------- * constantWrapper() * ------------------------------------------------------------------------ */ virtual int constantWrapper(Node *n) { String *symname = Getattr(n,"sym:name"); SwigType *t = Getattr(n,"type"); ParmList *l = Getattr(n,"parms"); String *tm; String *return_type = NewString(""); String *constants_code = NewString(""); SwigType *original_type = t; if (!addSymbol(symname,n)) return SWIG_ERROR; bool is_enum_item = (Cmp(nodeType(n), "enumitem") == 0); /* Adjust the enum type for the Swig_typemap_lookup. We want the same jstype typemap for all the enum items. * The type of each enum item depends on what value it is assigned, but is usually a C int. */ if (is_enum_item) { t = NewStringf("enum %s", Getattr(parentNode(n), "sym:name")); Setattr(n,"type", t); } /* Attach the non-standard typemaps to the parameter list. */ Swig_typemap_attach_parms("jstype", l, NULL); /* Get Java return types */ bool classname_substituted_flag = false; if ((tm = Swig_typemap_lookup_new("jstype",n,"",0))) { classname_substituted_flag = substituteClassname(t, tm); Printf(return_type, "%s", tm); } else { Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, "No jstype typemap defined for %s\n", SwigType_str(t,0)); } // Add the stripped quotes back in String *new_value = NewString(""); Swig_save("constantWrapper",n,"value",NIL); if(SwigType_type(t) == T_STRING) { Printf(new_value, "\"%s\"", Copy(Getattr(n, "value"))); Setattr(n, "value", new_value); } else if(SwigType_type(t) == T_CHAR) { Printf(new_value, "\'%s\'", Copy(Getattr(n, "value"))); Setattr(n, "value", new_value); } // The %javaconst feature determines how the constant value is obtained String *const_feature = Getattr(n,"feature:java:const"); bool const_feature_flag = const_feature && Cmp(const_feature, "0") != 0; // enums are wrapped using a public final static int in java. // Other constants are wrapped using a public final static [jstype] in Java. Printf(constants_code, " public final static %s %s = ", return_type, ((proxy_flag && wrapping_member_flag) ? variable_name : symname)); if ((is_enum_item && Getattr(n,"enumvalue") == 0) || !const_feature_flag) { // Enums without value and default constant handling will work with any type of C constant and initialises the Java variable from C through a JNI call. if(classname_substituted_flag) // 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)); else Printf(constants_code, "%s.%s();\n", imclass_name, Swig_name_get(symname)); // Each constant and enum value is wrapped with a separate JNI function call enum_constant_flag = true; variableWrapper(n); enum_constant_flag = false; } else if (is_enum_item) { // Alternative enum item handling will use the explicit value of the enum item and hope that it compiles as Java code Printf(constants_code, "%s;\n", Getattr(n,"enumvalue")); } else { // Alternative constant handling will use the C syntax to make a true Java constant and hope that it compiles as Java code Printf(constants_code, "%s;\n", Getattr(n,"value")); } if(proxy_flag && wrapping_member_flag) Printv(proxy_class_constants_code, constants_code, NIL); else Printv(module_class_constants_code, constants_code, NIL); Swig_restore(n); if (is_enum_item) { Delete(Getattr(n,"type")); Setattr(n,"type", original_type); } Delete(new_value); Delete(return_type); Delete(constants_code); return SWIG_OK; } /* ----------------------------------------------------------------------------- * pragmaDirective() * * Valid Pragmas: * jniclassbase - base (extends) for the intermediary class * jniclassclassmodifiers - class modifiers for the intermediary class * jniclasscode - text (java code) is copied verbatim to the intermediary class * jniclassimports - import statements for the intermediary class * jniclassinterfaces - interface (implements) for the intermediary class * * modulebase - base (extends) for the module class * moduleclassmodifiers - class modifiers for the module class * modulecode - text (java code) is copied verbatim to the module class * moduleimports - import statements for the module class * moduleinterfaces - interface (implements) for the module class * * ----------------------------------------------------------------------------- */ virtual int pragmaDirective(Node *n) { if (!ImportMode) { String *lang = Getattr(n,"lang"); String *code = Getattr(n,"name"); String *value = Getattr(n,"value"); if(Strcmp(lang, "java") == 0) { String *strvalue = NewString(value); Replaceall(strvalue,"\\\"", "\""); if(Strcmp(code, "jniclassbase") == 0) { Delete(imclass_baseclass); imclass_baseclass = Copy(strvalue); } else if(Strcmp(code, "jniclassclassmodifiers") == 0) { Delete(imclass_class_modifiers); imclass_class_modifiers = Copy(strvalue); } else if(Strcmp(code, "jniclasscode") == 0) { Printf(imclass_class_code, "%s\n", strvalue); } else if(Strcmp(code, "jniclassimports") == 0) { Delete(imclass_imports); imclass_imports = Copy(strvalue); } else if(Strcmp(code, "jniclassinterfaces") == 0) { Delete(imclass_interfaces); imclass_interfaces = Copy(strvalue); } else if(Strcmp(code, "modulebase") == 0) { Delete(module_baseclass); module_baseclass = Copy(strvalue); } else if(Strcmp(code, "moduleclassmodifiers") == 0) { Delete(module_class_modifiers); module_class_modifiers = Copy(strvalue); } else if(Strcmp(code, "modulecode") == 0) { Printf(module_class_code, "%s\n", strvalue); } else if(Strcmp(code, "moduleimports") == 0) { Delete(module_imports); module_imports = Copy(strvalue); } else if(Strcmp(code, "moduleinterfaces") == 0) { Delete(module_interfaces); module_interfaces = Copy(strvalue); } else if(Strcmp(code, "moduleimport") == 0) { Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use the moduleimports pragma.\n", input_file, line_number); } else if(Strcmp(code, "moduleinterface") == 0) { Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use the moduleinterfaces pragma.\n", input_file, line_number); } else if(Strcmp(code, "modulemethodmodifiers") == 0) { Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %javamethodmodifiers.\n", input_file, line_number); } else if(Strcmp(code, "allshadowimport") == 0) { Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %typemap(javaimports).\n", input_file, line_number); } else if(Strcmp(code, "allshadowcode") == 0) { Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %typemap(javacode).\n", input_file, line_number); } else if(Strcmp(code, "allshadowbase") == 0) { Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %typemap(javabase).\n", input_file, line_number); } else if(Strcmp(code, "allshadowinterface") == 0) { Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %typemap(javainterfaces).\n", input_file, line_number); } else if(Strcmp(code, "allshadowclassmodifiers") == 0) { Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %typemap(javaclassmodifiers).\n", input_file, line_number); } 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); } else if (Strcmp(code,"shadowimport") == 0) { Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %typemap(javaimports).\n", input_file, line_number); } else if (Strcmp(code,"shadowbase") == 0) { Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %typemap(javabase).\n", input_file, line_number); } else if (Strcmp(code,"shadowinterface") == 0) { Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %typemap(javainterfaces).\n", input_file, line_number); } else if (Strcmp(code,"shadowclassmodifiers") == 0) { Printf(stderr,"%s : Line %d. Ignored: Deprecated pragma. Please use %typemap(javaclassmodifiers).\n", input_file, line_number); } else { Printf(stderr,"%s : Line %d. Unrecognized pragma.\n", input_file, line_number); } } else { Printf(stderr,"%s : Line %d. Unrecognized pragma.\n", input_file, line_number); } Delete(strvalue); } } return Language::pragmaDirective(n); } /* ----------------------------------------------------------------------------- * emitProxyClassDefAndCPPCasts() * ----------------------------------------------------------------------------- */ void emitProxyClassDefAndCPPCasts(Node *n) { String *c_classname = SwigType_namestr(Getattr(n,"name")); String *c_baseclass = NULL; String *baseclass = NULL; String *c_baseclassname = NULL; String *typemap_lookup_type = Getattr(n,"classtypeobj"); /* Deal with inheritance */ List *baselist = Getattr(n,"bases"); if (baselist) { Iterator base = First(baselist); c_baseclassname = Getattr(base.item,"name"); baseclass = Copy(getProxyName(c_baseclassname)); if (baseclass){ c_baseclass = SwigType_namestr(Getattr(base.item,"name")); } base = Next(base); if (base.item) { Swig_warning(WARN_JAVA_MULTIPLE_INHERITANCE, input_file, line_number, "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Java.\n", typemap_lookup_type, Getattr(base.item,"name")); } } bool derived = baseclass && getProxyName(c_baseclassname); if (!baseclass) baseclass = NewString(""); // Inheritance from pure Java classes const String *pure_baseclass = typemapLookup("javabase", typemap_lookup_type, WARN_NONE); if (Len(pure_baseclass) > 0 && Len(baseclass) > 0) { Swig_warning(WARN_JAVA_MULTIPLE_INHERITANCE, input_file, line_number, "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in Java.\n", typemap_lookup_type, pure_baseclass); } // Pure Java interfaces const String *pure_interfaces = typemapLookup("javainterfaces", typemap_lookup_type, WARN_NONE); // Start writing the proxy class Printv(proxy_class_def, typemapLookup("javaimports", typemap_lookup_type, WARN_NONE), // Import statements "\n", typemapLookup("javaclassmodifiers", typemap_lookup_type, WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers " class $javaclassname", // Class name and bases (derived || *Char(pure_baseclass)) ? " extends " : "", baseclass, pure_baseclass, *Char(pure_interfaces) ? // Pure Java interfaces " implements " : "", pure_interfaces, " {\n", " private long swigCPtr;\n", // Member variables for memory handling derived ? "" : " protected boolean swigCMemOwn;\n", "\n", " ", typemapLookup("javaptrconstructormodifiers", typemap_lookup_type, WARN_JAVA_TYPEMAP_PTRCONSTMOD_UNDEF), // pointer constructor modifiers " $javaclassname(long cPtr, boolean cMemoryOwn) {\n", // Constructor used for wrapping pointers derived ? " super($imclassname.SWIG$javaclassnameTo$baseclass(cPtr), cMemoryOwn);\n" : " swigCMemOwn = cMemoryOwn;\n", " swigCPtr = cPtr;\n", " }\n", NIL); if(!have_default_constructor_flag) { // All proxy classes need a constructor Printv(proxy_class_def, "\n", " protected $javaclassname() {\n", " this(0, false);\n", " }\n", NIL); } // C++ destructor is wrapped by the delete method // Note that the method name is specified in a typemap attribute called methodname String *destruct = NewString(""); const String *tm = NULL; Node *attributes = NewHash(); String *destruct_methodname = NULL; if (derived) { tm = typemapLookup("javadestruct_derived", typemap_lookup_type, WARN_NONE, attributes); destruct_methodname = Getattr(attributes, "tmap:javadestruct_derived:methodname"); } else { tm = typemapLookup("javadestruct", typemap_lookup_type, WARN_NONE, attributes); destruct_methodname = Getattr(attributes, "tmap:javadestruct:methodname"); } if (!destruct_methodname) { Swig_error(input_file, line_number, "No methodname attribute defined in javadestruct%s typemap for %s\n", (derived ? "_derived" : ""), proxy_class_name); } // Emit the finalize and delete methods if (tm) { // Finalize method if (*Char(destructor_call)) { Printv(proxy_class_def, typemapLookup("javafinalize", typemap_lookup_type, WARN_NONE), NIL); } // delete method Printv(destruct, tm, NIL); if (*Char(destructor_call)) Replaceall(destruct, "$jnicall", destructor_call); else Replaceall(destruct, "$jnicall", "throw new UnsupportedOperationException(\"C++ destructor does not have public access\")"); if (*Char(destruct)) Printv(proxy_class_def, "\n ", "public void ", destruct_methodname, "() ", destruct, "\n", NIL); } Delete(attributes); Delete(destruct); // Emit various other methods Printv(proxy_class_def, typemapLookup("javagetcptr", typemap_lookup_type, WARN_JAVA_TYPEMAP_GETCPTR_UNDEF), // getCPtr method typemapLookup("javacode", typemap_lookup_type, WARN_NONE), // extra Java code "\n", NIL); /* Insert declaration for swig_director_connect(), if this class has directors enabled */ if (Swig_directorclass(n)) { Printf(proxy_class_def, " protected void swigDirectorDisconnect() {\n"); Printf(proxy_class_def, " swigCMemOwn = false;\n"); Printf(proxy_class_def, " %s();\n", destruct_methodname); Printf(proxy_class_def, " }\n\n"); } // 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, "$baseclass", baseclass); Replaceall(proxy_class_code, "$baseclass", baseclass); 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$javaclassnameTo$baseclass(long jarg1);\n", NIL); Replaceall(imclass_cppcasts_code, "$javaclassname", proxy_class_name); Replaceall(imclass_cppcasts_code, "$baseclass", baseclass); Printv(upcasts_code, "JNIEXPORT jlong JNICALL Java_$jnipackage$imimclass_SWIG$imclazznameTo$imbaseclass", "(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); String *imbaseclass = makeValidJniName(baseclass); Replaceall(upcasts_code, "$imbaseclass", imbaseclass); 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(imbaseclass); Delete(imclazzname); Delete(imimclass); } Delete(baseclass); } /* ---------------------------------------------------------------------- * classHandler() * ---------------------------------------------------------------------- */ virtual int classHandler(Node *n) { File *f_proxy = NULL; if (proxy_flag) { proxy_class_name = NewString(Getattr(n,"sym:name")); if (!addSymbol(proxy_class_name,n)) 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); f_proxy = NewFile(filen,"w"); if(!f_proxy) { Printf(stderr, "Unable to create proxy class file: %s\n", filen); SWIG_exit(EXIT_FAILURE); } Delete(filen); filen = NULL; emitBanner(f_proxy); if(Len(package) > 0) Printf(f_proxy, "package %s;\n\n", package); Clear(proxy_class_def); Clear(proxy_class_code); have_default_constructor_flag = false; destructor_call = NewString(""); proxy_class_constants_code = NewString(""); } Language::classHandler(n); if (proxy_flag) { emitProxyClassDefAndCPPCasts(n); Printv(f_proxy, proxy_class_def, proxy_class_code, NIL); // Write out all the enums and constants if (Len(proxy_class_constants_code) != 0 ) Printv(f_proxy, " // enums and constants\n", proxy_class_constants_code, NIL); Printf(f_proxy, "}\n"); Close(f_proxy); f_proxy = NULL; /* Output the downcast method, if necessary. Note: There's no other really good place to put this code, since Abstract Base Classes (ABCs) can and should have downcasts, making the constructorHandler() a bad place (because ABCs don't get to have constructors emitted.) */ if (Getattr(n, "feature:javadowncast")) { String *jni_imclass_name = makeValidJniName(imclass_name); String *jni_class_name = makeValidJniName(proxy_class_name); 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); Wrapper *dcast_wrap = NewWrapper(); Printf(dcast_wrap->def, "JNIEXPORT 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->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); Printf(dcast_wrap->code, " if (obj) director = dynamic_cast(obj);\n"); Printf(dcast_wrap->code, " if (director) jresult = director->swig_get_self();\n"); Printf(dcast_wrap->code, " return jresult;\n"); Printf(dcast_wrap->code, "}\n"); Wrapper_print(dcast_wrap, f_wrappers); DelWrapper(dcast_wrap); } Delete(proxy_class_name); proxy_class_name = NULL; Delete(destructor_call); destructor_call = NULL; Delete(proxy_class_constants_code); proxy_class_constants_code = NULL; } /* Reinitialize per-class director vars */ emitted_connect = false; return SWIG_OK; } /* ---------------------------------------------------------------------- * memberfunctionHandler() * ---------------------------------------------------------------------- */ virtual int memberfunctionHandler(Node *n) { member_func_flag = true; Language::memberfunctionHandler(n); if (proxy_flag) { String *overloaded_name = getOverloadedName(n); String *intermediary_function_name = Swig_name_member(proxy_class_name, overloaded_name); Setattr(n,"proxyfuncname", Getattr(n, "sym:name")); Setattr(n,"imfuncname", intermediary_function_name); proxyClassFunctionHandler(n); Delete(overloaded_name); } member_func_flag = false; return SWIG_OK; } /* ---------------------------------------------------------------------- * staticmemberfunctionHandler() * ---------------------------------------------------------------------- */ virtual int staticmemberfunctionHandler(Node *n) { static_flag = true; member_func_flag = true; Language::staticmemberfunctionHandler(n); if (proxy_flag) { String *overloaded_name = getOverloadedName(n); String *intermediary_function_name = Swig_name_member(proxy_class_name, overloaded_name); Setattr(n,"proxyfuncname", Getattr(n,"sym:name")); Setattr(n,"imfuncname", intermediary_function_name); proxyClassFunctionHandler(n); Delete(overloaded_name); } static_flag = false; member_func_flag = false; return SWIG_OK; } /* ----------------------------------------------------------------------------- * proxyClassFunctionHandler() * * Function called for creating a Java wrapper function around a c++ function in the * proxy class. Used for both static and non-static C++ class functions. * C++ class static functions map to Java static functions. * Two extra attributes in the Node must be available. These are "proxyfuncname" - * the name of the Java class proxy function, which in turn will call "imfuncname" - * the intermediary (JNI) function name in the intermediary class. * ----------------------------------------------------------------------------- */ void proxyClassFunctionHandler(Node *n) { SwigType *t = Getattr(n,"type"); ParmList *l = Getattr(n,"parms"); String *intermediary_function_name = Getattr(n,"imfuncname"); String *proxy_function_name = Getattr(n,"proxyfuncname"); String *tm; Parm *p; int i; String *imcall = NewString(""); String *return_type = NewString(""); String *function_code = NewString(""); if(!proxy_flag) return; // Wrappers not wanted for some methods where the parameters cannot be overloaded in Java if (Getattr(n, "overload:ignore")) return; if (l) { if (SwigType_type(Getattr(l,"type")) == T_VOID) { l = nextSibling(l); } } /* Attach the non-standard typemaps to the parameter list */ Swig_typemap_attach_parms("in", l, NULL); Swig_typemap_attach_parms("jstype", l, NULL); Swig_typemap_attach_parms("javain", l, NULL); /* Get return types */ if ((tm = Swig_typemap_lookup_new("jstype",n,"",0))) { // Note that in the case of polymorphic (covariant) return types, the method's return type is changed to be the base of the C++ return type SwigType *virtualtype = Getattr(n,"virtual:type"); substituteClassname(virtualtype ? virtualtype : t, tm); Printf(return_type, "%s", tm); if (virtualtype) Swig_warning(WARN_JAVA_COVARIANT_RET, input_file, line_number, "Covariant return types not supported in Java. Proxy method will return %s.\n", SwigType_str(virtualtype,0)); } else { Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, "No jstype typemap defined for %s\n", SwigType_str(t,0)); } /* Start generating the proxy function */ const String *methodmods = Getattr(n,"feature:java:methodmodifiers"); methodmods = methodmods ? methodmods : (is_protected(n) ? protected_string : public_string); Printf(function_code, " %s ", methodmods); if (static_flag) Printf(function_code, "static "); Printf(function_code, "%s %s(", return_type, proxy_function_name); Printv(imcall, imclass_name, ".", intermediary_function_name, "(", NIL); if (!static_flag) Printf(imcall, "swigCPtr"); emit_mark_varargs(l); int gencomma = !static_flag; /* Output each parameter */ for (i = 0, p=l; p; i++) { /* Ignored varargs */ if (checkAttribute(p,"varargs:ignore","1")) { p = nextSibling(p); continue; } /* Ignored parameters */ if (checkAttribute(p,"tmap:in:numinputs","0")) { p = Getattr(p,"tmap:in:next"); continue; } /* Ignore the 'this' argument for variable wrappers */ if (!(variable_wrapper_flag && i==0) || static_flag) { SwigType *pt = Getattr(p,"type"); String *param_type = NewString(""); /* Get the Java parameter type */ if ((tm = Getattr(p,"tmap:jstype"))) { substituteClassname(pt, tm); Printf(param_type, "%s", tm); } else { Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, "No jstype typemap defined for %s\n", SwigType_str(pt,0)); } if (gencomma) Printf(imcall, ", "); String *arg = makeParameterName(n, p, i); // Use typemaps to transform type used in Java proxy wrapper (in proxy class) to type used in JNI function (in intermediary class) if ((tm = Getattr(p,"tmap:javain"))) { addThrows(n, "tmap:javain", p); substituteClassname(pt, tm); Replaceall(tm, "$javainput", arg); Printv(imcall, tm, NIL); } else { Swig_warning(WARN_JAVA_TYPEMAP_JAVAIN_UNDEF, input_file, line_number, "No javain typemap defined for %s\n", SwigType_str(pt,0)); } /* Add parameter to proxy function */ if (gencomma >= 2) Printf(function_code, ", "); gencomma = 2; Printf(function_code, "%s %s", param_type, arg); Delete(arg); Delete(param_type); } p = Getattr(p,"tmap:in:next"); } Printf(imcall, ")"); Printf(function_code, ")"); // Transform return type used in JNI function (in intermediary class) to type used in Java wrapper function (in proxy class) if ((tm = Swig_typemap_lookup_new("javaout",n,"",0))) { addThrows(n, "tmap:javaout", n); if (Getattr(n,"feature:new")) Replaceall(tm,"$owner","true"); else Replaceall(tm,"$owner","false"); substituteClassname(t, tm); Replaceall(tm, "$imclassname", imclass_name); Replaceall(tm, "$jnicall", imcall); } else { Swig_warning(WARN_JAVA_TYPEMAP_JAVAOUT_UNDEF, input_file, line_number, "No javaout typemap defined for %s\n", SwigType_str(t,0)); } generateThrowsClause(n, function_code); Printf(function_code, " %s\n\n", tm ? tm : empty_string); Printv(proxy_class_code, function_code, NIL); Delete(function_code); Delete(return_type); Delete(imcall); } /* ---------------------------------------------------------------------- * constructorHandler() * ---------------------------------------------------------------------- */ virtual int constructorHandler(Node *n) { ParmList *l = Getattr(n,"parms"); String *tm; Parm *p; int i; Node *parentNode = parentNode(n); bool feature_director = (parentNode && Swig_directorclass(n)); Language::constructorHandler(n); // Wrappers not wanted for some methods where the parameters cannot be overloaded in Java if (Getattr(n, "overload:ignore")) return SWIG_OK; if(proxy_flag) { String *overloaded_name = getOverloadedName(n); String *mangled_overname = Swig_name_construct(overloaded_name); String *imcall = NewString(""); const String *methodmods = Getattr(n,"feature:java:methodmodifiers"); methodmods = methodmods ? methodmods : (is_protected(n) ? protected_string : public_string); Printf(proxy_class_code, " %s %s(", methodmods, proxy_class_name); Printv(imcall, "this(", imclass_name, ".", mangled_overname, "(", NIL); /* Attach the non-standard typemaps to the parameter list */ Swig_typemap_attach_parms("in", l, NULL); Swig_typemap_attach_parms("jstype", l, NULL); Swig_typemap_attach_parms("javain", l, NULL); emit_mark_varargs(l); int gencomma = 0; int ctor_arg_cnt = 0; /* Output each parameter */ for (i = 0, p=l; p; i++) { /* Ignored varargs */ if (checkAttribute(p,"varargs:ignore","1")) { p = nextSibling(p); continue; } /* Ignored parameters */ if (checkAttribute(p,"tmap:in:numinputs","0")) { p = Getattr(p,"tmap:in:next"); continue; } SwigType *pt = Getattr(p,"type"); String *param_type = NewString(""); /* Get the Java parameter type */ if ((tm = Getattr(p,"tmap:jstype"))) { substituteClassname(pt, tm); Printf(param_type, "%s", tm); } else { Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, "No jstype typemap defined for %s\n", SwigType_str(pt,0)); } if (gencomma) Printf(imcall, ", "); String *arg = makeParameterName(n, p, i); // Use typemaps to transform type used in Java wrapper function (in proxy class) to type used in JNI function (in intermediary class) if ((tm = Getattr(p,"tmap:javain"))) { addThrows(n, "tmap:javain", p); substituteClassname(pt, tm); Replaceall(tm, "$javainput", arg); Printv(imcall, tm, NIL); } else { Swig_warning(WARN_JAVA_TYPEMAP_JAVAIN_UNDEF, input_file, line_number, "No javain typemap defined for %s\n", SwigType_str(pt,0)); } /* Add parameter to proxy function */ if(gencomma) Printf(proxy_class_code, ", "); Printf(proxy_class_code, "%s %s", param_type, arg); ++gencomma; ctor_arg_cnt++; Delete(arg); Delete(param_type); p = Getattr(p,"tmap:in:next"); } Printf(imcall, "), true);\n"); Printf(proxy_class_code, ")"); generateThrowsClause(n, proxy_class_code); Printf(proxy_class_code, " {\n"); Printf(proxy_class_code, " %s", imcall); /* Add director connection call if this class has directors. */ if (feature_director) { 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); Printv(proxy_class_code, " ", imclass_name, ".", swig_director_connect, "(this, swigCPtr);\n", NIL); if (!emitted_connect) { String *swig_director_connect_jni = makeValidJniName(swig_director_connect); Wrapper *conn_wrap; Printf(imclass_class_code, " public final static native void %s(%s obj, long cptr);\n", swig_director_connect, proxy_class_name); conn_wrap = NewWrapper(); Printf(conn_wrap->def, "JNIEXPORT void JNICALL Java_%s%s_%s(JNIEnv *jenv, jclass jcls, jobject jself, jlong objarg) {", jnipackage, jni_imclass_name, swig_director_connect_jni); Printf(conn_wrap->code, " %s *obj = *((%s **) &objarg);\n", norm_name, norm_name); Printf(conn_wrap->code, " SwigDirector_%s *director = dynamic_cast(obj);\n", Getattr(n, "sym:name"), Getattr(n, "sym:name")); Printf(conn_wrap->code, " if (director) {\n"); Printf(conn_wrap->code, " director->swig_connect_director(jenv, jself, jenv->GetObjectClass(jself));\n"); Printf(conn_wrap->code, " }\n"); Printf(conn_wrap->code, "}\n"); Wrapper_print(conn_wrap, f_wrappers); DelWrapper(conn_wrap); Delete(swig_director_connect_jni); emitted_connect = true; } Delete(norm_name); Delete(jni_imclass_name); Delete(swig_director_connect); } Printf(proxy_class_code, " }\n\n"); if(!ctor_arg_cnt) // We must have a default constructor have_default_constructor_flag = true; Delete(overloaded_name); Delete(imcall); } return SWIG_OK; } /* ---------------------------------------------------------------------- * destructorHandler() * ---------------------------------------------------------------------- */ virtual int destructorHandler(Node *n) { Language::destructorHandler(n); String *symname = Getattr(n,"sym:name"); if(proxy_flag) { Printv(destructor_call, imclass_name, ".", Swig_name_destroy(symname), "(swigCPtr)", NIL); } return SWIG_OK; } /* ---------------------------------------------------------------------- * membervariableHandler() * ---------------------------------------------------------------------- */ virtual int membervariableHandler(Node *n) { variable_name = Getattr(n,"sym:name"); wrapping_member_flag = true; variable_wrapper_flag = true; Language::membervariableHandler(n); wrapping_member_flag = false; variable_wrapper_flag = false; return SWIG_OK; } /* ---------------------------------------------------------------------- * staticmembervariableHandler() * ---------------------------------------------------------------------- */ virtual int staticmembervariableHandler(Node *n) { variable_name = Getattr(n,"sym:name"); wrapping_member_flag = true; static_flag = true; Language::staticmembervariableHandler(n); wrapping_member_flag = false; static_flag = false; return SWIG_OK; } /* ---------------------------------------------------------------------- * memberconstantHandler() * ---------------------------------------------------------------------- */ virtual int memberconstantHandler(Node *n) { variable_name = Getattr(n,"sym:name"); wrapping_member_flag = true; Language::memberconstantHandler(n); wrapping_member_flag = false; return SWIG_OK; } /* ----------------------------------------------------------------------------- * getOverloadedName() * ----------------------------------------------------------------------------- */ String *getOverloadedName(Node *n) { /* Although JNI functions are designed to handle overloaded Java functions, * a Java long is used for all classes in the SWIG intermediary class. * The intermediary class methods are thus mangled when overloaded to give * a unique name. */ String *overloaded_name = NewStringf("%s", Getattr(n,"sym:name")); if (Getattr(n,"sym:overloaded")) { Printv(overloaded_name, Getattr(n,"sym:overname"), NIL); } return overloaded_name; } /* ----------------------------------------------------------------------------- * moduleClassFunctionHandler() * ----------------------------------------------------------------------------- */ void moduleClassFunctionHandler(Node *n) { SwigType *t = Getattr(n,"type"); ParmList *l = Getattr(n,"parms"); String *tm; Parm *p; int i; String *imcall = NewString(""); String *return_type = NewString(""); String *function_code = NewString(""); int num_arguments = 0; int num_required = 0; String *overloaded_name = getOverloadedName(n); String *func_name = NULL; bool setter_flag = false; if (l) { if (SwigType_type(Getattr(l,"type")) == T_VOID) { l = nextSibling(l); } } /* Attach the non-standard typemaps to the parameter list */ Swig_typemap_attach_parms("jstype", l, NULL); Swig_typemap_attach_parms("javain", l, NULL); /* Get return types */ if ((tm = Swig_typemap_lookup_new("jstype",n,"",0))) { substituteClassname(t, tm); Printf(return_type, "%s", tm); } else { Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, "No jstype typemap defined for %s\n", SwigType_str(t,0)); } /* Change function name for global variables */ if (proxy_flag && global_variable_flag) { // Capitalize the first letter in the variable to create a JavaBean type getter/setter function name func_name = NewString(""); setter_flag = (Cmp(Getattr(n,"sym:name"), Swig_name_set(variable_name)) == 0); if(setter_flag) Printf(func_name,"set"); else Printf(func_name,"get"); Putc(toupper((int) *Char(variable_name)), func_name); Printf(func_name, "%s", Char(variable_name)+1); } else { func_name = Copy(Getattr(n,"sym:name")); } /* Start generating the function */ const String *methodmods = Getattr(n,"feature:java:methodmodifiers"); methodmods = methodmods ? methodmods : (is_protected(n) ? protected_string : public_string); Printf(function_code, " %s static %s %s(", methodmods, return_type, func_name); Printv(imcall, imclass_name, ".", overloaded_name, "(", NIL); /* Get number of required and total arguments */ num_arguments = emit_num_arguments(l); num_required = emit_num_required(l); int gencomma = 0; /* Output each parameter */ for (i = 0, p=l; i < num_arguments; i++) { /* Ignored parameters */ while (checkAttribute(p,"tmap:in:numinputs","0")) { p = Getattr(p,"tmap:in:next"); } SwigType *pt = Getattr(p,"type"); String *param_type = NewString(""); /* Get the Java parameter type */ if ((tm = Getattr(p,"tmap:jstype"))) { substituteClassname(pt, tm); Printf(param_type, "%s", tm); } else { Swig_warning(WARN_JAVA_TYPEMAP_JSTYPE_UNDEF, input_file, line_number, "No jstype typemap defined for %s\n", SwigType_str(pt,0)); } if (gencomma) Printf(imcall, ", "); String *arg = makeParameterName(n, p, i); // Use typemaps to transform type used in Java wrapper function (in proxy class) to type used in JNI function (in intermediary class) if ((tm = Getattr(p,"tmap:javain"))) { addThrows(n, "tmap:javain", p); substituteClassname(pt, tm); Replaceall(tm, "$javainput", arg); Printv(imcall, tm, NIL); } else { Swig_warning(WARN_JAVA_TYPEMAP_JAVAIN_UNDEF, input_file, line_number, "No javain typemap defined for %s\n", SwigType_str(pt,0)); } /* Add parameter to module class function */ if (gencomma >= 2) Printf(function_code, ", "); gencomma = 2; Printf(function_code, "%s %s", param_type, arg); p = Getattr(p,"tmap:in:next"); Delete(arg); Delete(param_type); } Printf(imcall, ")"); Printf(function_code, ")"); // Transform return type used in JNI function (in intermediary class) to type used in Java wrapper function (in module class) if ((tm = Swig_typemap_lookup_new("javaout",n,"",0))) { addThrows(n, "tmap:javaout", n); if (Getattr(n,"feature:new")) Replaceall(tm,"$owner","true"); else Replaceall(tm,"$owner","false"); substituteClassname(t, tm); Replaceall(tm, "$imclassname", imclass_name); Replaceall(tm, "$jnicall", imcall); } else { Swig_warning(WARN_JAVA_TYPEMAP_JAVAOUT_UNDEF, input_file, line_number, "No javaout typemap defined for %s\n", SwigType_str(t,0)); } generateThrowsClause(n, function_code); Printf(function_code, " %s\n\n", tm ? tm : empty_string); Printv(module_class_code, function_code, NIL); Delete(function_code); Delete(return_type); Delete(imcall); Delete(func_name); } /* ----------------------------------------------------------------------------- * substituteClassname() * * Substitute $javaclassname with the proxy class name for classes/structs/unions that SWIG knows about. * Otherwise use the $descriptor name for the Java class name. Note that the $&javaclassname substitution * is the same as a $&descriptor substitution, ie one pointer added to descriptor name. * Inputs: * pt - parameter type * tm - jstype typemap * Outputs: * tm - jstype typemap with $javaclassname substitution * Return: * substitution_performed - flag indicating if a substitution was performed * ----------------------------------------------------------------------------- */ bool substituteClassname(SwigType *pt, String *tm) { bool substitution_performed = false; if (Strstr(tm, "$javaclassname") || Strstr(tm,"$&javaclassname")) { String *classname = getProxyName(pt); if (classname) { Replaceall(tm,"$&javaclassname", classname); // getProxyName() works for pointers to classes too Replaceall(tm,"$javaclassname", classname); } else { // use $descriptor if SWIG does not know anything about this type. Note that any typedefs are resolved. String *descriptor = NULL; SwigType *type = Copy(SwigType_typedef_resolve_all(pt)); if (Strstr(tm, "$&javaclassname")) { SwigType_add_pointer(type); descriptor = NewStringf("SWIGTYPE%s", SwigType_manglestr(type)); Replaceall(tm, "$&javaclassname", descriptor); } else { // $javaclassname descriptor = NewStringf("SWIGTYPE%s", SwigType_manglestr(type)); Replaceall(tm, "$javaclassname", descriptor); } // Add to hash table so that the type wrapper classes can be created later Setattr(swig_types_hash, descriptor, type); Delete(descriptor); Delete(type); } substitution_performed = true; } return substitution_performed; } /* ----------------------------------------------------------------------------- * makeParameterName() * * Inputs: * n - Node * p - parameter node * arg_num - parameter argument number * Return: * arg - a unique parameter name * ----------------------------------------------------------------------------- */ String *makeParameterName(Node *n, Parm *p, int arg_num) { // Use C parameter name unless it is a duplicate or an empty parameter name String *pn = Getattr(p,"name"); int count = 0; ParmList *plist = Getattr(n,"parms"); while (plist) { if ((Cmp(pn, Getattr(plist,"name")) == 0)) count++; plist = nextSibling(plist); } String *arg = (!pn || (count > 1)) ? NewStringf("arg%d",arg_num) : Copy(Getattr(p,"name")); return arg; } /* ----------------------------------------------------------------------------- * emitTypeWrapperClass() * ----------------------------------------------------------------------------- */ void emitTypeWrapperClass(String *classname, SwigType *type) { String *swigtype = NewString(""); String *filen = NewStringf("%s%s.java", SWIG_output_directory(), classname); File *f_swigtype = NewFile(filen,"w"); if(!f_swigtype) { Printf(stderr,"Unable to open %s\n", filen); SWIG_exit(EXIT_FAILURE); } Delete(filen); filen = NULL; // Emit banner and package name emitBanner(f_swigtype); if(Len(package) > 0) Printf(f_swigtype, "package %s;\n\n", package); // Pure Java baseclass and interfaces const String *pure_baseclass = typemapLookup("javabase", type, WARN_NONE); const String *pure_interfaces = typemapLookup("javainterfaces", type, WARN_NONE); // Emit the class Printv(swigtype, typemapLookup("javaimports", type, WARN_NONE), // Import statements "\n", typemapLookup("javaclassmodifiers", type, WARN_JAVA_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers " class $javaclassname", // Class name and bases *Char(pure_baseclass) ? " extends " : "", pure_baseclass, *Char(pure_interfaces) ? // Interfaces " implements " : "", pure_interfaces, " {\n", " private long swigCPtr;\n", "\n", " ", typemapLookup("javaptrconstructormodifiers", type, WARN_JAVA_TYPEMAP_PTRCONSTMOD_UNDEF), // pointer constructor modifiers " $javaclassname(long cPtr, boolean bFutureUse) {\n", // Constructor used for wrapping pointers " swigCPtr = cPtr;\n", " }\n", "\n", " protected $javaclassname() {\n", // Default constructor " swigCPtr = 0;\n", " }\n", typemapLookup("javagetcptr", type, WARN_JAVA_TYPEMAP_GETCPTR_UNDEF), // getCPtr method typemapLookup("javacode", type, WARN_NONE), // extra Java code "}\n", "\n", NIL); Replaceall(swigtype, "$javaclassname", classname); Printv(f_swigtype, swigtype, NIL); Close(f_swigtype); Delete(swigtype); } /* ----------------------------------------------------------------------------- * typemapLookup() * ----------------------------------------------------------------------------- */ const String *typemapLookup(const String *op, String *type, int warning, Node *typemap_attributes=NULL) { String *tm = NULL; const String *code = NULL; if((tm = Swig_typemap_search(op, type, NULL, NULL))) { code = Getattr(tm,"code"); if (typemap_attributes) Swig_typemap_attach_kwargs(tm,op,typemap_attributes); } if (!code) { code = empty_string; if (warning != WARN_NONE) Swig_warning(warning, input_file, line_number, "No %s typemap defined for %s\n", op, type); } return code ? code : empty_string; } /* ----------------------------------------------------------------------------- * addThrows() * ----------------------------------------------------------------------------- */ void addThrows(Node *n, const String *typemap, Node *parameter) { // Get the comma separated throws clause - held in "throws" attribute in the typemap passed in String *throws_attribute = NewStringf("%s:throws", typemap); String *throws = Getattr(parameter,throws_attribute); if (throws) { String *throws_list = Getattr(n,"java:throwslist"); if (!throws_list) { throws_list = NewList(); Setattr(n,"java:throwslist", throws_list); } // Put the exception classes in the throws clause into a temporary List List *temp_classes_list = Split(throws,',',INT_MAX); // Add the exception classes to the node throws list, but don't duplicate if already in list if (temp_classes_list && Len(temp_classes_list) > 0) { for (Iterator cls = First(temp_classes_list); cls.item; cls = Next(cls)) { String *exception_class = NewString(cls.item); Replaceall(exception_class," ",""); // remove spaces Replaceall(exception_class,"\t",""); // remove tabs if (Len(exception_class) > 0) { // $javaclassname substitution SwigType *pt = Getattr(parameter,"type"); substituteClassname(pt, exception_class); // Don't duplicate the Java exception class in the throws clause bool found_flag = false; for (Iterator item = First(throws_list); item.item; item = Next(item)) { if (Strcmp(item.item, exception_class) == 0) found_flag = true; } if (!found_flag) Append(throws_list, exception_class); } Delete(exception_class); } } Delete(temp_classes_list); } Delete(throws_attribute); } /* ----------------------------------------------------------------------------- * generateThrowsClause() * ----------------------------------------------------------------------------- */ void generateThrowsClause(Node *n, String *code) { // Add the throws clause into code List *throws_list = Getattr(n,"java:throwslist"); if (throws_list) { Iterator cls = First(throws_list); Printf(code, " throws %s", cls.item); while ( (cls = Next(cls)).item) Printf(code, ", %s", cls.item); } } /*---------------------------------------------------------------------- * getUpcallJNIMethod() *--------------------------------------------------------------------*/ String * getUpcallJNIMethod(String *descrip) { static struct { char code; const char *method; } upcall_methods[] = { { 'B', "CallStaticByteMethod" }, { 'C', "CallStaticCharMethod" }, { 'D', "CallStaticDoubleMethod" }, { 'F', "CallStaticFloatMethod" }, { 'I', "CallStaticIntMethod" }, { 'J', "CallStaticLongMethod" }, { 'L', "CallStaticObjectMethod" }, { 'S', "CallStaticShortMethod" }, { 'V', "CallStaticVoidMethod" }, { 'Z', "CallStaticBooleanMethod" }, { '[', "CallStaticObjectMethod" } }; char code; int i; code = *Char(descrip); for (i = 0; i < (int) (sizeof(upcall_methods)/sizeof(upcall_methods[0])); ++i) if (code == upcall_methods[i].code) return NewString(upcall_methods[i].method); return NULL; } /*---------------------------------------------------------------------- * emitDirectorUpcalls() *--------------------------------------------------------------------*/ void emitDirectorUpcalls() { if (n_dmethods) { Wrapper *w = NewWrapper(); String *jni_imclass_name = makeValidJniName(imclass_name); String *swig_module_init = NewString("swig_module_init"); String *swig_module_init_jni = makeValidJniName(swig_module_init); String *dmethod_data = NewString(""); int n_methods = 0; Iterator udata_iter; udata_iter = First(dmethods_seq); while (udata_iter.item) { UpcallData *udata = udata_iter.item; Printf(dmethod_data, " { \"%s\", \"%s\" }", Getattr(udata, "imclass_method"), Getattr(udata, "imclass_fdesc")); ++n_methods; udata_iter = Next(udata_iter); if (udata_iter.item) Putc(',', dmethod_data); Putc('\n', dmethod_data); } Printf(f_runtime, "namespace Swig {\n"); Printf(f_runtime, " static jclass jclass_%s = NULL;\n", imclass_name); Printf(f_runtime, " static jmethodID director_methids[%d];\n", n_methods); Printf(f_runtime, "}\n"); Printf(w->def, "JNIEXPORT void JNICALL Java_%s%s_%s(JNIEnv *jenv, jclass jcls) {", jnipackage, jni_imclass_name, swig_module_init_jni); Printf(w->code, "static struct {\n"); Printf(w->code, " const char *method;\n"); Printf(w->code, " const char *signature;\n"); Printf(w->code, "} methods[%d] = {\n", n_methods); Printv(w->code, dmethod_data, NIL); Printf(w->code, "};\n"); Wrapper_add_local(w, "i", "int i"); Printf(w->code, "Swig::jclass_%s = (jclass) jenv->NewGlobalRef(jcls);\n", imclass_name); Printf(w->code, "if (Swig::jclass_%s == NULL) return;\n", imclass_name); Printf(w->code, "for (i = 0; i < (int) (sizeof(methods)/sizeof(methods[0])); ++i) {\n"); Printf(w->code, " Swig::director_methids[i] = jenv->GetStaticMethodID(jcls, methods[i].method, methods[i].signature);\n"); Printf(w->code, " if (Swig::director_methids[i] == NULL) return;\n"); Printf(w->code, "}\n"); Printf(w->code, "}\n"); Wrapper_print(w, f_wrappers); Delete(dmethod_data); Delete(swig_module_init_jni); Delete(swig_module_init); Delete(jni_imclass_name); DelWrapper(w); } } /* --------------------------------------------------------------- * Reduce and canonicalize the input type * * (scottm) There is probably a SWIG function to do this, but I * haven't found it yet. * --------------------------------------------------------------- */ Node *canonicalizeType(Node *n, String *classtype) { String *reduced_type = SwigType_typedef_resolve_all(classtype); String *base_type = SwigType_base(reduced_type); Node *classnode = Swig_symbol_clookup(base_type, Getattr(n, "sym:symtab")); if (classnode != NULL) { /* This takes care of the case when there are forward declared * classes that Language::classHandler() hasn't encountered yet. * * Swig_symbol_clookup() will find <> attached to * the base_type name, and there will be a csym:nextSibling node * chain. Most of the time, there **wont** be * a "class"-type * node. Mostly, what I've seen are "constructor"-type nodes. * Eventutally, however, a node is encountered with its * sym:name set and this happens to be the right name. * * The worst that can happen here is that base_type is unchanged, * which tends also to be the right thing to do. * * Dunno, this seems to work, so... contemplate what the "right" * SWIG thing is to do... */ while (classnode && Getattr(classnode, "sym:name") == NULL) { classnode = Getattr(classnode, "csym:nextSibling"); } } Delete(reduced_type); Delete(base_type); return classnode; } /* --------------------------------------------------------------- * Canonicalize the JNI field descriptor * * Take the input type name, reduce the typedef to its fundamental * type if necessary, normalize its name. * * See if the resulting typdef-reduced, normalized type name also * has a "javapackage" typemap, and use it instead of the default * package_path. * * !!SFM!! If $packagepath occurs in the field descriptor, but * package_path isn't set (length == 0), then strip it and the * optional trailing '/' from the resulting name. * * --------------------------------------------------------------- */ String *canonicalJNIFDesc(String *in_desc, Node *n, String *classtype) { Node *classnode = canonicalizeType(n, classtype); String *name = (classnode ? Getattr(classnode, "name") : classtype); String *symname = (classnode ? Getattr(classnode, "sym:name") : classtype); Parm *tp = NewParm(name, (String *) empty_string); String *pkg_path; pkg_path = Swig_typemap_lookup_new("javapackage", tp, "", 0); Delete(tp); if (pkg_path != NULL && Len(pkg_path) != 0) { Replaceall(pkg_path, ".", "/"); } else pkg_path = package_path; String *mod_desc = Copy(in_desc); if (Len(pkg_path) > 0) { Replaceall(mod_desc, "$packagepath", pkg_path); } else { Replaceall(mod_desc, "$packagepath/", empty_string); Replaceall(mod_desc, "$packagepath", empty_string); } Replaceall(mod_desc, "$javaclassname", symname); if (pkg_path != package_path) Delete(pkg_path); return mod_desc; } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // (scottm) Class director mods: //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /* --------------------------------------------------------------- * classDirectorMethod() * * Emit a virtual director method to pass a method call on to the * underlying Java object. * * --------------------------------------------------------------- */ int classDirectorMethod(Node *n, Node *parent, String *super) { String *empty_str = NewString(""); String *classname = Getattr(parent, "sym:name"); String *name = Getattr(n, "name"); String *symname = Getattr(n, "sym:name"); String *type = Getattr(n, "type"); String *c_classname = NULL; String *overloaded_name = getOverloadedName(n); String *storage = Getattr(n, "storage"); String *value = Getattr(n, "value"); String *decl = Getattr(n, "decl"); String *declaration = NewString(""); String *return_type = Copy(type); String *tm; Parm *p; int i, num_arguments, num_required; Wrapper *w = NewWrapper(); ParmList *l = Getattr(n, "parms"); bool is_void = !(Cmp(type, "void")); String *qualified_return = NewString(""); bool pure_virtual = (!(Cmp(storage, "virtual")) && !(Cmp(value, "0"))); int status = SWIG_OK; bool output_director = true; String *dirclassname = directorClassName(parent); String *qualified_name = NewStringf("%s::%s", dirclassname, name); String *jnidesc = NewString(""); String *classdesc = NewString(""); String *jniret_desc = NewString(""); String *classret_desc = NewString(""); String *jniret_type = NULL; String *jupcall_args = NewString("swig_get_self()"); String *imclass_dmethod; Wrapper *imw = NewWrapper(); String *imcall_args = NewString(""); int gencomma = 0; int classmeth_off = curr_class_dmethod - first_class_dmethod; // This is a kludge: functionWrapper has sym:overload set properly, but it // isn't at this point, so we have to manufacture it ourselves. At least // we're consistent with the sym:overload name in functionWrapper. (?? when // does the overloaded method name get set?) imclass_dmethod = NewStringf("SwigDirector_%s", Swig_name_member(classname, overloaded_name)); // Get the proper name for the parent node (should be a class... hint) c_classname = Getattr(parent, "name"); if (!(Cmp(type, "class"))) c_classname = classname; /* Handle and form complete return type, including the modification to a pointer, if return type is a reference. */ if (return_type) { if (!is_void) { SwigType *t = Copy(decl); SwigType *f = SwigType_pop_function(t); SwigType_push(return_type, t); Delete(f); Delete(t); qualified_return = SwigType_rcaststr(return_type, "result"); if (!SwigType_isclass(return_type)) { if (!(SwigType_ispointer(return_type) || SwigType_isreference(return_type))) { Wrapper_add_localv(w, "result", SwigType_lstr(return_type, "result"), NIL); } else { /* initialize pointers to something sane. */ Wrapper_add_localv(w, "result", SwigType_lstr(return_type, "result"), "= 0", NIL); } } else { SwigType *vt; vt = cplus_value_type(return_type); if (vt == NULL) { Wrapper_add_localv(w, "result", SwigType_lstr(return_type, "result"), NIL); } else { Wrapper_add_localv(w, "result", SwigType_lstr(vt, "result"), NIL); Delete(vt); } } /* Create the intermediate class wrapper */ Parm *tp = NewParm(return_type, empty_str); tm = Swig_typemap_lookup_new("jtype", tp, "", 0); if (tm != NULL) { Printf(imw->def, "public static %s %s(%s self", tm, imclass_dmethod, classname); } else { Swig_warning(WARN_JAVA_TYPEMAP_JTYPE_UNDEF, input_file, line_number, "No jtype typemap defined for %s\n", SwigType_str(t,0)); } } else Printf(imw->def, "public static void %s(%s self", imclass_dmethod, classname); /* Get the JNI field descriptor for this return type, add the JNI field descriptor to jniret_desc */ Parm *retpm = NewParm(return_type, empty_str); if ((jniret_type = Swig_typemap_lookup_new("jni", retpm, "", 0)) != NULL) { String *jdesc; Parm *tp = NewParm(jniret_type, empty_str); if (!is_void) { String *jretval_decl = NewStringf("%s jresult", jniret_type); Wrapper_add_localv(w, "jresult", jretval_decl, " = 0", NIL); Delete(jretval_decl); } if ((tm = Swig_typemap_lookup_new("directorin", tp, "", 0)) != NULL && (jdesc = Getattr(tp, "tmap:directorin:descriptor")) != NULL) { String *jnidesc_canon; jnidesc_canon = canonicalJNIFDesc(jdesc, n, jniret_type); Append(jniret_desc, jnidesc_canon); Delete(jnidesc_canon); } else { Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number, "No or improper directorin typemap defined for %s\n", SwigType_str(jniret_type,0)); output_director = false; } Delete(tp); } else { Swig_warning(WARN_JAVA_TYPEMAP_JNI_UNDEF, input_file, line_number, "No jni typemap defined for %s\n", SwigType_str(type,0)); output_director = false; } String *jdesc; if ((tm = Swig_typemap_lookup_new("directorin", retpm, "", 0)) != NULL && (jdesc = Getattr(retpm, "tmap:directorin:descriptor")) != NULL) { String *jnidesc_canon; // Note that in the case of polymorphic (covariant) return types, the method's return type is changed to be the base of the C++ return type SwigType *virtualtype = Getattr(n,"virtual:type"); jnidesc_canon = canonicalJNIFDesc(jdesc, n, virtualtype ? virtualtype : return_type); Append(classret_desc, jnidesc_canon); Delete(jnidesc_canon); } else { Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number, "No or improper directorin typemap defined for %s\n", SwigType_str(jniret_type,0)); output_director = false; } Delete(retpm); } /* Go through argument list, attach lnames for arguments */ for (i = 0, p=l; p; p = nextSibling(p), ++i) { String *arg = Getattr(p, "name"); String *lname = NewString(""); if (arg == NULL && Cmp(Getattr(p, "type"), "void")) { lname = NewStringf("arg%d", i); Setattr(p, "name", lname); } else lname = arg; Setattr(p, "lname", lname); } /* Attach the standard typemaps */ emit_attach_parmmaps(l, w); Swig_typemap_attach_parms("in", l, w); Swig_typemap_attach_parms("out", l, w); Swig_typemap_attach_parms("jni", l, w); Swig_typemap_attach_parms("jtype", l, w); Swig_typemap_attach_parms("directorin", l, 0); Swig_typemap_attach_parms("javadirectorin", l, 0); /* Add Java environment pointer to wrapper */ { String *jenvstr = NewString("jenv"); Wrapper_add_localv(w, jenvstr, "JNIEnv *", jenvstr, "= (JNIEnv *) NULL", NIL); Delete(jenvstr); } /* Preamble code */ Printf(w->code, "jenv = swig_acquire_jenv();\n"); Printf(w->code, "if (!swig_override[%d]) {\n", classmeth_off); if (!pure_virtual) { if (is_void) { Printf(w->code, "%s;\n", Swig_method_call(super,l)); Printf(w->code, "return;\n"); } else { String *super_call = Swig_method_call(super, l); Printf(w->code, "return %s;\n", super_call); Delete(super_call); } } else { Printf(w->code, "SWIG_JavaThrowException(jenv, SWIG_JavaDirectorPureVirtual,\n"); Printf(w->code, " \"Attempted to invoke pure virtual method %s::%s.\");\n", c_classname, name); /* Make sure that we return something in the case of a pure * virtual method call for syntactical reasons. */ if (!is_void) Printf(w->code, "return %s;", qualified_return); else Printf(w->code, "return;\n"); } Printf(w->code, "}\n"); /* Start the Java field descriptor for the intermediate class's upcall (insert self object) */ { Parm *tp = NewParm(classname, empty_str); String *jdesc; if ((tm = Swig_typemap_lookup_new("directorin", tp, "", 0)) != NULL && (jdesc = Getattr(tp, "tmap:directorin:descriptor")) != NULL) { String *jni_canon; jni_canon = canonicalJNIFDesc(jdesc, n, classname); Append(jnidesc, jni_canon); Delete(jni_canon); Delete(tm); } else { Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number, "No or improper directorin typemap defined for %s\n", SwigType_str(classname, 0)); output_director = false; } Delete(tp); } /* Get number of required and total arguments */ num_arguments = emit_num_arguments(l); num_required = emit_num_required(l); /* Go through argument list, convert from native to Java */ for (i = 0, p=l; i < num_arguments; i++) { while (checkAttribute(p,"tmap:in:numinputs","0")) { p = Getattr(p,"tmap:in:next"); } SwigType *pt = Getattr(p,"type"); String *ln = Copy(Getattr(p,"name")); String *c_param_type = NULL; String *c_decl = NewString(""); String *arg = NewString(""); Printf(arg, "j%s", ln); /* Add various typemap's 'throws' clauses */ addThrows(n, "tmap:in", p); addThrows(n, "tmap:out", p); /* And add to the upcall args */ Printf(jupcall_args, ", %s", arg); /* Get parameter's JNI C type */ if ((c_param_type = Getattr(p, "tmap:jni")) != NULL) { Parm *tp = NewParm(c_param_type, empty_str); String *desc_tm, *jdesc, *cdesc; /* Add to local variables */ Printf(c_decl, "%s %s", c_param_type, arg); Wrapper_add_localv(w, arg, c_decl, (!(SwigType_ispointer(pt) || SwigType_isreference(pt)) ? "" : "= 0"), NIL); /* Add input marshalling code and update JNI field descriptor */ if ((desc_tm = Swig_typemap_lookup_new("directorin", tp, "", 0)) != NULL && (jdesc = Getattr(tp, "tmap:directorin:descriptor")) != NULL) { if ((tm = Getattr(p, "tmap:directorin")) != NULL && (cdesc = Getattr(p, "tmap:directorin:descriptor")) != NULL) { String *jni_canon; jni_canon = canonicalJNIFDesc(jdesc, n, c_param_type); Append(jnidesc, jni_canon); Delete(jni_canon); Replaceall(tm,"$input", arg); if (Len(tm)) Printf(w->code,"%s\n", tm); Delete(tm); /* Add parameter to the intermediate class code if generating the * intermediate's upcall code */ if ((tm = Getattr(p, "tmap:jtype")) != NULL) { String *din; Node *canon_node = canonicalizeType(n, pt); String *canon_type = (canon_node ? Getattr(canon_node, "sym:name") : pt); din = Copy(Getattr(p, "tmap:javadirectorin")); if (din != NULL) { Replaceall(din, "$imclassname", imclass_name); Replaceall(din, "$javaclassname", canon_type); Replaceall(din, "$jniinput", ln); Printf(imw->def, ", %s %s", tm, ln); if (++gencomma > 1) Printf(imcall_args, ", "); if (Cmp(din, ln)) { Printv(imcall_args, din, NIL); } else Printv(imcall_args, ln, NIL); jni_canon = canonicalJNIFDesc(cdesc, n, pt); Append(classdesc, jni_canon); Delete(jni_canon); } else { Swig_warning(WARN_JAVA_TYPEMAP_JAVADIRECTORIN_UNDEF, input_file, line_number, "No javadirectorin typemap defined for %s\n", SwigType_str(pt,0)); output_director = false; } } else { Swig_warning(WARN_JAVA_TYPEMAP_JTYPE_UNDEF, input_file, line_number, "No jtype typemap defined for %s\n", SwigType_str(pt,0)); output_director = false; } p = Getattr(p, "tmap:in:next"); } else { Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number, "No or improper directorin typemap defined for %s\n", SwigType_str(pt, 0)); output_director = false; p = nextSibling(p); } Delete(desc_tm); } else { Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number, "No or improper directorin typemap defined for %s\n", SwigType_str(c_param_type, 0)); output_director = false; p = nextSibling(p); } Delete(tp); } else { Swig_warning(WARN_JAVA_TYPEMAP_JNI_UNDEF, input_file, line_number, "No jni typemap defined for %s\n", SwigType_str(pt,0)); output_director = false; p = nextSibling(p); } Delete(arg); Delete(c_decl); Delete(c_param_type); } /* header declaration, start wrapper definition */ String *target; target = Swig_method_decl(decl, qualified_name, l, 0, 0); String *rtype = SwigType_str(type, 0); Printf(w->def, "%s %s", rtype, target); Delete(qualified_name); Delete(target); target = Swig_method_decl(decl, name, l, 0, 1); Printf(declaration, " virtual %s %s", rtype, target); Delete(rtype); Delete(target); // Get any Java exception classes in the throws typemap ParmList *throw_parm_list = NULL; if ((tm = Swig_typemap_lookup_new("out",n,"",0))) addThrows(n, "tmap:out", n); if ((throw_parm_list = Getattr(n,"throws"))) { int gencomma = 0; Append(w->def, " throw("); Append(declaration, " throw("); Swig_typemap_attach_parms("throws", throw_parm_list, 0); for (p = throw_parm_list; p; p=nextSibling(p)) { if ((tm = Getattr(p,"tmap:throws"))) { addThrows(n, "tmap:throws", p); if (gencomma++) { Append(w->def, ", "); Append(declaration, ", "); } Printf(w->def, "%s", Getattr(p, "type")); Printf(declaration, "%s", Getattr(p, "type")); } } Append(w->def, ")"); Append(declaration, ")"); } Append(w->def, " {"); Append(declaration, ";\n"); /* Finish off the inherited upcall's definition */ Putc(')', imw->def); generateThrowsClause(n, imw->def); Printf(imw->def, " {"); /* Emit the intermediate class's upcall to the actual class */ String *upcall = NewStringf("self.%s(%s)", symname, imcall_args); if (!is_void) { Parm *tp = NewParm(return_type, empty_str); String *base_type = SwigType_base(return_type); Node *canon_node = canonicalizeType(n, return_type); String *canon_type = (canon_node ? Getattr(canon_node, "sym:name") : base_type); tm = Swig_typemap_lookup_new("javadirectorout", tp, "", 0); if (tm != NULL) { Replaceall(tm, "$javaclassname", canon_type); Replaceall(tm, "$javacall", upcall); Printf(imw->code, "return %s;\n", tm); } Delete(base_type); Delete(tm); Delete(tp); } else Printf(imw->code, "%s;", upcall); Printf(imw->code, " }"); Delete(upcall); /* Emit the actual upcall through JNI */ String *imclass_desc = NewStringf("(%s)%s", jnidesc, jniret_desc); String *class_desc = NewStringf("(%s)%s", classdesc, classret_desc); UpcallData *udata = addUpcallMethod(imclass_dmethod, symname, imclass_desc, class_desc, decl); String *methid = Getattr(udata, "imclass_methodidx"); String *methop = getUpcallJNIMethod(jniret_desc); if (!is_void) { Printf(w->code, "jresult = (%s) jenv->%s(Swig::jclass_%s, Swig::director_methids[%s], %s);\n", jniret_type, methop, imclass_name, methid, jupcall_args); } else { Printf(w->code, "jenv->%s(Swig::jclass_%s, Swig::director_methids[%s], %s);\n", methop, imclass_name, methid, jupcall_args); } Printf(w->code, "if (jenv->ExceptionOccurred()) return $null;\n"); if (!is_void) { String *jresult_str = NewString("jresult"); String *result_str = NewString("result"); Parm *tp = NewParm(return_type, result_str); /* Copy jresult into result... */ if ((tm = Swig_typemap_lookup_new("in", tp, result_str, w))) { addThrows(n, "tmap:in", tp); Replaceall(tm,"$source", jresult_str); /* deprecated */ Replaceall(tm,"$target", result_str); /* deprecated */ Replaceall(tm,"$arg", jresult_str); /* deprecated? */ Replaceall(tm,"$input", jresult_str); Printf(w->code, "%s\n", tm); } else { Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n",SwigType_str(tp,0)); output_director = false; } Delete(tp); Delete(jresult_str); Delete(result_str); } Delete(imclass_desc); Delete(class_desc); /* Terminate wrapper code */ if (!is_void) Printf(w->code, "return %s;", qualified_return); Printf(w->code, "}"); /* emit code */ if (status == SWIG_OK && output_director) { if(!is_void) { Replaceall(w->code,"$null", qualified_return); } else Replaceall(w->code,"$null",""); Wrapper_print(w, f_directors); Wrapper_print(imw, imclass_directors); Printv(f_directors_h, declaration, NIL); } Delete(qualified_return); Delete(jnidesc); Delete(jniret_type); Delete(jniret_desc); Delete(declaration); DelWrapper(w); ++curr_class_dmethod; return status; } /* ------------------------------------------------------------ * directorPrefixArgs() * ------------------------------------------------------------ */ void directorPrefixArgs(Node *n) { Parm *p; /* Need to prepend 'jenv' to the director constructor's argument list */ String *jenv_type = NewString("JNIEnv"); SwigType_add_pointer(jenv_type); p = NewParm(jenv_type, NewString("jenv")); Setattr(p, "arg:byname", "1"); set_nextSibling(p, NULL); Setattr(n, "director:prefix_args", p); } /* ------------------------------------------------------------ * classDirectorConstructor() * ------------------------------------------------------------ */ int classDirectorConstructor(Node *n) { Node *parent = parentNode(n); String *decl = Getattr(n, "decl");; String *supername = Swig_class_name(parent); String *classname = directorClassName(parent); String *sub = NewString(""); Parm *p; ParmList *superparms = Getattr(n, "parms"); ParmList *parms; int argidx = 0; /* Assign arguments to superclass's parameters, if not already done */ for (p = superparms; p; p = nextSibling(p)) { String *pname = Getattr(p, "name"); if (pname == NULL) { pname = NewStringf("arg%d", argidx++); Setattr(p, "name", pname); } } /* insert jenv prefix argument */ parms = CopyParmList(superparms); String *jenv_type = NewString("JNIEnv"); SwigType_add_pointer(jenv_type); p = NewParm(jenv_type, NewString("jenv")); set_nextSibling(p, parms); parms = p; directorPrefixArgs(n); /* constructor */ { String *basetype = Getattr(parent, "classtype"); String *target = Swig_method_decl(decl, classname, parms, 0, 0); String *call = Swig_csuperclass_call(0, basetype, superparms); String *classtype = SwigType_namestr(Getattr(n, "name")); String *dirclass_type = SwigType_namestr(Getattr(n, "sym:name")); Printf(f_directors, "%s::%s: %s, %s {\n", classname, target, call, Getattr(parent, "director:ctor")); Printf(f_directors, "}\n\n"); Delete(dirclass_type); Delete(classtype); Delete(target); Delete(call); } /* constructor header */ { String *target = Swig_method_decl(decl, classname, parms, 0, 1); Printf(f_directors_h, " %s;\n", target); Delete(target); } Delete(sub); Delete(supername); Delete(jenv_type); Delete(parms); return Language::classDirectorConstructor(n); } /* ------------------------------------------------------------ * classDirectorDefaultConstructor() * ------------------------------------------------------------ */ int classDirectorDefaultConstructor(Node *n) { String *classname = Swig_class_name(n); String *classtype = SwigType_namestr(Getattr(n, "name")); String *dirclass_type = SwigType_namestr(Getattr(n, "sym:name")); Wrapper *w = NewWrapper(); Printf(w->def, "SwigDirector_%s::SwigDirector_%s(JNIEnv *jenv) : %s {", classname, classname, Getattr(n, "director:ctor")); Printf(w->code, "}\n"); Wrapper_print(w, f_directors); Printf(f_directors_h, " SwigDirector_%s(JNIEnv *jenv);\n", classname); DelWrapper(w); Delete(dirclass_type); Delete(classtype); Delete(classname); directorPrefixArgs(n); return Language::classDirectorDefaultConstructor(n); } /* ------------------------------------------------------------ * classDirectorInit() * ------------------------------------------------------------ */ int classDirectorInit(Node *n) { String *director_classname = directorClassName(n); Delete(none_comparison); none_comparison = NewString(""); // not used Delete(director_ctor_code); director_ctor_code = NewString("$director_new"); Java_director_declaration(n); Printf(f_directors_h, "%s {\n", Getattr(n, "director:decl")); Printf(f_directors_h, "\npublic:\n"); Printf(f_directors_h, " virtual ~%s();\n", director_classname); Printf(f_directors_h, " void swig_connect_director(JNIEnv *jenv, jobject jself, jclass jcls);\n"); Printf(f_directors_h, " bool swig_overrides(int n) {\n"); Printf(f_directors_h, " return swig_override[n];\n"); Printf(f_directors_h, " }\n"); /* Emit the destructor (this is basically a hack for G++ and shared libraries, at least on the FreeBSD platform, if not for others. It also doesn't hurt to put "default" destructors into the code, even if they don't appear to do anything.) */ Printf(f_directors, "%s::~%s() {\n", director_classname, director_classname); Printf(f_directors, "}\n\n"); /* Keep track of the director methods for this class */ first_class_dmethod = curr_class_dmethod = n_dmethods; return Language::classDirectorInit(n); } /* ------------------------------------------------------------ * classDirectorEnd() * ------------------------------------------------------------ */ int classDirectorEnd(Node *n) { String *classname = Getattr(n, "sym:name"); String *director_classname = directorClassName(n); String *internal_classname; Wrapper *w = NewWrapper(); if (Len(package_path) > 0) internal_classname = NewStringf("%s/%s", package_path, classname); else internal_classname = NewStringf("%s", classname); Wrapper_add_localv(w, "baseclass", "static jclass baseclass", " = 0", NIL); Printf(w->def, "void %s::swig_connect_director(JNIEnv *jenv, jobject jself, jclass jcls) {", director_classname); if (first_class_dmethod != curr_class_dmethod) { Printf(w->def, "static struct {\n"); Printf(w->def, "const char *mname;\n"); Printf(w->def, "const char *mdesc;\n"); Printf(w->def, "jmethodID base_methid;\n"); Printf(w->def, "} methods[] = {\n"); for (int i = first_class_dmethod; i < curr_class_dmethod; ++i) { UpcallData *udata = Getitem(dmethods_seq, i); Printf(w->def, "{ \"%s\", \"%s\" }", Getattr(udata, "method"), Getattr(udata, "fdesc")); if (i != curr_class_dmethod - 1) Putc(',', w->def); Putc('\n', w->def); } Printf(w->def, "};\n"); } Printf(w->code, "swig_set_self(jenv, jself);\n"); Printf(w->code, "if (baseclass == NULL) {\n"); Printf(w->code, "baseclass = jenv->FindClass(\"%s\");\n", internal_classname); Printf(w->code, "if (baseclass == NULL) return;\n"); Printf(w->code, "baseclass = (jclass) jenv->NewGlobalRef(baseclass);\n"); Printf(w->code, "}\n"); Printf(w->code, "bool derived = (jenv->IsSameObject(baseclass, jcls) ? false : true);\n"); int n_methods = curr_class_dmethod - first_class_dmethod; Printf(f_directors_h, "protected:\n"); Printf(f_directors_h, " bool swig_override[%d];\n", n_methods); if (n_methods) { /* Emit the code to look up the class's methods, initialize the override array */ Printf(w->code, "for (int i = 0; i < %d; ++i) {\n", n_methods); Printf(w->code, " if (methods[i].base_methid == NULL) {\n"); Printf(w->code, " methods[i].base_methid = jenv->GetMethodID(baseclass, methods[i].mname, methods[i].mdesc);\n"); Printf(w->code, " }\n"); Printf(w->code, " if (derived) {\n"); Printf(w->code, " jmethodID methid = jenv->GetMethodID(jcls, methods[i].mname, methods[i].mdesc);\n"); Printf(w->code, " swig_override[i] = (methid && jenv->IsSameObject((jobject) methid, (jobject) methods[i].base_methid) ? false : true);\n"); Printf(w->code, " jenv->ExceptionClear();\n"); Printf(w->code, " } else {\n"); Printf(w->code, " swig_override[i] = false;\n"); Printf(w->code, " }\n"); Printf(w->code, "}\n"); } Printf(f_directors_h, "};\n\n"); Printf(w->code, "}\n"); Wrapper_print(w, f_directors); DelWrapper(w); Delete(internal_classname); return Language::classDirectorEnd(n); } /* -------------------------------------------------------------------- * classDirectorDisown() * ------------------------------------------------------------------*/ virtual int classDirectorDisown(Node *n) { (void)n; return SWIG_OK; } /* -------------------------------------------------------------------- * Java_director_declaration() * * Generate the director class's declaration * e.g. "class SwigDirector_myclass : public myclass, public Swig::Director {" * ------------------------------------------------------------------*/ void Java_director_declaration(Node *n) { String *base = Getattr(n, "classtype"); String *class_ctor = NewString("Swig::Director(jenv)"); String* classname = Swig_class_name(n); String *directorname = NewStringf("SwigDirector_%s", classname); String *declaration = Swig_class_declaration(n, directorname); Printf(declaration, " : public %s, public Swig::Director", base); // Stash stuff for later. Setattr(n, "director:decl", declaration); Setattr(n, "director:ctor", class_ctor); } /* ----------------------------------------------------------------------------- * abstractClassTest() * * Make sure that the constructors are always generated for director-based * classes derived from abstract classes, since Java always allocates the * director-based class. * ----------------------------------------------------------------------------- */ virtual int abstractClassTest(Node *n) { if (!Cmp(Getattr(n, "feature:director"), "1")) return 0; return Language::abstractClassTest(n); } }; /* class JAVA */ /* ----------------------------------------------------------------------------- * swig_java() - Instantiate module * ----------------------------------------------------------------------------- */ static Language * new_swig_java() { return new JAVA(); } extern "C" Language * swig_java(void) { return new_swig_java(); } /* ----------------------------------------------------------------------------- * Static member variables * ----------------------------------------------------------------------------- */ const char *JAVA::usage = (char*)"\ Java Options (available with -java)\n\ -package - set name of the Java package to \n\ -noproxy - Generate the low-level functional interface instead\n\ of proxy classes\n\ \n"; cableswig-0.1.0+git20150808.orig/SWIG/Source/Modules/mzscheme.cxx0000644000175000000620000005017612561312227023016 0ustar stevestaff/****************************************************************************** * Simplified Wrapper and Interface Generator (SWIG) * * Author : David Beazley * * Department of Computer Science * University of Chicago * 1100 E 58th Street * Chicago, IL 60637 * beazley@cs.uchicago.edu * * Please read the file LICENSE for the copyright and terms by which SWIG * can be used and distributed. *****************************************************************************/ char cvsroot_mzscheme_cxx[] = "/cvsroot/SWIG/Source/Modules/mzscheme.cxx,v 1.6 2004/01/22 22:42:15 cheetah Exp"; /*********************************************************************** * /cvsroot/SWIG/Source/Modules/mzscheme.cxx,v 1.6 2004/01/22 22:42:15 cheetah Exp * * mzscheme.cxx * * Definitions for adding functions to Mzscheme 101 ***********************************************************************/ #include "swigmod.h" #include static const char *usage = (char*)"\ Mzscheme Options (available with -mzscheme)\n\ -ldflags - Print runtime libraries to link with\n\ -prefix - Set a prefix to be prepended to all names\n\ -declaremodule - Create extension that declares a module\n\ \n"; static char *prefix=0; static bool declaremodule = false; static String *module=0; static char *mzscheme_path=(char*)"mzscheme"; static String *init_func_def = 0; static File *f_runtime = 0; static File *f_header = 0; static File *f_wrappers = 0; static File *f_init = 0; // Used for garbage collection static int exporting_destructor = 0; static String *swigtype_ptr = 0; class MZSCHEME : public Language { public: /* ------------------------------------------------------------ * main() * ------------------------------------------------------------ */ virtual void main (int argc, char *argv[]) { int i; SWIG_library_directory(mzscheme_path); // Look for certain command line options for (i = 1; i < argc; i++) { if (argv[i]) { if (strcmp (argv[i], "-help") == 0) { fputs (usage, stderr); SWIG_exit (0); } else if (strcmp (argv[i], "-prefix") == 0) { if (argv[i + 1]) { prefix = new char[strlen(argv[i + 1]) + 2]; strcpy(prefix, argv[i + 1]); Swig_mark_arg (i); Swig_mark_arg (i + 1); i++; } else { Swig_arg_error(); } } else if (strcmp (argv[i], "-declaremodule") == 0) { declaremodule = true; Swig_mark_arg (i); } else if (strcmp (argv[i], "-ldflags") == 0) { printf("%s\n", SWIG_MZSCHEME_RUNTIME); SWIG_exit (EXIT_SUCCESS); } } } // If a prefix has been specified make sure it ends in a '_' if (prefix) { if (prefix[strlen (prefix)] != '_') { prefix[strlen (prefix) + 1] = 0; prefix[strlen (prefix)] = '_'; } } else prefix = (char*)"swig_"; // Add a symbol for this module Preprocessor_define ("SWIGMZSCHEME 1",0); // Set name of typemaps SWIG_typemap_lang("mzscheme"); // Read in default typemaps */ SWIG_config_file("mzscheme.swg"); allow_overloading(); } /* ------------------------------------------------------------ * top() * ------------------------------------------------------------ */ virtual int top(Node *n) { /* Initialize all of the output files */ String *outfile = Getattr(n,"outfile"); f_runtime = NewFile(outfile,"w"); if (!f_runtime) { Printf(stderr,"*** Can't open '%s'\n", outfile); SWIG_exit(EXIT_FAILURE); } f_init = NewString(""); f_header = NewString(""); f_wrappers = NewString(""); /* Register file targets with the SWIG file handler */ Swig_register_filebyname("header",f_header); Swig_register_filebyname("wrapper",f_wrappers); Swig_register_filebyname("runtime",f_runtime); init_func_def = NewString(""); Swig_register_filebyname("init",init_func_def); Printf(f_runtime, "/* -*- buffer-read-only: t -*- vi: set ro: */\n"); Swig_banner (f_runtime); if (NoInclude) { Printf(f_runtime, "#define SWIG_NOINCLUDE\n"); } module = Getattr(n,"name"); Language::top(n); SwigType_emit_type_table (f_runtime, f_wrappers); Printf(f_init, "Scheme_Object *scheme_reload(Scheme_Env *env) {\n"); Printf(f_init, "\tScheme_Env *menv = env;\n"); if (declaremodule) { Printf(f_init, "\tmenv = scheme_primitive_module(scheme_intern_symbol(\"%s\"), env);\n", module); } Printf(f_init, "%s\n", Char(init_func_def)); if (declaremodule) { Printf(f_init, "\tscheme_finish_primitive_module(menv);\n"); } Printf (f_init, "\treturn scheme_void;\n}\n"); Printf(f_init, "Scheme_Object *scheme_initialize(Scheme_Env *env) {\n"); Printf(f_init, "\treturn scheme_reload(env);\n"); Printf (f_init, "}\n"); Printf(f_init,"Scheme_Object *scheme_module_name(void) {\n"); if (declaremodule) { Printf(f_init, " return scheme_intern_symbol((char*)\"%s\");\n", module); } else { Printf(f_init," return scheme_make_symbol((char*)\"%s\");\n", module); } Printf(f_init,"}\n"); /* Close all of the files */ Dump(f_header,f_runtime); Dump(f_wrappers,f_runtime); Wrapper_pretty_print(f_init,f_runtime); Delete(f_header); Delete(f_wrappers); Delete(f_init); Close(f_runtime); Delete(f_runtime); return SWIG_OK; } /* ------------------------------------------------------------ * functionWrapper() * Create a function declaration and register it with the interpreter. * ------------------------------------------------------------ */ void throw_unhandled_mzscheme_type_error (SwigType *d) { Swig_warning(WARN_TYPEMAP_UNDEF, input_file, line_number, "Unable to handle type %s.\n", SwigType_str(d,0)); } /* Return true iff T is a pointer type */ int is_a_pointer (SwigType *t) { return SwigType_ispointer(SwigType_typedef_resolve_all(t)); } virtual int functionWrapper(Node *n) { char *iname = GetChar(n,"sym:name"); SwigType *d = Getattr(n,"type"); ParmList *l = Getattr(n,"parms"); Parm *p; Wrapper *f = NewWrapper(); String *proc_name = NewString(""); String *source = NewString(""); String *target = NewString(""); String *arg = NewString(""); String *cleanup = NewString(""); String *outarg = NewString(""); String *build = NewString(""); String *tm; int argout_set = 0; int i = 0; int numargs; int numreq; String *overname = 0; // Make a wrapper name for this String *wname = Swig_name_wrapper(iname); if (Getattr(n,"sym:overloaded")) { overname = Getattr(n,"sym:overname"); } else { if (!addSymbol(iname,n)) return SWIG_ERROR; } if (overname) { Append(wname, overname); } Setattr(n,"wrap:name",wname); // Build the name for Scheme. Printv(proc_name, iname,NIL); Replaceall(proc_name, "_", "-"); // writing the function wrapper function Printv(f->def, "static Scheme_Object *", wname, " (", NIL); Printv(f->def, "int argc, Scheme_Object **argv", NIL); Printv(f->def, ")\n{", NIL); /* Define the scheme name in C. This define is used by several macros. */ Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL); // Declare return variable and arguments // number of parameters // they are called arg0, arg1, ... // the return value is called result emit_args(d, l, f); /* Attach the standard typemaps */ emit_attach_parmmaps(l,f); Setattr(n,"wrap:parms",l); numargs = emit_num_arguments(l); numreq = emit_num_required(l); // adds local variables Wrapper_add_local(f, "_len", "int _len"); Wrapper_add_local(f, "lenv", "int lenv = 1"); Wrapper_add_local(f, "values", "Scheme_Object *values[MAXVALUES]"); // Now write code to extract the parameters (this is super ugly) for (i = 0, p = l; i < numargs; i++) { /* Skip ignored arguments */ while (checkAttribute(p,"tmap:in:numinputs","0")) { p = Getattr(p,"tmap:in:next"); } SwigType *pt = Getattr(p,"type"); String *ln = Getattr(p,"lname"); // Produce names of source and target Clear(source); Clear(target); Clear(arg); Printf(source, "argv[%d]", i); Printf(target, "%s",ln); Printv(arg, Getattr(p,"name"),NIL); if (i >= numreq) { Printf(f->code,"if (argc > %d) {\n",i); } // Handle parameter types. if ((tm = Getattr(p,"tmap:in"))) { Replaceall(tm,"$source",source); Replaceall(tm,"$target",target); Replaceall(tm,"$input",source); Setattr(p,"emit:input",source); Printv(f->code, tm, "\n", NIL); p = Getattr(p,"tmap:in:next"); } else { // no typemap found // check if typedef and resolve throw_unhandled_mzscheme_type_error (pt); p = nextSibling(p); } if (i >= numreq) { Printf(f->code,"}\n"); } } /* Insert constraint checking code */ for (p = l; p;) { if ((tm = Getattr(p,"tmap:check"))) { Replaceall(tm,"$target",Getattr(p,"lname")); Printv(f->code,tm,"\n",NIL); p = Getattr(p,"tmap:check:next"); } else { p = nextSibling(p); } } // Pass output arguments back to the caller. for (p = l; p;) { if ((tm = Getattr(p,"tmap:argout"))) { Replaceall(tm,"$source",Getattr(p,"emit:input")); /* Deprecated */ Replaceall(tm,"$target",Getattr(p,"lname")); /* Deprecated */ Replaceall(tm,"$arg",Getattr(p,"emit:input")); Replaceall(tm,"$input",Getattr(p,"emit:input")); Printv(outarg,tm,"\n",NIL); p = Getattr(p,"tmap:argout:next"); argout_set = 1; } else { p = nextSibling(p); } } // Free up any memory allocated for the arguments. /* Insert cleanup code */ for (p = l; p;) { if ((tm = Getattr(p,"tmap:freearg"))) { Replaceall(tm,"$target",Getattr(p,"lname")); Printv(cleanup,tm,"\n",NIL); p = Getattr(p,"tmap:freearg:next"); } else { p = nextSibling(p); } } // Now write code to make the function call emit_action(n,f); // Now have return value, figure out what to do with it. if ((tm = Swig_typemap_lookup_new("out",n,"result",0))) { Replaceall(tm,"$source","result"); Replaceall(tm,"$target","values[0]"); Replaceall(tm,"$result","values[0]"); if (Getattr(n, "feature:new")) Replaceall(tm, "$owner", "1"); else Replaceall(tm, "$owner", "0"); Printv(f->code, tm, "\n",NIL); } else { throw_unhandled_mzscheme_type_error (d); } // Dump the argument output code Printv(f->code, Char(outarg),NIL); // Dump the argument cleanup code Printv(f->code, Char(cleanup),NIL); // Look for any remaining cleanup if (Getattr(n,"feature:new")) { if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) { Replaceall(tm,"$source","result"); Printv(f->code, tm, "\n",NIL); } } // Free any memory allocated by the function being wrapped.. if ((tm = Swig_typemap_lookup_new("ret",n,"result",0))) { Replaceall(tm,"$source","result"); Printv(f->code, tm, "\n",NIL); } // Wrap things up (in a manner of speaking) Printv(f->code, tab4, "return SWIG_MzScheme_PackageValues(lenv, values);\n", NIL); Printf(f->code, "#undef FUNC_NAME\n"); Printv(f->code, "}\n",NIL); Wrapper_print(f, f_wrappers); if (!Getattr(n,"sym:overloaded")) { // Now register the function char temp[256]; sprintf(temp, "%d", numargs); if (exporting_destructor) { Printf(init_func_def, "SWIG_TypeClientData(SWIGTYPE%s, (void *) %s);\n", swigtype_ptr, wname); } else { Printf(init_func_def, "scheme_add_global(\"%s\", scheme_make_prim_w_arity(%s,\"%s\",%d,%d),menv);\n", proc_name, wname, proc_name, numreq, numargs); } } else { if (!Getattr(n,"sym:nextSibling")) { /* Emit overloading dispatch function */ int maxargs; String *dispatch = Swig_overload_dispatch(n,"return %s(argc,argv);",&maxargs); /* Generate a dispatch wrapper for all overloaded functions */ Wrapper *df = NewWrapper(); String *dname = Swig_name_wrapper(iname); Printv(df->def, "static Scheme_Object *\n", dname, "(int argc, Scheme_Object **argv) {", NIL); Printv(df->code,dispatch,"\n",NIL); Printf(df->code,"scheme_signal_error(\"No matching function for overloaded '%s'\");\n", iname); Printv(df->code,"}\n",NIL); Wrapper_print(df,f_wrappers); Printf(init_func_def, "scheme_add_global(\"%s\", scheme_make_prim_w_arity(%s,\"%s\",%d,%d),menv);\n", proc_name, dname, proc_name, 0, maxargs); DelWrapper(df); Delete(dispatch); Delete(dname); } } Delete(proc_name); Delete(source); Delete(target); Delete(arg); Delete(outarg); Delete(cleanup); Delete(build); DelWrapper(f); return SWIG_OK; } /* ------------------------------------------------------------ * variableWrapper() * * Create a link to a C variable. * This creates a single function _wrap_swig_var_varname(). * This function takes a single optional argument. If supplied, it means * we are setting this variable to some value. If omitted, it means we are * simply evaluating this variable. Either way, we return the variables * value. * ------------------------------------------------------------ */ virtual int variableWrapper(Node *n) { char *name = GetChar(n,"name"); char *iname = GetChar(n,"sym:name"); SwigType *t = Getattr(n,"type"); String *proc_name = NewString(""); char var_name[256]; String *tm; String *tm2 = NewString("");; String *argnum = NewString("0"); String *arg = NewString("argv[0]"); Wrapper *f; if (!addSymbol(iname,n)) return SWIG_ERROR; f = NewWrapper(); // evaluation function names strcpy(var_name, Char(Swig_name_wrapper(iname))); // Build the name for scheme. Printv(proc_name, iname,NIL); Replaceall(proc_name, "_", "-"); if ((SwigType_type(t) != T_USER) || (is_a_pointer(t))) { Printf (f->def, "static Scheme_Object *%s(int argc, Scheme_Object** argv) {\n", var_name); Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL); Wrapper_add_local (f, "swig_result", "Scheme_Object *swig_result"); if (!Getattr(n,"feature:immutable")) { /* Check for a setting of the variable value */ Printf (f->code, "if (argc) {\n"); if ((tm = Swig_typemap_lookup_new("varin",n,name,0))) { Replaceall(tm,"$source","argv[0]"); Replaceall(tm,"$target",name); Replaceall(tm,"$input","argv[0]"); Printv(f->code, tm, "\n",NIL); } else { throw_unhandled_mzscheme_type_error (t); } Printf (f->code, "}\n"); } // Now return the value of the variable (regardless // of evaluating or setting) if ((tm = Swig_typemap_lookup_new("varout",n,name,0))) { Replaceall(tm,"$source",name); Replaceall(tm,"$target","swig_result"); Replaceall(tm,"$result","swig_result"); Printf (f->code, "%s\n", tm); } else { throw_unhandled_mzscheme_type_error (t); } Printf (f->code, "\nreturn swig_result;\n"); Printf (f->code, "#undef FUNC_NAME\n"); Printf (f->code, "}\n"); Wrapper_print (f, f_wrappers); // Now add symbol to the MzScheme interpreter Printv(init_func_def, "scheme_add_global(\"", proc_name, "\", scheme_make_prim_w_arity(", var_name, ", \"", proc_name, "\", ", "0", ", ", "1", "), menv);\n",NIL); } else { Swig_warning(WARN_TYPEMAP_VAR_UNDEF, input_file, line_number, "Unsupported variable type %s (ignored).\n", SwigType_str(t,0)); } Delete(proc_name); Delete(argnum); Delete(arg); Delete(tm2); DelWrapper(f); return SWIG_OK; } /* ------------------------------------------------------------ * constantWrapper() * ------------------------------------------------------------ */ virtual int constantWrapper(Node *n) { char *name = GetChar(n,"name"); char *iname = GetChar(n,"sym:name"); SwigType *type = Getattr(n,"type"); String *value = Getattr(n,"value"); String *var_name = NewString(""); String *proc_name = NewString(""); String *rvalue = NewString(""); String *temp = NewString(""); String *tm; // Make a static variable; Printf (var_name, "_wrap_const_%s", Swig_name_mangle(iname)); // Build the name for scheme. Printv(proc_name, iname,NIL); Replaceall(proc_name, "_", "-"); if ((SwigType_type(type) == T_USER) && (!is_a_pointer(type))) { Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n"); return SWIG_NOWRAP; } // See if there's a typemap Printv(rvalue, value,NIL); if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 1)) { temp = Copy(rvalue); Clear(rvalue); Printv(rvalue, "\"", temp, "\"",NIL); } if ((SwigType_type(type) == T_CHAR) && (is_a_pointer(type) == 0)) { Delete(temp); temp = Copy(rvalue); Clear(rvalue); Printv(rvalue, "'", temp, "'",NIL); } if ((tm = Swig_typemap_lookup_new("constant",n,name,0))) { Replaceall(tm,"$source",rvalue); Replaceall(tm,"$value",rvalue); Replaceall(tm,"$target",name); Printf (f_init, "%s\n", tm); } else { // Create variable and assign it a value Printf (f_header, "static %s = ", SwigType_lstr(type,var_name)); if ((SwigType_type(type) == T_STRING)) { Printf (f_header, "\"%s\";\n", value); } else if (SwigType_type(type) == T_CHAR) { Printf (f_header, "\'%s\';\n", value); } else { Printf (f_header, "%s;\n", value); } // Now create a variable declaration { /* Hack alert: will cleanup later -- Dave */ Node *n = NewHash(); Setattr(n,"name",var_name); Setattr(n,"sym:name",iname); Setattr(n,"type", type); variableWrapper(n); Delete(n); } } Delete(proc_name); Delete(rvalue); Delete(temp); return SWIG_OK; } virtual int destructorHandler(Node *n) { exporting_destructor = true; Language::destructorHandler(n); exporting_destructor = false; return SWIG_OK; } virtual int classHandler(Node *n) { SwigType *t = NewStringf("p.%s", Getattr(n, "name")); swigtype_ptr = SwigType_manglestr(t); Delete(t); Language::classHandler(n); Delete(swigtype_ptr); swigtype_ptr = 0; return SWIG_OK; } /* ------------------------------------------------------------ * validIdentifer() * ------------------------------------------------------------ */ virtual int validIdentifier(String *s) { char *c = Char(s); /* Check whether we have an R5RS identifier.*/ /* --> * | */ /* --> | */ if (!(isalpha(*c) || (*c == '!') || (*c == '$') || (*c == '%') || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':') || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?') || (*c == '^') || (*c == '_') || (*c == '~'))) { /* --> + | - | ... */ if ((strcmp(c, "+") == 0) || strcmp(c, "-") == 0 || strcmp(c, "...") == 0) return 1; else return 0; } /* --> | | */ while (*c) { if (!(isalnum(*c) || (*c == '!') || (*c == '$') || (*c == '%') || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':') || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?') || (*c == '^') || (*c == '_') || (*c == '~') || (*c == '+') || (*c == '-') || (*c == '.') || (*c == '@'))) return 0; c++; } return 1; } }; /* ----------------------------------------------------------------------------- * swig_mzscheme() - Instantiate module * ----------------------------------------------------------------------------- */ static Language * new_swig_mzscheme() { return new MZSCHEME(); } extern "C" Language * swig_mzscheme(void) { return new_swig_mzscheme(); } cableswig-0.1.0+git20150808.orig/SWIG/Source/Modules/python.cxx0000644000175000000620000022375412561312227022530 0ustar stevestaff/* ----------------------------------------------------------------------------- * python.cxx * * Python module. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_python_cxx[] = "/cvsroot/SWIG/Source/Modules/python.cxx,v 1.44 2004/02/09 23:08:54 ljohnson Exp"; #include "swigmod.h" #include #define PYSHADOW_MEMBER 0x2 static String *const_code = 0; static String *shadow_methods = 0; static String *module = 0; static String *mainmodule = 0; static String *interface = 0; static String *global_name = 0; static int shadow = 1; static int use_kw = 0; static File *f_runtime = 0; static File *f_runtime_h = 0; static File *f_header = 0; static File *f_wrappers = 0; static File *f_directors = 0; static File *f_directors_h = 0; static File *f_init = 0; static File *f_shadow = 0; static File *f_shadow_stubs = 0; static String *methods; static String *class_name; static String *shadow_indent = 0; static int in_class = 0; static int classic = 0; static int modern = 0; static int apply = 0; static int new_repr = 0; /* C++ Support + Shadow Classes */ static int have_constructor; static int have_repr; static String *real_classname; static const char *usage = (char *)"\ Python Options (available with -python)\n\ -ldflags - Print runtime libraries to link with\n\ -globals - Set used to access C global variable [default: 'cvar']\n\ -interface - Set the lib name to \n\ -keyword - Use keyword arguments\n\ -classic - Use classic classes only\n\ -modern - Use modern python features only, without compatibility code\n\ -apply - Use apply() in proxy classes\n\ -new_repr - Use more informative version of __repr__ in proxy classes\n\ -noexcept - No automatic exception handling\n\ -noproxy - Don't generate proxy classes \n\n"; class PYTHON : public Language { public: /* ------------------------------------------------------------ * main() * ------------------------------------------------------------ */ virtual void main(int argc, char *argv[]) { SWIG_library_directory("python"); for (int i = 1; i < argc; i++) { if (argv[i]) { if(strcmp(argv[i],"-interface") == 0) { if (argv[i+1]) { interface = NewString(argv[i+1]); Swig_mark_arg(i); Swig_mark_arg(i+1); i++; } else { Swig_arg_error(); } /* end added */ } else if (strcmp(argv[i],"-globals") == 0) { if (argv[i+1]) { global_name = NewString(argv[i+1]); Swig_mark_arg(i); Swig_mark_arg(i+1); i++; } else { Swig_arg_error(); } } else if ((strcmp(argv[i],"-shadow") == 0) || ((strcmp(argv[i],"-proxy") == 0))) { shadow = 1; Swig_mark_arg(i); } else if (strcmp(argv[i],"-apply") == 0) { apply = 1; Swig_mark_arg(i); } else if (strcmp(argv[i],"-new_repr") == 0) { new_repr = 1; Swig_mark_arg(i); } else if ((strcmp(argv[i],"-noproxy") == 0)) { shadow = 0; Swig_mark_arg(i); } else if (strcmp(argv[i],"-keyword") == 0) { use_kw = 1; Swig_mark_arg(i); } else if (strcmp(argv[i],"-classic") == 0) { classic = 1; Swig_mark_arg(i); } else if (strcmp(argv[i],"-modern") == 0) { classic = 0; modern = 1; Swig_mark_arg(i); } else if (strcmp(argv[i],"-help") == 0) { fputs(usage,stderr); } else if (strcmp (argv[i], "-ldflags") == 0) { printf("%s\n", SWIG_PYTHON_RUNTIME); SWIG_exit (EXIT_SUCCESS); } } } if (!global_name) global_name = NewString("cvar"); Preprocessor_define("SWIGPYTHON 1", 0); SWIG_typemap_lang("python"); SWIG_config_file("python.swg"); allow_overloading(); } /* ------------------------------------------------------------ * top() * ------------------------------------------------------------ */ virtual int top(Node *n) { /* check if directors are enabled for this module. note: this * is a "master" switch, without which no director code will be * emitted. %feature("director") statements are also required * to enable directors for individual classes or methods. * * use %module(directors="1") modulename at the start of the * interface file to enable director generation. */ { Node *module = Getattr(n, "module"); if (module) { Node *options = Getattr(module, "options"); if (options) { if (Getattr(options, "directors")) { allow_directors(); } if (Getattr(options, "dirprot")) { allow_dirprot(); } } } } /* Set comparison with none for ConstructorToFunction */ setSubclassInstanceCheck(NewString("$arg != Py_None")); /* Initialize all of the output files */ String *outfile = Getattr(n,"outfile"); String *outfile_h = Getattr(n, "outfile_h"); f_runtime = NewFile(outfile,"w"); if (!f_runtime) { Printf(stderr,"*** Can't open '%s'\n", outfile); SWIG_exit(EXIT_FAILURE); } if (directorsEnabled()) { f_runtime_h = NewFile(outfile_h,"w"); if (!f_runtime_h) { Printf(stderr,"*** Can't open '%s'\n", outfile_h); SWIG_exit(EXIT_FAILURE); } } f_init = NewString(""); f_header = NewString(""); f_wrappers = NewString(""); f_directors_h = NewString(""); f_directors = NewString(""); /* Register file targets with the SWIG file handler */ Swig_register_filebyname("header",f_header); Swig_register_filebyname("wrapper",f_wrappers); Swig_register_filebyname("runtime",f_runtime); Swig_register_filebyname("init",f_init); Swig_register_filebyname("director",f_directors); Swig_register_filebyname("director_h",f_directors_h); const_code = NewString(""); shadow_methods = NewString(""); methods = NewString(""); Swig_banner(f_runtime); Printf(f_runtime,"#define SWIGPYTHON\n"); if (NoInclude) Printf(f_runtime,"#define SWIG_NOINCLUDE\n"); if (directorsEnabled()) { Printf(f_runtime,"#define SWIG_DIRECTORS\n"); } /* Set module name */ module = Copy(Getattr(n,"name")); mainmodule = Getattr(n,"name"); if (directorsEnabled()) { Swig_banner(f_directors_h); Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", module); Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", module); if (dirprot_mode()) { Printf(f_directors_h, "#include \n"); Printf(f_directors_h, "#include \n\n"); } Printf(f_directors_h, "class Swig::Director;\n\n"); Swig_insert_file("director.swg", f_directors); Printf(f_directors, "\n\n"); Printf(f_directors, "/* ---------------------------------------------------\n"); Printf(f_directors, " * C++ director class methods\n"); Printf(f_directors, " * --------------------------------------------------- */\n\n"); Printf(f_directors, "#include \"%s\"\n\n", Swig_file_filename(outfile_h)); } /* If shadow classing is enabled, we're going to change the module name to "_module" */ if (shadow) { String *filen = NewStringf("%s%s.py", SWIG_output_directory(), Char(module)); // If we don't have an interface then change the module name X to _X if (interface) module = interface; else Insert(module,0,"_"); if ((f_shadow = NewFile(filen,"w")) == 0) { Printf(stderr,"Unable to open %s\n", filen); SWIG_exit (EXIT_FAILURE); } Delete(filen); filen = NULL; f_shadow_stubs = NewString(""); Swig_register_filebyname("shadow",f_shadow); Swig_register_filebyname("python",f_shadow); Printv(f_shadow, "# This file was created automatically by SWIG.\n", "# Don't modify this file, modify the SWIG interface instead.\n", NIL); if (! modern) { Printv(f_shadow, "# This file is compatible with both classic and new-style classes.\n", NIL); } Printf(f_shadow,"\nimport %s\n\n", module); if (! modern) { // Python-2.2 object hack Printv(f_shadow, "def _swig_setattr(self,class_type,name,value):\n", tab4, "if (name == \"this\"):\n", tab4, tab4, "if isinstance(value, class_type):\n", tab4, tab8, "self.__dict__[name] = value.this\n", tab4, tab8, "if hasattr(value,\"thisown\"): self.__dict__[\"thisown\"] = value.thisown\n", tab4, tab8, "del value.thisown\n", tab4, tab8, "return\n", // tab8, "if (name == \"this\") or (name == \"thisown\"): self.__dict__[name] = value; return\n", tab4, "method = class_type.__swig_setmethods__.get(name,None)\n", tab4, "if method: return method(self,value)\n", tab4, "self.__dict__[name] = value\n\n", NIL); Printv(f_shadow, "def _swig_getattr(self,class_type,name):\n", tab4, "method = class_type.__swig_getmethods__.get(name,None)\n", tab4, "if method: return method(self)\n", tab4, "raise AttributeError,name\n\n", NIL); if (!classic) { Printv(f_shadow, "import types\n", "try:\n", " _object = types.ObjectType\n", " _newclass = 1\n", "except AttributeError:\n", " class _object : pass\n", " _newclass = 0\n", "del types\n", "\n\n", NIL); } } if (directorsEnabled()) { // Try loading weakref.proxy, which is only available in Python 2.1 and higher Printv(f_shadow, "try:\n", tab4, "from weakref import proxy as weakref_proxy\n", "except:\n", tab4, "weakref_proxy = lambda x: x\n", "\n\n", NIL); } // Include some information in the code Printf(f_header,"\n/*-----------------------------------------------\n @(target):= %s.so\n\ ------------------------------------------------*/\n", module); } Printf(f_header,"#define SWIG_init init%s\n\n", module); Printf(f_header,"#define SWIG_name \"%s\"\n", module); Printf(f_wrappers,"#ifdef __cplusplus\n"); Printf(f_wrappers,"extern \"C\" {\n"); Printf(f_wrappers,"#endif\n"); Printf(const_code,"static swig_const_info swig_const_table[] = {\n"); Printf(methods,"static PyMethodDef SwigMethods[] = {\n"); /* emit code */ Language::top(n); /* Close language module */ Printf(methods,"\t { NULL, NULL, 0, NULL }\n"); Printf(methods,"};\n"); Printf(f_wrappers,"%s\n",methods); SwigType_emit_type_table(f_runtime,f_wrappers); Printf(const_code, "{0, 0, 0, 0.0, 0, 0}};\n"); Printf(f_wrappers,"%s\n",const_code); Printf(f_init,"}\n"); Printf(f_wrappers,"#ifdef __cplusplus\n"); Printf(f_wrappers,"}\n"); Printf(f_wrappers,"#endif\n"); if (shadow) { Printv(f_shadow, f_shadow_stubs, "\n",NIL); Close(f_shadow); Delete(f_shadow); } /* Close all of the files */ Dump(f_header,f_runtime); if (directorsEnabled()) { Dump(f_directors, f_runtime); Dump(f_directors_h, f_runtime_h); Printf(f_runtime_h, "\n"); Printf(f_runtime_h, "#endif\n"); Close(f_runtime_h); } Dump(f_wrappers,f_runtime); Wrapper_pretty_print(f_init,f_runtime); Delete(f_header); Delete(f_wrappers); Delete(f_init); Delete(f_directors); Delete(f_directors_h); Close(f_runtime); return SWIG_OK; } /* ------------------------------------------------------------ * importDirective() * ------------------------------------------------------------ */ virtual int importDirective(Node *n) { if (shadow) { String *modname = Getattr(n,"module"); if (modname) { Printf(f_shadow,"import %s\n", modname); } } return Language::importDirective(n); } /* ------------------------------------------------------------ * emitFuncCallHelper() * Write the shadow code to call a function in the extension * module. Takes into account the -apply flag and whether * to use keyword args or not. * ------------------------------------------------------------ */ String *funcCallHelper(String *name, int kw) { String *str; str = NewString(""); if (apply) { Printv(str, "apply(", module, ".", name, ", args", (kw ? ", kwargs" : ""), ")", NIL); } else { Printv(str, module, ".", name, "(*args", (kw ? ", **kwargs" : ""), ")", NIL); } return str; } /* ------------------------------------------------------------ * emitFunctionShadowHelper() * Refactoring some common code out of functionWrapper and * dispatchFunction that writes the proxy code for non-member * functions. * ------------------------------------------------------------ */ void emitFunctionShadowHelper(Node *n, File *f_dest, String *name, int kw) { if ( ! have_addtofunc(n) ) { /* If there is no addtofunc directive then just assign from the extension module */ Printv(f_dest, "\n", name, " = ", module, ".", name, "\n", NIL); } else { /* Otherwise make a wrapper function to insert the code into */ Printv(f_dest, "\ndef ", name, "(*args", (kw ? ", **kwargs" : ""), "):\n", NIL); Printv(f_dest, tab4, "val = ", funcCallHelper(name, kw), "\n", NIL); Printv(f_dest, tab4, addtofunc(n), "\n", NIL); Printv(f_dest, tab4, "return val\n", NIL); } } /* ------------------------------------------------------------ * check_kwargs() * check if using kwargs is allowed for this Node * ------------------------------------------------------------ */ int check_kwargs(Node *n) { return ((use_kw || Getattr(n,"feature:kwargs")) && !Getattr(n, "feature:nokwargs")) ? 1 : 0; } /* ------------------------------------------------------------ * have_addtofunc() * Check if there is a %addtofunc directive and it has text * ------------------------------------------------------------ */ bool have_addtofunc(Node *n) { String* str = Getattr(n, "feature:addtofunc"); return (str != NULL && Len(str) > 0); } /* ------------------------------------------------------------ * addtofunc() * Get the %addtofunc code, stripping off {} if neccessary * ------------------------------------------------------------ */ String *addtofunc(Node *n) { String* str = Getattr(n, "feature:addtofunc"); char* t = Char(str); if (*t == '{') { Delitem(str ,0); Delitem(str,DOH_END); } return str; } /* ------------------------------------------------------------ * add_method() * ------------------------------------------------------------ */ void add_method(String *name, String *function, int kw) { if (!kw) Printf(methods,"\t { (char *)\"%s\", %s, METH_VARARGS, NULL },\n", name, function); else Printf(methods,"\t { (char *)\"%s\", (PyCFunction) %s, METH_VARARGS | METH_KEYWORDS, NULL },\n", name, function); } /* ------------------------------------------------------------ * functionWrapper() * ------------------------------------------------------------ */ virtual int functionWrapper(Node *n) { String *name = Getattr(n,"name"); String *iname = Getattr(n,"sym:name"); SwigType *d = Getattr(n,"type"); ParmList *l = Getattr(n,"parms"); Node *parent = Getattr(n,"parentNode"); Parm *p; int i; char wname[256]; char source[64]; Wrapper *f; String *parse_args; String *arglist; String *get_pointers; String *cleanup; String *outarg; String *kwargs; String *tm; String *overname = 0; int num_required; int num_arguments; int varargs = 0; int allow_kwargs = check_kwargs(n); String *nodeType = Getattr(n, "nodeType"); int constructor = (!Cmp(nodeType, "constructor")); int destructor = (!Cmp(nodeType, "destructor")); String *storage = Getattr(n,"storage"); int isVirtual = (Cmp(storage,"virtual") == 0); if (Getattr(n,"sym:overloaded")) { overname = Getattr(n,"sym:overname"); } else { if (!addSymbol(iname,n)) return SWIG_ERROR; } f = NewWrapper(); parse_args = NewString(""); arglist = NewString(""); get_pointers = NewString(""); cleanup = NewString(""); outarg = NewString(""); kwargs = NewString(""); Wrapper_add_local(f,"resultobj", "PyObject *resultobj"); /* Write code to extract function parameters. */ emit_args(d, l, f); /* Attach the standard typemaps */ emit_attach_parmmaps(l,f); Setattr(n,"wrap:parms",l); /* Get number of required and total arguments */ num_arguments = emit_num_arguments(l); num_required = emit_num_required(l); varargs = emit_isvarargs(l); strcpy(wname,Char(Swig_name_wrapper(iname))); if (overname) { strcat(wname,Char(overname)); } if (!allow_kwargs || Getattr(n,"sym:overloaded")) { if (!varargs) { if (CPlusPlus) { Printv(f->def, "static PyObject *", wname, "(PyObject *, PyObject *args) {", NIL); } else { Printv(f->def, "static PyObject *", wname, "(PyObject *self, PyObject *args) {", NIL); } } else { if (CPlusPlus) { Printv(f->def, "static PyObject *", wname, "__varargs__", "(PyObject *, PyObject *args, PyObject *varargs) {", NIL); } else { Printv(f->def, "static PyObject *", wname, "__varargs__", "(PyObject *self, PyObject *args, PyObject *varargs) {", NIL); } } if (allow_kwargs) { Swig_warning(WARN_LANG_OVERLOAD_KEYWORD, input_file, line_number, "Can't use keyword arguments with overloaded functions.\n"); allow_kwargs = 0; } } else { if (varargs) { Swig_warning(WARN_LANG_VARARGS_KEYWORD, input_file, line_number, "Can't wrap varargs with keyword arguments enabled\n"); varargs = 0; } if (CPlusPlus) { Printv(f->def, "static PyObject *", wname, "(PyObject *, PyObject *args, PyObject *kwargs) {", NIL); } else { Printv(f->def, "static PyObject *", wname, "(PyObject *self, PyObject *args, PyObject *kwargs) {", NIL); } } if (!allow_kwargs) { Printf(parse_args," if(!PyArg_ParseTuple(args,(char *)\""); } else { Printf(parse_args," if(!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)\""); Printf(arglist,",kwnames"); } /* Generate code for argument marshalling */ Printf(kwargs,"{ "); for (i = 0, p=l; i < num_arguments; i++) { while (checkAttribute(p,"tmap:in:numinputs","0")) { p = Getattr(p,"tmap:in:next"); } SwigType *pt = Getattr(p,"type"); String *pn = Getattr(p,"name"); String *ln = Getattr(p,"lname"); sprintf(source,"obj%d",i); Putc(',',arglist); if (i == num_required) Putc('|', parse_args); /* Optional argument separator */ /* Keyword argument handling */ if (Len(pn)) { Printf(kwargs,"(char *) \"%s\",", pn); } else { Printf(kwargs,"\"arg%d\",", i+1); } /* Look for an input typemap */ if ((tm = Getattr(p,"tmap:in"))) { String *parse = Getattr(p,"tmap:in:parse"); if (!parse) { Replaceall(tm,"$source",source); Replaceall(tm,"$target",ln); Replaceall(tm,"$input", source); Setattr(p,"emit:input", source); /* Save the location of the object */ if (Getattr(p,"wrap:disown") || (Getattr(p,"tmap:in:disown"))) { Replaceall(tm,"$disown","SWIG_POINTER_DISOWN"); } else { Replaceall(tm,"$disown","0"); } Putc('O',parse_args); Wrapper_add_localv(f, source, "PyObject *",source, "= 0", NIL); Printf(arglist,"&%s",source); if (i >= num_required) Printv(get_pointers, "if (", source, ") {\n", NIL); Printv(get_pointers,tm,"\n", NIL); if (i >= num_required) Printv(get_pointers, "}\n", NIL); } else { Printf(parse_args,"%s",parse); Printf(arglist,"&%s", ln); } p = Getattr(p,"tmap:in:next"); continue; } else { Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n",SwigType_str(pt,0)); break; } p = nextSibling(p); } /* finish argument marshalling */ Printf(kwargs," NULL }"); if (allow_kwargs) { Printv(f->locals,tab4, "char *kwnames[] = ", kwargs, ";\n", NIL); } Printf(parse_args,":%s\"", iname); Printv(parse_args, arglist, ")) goto fail;\n", NIL); /* Now piece together the first part of the wrapper function */ Printv(f->code, parse_args, get_pointers, NIL); /* Check for trailing varargs */ if (varargs) { if (p && (tm = Getattr(p,"tmap:in"))) { Replaceall(tm,"$input", "varargs"); Printv(f->code,tm,"\n",NIL); } } /* Insert constraint checking code */ for (p = l; p;) { if ((tm = Getattr(p,"tmap:check"))) { Replaceall(tm,"$target",Getattr(p,"lname")); Printv(f->code,tm,"\n",NIL); p = Getattr(p,"tmap:check:next"); } else { p = nextSibling(p); } } /* Insert cleanup code */ for (p = l; p;) { if ((tm = Getattr(p,"tmap:freearg"))) { Replaceall(tm,"$source",Getattr(p,"lname")); Printv(cleanup,tm,"\n",NIL); p = Getattr(p,"tmap:freearg:next"); } else { p = nextSibling(p); } } /* Insert argument output code */ for (p = l; p;) { if ((tm = Getattr(p,"tmap:argout"))) { Replaceall(tm,"$source",Getattr(p,"lname")); Replaceall(tm,"$target","resultobj"); Replaceall(tm,"$arg",Getattr(p,"emit:input")); Replaceall(tm,"$input",Getattr(p,"emit:input")); Printv(outarg,tm,"\n",NIL); p = Getattr(p,"tmap:argout:next"); } else { p = nextSibling(p); } } /* if the object is a director, and the method call originated from its * underlying python object, resolve the call by going up the c++ * inheritance chain. otherwise try to resolve the method in python. * without this check an infinite loop is set up between the director and * shadow class method calls. */ // NOTE: this code should only be inserted if this class is the // base class of a director class. however, in general we haven't // yet analyzed all classes derived from this one to see if they are // directors. furthermore, this class may be used as the base of // a director class defined in a completely different module at a // later time, so this test must be included whether or not directorbase // is true. we do skip this code if directors have not been enabled // at the command line to preserve source-level compatibility with // non-polymorphic swig. also, if this wrapper is for a smart-pointer // method, there is no need to perform the test since the calling object // (the smart-pointer) and the director object (the "pointee") are // distinct. if (directorsEnabled()) { if (!is_smart_pointer()) { if (/*directorbase &&*/ !constructor && !destructor && isVirtual) { Wrapper_add_local(f, "director", "Swig::Director *director = 0"); Printf(f->code, "director = dynamic_cast(arg1);\n"); if (dirprot_mode() && is_protected(n)) { Printf(f->code, "if (!director || !(director->swig_get_inner(\"%s\"))) {\n", name); Printf(f->code, "PyErr_SetString(PyExc_RuntimeError,\"accessing protected member %s\");\n", name); Printf(f->code, "SWIG_fail;\n"); Printf(f->code, "}\n"); } Printf(f->code, "if (director && (director->swig_get_self()==obj0)) director->swig_set_up();\n"); } } } /* for constructor, determine if Python class has been subclassed. * if so, create a director instance. otherwise, just create a normal instance. */ /* MOVED TO Swig_ConstructorToFunction() */ /* if (constructor && (Getattr(n, "wrap:self") != 0)) { Wrapper_add_local(f, "subclassed", "int subclassed = 0"); Printf(f->code, "subclassed = (arg1 != Py_None);\n"); } */ /* Emit the function call */ emit_action(n,f); /* This part below still needs cleanup */ /* Return the function value */ if ((tm = Swig_typemap_lookup_new("out",n,"result",0))) { Replaceall(tm,"$source", "result"); Replaceall(tm,"$target", "resultobj"); Replaceall(tm,"$result", "resultobj"); if (Getattr(n,"feature:new")) { Replaceall(tm,"$owner","1"); } else { Replaceall(tm,"$owner","0"); } // FIXME: this will not try to unwrap directors returned as non-director // base class pointers! /* New addition to unwrap director return values so that the original * python object is returned instead. */ int unwrap = 0; String *decl = Getattr(n, "decl"); int is_pointer = SwigType_ispointer_return(decl); int is_reference = SwigType_isreference_return(decl); if (is_pointer || is_reference) { String *type = Getattr(n, "type"); //Node *classNode = Swig_methodclass(n); //Node *module = Getattr(classNode, "module"); Node *module = Getattr(parent, "module"); Node *target = Swig_directormap(module, type); if (target) unwrap = 1; } if (unwrap) { Wrapper_add_local(f, "resultdirector", "Swig::Director *resultdirector = 0"); Printf(f->code, "resultdirector = dynamic_cast(result);\n"); Printf(f->code, "if (resultdirector) {\n"); Printf(f->code, " resultobj = resultdirector->swig_get_self();\n"); Printf(f->code, " Py_INCREF(resultobj);\n"); Printf(f->code, "} else {\n"); Printf(f->code,"%s\n", tm); Printf(f->code, "}\n"); } else { Printf(f->code,"%s\n", tm); } } else { Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d,0), name); } /* Output argument output code */ Printv(f->code,outarg,NIL); /* Output cleanup code */ Printv(f->code,cleanup,NIL); /* Look to see if there is any newfree cleanup code */ if (Getattr(n,"feature:new")) { if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) { Replaceall(tm,"$source","result"); Printf(f->code,"%s\n",tm); } } /* See if there is any return cleanup code */ if ((tm = Swig_typemap_lookup_new("ret", n, "result", 0))) { Replaceall(tm,"$source","result"); Printf(f->code,"%s\n",tm); } Printf(f->code," return resultobj;\n"); /* Error handling code */ Printf(f->code,"fail:\n"); Printv(f->code,cleanup,NIL); Printf(f->code,"return NULL;\n"); Printf(f->code,"}\n"); /* Substitute the cleanup code */ Replaceall(f->code,"$cleanup",cleanup); /* Substitute the function name */ Replaceall(f->code,"$symname",iname); Replaceall(f->code,"$result","resultobj"); /* Dump the function out */ Wrapper_print(f,f_wrappers); /* If varargs. Need to emit a varargs stub */ if (varargs) { DelWrapper(f); f = NewWrapper(); Printv(f->def, "static PyObject *", wname, "(PyObject *self, PyObject *args) {", NIL); Wrapper_add_local(f,"resultobj", "PyObject *resultobj"); Wrapper_add_local(f,"varargs", "PyObject *varargs"); Wrapper_add_local(f,"newargs", "PyObject *newargs"); Printf(f->code,"newargs = PyTuple_GetSlice(args,0,%d);\n", num_arguments); Printf(f->code,"varargs = PyTuple_GetSlice(args,%d,PyTuple_Size(args)+1);\n", num_arguments); Printf(f->code,"resultobj = %s__varargs__(self,newargs,varargs);\n", wname); Printf(f->code,"Py_XDECREF(newargs);\n"); Printf(f->code,"Py_XDECREF(varargs);\n"); Printf(f->code,"return resultobj;\n"); Printf(f->code,"}\n"); Wrapper_print(f,f_wrappers); } Setattr(n,"wrap:name", wname); /* Now register the function with the interpreter. */ if (!Getattr(n,"sym:overloaded")) { add_method(iname, wname, allow_kwargs); /* Create a shadow for this function (if enabled and not in a member function) */ if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) { emitFunctionShadowHelper(n, in_class ? f_shadow_stubs : f_shadow, iname, allow_kwargs); } } else { if (!Getattr(n,"sym:nextSibling")) { dispatchFunction(n); } } Delete(parse_args); Delete(arglist); Delete(get_pointers); Delete(cleanup); Delete(outarg); Delete(kwargs); DelWrapper(f); return SWIG_OK; } /* ------------------------------------------------------------ * dispatchFunction() * ------------------------------------------------------------ */ void dispatchFunction(Node *n) { /* Last node in overloaded chain */ int maxargs; String *tmp = NewString(""); String *dispatch = Swig_overload_dispatch(n,"return %s(self,args);",&maxargs); /* Generate a dispatch wrapper for all overloaded functions */ Wrapper *f = NewWrapper(); String *symname = Getattr(n,"sym:name"); String *wname = Swig_name_wrapper(symname); Printv(f->def, "static PyObject *", wname, "(PyObject *self, PyObject *args) {", NIL); Wrapper_add_local(f,"argc","int argc"); Printf(tmp,"PyObject *argv[%d]", maxargs+1); Wrapper_add_local(f,"argv",tmp); Wrapper_add_local(f,"ii","int ii"); Printf(f->code,"argc = PyObject_Length(args);\n"); Printf(f->code,"for (ii = 0; (ii < argc) && (ii < %d); ii++) {\n",maxargs); Printf(f->code,"argv[ii] = PyTuple_GetItem(args,ii);\n"); Printf(f->code,"}\n"); Replaceall(dispatch,"$args","self,args"); Printv(f->code,dispatch,"\n",NIL); Printf(f->code,"PyErr_SetString(PyExc_TypeError,\"No matching function for overloaded '%s'\");\n", symname); Printf(f->code,"return NULL;\n"); Printv(f->code,"}\n",NIL); Wrapper_print(f,f_wrappers); add_method(symname,wname,0); /* Create a shadow for this function (if enabled and not in a member function) */ if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) { emitFunctionShadowHelper(n, f_shadow_stubs, symname, 0); } DelWrapper(f); Delete(dispatch); Delete(tmp); Delete(wname); } /* ------------------------------------------------------------ * variableWrapper() * ------------------------------------------------------------ */ virtual int variableWrapper(Node *n) { String *name = Getattr(n,"name"); String *iname = Getattr(n,"sym:name"); SwigType *t = Getattr(n,"type"); String *wname; static int have_globals = 0; String *tm; Wrapper *getf, *setf; if (!addSymbol(iname,n)) return SWIG_ERROR; getf = NewWrapper(); setf = NewWrapper(); /* If this is our first call, add the globals variable to the Python dictionary. */ if (!have_globals) { Printf(f_init,"\t PyDict_SetItemString(d,(char*)\"%s\", SWIG_globals);\n",global_name); have_globals=1; if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) { Printf(f_shadow_stubs,"%s = %s.%s\n", global_name, module, global_name); } } if ((shadow) && (SwigType_isconst(t))) { if (!in_class) { Printf(f_shadow_stubs,"%s = %s.%s\n", iname, global_name, iname); } } wname = Swig_name_wrapper(iname); /* Create a function for setting the value of the variable */ if (!Getattr(n,"feature:immutable")) { Printf(setf->def,"static int %s_set(PyObject *_val) {", wname); if ((tm = Swig_typemap_lookup_new("varin",n,name,0))) { Replaceall(tm,"$source","_val"); Replaceall(tm,"$target",name); Replaceall(tm,"$input","_val"); Printf(setf->code,"%s\n",tm); Delete(tm); } else { Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t,0)); } Printf(setf->code," return 0;\n"); } else { /* Is a readonly variable. Issue an error */ Printf(setf->def,"static int %s_set(PyObject *) {", wname); Printv(setf->code, tab4, "PyErr_SetString(PyExc_TypeError,\"Variable ", iname, " is read-only.\");\n", tab4, "return 1;\n", NIL); } Printf(setf->code,"}\n"); Wrapper_print(setf,f_wrappers); /* Create a function for getting the value of a variable */ Printf(getf->def,"static PyObject *%s_get() {", wname); Wrapper_add_local(getf,"pyobj", "PyObject *pyobj"); if ((tm = Swig_typemap_lookup_new("varout",n,name,0))) { Replaceall(tm,"$source",name); Replaceall(tm,"$target","pyobj"); Replaceall(tm,"$result","pyobj"); Printf(getf->code,"%s\n", tm); } else { Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t,0)); } Printf(getf->code," return pyobj;\n}\n"); Wrapper_print(getf,f_wrappers); /* Now add this to the variable linking mechanism */ Printf(f_init,"\t SWIG_addvarlink(SWIG_globals,(char*)\"%s\",%s_get, %s_set);\n", iname, wname, wname); DelWrapper(setf); DelWrapper(getf); return SWIG_OK; } /* ------------------------------------------------------------ * constantWrapper() * ------------------------------------------------------------ */ virtual int constantWrapper(Node *n) { String *name = Getattr(n,"name"); String *iname = Getattr(n,"sym:name"); SwigType *type = Getattr(n,"type"); String *rawval = Getattr(n,"rawval"); String *value = rawval ? rawval : Getattr(n,"value"); String *tm; int have_tm = 0; if (!addSymbol(iname,n)) return SWIG_ERROR; /* Special hook for member pointer */ if (SwigType_type(type) == T_MPOINTER) { String *wname = Swig_name_wrapper(iname); Printf(f_header, "static %s = %s;\n", SwigType_str(type,wname), value); value = wname; } if ((tm = Swig_typemap_lookup_new("consttab",n,name,0))) { Replaceall(tm,"$source",value); Replaceall(tm,"$target",name); Replaceall(tm,"$value", value); Printf(const_code,"%s,\n", tm); have_tm = 1; } if ((tm = Swig_typemap_lookup_new("constcode", n, name, 0))) { Replaceall(tm,"$source",value); Replaceall(tm,"$target",name); Replaceall(tm,"$value",value); Printf(f_init, "%s\n", tm); have_tm = 1; } if (!have_tm) { Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n"); return SWIG_NOWRAP; } if ((shadow) && (!(shadow & PYSHADOW_MEMBER))) { if (!in_class) { Printv(f_shadow,iname, " = ", module, ".", iname, "\n", NIL); } else { Printv(f_shadow_stubs,iname, " = ", module, ".", iname, "\n", NIL); } } return SWIG_OK; } /* ------------------------------------------------------------ * nativeWrapper() * ------------------------------------------------------------ */ virtual int nativeWrapper(Node *n) { String *name = Getattr(n,"sym:name"); String *wrapname = Getattr(n,"wrap:name"); if (!addSymbol(wrapname,n)) return SWIG_ERROR; add_method(name, wrapname,0); if (shadow) { Printv(f_shadow_stubs, name, " = ", module, ".", name, "\n\n", NIL); } return SWIG_OK; } /************************************************************************************* * BEGIN C++ Director Class modifications ************************************************************************************/ /* C++/Python polymorphism demo code, copyright (C) 2002 Mark Rose * * TODO * * Move some boilerplate code generation to Swig_...() functions. * */ /* --------------------------------------------------------------- * classDirectorMethod() * * Emit a virtual director method to pass a method call on to the * underlying Python object. * * --------------------------------------------------------------- */ int classDirectorMethod(Node *n, Node *parent, String *super) { int is_void = 0; int is_pointer = 0; String *decl; String *type; String *name; String *classname; String *declaration; ParmList *l; Wrapper *w; String *tm; String *wrap_args; String *return_type; String *value = Getattr(n, "value"); String *storage = Getattr(n,"storage"); bool pure_virtual = false; int status = SWIG_OK; int idx; String* xdecref = NewString(""); if (Cmp(storage,"virtual") == 0) { if (Cmp(value,"0") == 0) { pure_virtual = true; } } classname = Getattr(parent, "sym:name"); type = Getattr(n, "type"); name = Getattr(n, "name"); w = NewWrapper(); declaration = NewString(""); /* determine if the method returns a pointer */ decl = Getattr(n, "decl"); is_pointer = SwigType_ispointer_return(decl); is_void = (!Cmp(type, "void") && !is_pointer); /* form complete return type */ return_type = Copy(type); { SwigType *t = Copy(decl); SwigType *f = 0; f = SwigType_pop_function(t); SwigType_push(return_type, t); Delete(f); Delete(t); } /* virtual method definition */ l = Getattr(n, "parms"); String *target; String *pclassname = NewStringf("SwigDirector_%s", classname); String *qualified_name = NewStringf("%s::%s", pclassname, name); target = Swig_method_decl(decl, qualified_name, l, 0, 0); String *rtype = SwigType_str(type, 0); Printf(w->def, "%s %s", rtype, target); Delete(qualified_name); Delete(target); /* header declaration */ target = Swig_method_decl(decl, name, l, 0, 1); Printf(declaration, " virtual %s %s", rtype, target); Delete(target); // Get any exception classes in the throws typemap ParmList *throw_parm_list = 0; if ((throw_parm_list = Getattr(n,"throws"))) { Parm *p; int gencomma = 0; Append(w->def, " throw("); Append(declaration, " throw("); Swig_typemap_attach_parms("throws", throw_parm_list, 0); for (p = throw_parm_list; p; p=nextSibling(p)) { if ((tm = Getattr(p,"tmap:throws"))) { if (gencomma++) { Append(w->def, ", "); Append(declaration, ", "); } Printf(w->def, "%s", SwigType_str(Getattr(p, "type"),0)); Printf(declaration, "%s", SwigType_str(Getattr(p, "type"),0)); } } Append(w->def, ")"); Append(declaration, ")"); } Append(w->def, " {"); Append(declaration, ";\n"); /* attach typemaps to arguments (C/C++ -> Python) */ String *arglist = NewString(""); String* parse_args = NewString(""); /* remove the wrapper 'w' since it was producing spurious temps */ Swig_typemap_attach_parms("in", l, 0); Swig_typemap_attach_parms("directorin", l, 0); Swig_typemap_attach_parms("directorout", l, 0); Swig_typemap_attach_parms("directorargout", l, w); Parm* p; int num_arguments = emit_num_arguments(l); int i; char source[256]; wrap_args = NewString(""); int outputs = 0; if (!is_void) outputs++; /* build argument list and type conversion string */ for (i=0, idx=0, p = l; i < num_arguments && p != 0; i++) { if (checkAttribute(p,"tmap:in:numinputs","0")) { p = Getattr(p,"tmap:in:next"); continue; } /* old style? caused segfaults without the p!=0 check in the for() condition, and seems dangerous in the while loop as well. while (Getattr(p, "tmap:ignore")) { p = Getattr(p, "tmap:ignore:next"); } */ if (Getattr(p, "tmap:directorargout") != 0) outputs++; String* pname = Getattr(p, "name"); String* ptype = Getattr(p, "type"); Putc(',',arglist); if ((tm = Getattr(p, "tmap:directorin")) != 0) { String* parse = Getattr(p, "tmap:directorin:parse"); if (!parse) { sprintf(source, "obj%d", idx++); Replaceall(tm, "$input", source); Replaceall(tm, "$owner", "0"); Printv(wrap_args, tm, "\n", NIL); Wrapper_add_localv(w, source, "PyObject *", source, "= 0", NIL); Printv(arglist, source, NIL); Putc('O', parse_args); Printf(xdecref,"Py_XDECREF(%s);\n", source); } else { Printf(parse_args, "%s", parse); Replaceall(tm, "$input", pname); Replaceall(tm, "$owner", "0"); if (Len(tm) == 0) Append(tm, pname); Printf(arglist, "%s", tm); } p = Getattr(p, "tmap:directorin:next"); continue; } else if (Cmp(ptype, "void")) { /* special handling for pointers to other C++ director classes. * ideally this would be left to a typemap, but there is currently no * way to selectively apply the dynamic_cast<> to classes that have * directors. in other words, the type "SwigDirector_$1_lname" only exists * for classes with directors. we avoid the problem here by checking * module.wrap::directormap, but it's not clear how to get a typemap to * do something similar. perhaps a new default typemap (in addition * to SWIGTYPE) called DIRECTORTYPE? */ if (SwigType_ispointer(ptype) || SwigType_isreference(ptype)) { Node *module = Getattr(parent, "module"); Node *target = Swig_directormap(module, ptype); sprintf(source, "obj%d", idx++); String *nonconst = 0; /* strip pointer/reference --- should move to Swig/stype.c */ String *nptype = NewString(Char(ptype)+2); /* name as pointer */ String *ppname = Copy(pname); if (SwigType_isreference(ptype)) { Insert(ppname,0,"&"); } /* if necessary, cast away const since Python doesn't support it! */ if (SwigType_isconst(nptype)) { nonconst = NewStringf("nc_tmp_%s", pname); String *nonconst_i = NewStringf("= const_cast<%s>(%s)", SwigType_lstr(ptype, 0), ppname); Wrapper_add_localv(w, nonconst, SwigType_lstr(ptype, 0), nonconst, nonconst_i, NIL); Delete(nonconst_i); Swig_warning(WARN_LANG_DISCARD_CONST, input_file, line_number, "Target language argument '%s' discards const in director method %s::%s.\n", SwigType_str(ptype, pname), classname, name); } else { nonconst = Copy(ppname); } Delete(nptype); Delete(ppname); String *mangle = SwigType_manglestr(ptype); if (target) { String *director = NewStringf("director_%s", mangle); Wrapper_add_localv(w, director, "Swig::Director *", director, "= 0", NIL); Wrapper_add_localv(w, source, "PyObject *", source, "= 0", NIL); Printf(wrap_args, "%s = dynamic_cast(%s);\n", director, nonconst); Printf(wrap_args, "if (!%s) {\n", director); Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle); Printf(wrap_args, "} else {\n"); Printf(wrap_args, "%s = %s->swig_get_self();\n", source, director); Printf(wrap_args, "Py_INCREF(%s);\n", source); Printf(wrap_args, "}\n"); Delete(director); Printf(xdecref,"Py_XDECREF(%s);\n", source); Printv(arglist, source, NIL); } else { Wrapper_add_localv(w, source, "PyObject *", source, "= 0", NIL); Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle); //Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE_p_%s, 0);\n", // source, nonconst, base); Printf(xdecref,"Py_XDECREF(%s);\n", source); Printv(arglist, source, NIL); } Putc('O', parse_args); Delete(mangle); Delete(nonconst); } else { Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0), classname, name); status = SWIG_NOWRAP; break; } } p = nextSibling(p); } /* declare method return value * if the return value is a reference or const reference, a specialized typemap must * handle it, including declaration of c_result ($result). */ if (!is_void) { Wrapper_add_localv(w, "c_result", SwigType_lstr(return_type, "c_result"), NIL); } /* declare Python return value */ Wrapper_add_local(w, "result", "PyObject *result"); /* direct call to superclass if _up is set */ Printf(w->code, "if (swig_get_up()) {\n"); if (pure_virtual) { Printf(w->code, "throw Swig::DirectorPureVirtualException();\n"); } else { if (is_void) { Printf(w->code, "%s;\n", Swig_method_call(super,l)); Printf(w->code, "return;\n"); } else { Printf(w->code, "return %s;\n", Swig_method_call(super,l)); } } Printf(w->code, "}\n"); /* wrap complex arguments to PyObjects */ Printv(w->code, wrap_args, NIL); String *pyname = Getattr(n,"sym:name"); /* pass the method call on to the Python object */ if (dirprot_mode() && is_protected(n)) Printf(w->code, "swig_set_inner(\"%s\", true);\n", name); if (Len(parse_args) > 0) { Printf(w->code, "result = PyObject_CallMethod(swig_get_self(), \"%s\", \"%s\" %s);\n", pyname, parse_args, arglist); } else { Printf(w->code, "result = PyObject_CallMethod(swig_get_self(), \"%s\", NULL);\n", pyname); } Printv(xdecref, "Py_XDECREF(result);\n", NULL); if (dirprot_mode() && is_protected(n)) Printf(w->code, "swig_set_inner(\"%s\", false);\n", name); /* exception handling */ tm = Swig_typemap_lookup_new("director:except", n, "result", 0); if (!tm) { tm = Getattr(n, "feature:director:except"); } if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) { Printf(w->code, "if (result == NULL) {\n"); Printf(w->code, " PyObject *error = PyErr_Occurred();\n"); Replaceall(tm, "$error", "error"); Printv(w->code, Str(tm), "\n", NIL); Printf(w->code, "}\n"); } /* * Python method may return a simple object, or a tuple. * for in/out aruments, we have to extract the appropriate PyObjects from the tuple, * then marshal everything back to C/C++ (return value and output arguments). * */ /* marshal return value and other outputs (if any) from PyObject to C/C++ type */ String* cleanup = NewString(""); String* outarg = NewString(""); if (outputs > 1) { Wrapper_add_local(w, "output", "PyObject *output"); Printf(w->code, "if (!PyTuple_Check(result)) {\n"); Printf(w->code, "throw Swig::DirectorTypeMismatchException(\"Python method failed to return a tuple.\");\n"); Printf(w->code, "}\n"); } idx = 0; /* marshal return value */ if (!is_void) { /* this seems really silly. the node's type excludes qualifier/pointer/reference markers, * which have to be retrieved from the decl field to construct return_type. but the typemap * lookup routine uses the node's type, so we have to swap in and out the correct type. * it's not just me, similar silliness also occurs in Language::cDeclaration(). */ Setattr(n, "type", return_type); tm = Swig_typemap_lookup_new("directorout", n, "result", w); Setattr(n, "type", type); if (tm == 0) { String *name = NewString("result"); tm = Swig_typemap_search("directorout", return_type, name, NULL); Delete(name); } if (tm != 0) { if (outputs > 1) { Printf(w->code, "output = PyTuple_GetItem(result, %d);\n", idx++); Replaceall(tm, "$input", "output"); } else { Replaceall(tm, "$input", "result"); } /* TODO check this */ if (Getattr(n,"wrap:disown")) { Replaceall(tm,"$disown","SWIG_POINTER_DISOWN"); } else { Replaceall(tm,"$disown","0"); } Replaceall(tm, "$result", "c_result"); Printv(w->code, tm, "\n", NIL); } else { Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to return type %s in director method %s::%s (skipping method).\n", SwigType_str(return_type, 0), classname, name); status = SWIG_ERROR; } } /* marshal outputs */ for (p = l; p; ) { if ((tm = Getattr(p, "tmap:directorargout")) != 0) { if (outputs > 1) { Printf(w->code, "output = PyTuple_GetItem(result, %d);\n", idx++); Replaceall(tm, "$input", "output"); } else { Replaceall(tm, "$input", "result"); } Replaceall(tm, "$result", Getattr(p, "name")); Printv(w->code, tm, "\n", NIL); p = Getattr(p, "tmap:directorargout:next"); } else { p = nextSibling(p); } } Printv(w->code, xdecref, NULL); Delete(xdecref); /* any existing helper functions to handle this? */ if (!is_void) { String* rettype = SwigType_str(return_type, 0); if (!SwigType_isreference(return_type)) { Printf(w->code, "return (%s) c_result;\n", rettype); } else { Printf(w->code, "return (%s) *c_result;\n", rettype); } Delete(rettype); } Printf(w->code, "}\n"); /* emit the director method */ if (status == SWIG_OK) { Wrapper_print(w, f_directors); Printv(f_directors_h, declaration, NIL); } /* clean up */ Delete(wrap_args); Delete(parse_args); Delete(arglist); Delete(rtype); Delete(return_type); Delete(pclassname); Delete(cleanup); Delete(outarg); DelWrapper(w); return status; } /* ------------------------------------------------------------ * classDirectorConstructor() * ------------------------------------------------------------ */ int classDirectorConstructor(Node *n) { Node *parent = Getattr(n, "parentNode"); String *sub = NewString(""); String *decl = Getattr(n, "decl"); String *supername = Swig_class_name(parent); String *classname = NewString(""); Printf(classname, "SwigDirector_%s", supername); /* insert self and disown parameters */ Parm *p, *ip; ParmList *superparms = Getattr(n, "parms"); ParmList *parms = CopyParmList(superparms); String *type = NewString("PyObject"); SwigType_add_pointer(type); p = NewParm(type, NewString("self")); set_nextSibling(p, parms); parms = p; for (ip = parms; nextSibling(ip); ) ip = nextSibling(ip); p = NewParm(NewString("bool"), NewString("disown")); Setattr(p, "arg:byname", "1"); Setattr(n, "director:postfix_args", p); Setattr(p, "value", "false"); set_nextSibling(ip, p); /* constructor */ { Wrapper *w = NewWrapper(); String *call; String *basetype = Getattr(parent, "classtype"); String *target = Swig_method_decl(decl, classname, parms, 0, 0); call = Swig_csuperclass_call(0, basetype, superparms); Printf(w->def, "%s::%s: %s, Swig::Director(self, disown) { }", classname, target, call); Delete(target); Wrapper_print(w, f_directors); Delete(call); DelWrapper(w); } /* constructor header */ { String *target = Swig_method_decl(decl, classname, parms, 0, 1); Printf(f_directors_h, " %s;\n", target); Delete(target); } Delete(sub); Delete(classname); Delete(supername); Delete(parms); return Language::classDirectorConstructor(n); } /* ------------------------------------------------------------ * classDirectorDefaultConstructor() * ------------------------------------------------------------ */ int classDirectorDefaultConstructor(Node *n) { String *classname; classname = Swig_class_name(n); { Wrapper *w = NewWrapper(); Printf(w->def, "SwigDirector_%s::SwigDirector_%s(PyObject* self, bool disown) : Swig::Director(self, disown) { }", classname, classname); Wrapper_print(w, f_directors); DelWrapper(w); } Printf(f_directors_h, " SwigDirector_%s(PyObject* self, bool disown = false);\n", classname); Delete(classname); return Language::classDirectorDefaultConstructor(n); } /* ------------------------------------------------------------ * classDirectorInit() * ------------------------------------------------------------ */ int classDirectorInit(Node *n) { String *declaration = Swig_director_declaration(n); Printf(f_directors_h, "\n"); Printf(f_directors_h, "%s\n", declaration); Printf(f_directors_h, "public:\n"); Delete(declaration); return Language::classDirectorInit(n); } /* ------------------------------------------------------------ * classDirectorEnd() * ------------------------------------------------------------ */ int classDirectorEnd(Node *n) { if (dirprot_mode()) { /* This implementation uses a std::map. It should be possible to rewrite it using a more elegant way, like copying the Java approach for the 'override' array. But for know, this seems to be the least intrusive way. */ 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," }\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,"private:\n"); Printf(f_directors_h," mutable std::map inner;\n"); } Printf(f_directors_h, "};\n\n"); return Language::classDirectorEnd(n); } /* ------------------------------------------------------------ * classDirectorDisown() * ------------------------------------------------------------ */ int classDirectorDisown(Node *n) { int result; int oldshadow = shadow; /* disable shadowing */ if (shadow) shadow = shadow | PYSHADOW_MEMBER; result = Language::classDirectorDisown(n); shadow = oldshadow; if (shadow) { String *symname = Getattr(n,"sym:name"); String *mrename = Swig_name_disown(symname); //Getattr(n, "name")); Printv(f_shadow, tab4, "def __disown__(self):\n", NIL); Printv(f_shadow, tab8, "self.thisown = 0\n", NIL); Printv(f_shadow, tab8, module, ".", mrename,"(self)\n", NIL); Printv(f_shadow, tab8, "return weakref_proxy(self)\n", NIL); Delete(mrename); } return result; } /************************************************************************************* * END of C++ Director Class modifications ************************************************************************************/ /* ------------------------------------------------------------ * classDeclaration() * ------------------------------------------------------------ */ virtual int classDeclaration(Node *n) { String *importname; Node *mod; if (shadow) { mod = Getattr(n,"module"); if (mod) { String *modname = Getattr(mod,"name"); if (Strcmp(modname,mainmodule) != 0) { importname = NewStringf("%s.%s", modname, Getattr(n,"sym:name")); } else { importname = NewString(Getattr(n,"sym:name")); } Setattr(n,"python:proxy",importname); } } return Language::classDeclaration(n); } /* ------------------------------------------------------------ * classHandler() * ------------------------------------------------------------ */ virtual int classHandler(Node *n) { int oldclassic = classic; int oldmodern = modern; File *f_shadow_file = f_shadow; if (shadow) { /* Create new strings for building up a wrapper function */ have_constructor = 0; have_repr = 0; if (Getattr(n,"cplus:exceptionclass")) { classic = 1; modern = 0; } if (Getattr(n,"feature:classic")) { classic = 1; modern = 0; } if (Getattr(n,"feature:modern")) { classic = 0; modern = 1; } shadow_indent = (String *) tab4; class_name = Getattr(n,"sym:name"); real_classname = Getattr(n,"name"); if (!addSymbol(class_name,n)) return SWIG_ERROR; /* Handle inheritance */ String *base_class = NewString(""); List *baselist = Getattr(n,"bases"); if (baselist && Len(baselist)) { Iterator b; b = First(baselist); while (b.item) { String *bname = Getattr(b.item, "python:proxy"); if (!bname) { b = Next(b); continue; } Printv(base_class,bname,NIL); b = Next(b); if (b.item) { Putc(',',base_class); } } } Printv(f_shadow,"class ", class_name, NIL); if (Len(base_class)) { Printf(f_shadow,"(%s)", base_class); } else { if (!classic) { Printf(f_shadow, modern ? "(object)" : "(_object)"); } } Printf(f_shadow,":\n"); if (!modern) { Printv(f_shadow,tab4,"__swig_setmethods__ = {}\n",NIL); if (Len(base_class)) { Printf(f_shadow,"%sfor _s in [%s]: __swig_setmethods__.update(_s.__swig_setmethods__)\n",tab4,base_class); } Printv(f_shadow, tab4, "__setattr__ = lambda self, name, value: _swig_setattr(self, ", class_name, ", name, value)\n", NIL); Printv(f_shadow,tab4,"__swig_getmethods__ = {}\n",NIL); if (Len(base_class)) { Printf(f_shadow,"%sfor _s in [%s]: __swig_getmethods__.update(_s.__swig_getmethods__)\n",tab4,base_class); } Printv(f_shadow, tab4, "__getattr__ = lambda self, name: _swig_getattr(self, ", class_name, ", name)\n", NIL); } } /* Emit all of the members */ in_class = 1; /* Overide the shadow file so we can capture its methods */ f_shadow = NewString(""); Language::classHandler(n); in_class = 0; /* Complete the class */ if (shadow) { /* Generate a class registration function */ { SwigType *ct = NewStringf("p.%s", real_classname); SwigType_remember(ct); if (CPlusPlus) { Printv(f_wrappers, "static PyObject * ", class_name, "_swigregister(PyObject *, PyObject *args) {\n", tab4, "PyObject *obj;\n", tab4, "if (!PyArg_ParseTuple(args,(char*)\"O\", &obj)) return NULL;\n", tab4, "SWIG_TypeClientData(SWIGTYPE", SwigType_manglestr(ct),", obj);\n", tab4, "Py_INCREF(obj);\n", tab4, "return Py_BuildValue((char *)\"\");\n", "}\n",NIL); } else { Printv(f_wrappers, "static PyObject * ", class_name, "_swigregister(PyObject *self, PyObject *args) {\n", tab4, "PyObject *obj;\n", tab4, "if (!PyArg_ParseTuple(args,(char*)\"O\", &obj)) return NULL;\n", tab4, "SWIG_TypeClientData(SWIGTYPE", SwigType_manglestr(ct),", obj);\n", tab4, "Py_INCREF(obj);\n", tab4, "return Py_BuildValue((char *)\"\");\n", "}\n",NIL); } String *cname = NewStringf("%s_swigregister", class_name); add_method(cname, cname, 0); Delete(cname); Delete(ct); } if (!have_constructor) { Printv(f_shadow_file,tab4,"def __init__(self): raise RuntimeError, \"No constructor defined\"\n",NIL); } if (!have_repr) { /* Supply a repr method for this class */ if (new_repr) { Printv(f_shadow_file, tab4, "def __repr__(self):\n", tab8, "return \"<%s.%s; proxy of ", CPlusPlus ? "C++ " : "C ", real_classname," instance at %s>\" % (self.__class__.__module__, self.__class__.__name__, self.this,)\n", NIL); } else { Printv(f_shadow_file, tab4, "def __repr__(self):\n", tab8, "return \"\" % (self.this,)\n", NIL); } } /* Now emit methods */ Printv(f_shadow_file, f_shadow, NIL); /* Now the Ptr class */ Printv(f_shadow_file, "\nclass ", class_name, "Ptr(", class_name, "):\n", tab4, "def __init__(self, this):\n", NIL); if (!modern) { Printv(f_shadow_file, tab8, "_swig_setattr(self, ", class_name, ", 'this', this)\n", tab8, "if not hasattr(self,\"thisown\"): _swig_setattr(self, ", class_name, ", 'thisown', 0)\n", tab8, "_swig_setattr(self, ", class_name, ",self.__class__,", class_name, ")\n", NIL); } else { Printv(f_shadow_file, tab8, "self.this = this\n", tab8, "if not hasattr(self,\"thisown\"): self.thisown = 0\n", tab8, "self.__class__ = ", class_name, "\n", NIL); // tab8,"try: self.this = this.this; self.thisown = getattr(this,'thisown',0); this.thisown=0\n", // tab8,"except AttributeError: self.this = this\n" } Printf(f_shadow_file,"%s.%s_swigregister(%sPtr)\n", module, class_name, class_name,0); shadow_indent = 0; Printf(f_shadow_file,"%s\n", f_shadow_stubs); Clear(f_shadow_stubs); } classic = oldclassic; modern = oldmodern; /* Restore shadow file back to original version */ f_shadow = f_shadow_file; return SWIG_OK; } /* ------------------------------------------------------------ * memberfunctionHandler() * ------------------------------------------------------------ */ virtual int memberfunctionHandler(Node *n) { String *symname = Getattr(n,"sym:name"); int oldshadow; /* Create the default member function */ oldshadow = shadow; /* Disable shadowing when wrapping member functions */ if (shadow) shadow = shadow | PYSHADOW_MEMBER; Language::memberfunctionHandler(n); shadow = oldshadow; if (!Getattr(n,"sym:nextSibling")) { if (shadow) { int allow_kwargs = (check_kwargs(n) && !Getattr(n,"sym:overloaded")) ? 1 : 0; if (Strcmp(symname,"__repr__") == 0) have_repr = 1; 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)); Replaceall(pycode,"$action", pyaction); Delete(pyaction); Printv(f_shadow,pycode,"\n",NIL); } else { Printv(f_shadow, tab4, "def ", symname, "(*args", (allow_kwargs ? ", **kwargs" : ""), "): ", NIL); if ( have_addtofunc(n) ) { Printv(f_shadow, "\n", NIL); Printv(f_shadow, tab8, "val = ", funcCallHelper(Swig_name_member(class_name,symname), allow_kwargs), "\n", NIL); Printv(f_shadow, tab8, addtofunc(n), "\n", NIL); Printv(f_shadow, tab8, "return val\n", NIL); } else { Printv(f_shadow, "return ", funcCallHelper(Swig_name_member(class_name,symname), allow_kwargs), "\n", NIL); } } } } return SWIG_OK; } /* ------------------------------------------------------------ * staticmemberfunctionHandler() * ------------------------------------------------------------ */ virtual int staticmemberfunctionHandler(Node *n) { String *symname = Getattr(n,"sym:name"); Language::staticmemberfunctionHandler(n); if (shadow) { if ( !classic && have_addtofunc(n) ) { int kw = (check_kwargs(n) && !Getattr(n,"sym:overloaded")) ? 1 : 0; Printv(f_shadow, tab4, "def ", symname, "(*args", (kw ? ", **kwargs" : ""), "):\n", NIL); Printv(f_shadow, tab8, "val = ", funcCallHelper(Swig_name_member(class_name, symname), kw), "\n", NIL); Printv(f_shadow, tab8, addtofunc(n), "\n", NIL); Printv(f_shadow, tab8, "return val\n", NIL); Printv(f_shadow, tab4, modern ? "" : "if _newclass:", symname, " = staticmethod(", symname, ")\n", NIL); if (!modern) { Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = lambda x: ", symname, "\n", NIL); } } else { if (!modern) { Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = lambda x: ", module, ".", Swig_name_member(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); } } } return SWIG_OK; } /* ------------------------------------------------------------ * constructorDeclaration() * ------------------------------------------------------------ */ virtual int constructorHandler(Node *n) { String *symname = Getattr(n,"sym:name"); int oldshadow = shadow; int use_director = Swig_directorclass(n); /* * If we're wrapping the constructor of a C++ director class, prepend a new parameter * to receive the scripting language object (e.g. 'self') * */ Swig_save("python:constructorHandler",n,"parms",NIL); if (use_director) { Parm *parms = Getattr(n, "parms"); Parm *self; String *name = NewString("self"); String *type = NewString("PyObject"); SwigType_add_pointer(type); self = NewParm(type, name); Delete(type); Delete(name); Setattr(self, "lname", "O"); if (parms) set_nextSibling(self, parms); Setattr(n, "parms", self); Setattr(n, "wrap:self", "1"); Delete(self); } if (shadow) shadow = shadow | PYSHADOW_MEMBER; Language::constructorHandler(n); shadow = oldshadow; Delattr(n, "wrap:self"); Swig_restore(n); if (!Getattr(n,"sym:nextSibling")) { if (shadow) { int allow_kwargs = (check_kwargs(n) && (!Getattr(n,"sym:overloaded"))) ? 1 : 0; if (!have_constructor) { if (Getattr(n,"feature:shadow")) { String *pycode = pythoncode(Getattr(n,"feature:shadow"),tab4); String *pyaction = NewStringf("%s.%s",module, Swig_name_construct(symname)); Replaceall(pycode,"$action", pyaction); Delete(pyaction); Printv(f_shadow,pycode,"\n",NIL); } else { String *pass_self = NewString(""); Node *parent = Swig_methodclass(n); String *classname = Swig_class_name(parent); String *rclassname = Swig_class_name(getCurrentClass()); assert(rclassname); if (use_director) { Printv(pass_self, tab8, NIL); Printf(pass_self, "if self.__class__ == %s:\n", classname); Printv(pass_self, tab8, tab4, "args = (None,) + args\n", tab8, "else:\n", tab8, tab4, "args = (self,) + args\n", NIL); } Printv(f_shadow, tab4, "def __init__(self, *args", (allow_kwargs ? ", **kwargs" : ""), "):\n", NIL); Printv(f_shadow, pass_self, NIL); if (!modern) { Printv(f_shadow, tab8, "_swig_setattr(self, ", rclassname, ", 'this', ", funcCallHelper(Swig_name_construct(symname), allow_kwargs), ")\n", NIL); Printv(f_shadow, tab8, "_swig_setattr(self, ", rclassname, ", 'thisown', 1)\n", NIL); } else { Printv(f_shadow, tab8, "newobj = ", funcCallHelper(Swig_name_construct(symname), allow_kwargs), "\n", NIL); Printv(f_shadow, tab8, "self.this = newobj.this\n", NIL); Printv(f_shadow, tab8, "self.thisown = 1\n", NIL); Printv(f_shadow, tab8, "del newobj.thisown\n", NIL); } if ( have_addtofunc(n) ) Printv(f_shadow, tab8, addtofunc(n), "\n", NIL); Delete(pass_self); } have_constructor = 1; } else { /* Hmmm. We seem to be creating a different constructor. We're just going to create a function for it. */ if (Getattr(n,"feature:shadow")) { String *pycode = pythoncode(Getattr(n,"feature:shadow"),""); String *pyaction = NewStringf("%s.%s", module, Swig_name_construct(symname)); Replaceall(pycode,"$action", pyaction); Delete(pyaction); Printv(f_shadow_stubs,pycode,"\n",NIL); } else { Printv(f_shadow_stubs, "\ndef ", symname, "(*args", (allow_kwargs ? ", **kwargs" : ""), "):\n", NIL); Printv(f_shadow_stubs, tab4, "val = ", funcCallHelper(Swig_name_construct(symname), allow_kwargs), "\n", NIL); Printv(f_shadow_stubs, tab4, "val.thisown = 1\n", NIL); if ( have_addtofunc(n) ) Printv(f_shadow_stubs, tab4, addtofunc(n), "\n", NIL); Printv(f_shadow_stubs, tab4, "return val\n", NIL); } } } } return SWIG_OK; } /* ------------------------------------------------------------ * destructorHandler() * ------------------------------------------------------------ */ virtual int destructorHandler(Node *n) { String *symname = Getattr(n,"sym:name"); int oldshadow = shadow; if (shadow) shadow = shadow | PYSHADOW_MEMBER; Language::destructorHandler(n); shadow = oldshadow; 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)); Replaceall(pycode, "$action", pyaction); Delete(pyaction); Printv(f_shadow,pycode,"\n", NIL); } else { Printv(f_shadow, tab4, "def __del__(self, destroy=", module, ".", Swig_name_destroy(symname), "):\n", NIL); if ( have_addtofunc(n) ) Printv(f_shadow, tab8, addtofunc(n), "\n", NIL); Printv(f_shadow, tab8, "try:\n", NIL); Printv(f_shadow, tab4, tab8, "if self.thisown: destroy(self)\n", NIL); Printv(f_shadow, tab8, "except: pass\n", NIL); } } return SWIG_OK; } /* ------------------------------------------------------------ * membervariableHandler() * ------------------------------------------------------------ */ virtual int membervariableHandler(Node *n) { String *symname = Getattr(n,"sym:name"); int oldshadow = shadow; if (shadow) shadow = shadow | PYSHADOW_MEMBER; Language::membervariableHandler(n); shadow = oldshadow; if (shadow) { int immutable = (Getattr(n,"feature:immutable") != NULL); if (!modern) { if (!immutable) { Printv(f_shadow, tab4, "__swig_setmethods__[\"", symname, "\"] = ", module, ".", Swig_name_set(Swig_name_member(class_name,symname)), "\n", NIL); } Printv(f_shadow, tab4, "__swig_getmethods__[\"", symname, "\"] = ", module, ".", Swig_name_get(Swig_name_member(class_name,symname)),"\n", NIL); } if (!classic) { if (immutable) { Printv(f_shadow,tab4, modern ? "" : "if _newclass:", symname," = property(", module, ".", Swig_name_get(Swig_name_member(class_name,symname)),")\n", NIL); } else { Printv(f_shadow,tab4, modern ? "" : "if _newclass:", symname," = property(", module, ".", Swig_name_get(Swig_name_member(class_name,symname)),", ", module, ".", Swig_name_set(Swig_name_member(class_name,symname)),")\n", NIL); } } } return SWIG_OK; } /* ------------------------------------------------------------ * staticmembervariableHandler() * ------------------------------------------------------------ */ virtual int staticmembervariableHandler(Node *n) { String *symname; SwigType *t; Language::staticmembervariableHandler(n); if (shadow) { t = Getattr(n,"type"); symname = Getattr(n,"sym:name"); if (SwigType_isconst(t) && !Getattr(n, "value")) { Printf(f_shadow,"%s%s = %s.%s.%s\n", tab4, symname, module, global_name, Swig_name_member(class_name,symname)); } } return SWIG_OK; } /* ------------------------------------------------------------ * memberconstantHandler() * ------------------------------------------------------------ */ virtual int memberconstantHandler(Node *n) { String *symname = Getattr(n,"sym:name"); int oldshadow = shadow; if (shadow) shadow = shadow | PYSHADOW_MEMBER; Language::memberconstantHandler(n); shadow = oldshadow; if (shadow) { Printv(f_shadow, tab4, symname, " = ", module, ".", Swig_name_member(class_name,symname), "\n", NIL); } return SWIG_OK; } /* ------------------------------------------------------------ * pythoncode() - Output python code into the shadow file * ------------------------------------------------------------ */ String *pythoncode(String *code, const String *indent) { String *out = NewString(""); String *temp; char *t; if (!indent) indent = ""; temp = NewString(code); t = Char(temp); if (*t == '{') { Delitem(temp,0); Delitem(temp,DOH_END); } /* Split the input text into lines */ List *clist = DohSplitLines(temp); Delete(temp); int initial = 0; String *s = 0; Iterator si; /* Get the initial indentation */ for (si = First(clist); si.item; si = Next(si)) { s = si.item; if (Len(s)) { char *c = Char(s); while (*c) { if (!isspace(*c)) break; initial++; c++; } if (*c && !isspace(*c)) break; else { initial = 0; } } } while (si.item) { s = si.item; if (Len(s) > initial) { char *c = Char(s); c += initial; Printv(out,indent,c,"\n",NIL); } else { Printv(out,"\n",NIL); } si = Next(si); } Delete(clist); return out; } /* ------------------------------------------------------------ * insertDirective() * * Hook for %insert directive. We're going to look for special %shadow inserts * as a special case so we can do indenting correctly * ------------------------------------------------------------ */ virtual int insertDirective(Node *n) { String *code = Getattr(n,"code"); String *section = Getattr(n,"section"); if ((!ImportMode) && ((Cmp(section,"python") == 0) || (Cmp(section,"shadow") == 0))) { if (shadow) { String *pycode = pythoncode(code,shadow_indent); Printv(f_shadow, pycode, NIL); Delete(pycode); } } else { Language::insertDirective(n); } return SWIG_OK; } }; /* ----------------------------------------------------------------------------- * swig_python() - Instantiate module * ----------------------------------------------------------------------------- */ static Language * new_swig_python() { return new PYTHON(); } extern "C" Language * swig_python(void) { return new_swig_python(); } cableswig-0.1.0+git20150808.orig/SWIG/Source/Modules/php4.cxx0000644000175000000620000021324112561312227022050 0ustar stevestaff/* * PHP4 Support * * Richard Palmer * richard@magicality.org * Nov 2001 * * Portions copyright Sun Microsystems (c) 2001 * Tim Hockin * * Portions copyright Ananova Ltd (c) 2002 * Sam Liddicott * */ char cvsroot_php4_cxx[] = "/cvsroot/SWIG/Source/Modules/php4.cxx,v 1.8 2004/01/22 22:42:16 cheetah Exp"; #include "swigmod.h" #include static const char *usage = (char*)"\ PHP4 Options (available with -php4)\n\ -ldflags - Print runtime libraries to link with\n\ -cppext - cpp file extension (default to .cpp)\n\ -noproxy - Don't generate proxy classes.\n\ -dlname - Set module prefix to \n\ -make - Create simple makefile\n\ -phpfull - Create full make files\n\ -withincs - With -phpfull writes needed incs in config.m4\n\ -withlibs - With -phpfull writes needed libs in config.m4\n\ -withc - With -phpfull makes extra c files in Makefile.in\n\ -withcxx - With -phpfull makes extra c++ files in Makefile.in\n\ \n"; static int constructors=0; static String *NOTCLASS=NewString("Not a class"); static Node *classnode=0; static String *module = 0; static String *cap_module = 0; static String *dlname = 0; static String *withlibs = 0; static String *withincs = 0; static String *withc = 0; static String *withcxx = 0; //static char *package = 0; // Name of the package static char *shadow_classname; static Wrapper *f_php; static int gen_extra = 0; static int gen_make = 0; static File *f_runtime = 0; static File *f_h = 0; static File *f_phpcode = 0; static String *phpfilename =0; static String *s_header; static String *s_wrappers; static String *s_init; static String *s_vinit; static String *s_vdecl; static String *s_cinit; static String *s_oinit; static String *s_entry; static String *cs_entry; static String *all_cs_entry; static String *pragma_incl; static String *pragma_code; static String *pragma_phpinfo; /* Variables for using PHP classes */ static String *class_name = 0; static String *realpackage = 0; static String *package = 0; static Hash *shadow_get_vars; static Hash *shadow_set_vars; static String *shadow_classdef; static String *shadow_code; static int have_default_constructor = 0; #define NATIVE_CONSTRUCTOR 1 #define ALTERNATIVE_CONSTRUCTOR 2 static int native_constructor=0; static int destructor=0; static int enum_flag = 0; // Set to 1 when wrapping an enum static int static_flag = 0; // Set to 1 when wrapping a static functions or member variables static int const_flag = 0; // Set to 1 when wrapping a const member variables static int variable_wrapper_flag = 0; // Set to 1 when wrapping a member variable/enum/const static int wrapping_member = 0; static Hash *zend_types = 0; static String *shadow_enum_code = 0; static String *php_enum_code = 0; static String *all_shadow_extra_code = 0; //Extra code for all shadow classes from %pragma static String *this_shadow_extra_code = 0; //Extra Code for current single shadow class freom %pragma static String *all_shadow_import = 0; //import for all shadow classes from %pragma static String *this_shadow_import = 0; //import for current shadow classes from %pragma static String *module_baseclass = 0; //inheritance for module class from %pragma static String *all_shadow_baseclass = 0; //inheritence for all shadow classes from %pragma static String *this_shadow_baseclass = 0; //inheritance for shadow class from %pragma and cpp_inherit static String *this_shadow_multinherit = 0; static int shadow = 1; extern "C" { static void (*r_prevtracefunc)(SwigType *t, String *mangled, String *clientdata) = 0; } static const char *php_header = "/*" "\n +----------------------------------------------------------------------+" "\n | PHP version 4.0 |" "\n +----------------------------------------------------------------------+" "\n | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group |" "\n +----------------------------------------------------------------------+" "\n | This source file is subject to version 2.02 of the PHP license, |" "\n | that is bundled with this package in the file LICENSE, and is |" "\n | available at through the world-wide-web at |" "\n | http://www.php.net/license/2_02.txt. |" "\n | If you did not receive a copy of the PHP license and are unable to |" "\n | obtain it through the world-wide-web, please send a note to |" "\n | license@php.net so we can mail you a copy immediately. |" "\n +----------------------------------------------------------------------+" "\n | Authors: |" "\n | |" "\n +----------------------------------------------------------------------+" "\n */\n"; void SwigPHP_emit_resource_registrations() { DOH *key; Iterator ki; String *destructor=0; String *classname=0; String *shadow_classname=0; if (!zend_types) return; ki = First(zend_types); if (ki.key) Printf(s_oinit,"\n/* Register resource destructors for pointer types */\n"); while (ki.key) if (1 /* is pointer type*/) { key = ki.key; Node *class_node; if ((class_node=Getattr(zend_types,key))) { // Write out destructor function header Printf(s_wrappers,"/* NEW Destructor style */\nstatic ZEND_RSRC_DTOR_FUNC(_wrap_destroy%s) {\n",key); // write out body if ((class_node!=NOTCLASS)) { classname = Getattr(class_node,"name"); if (! (shadow_classname = Getattr(class_node,"sym:name"))) shadow_classname=classname; // Do we have a known destructor for this type? if ((destructor = Getattr(class_node,"destructor"))) { Printf(s_wrappers,"/* has destructor: %s */\n",destructor); Printf(s_wrappers,"%s(rsrc, SWIGTYPE%s->name TSRMLS_CC);\n",destructor,key); } else { Printf(s_wrappers,"/* bah! No destructor for this wrapped class!! */\n"); } } else { Printf(s_wrappers,"/* bah! No destructor for this simple type!! */\n"); } // close function Printf(s_wrappers,"}\n"); // declare le_swig_ to store php registration Printf(s_vdecl,"static int le_swig_%s=0; /* handle for %s */\n", key, shadow_classname); // register with php Printf(s_oinit,"le_swig_%s=zend_register_list_destructors_ex" "(_wrap_destroy%s,NULL,(char *)(SWIGTYPE%s->name),module_number);\n", key,key,key); // store php type in class struct Printf(s_oinit,"SWIG_TypeClientData(SWIGTYPE%s,&le_swig_%s);\n", key,key); } ki = Next(ki); } } class PHP4 : public Language { public: /* Test to see if a type corresponds to something wrapped with a shadow class. */ String *is_shadow(SwigType *t) { String *r = 0; Node *n = classLookup(t); if (n) { r = Getattr(n,"php:proxy"); // Set by classDeclaration() if (!r) { r = Getattr(n,"sym:name"); // Not seen by classDeclaration yet, but this is the name } } return r; } /* ----------------------------------------------------------------------------- * get_pointer() * ----------------------------------------------------------------------------- */ void get_pointer(char *iname, char *srcname, char *src, char *dest, SwigType *t, String *f, char *ret) { SwigType_remember(t); SwigType *lt = SwigType_ltype(t); Printv(f, "if (SWIG_ConvertPtr(", src, ",(void **) ", dest, ",", NIL); /* If we're passing a void pointer, we give the pointer conversion a NULL pointer, otherwise pass in the expected type. */ if (Cmp(lt,"p.void") == 0) { Printf(f, " 0 ) < 0) {\n"); } else { Printv(f, "SWIGTYPE", SwigType_manglestr(t), ") < 0) {\n",NIL); } Printv(f, "zend_error(E_ERROR, \"Type error in ", srcname, " of ", iname, " Expected %s\", SWIGTYPE", SwigType_manglestr(t), "->name);\n", ret, ";\n", "}\n", NIL); Delete(lt); } /* ------------------------------------------------------------ * main() * ------------------------------------------------------------ */ virtual void main(int argc, char *argv[]) { int i; SWIG_library_directory("php4"); SWIG_config_cppext("cpp"); for(i = 1; i < argc; i++) { if (argv[i]) { if(strcmp(argv[i], "-phpfull") == 0) { gen_extra = 1; Swig_mark_arg(i); } else if(strcmp(argv[i], "-dlname") == 0) { if (argv[i+1]) { dlname = NewString(argv[i+1]); Swig_mark_arg(i); Swig_mark_arg(i+1); i++; } else { Swig_arg_error(); } } else if(strcmp(argv[i], "-withlibs") == 0) { if (argv[i+1]) { withlibs = NewString(argv[i+1]); Swig_mark_arg(i); Swig_mark_arg(i+1); i++; } else { Swig_arg_error(); } } else if(strcmp(argv[i], "-withincs") == 0) { if (argv[i+1]) { withincs = NewString(argv[i+1]); Swig_mark_arg(i); Swig_mark_arg(i+1); i++; } else { Swig_arg_error(); } } else if(strcmp(argv[i], "-withc") == 0) { if (argv[i+1]) { withc = NewString(argv[i+1]); Swig_mark_arg(i); Swig_mark_arg(i+1); i++; } else { Swig_arg_error(); } } else if(strcmp(argv[i], "-withcxx") == 0) { if (argv[i+1]) { withcxx = NewString(argv[i+1]); Swig_mark_arg(i); Swig_mark_arg(i+1); i++; } else { Swig_arg_error(); } } else if(strcmp(argv[i], "-cppext") == 0) { if (argv[i+1]) { SWIG_config_cppext(argv[i+1]); Swig_mark_arg(i); Swig_mark_arg(i+1); i++; } else { Swig_arg_error(); } } else if((strcmp(argv[i], "-noshadow") == 0) || (strcmp(argv[i],"-noproxy") == 0)) { shadow = 0; Swig_mark_arg(i); } else if(strcmp(argv[i], "-make") == 0) { gen_make = 1; Swig_mark_arg(i); } else if(strcmp(argv[i], "-help") == 0) { fputs(usage, stderr); } else if (strcmp (argv[i], "-ldflags") == 0) { printf("%s\n", SWIG_PHP_RUNTIME); SWIG_exit (EXIT_SUCCESS); } } } Preprocessor_define((void *) "SWIGPHP 1", 0); Preprocessor_define((void *) "SWIGPHP4 1", 0); Preprocessor_define ("SWIG_NO_OVERLOAD 1", 0); SWIG_typemap_lang("php4"); /* DB: Suggest using a language configuration file */ SWIG_config_file("php4.swg"); } void create_simple_make(void) { File *f_make; f_make = NewFile((void *)"makefile", "w"); if(CPlusPlus) Printf(f_make, "CC=g++\n"); else Printf(f_make, "CC=gcc\n"); Printf(f_make, "OBJS=%s_wrap.o\n" "PROG=lib%s.so\n" "CFLAGS=-fpic\n" "LDFLAGS=-shared\n" "PHP_INC=`php-config --includes`\n" "EXTRA_INC=\n" "EXTRA_LIB=\n\n", module, module); Printf(f_make, "$(PROG): $(OBJS)\n" "\t$(CC) $(LDFLAGS) $(OBJS) -o $(PROG) $(EXTRA_LIB)\n\n" "%%.o: %%.%s\n" "\t$(CC) $(EXTRA_INC) $(PHP_INC) $(CFLAGS) -c $<\n", (CPlusPlus?"cpp":"c")); Close(f_make); } void create_extra_files(String *outfile) { File *f_extra; static String *configm4=0; static String *makefilein=0; static String *credits=0; configm4=NewString(""); Printv(configm4, SWIG_output_directory(), "config.m4", NIL); makefilein=NewString(""); Printv(makefilein, SWIG_output_directory(), "Makefile.in", NIL); credits=NewString(""); Printv(credits, SWIG_output_directory(), "CREDITS", NIL); // are we a --with- or --enable- int with=(withincs || withlibs)?1:0; // Note makefile.in only copes with one source file // also withincs and withlibs only take one name each now // the code they generate should be adapted to take multiple lines if(gen_extra) { /* Write out Makefile.in */ f_extra = NewFile(makefilein, "w"); if (!f_extra) { Printf(stderr,"Unable to open %s\n",makefilein); SWIG_exit(EXIT_FAILURE); } Printf(f_extra, "# php4.cxx,v 1.8 2004/01/22 22:42:16 cheetah Exp\n\n" "LTLIBRARY_NAME = php_%s.la\n", module); // CPP has more and different entires to C in Makefile.in if (! CPlusPlus) Printf(f_extra,"LTLIBRARY_SOURCES = %s %s\n" "LTLIBRARY_SOURCES_CPP = %s\n",Swig_file_filename(outfile),withc,withcxx); else Printf(f_extra,"LTLIBRARY_SOURCES = %s\n" "LTLIBRARY_SOURCES_CPP = %s %s\n" "LTLIBRARY_OBJECTS_X = $(LTLIBRARY_SOURCES_CPP:.cpp=.lo) $(LTLIBRARY_SOURCES_CPP:.cxx=.lo)\n" ,withc,Swig_file_filename(outfile),withcxx); Printf(f_extra,"LTLIBRARY_SHARED_NAME = php_%s.la\n" "LTLIBRARY_SHARED_LIBADD = $(%(upper)s_SHARED_LIBADD)\n\n" "include $(top_srcdir)/build/dynlib.mk\n", module,module); Printf(f_extra,"\n# patch in .cxx support to php build system to work like .cpp\n" ".SUFFIXES: .cxx\n\n" ".cxx.o:\n" " $(CXX_COMPILE) -c $<\n\n" ".cxx.lo:\n" " $(CXX_PHP_COMPILE)\n\n" ".cxx.slo:\n" " $(CXX_SHARED_COMPILE)\n\n"); Printf(f_extra,"\n# make it easy to test module\n" "testmodule:\n" " php -q -d extension_dir=modules %s\n\n",Swig_file_filename(phpfilename)); Close(f_extra); /* Now config.m4 */ // Note: # comments are OK in config.m4 if you don't mind them // appearing in the final ./configure file // (which can help with ./configure debugging) // NOTE2: phpize really ought to be able to write out a sample // config.m4 based on some simple data, I'll take this up with // the php folk! f_extra = NewFile(configm4, "w"); if (!f_extra) { Printf(stderr, "Unable to open %s\n",configm4); SWIG_exit(EXIT_FAILURE); } Printf(f_extra, "dnl php4.cxx,v 1.8 2004/01/22 22:42:16 cheetah Exp\n" "dnl ***********************************************************************\n" "dnl ** THIS config.m4 is provided for PHPIZE and PHP's consumption NOT\n" "dnl ** for any part of the rest of the %s build system\n" "dnl ***********************************************************************\n\n" ,module); if (! with) { // must be enable then Printf(f_extra, "PHP_ARG_ENABLE(%s, whether to enable %s support,\n" "[ --enable-%s Enable %s support])\n\n", module,module,module,module); } else { Printf(f_extra, "PHP_ARG_WITH(%s, for %s support,\n" "[ --with-%s[=DIR] Include %s support.])\n\n", module,module,module,module); // These tests try and file the library we need Printf(f_extra,"dnl THESE TESTS try and find the library and header files\n" "dnl your new php module needs. YOU MAY NEED TO EDIT THEM\n" "dnl as written they assume your header files are all in the same place\n\n"); Printf(f_extra,"dnl ** are we looking for %s_lib.h or something else?\n",module); if (withincs) Printf(f_extra,"HNAMES=\"%s\"\n\n",withincs); else Printf(f_extra,"HNAMES=\"\"; # %s_lib.h ?\n\n",module); Printf(f_extra,"dnl ** Are we looking for lib%s.a or lib%s.so or something else?\n",module,module); if (withlibs) Printf(f_extra,"LIBNAMES=\"%s\"\n\n",withlibs); else Printf(f_extra,"LIBNAMES=\"\"; # lib_%s.so ?\n\n",withlibs); Printf(f_extra,"dnl IF YOU KNOW one of the symbols in the library and you\n" "dnl specify it below then we can have a link test to see if it works\n" "LIBSYMBOL=\"\"\n\n"); } // Now write out tests to find thing.. they may need to extend tests Printf(f_extra,"if test \"$PHP_%(upper)s\" != \"no\"; then\n\n",module); // Ready for when we add libraries as we find them Printf(f_extra," PHP_SUBST(%(upper)s_SHARED_LIBADD)\n\n",module); if (withlibs) { // find more than one library Printf(f_extra," for LIBNAME in $LIBNAMES ; do\n"); Printf(f_extra," LIBDIR=\"\"\n"); // For each path element to try... Printf(f_extra," for i in $PHP_%(upper)s $PHP_%(upper)s/lib /usr/lib /usr/local/lib ; do\n",module,module); Printf(f_extra," if test -r $i/lib$LIBNAME.a -o -r $i/lib$LIBNAME.so ; then\n" " LIBDIR=\"$i\"\n" " break\n" " fi\n" " done\n\n"); Printf(f_extra," dnl ** and $LIBDIR should be the library path\n" " if test \"$LIBNAME\" != \"\" -a -z \"$LIBDIR\" ; then\n" " AC_MSG_RESULT(Library files $LIBNAME not found)\n" " AC_MSG_ERROR(Is the %s distribution installed properly?)\n" " else\n" " AC_MSG_RESULT(Library files $LIBNAME found in $LIBDIR)\n" " PHP_ADD_LIBRARY_WITH_PATH($LIBNAME, $LIBDIR, %(upper)s_SHARED_LIBADD)\n" " fi\n",module,module); Printf(f_extra," done\n\n"); } if (withincs) { // Find more than once include Printf(f_extra," for HNAME in $HNAMES ; do\n"); Printf(f_extra," INCDIR=\"\"\n"); // For each path element to try... Printf(f_extra," for i in $PHP_%(upper)s $PHP_%(upper)s/include $PHP_%(upper)s/includes $PHP_%(upper)s/inc $PHP_%(upper)s/incs /usr/local/include /usr/include; do\n",module,module,module,module,module); // Try and find header files Printf(f_extra," if test \"$HNAME\" != \"\" -a -r $i/$HNAME ; then\n" " INCDIR=\"$i\"\n" " break\n" " fi\n" " done\n\n"); Printf(f_extra, " dnl ** Now $INCDIR should be the include file path\n" " if test \"$HNAME\" != \"\" -a -z \"$INCDIR\" ; then\n" " AC_MSG_RESULT(Include files $HNAME not found)\n" " AC_MSG_ERROR(Is the %s distribution installed properly?)\n" " else\n" " AC_MSG_RESULT(Include files $HNAME found in $INCDIR)\n" " PHP_ADD_INCLUDE($INCDIR)\n" " fi\n\n",module); Printf(f_extra," done\n\n"); } if (CPlusPlus) Printf(f_extra, " # As this is a C++ module..\n" " PHP_REQUIRE_CXX\n" " AC_CHECK_LIB(stdc++, cin)\n"); if (with) { Printf(f_extra," if test \"$LIBSYMBOL\" != \"\" ; then\n" " old_LIBS=\"$LIBS\"\n" " LIBS=\"$LIBS -L$TEST_DIR/lib -lm -ldl\"\n" " AC_CHECK_LIB($LIBNAME, $LIBSYMBOL, [AC_DEFINE(HAVE_TESTLIB,1, [ ])],\n" " [AC_MSG_ERROR(wrong test lib version or lib not found)])\n" " LIBS=\"$old_LIBS\"\n" " fi\n\n"); } Printf(f_extra," AC_DEFINE(HAVE_%(upper)s, 1, [ ])\n",module); Printf(f_extra,"dnl AC_DEFINE_UNQUOTED(PHP_%(upper)s_DIR, \"$%(upper)s_DIR\", [ ])\n",module,module); Printf(f_extra," PHP_EXTENSION(%s, $ext_shared)\n",module); // and thats all! Printf(f_extra,"fi\n"); Close(f_extra); /* CREDITS */ f_extra = NewFile(credits, "w"); if (!f_extra) { Printf(stderr,"Unable to open %s\n",credits); SWIG_exit(EXIT_FAILURE); } Printf(f_extra, "%s\n", module); Close(f_extra); } } /* ------------------------------------------------------------ * top() * ------------------------------------------------------------ */ virtual int top(Node *n) { String *filen; String *s_type; /* Initialize all of the output files */ String *outfile = Getattr(n,"outfile"); /* main output file */ f_runtime = NewFile(outfile,"w"); if (!f_runtime) { Printf(stderr,"*** Can't open '%s'\n", outfile); SWIG_exit(EXIT_FAILURE); } Swig_banner(f_runtime); /* sections of the output file */ s_init = NewString("/* init section */\n"); s_header = NewString("/* header section */\n"); s_wrappers = NewString("/* wrapper section */\n"); s_type = NewString(""); /* subsections of the init section */ s_vinit = NewString("/* vinit subsection */\n"); s_vdecl = NewString("/* vdecl subsection */\n"); s_cinit = NewString("/* cinit subsection */\n"); s_oinit = NewString("/* oinit subsection */\n"); pragma_phpinfo = NewString(""); /* Register file targets with the SWIG file handler */ Swig_register_filebyname("runtime",f_runtime); Swig_register_filebyname("init",s_init); Swig_register_filebyname("header",s_header); Swig_register_filebyname("wrapper",s_wrappers); shadow_classdef = NewString(""); shadow_code = NewString(""); php_enum_code = NewString(""); module_baseclass = NewString(""); all_shadow_extra_code = NewString(""); all_shadow_import = NewString(""); all_shadow_baseclass = NewString(""); /* Set the module name */ module = Copy(Getattr(n,"name")); cap_module = NewStringf("%(upper)s",module); if(shadow) { realpackage = module; package = NewStringf("%sc", module); } /* Set the dlname */ if (!dlname) { #if defined(_WIN32) || defined(__WIN32__) dlname = NewStringf("%s.dll", module); #else dlname = NewStringf("%s.so", module); #endif } /* PHP module file */ filen = NewString(""); Printv(filen, SWIG_output_directory(), module, ".php", NIL); phpfilename = NewString(filen); f_phpcode = NewFile(filen, "w"); if (!f_phpcode) { Printf(stderr, "*** Can't open '%s'\n", filen); SWIG_exit(EXIT_FAILURE); } Printf(f_phpcode, "v)\n" "#define %s_FETCH() zend_%s_globals *%s_globals " "= ts_resource(%s_globals_id)\n" "#else\n" "#define %s_D\n" "#define %s_DC\n" "#define %s_C\n" "#define %s_CC\n" "#define %s_SG(v) (%s_globals.v)\n" "#define %s_FETCH()\n" "#endif\n\n" "#endif /* PHP_%s_H */\n", cap_module, module, module, cap_module, cap_module, cap_module, module, cap_module, cap_module, cap_module, module, cap_module, module, module, module, cap_module, cap_module, cap_module, cap_module, cap_module, module, cap_module, cap_module); Close(f_h); Printf(s_header, "%s\n\n",all_cs_entry); Printf(s_header, "%s" " {NULL, NULL, NULL}\n};\n\n" "zend_module_entry %s_module_entry = {\n" "#if ZEND_MODULE_API_NO > 20010900\n" " STANDARD_MODULE_HEADER,\n" "#endif\n" " \"%s\",\n" " %s_functions,\n" " PHP_MINIT(%s),\n" " PHP_MSHUTDOWN(%s),\n" " PHP_RINIT(%s),\n" " PHP_RSHUTDOWN(%s),\n" " PHP_MINFO(%s),\n" "#if ZEND_MODULE_API_NO > 20010900\n" " NO_VERSION_YET,\n" "#endif\n" " STANDARD_MODULE_PROPERTIES\n" "};\nzend_module_entry* SWIG_module_entry = &%s_module_entry;\n\n", s_entry, module, module, module, module, module, module, module,module,module); String *type_table = NewString(""); SwigType_emit_type_table(f_runtime,type_table); Printf(s_header,"%s",type_table); Delete(type_table); /* Oh dear, more things being called in the wrong order. This whole * function really needs totally redoing. */ Printv(f_runtime, s_header, NIL); // Wrapper_print(f_c, s_wrappers); Wrapper_print(f_php, s_wrappers); Printf(s_header, "/* end header section */\n"); Printf(s_wrappers, "/* end wrapper section */\n"); Printf(s_vdecl, "/* end vdecl subsection */\n"); Printv(f_runtime, s_vdecl, s_wrappers, s_init, NIL); Delete(s_header); Delete(s_wrappers); Delete(s_init); Delete(s_vdecl); Close(f_runtime); Printf(f_phpcode, "%s\n%s\n?>\n", pragma_incl, pragma_code); Close(f_phpcode); create_extra_files(outfile); if(!gen_extra && gen_make) create_simple_make(); return SWIG_OK; } /* Just need to append function names to function table to register with PHP */ void create_command(char *cname, char *iname) { // char *lower_cname = Swig_copy_string(cname); // char *c; // for(c = lower_cname; *c != '\0'; c++) { // if(*c >= 'A' && *c <= 'Z') // *c = *c + 32; // } Printf(f_h, "ZEND_NAMED_FUNCTION(%s);\n", iname); // This is for the single main function_entry record if (! cs_entry) Printf(s_entry, " ZEND_NAMED_FE(%(lower)s,\n" " %s, NULL)\n", cname,iname); // free(lower_cname); } /* ------------------------------------------------------------ * functionWrapper() * ------------------------------------------------------------ */ virtual int functionWrapper(Node *n) { char *name = GetChar(n,"name"); char *iname = GetChar(n,"sym:name"); SwigType *d = Getattr(n,"type"); ParmList *l = Getattr(n,"parms"); int newobject = (Getattr(n,"feature:new"))?1:0; Parm *p; char source[256],target[256],temp[256],argnum[32],args[32]; int i,numopt; String *tm; Wrapper *f; int num_saved = (Getattr(n,"feature:new"))?1:0; String *cleanup, *outarg; bool mvr=(shadow && variable_wrapper_flag && !enum_flag); bool mvrset=0; if (!addSymbol(iname,n)) return SWIG_ERROR; mvrset=(mvr && (strcmp(iname, Char(Swig_name_set(Swig_name_member(shadow_classname, name)))) == 0)); // if shadow and variable wrapper we want to snag the main contents // of this function to stick in to the property handler.... if (mvr) { //shadow && variable_wrapper_flag && !enum_flag) { String *member_function_name = NewString(""); String *php_function_name = NewString(iname); if(strcmp(iname, Char(Swig_name_set(Swig_name_member(shadow_classname, name)))) == 0) { Setattr(shadow_set_vars, php_function_name, name); } if(strcmp(iname, Char(Swig_name_get(Swig_name_member(shadow_classname, name)))) == 0) { Setattr(shadow_get_vars, php_function_name, name); } Putc(toupper((int )*iname), member_function_name); Printf(member_function_name, "%s", iname+1); cpp_func(l, php_function_name); Delete(php_function_name); Delete(member_function_name); } outarg = cleanup = NULL; f = NewWrapper(); numopt = 0; outarg = NewString(""); cleanup = NewString(""); // Special action for shadowing destructors under php. // The real destructor is the resource list destructor, this is // merely the thing that actually knows how to destroy... if (destructor) { String *destructorname=NewString(""); Printf(destructorname,"_%s",Swig_name_wrapper(iname)); Setattr(classnode,"destructor",destructorname); Wrapper *df = NewWrapper(); Printf(df->def,"/* This function is designed to be called by the zend list destructors to typecast and do the actual destruction */\n" "void %s(zend_rsrc_list_entry *rsrc, const char *type_name TSRMLS_DC) {\n",destructorname); Wrapper_add_localv(df, "value", "swig_object_wrapper *value=(swig_object_wrapper *) rsrc->ptr", NIL); Wrapper_add_localv(df, "ptr", "void *ptr=value->ptr", NIL); Wrapper_add_localv(df, "newobject", "int newobject=value->newobject", NIL); // Magic spell nicked from further down. emit_args(d, l, df); emit_attach_parmmaps(l,f); // Get type of first arg, thing to be destructed // Skip ignored arguments { p=l; //while (Getattr(p,"tmap:ignore")) {p = Getattr(p,"tmap:ignore:next");} while (checkAttribute(p,"tmap:in:numinputs","0")) { p = Getattr(p,"tmap:in:next"); } SwigType *pt = Getattr(p,"type"); Printf(df->code, " efree(value);\n" " if (! newobject) return; /* can't delete it! */\n" " SWIG_ZTS_ConvertResourceData(ptr,rsrc->type,type_name,(void **) &arg1,SWIGTYPE%s TSRMLS_CC);\n" " if (! arg1) zend_error(E_ERROR, \"%s resource already free'd\");\n" ,SwigType_manglestr(pt), shadow_classname); } emit_action(n,df); Printf(df->code,"}\n"); Wrapper_print(df,s_wrappers); } if (mvr) { // do prop[gs]et header if (mvrset) Printf(f->def, "static int _wrap_%s(zend_property_reference *property_reference, pval *value) {\n",iname); else Printf(f->def, "static pval _wrap_%s(zend_property_reference *property_reference) {\n",iname); } else { // regular header create_command(iname, Char(Swig_name_wrapper(iname))); Printv(f->def, "ZEND_NAMED_FUNCTION(" , Swig_name_wrapper(iname), ") {\n", NIL); } emit_args(d, l, f); /* Attach standard typemaps */ emit_attach_parmmaps(l,f); int num_arguments = emit_num_arguments(l); int num_required = emit_num_required(l); numopt = num_arguments - num_required; // we do +1 because we are going to push in this_ptr as arg0 if present // or do we need to? sprintf(args, "%s[%d]", "zval **args", num_arguments+1); Wrapper_add_local(f, "args",args); Wrapper_add_localv(f, "argbase", "int argbase=0", NIL); // This generated code may be called // 1) as an object method, or // 2) as a class-method/function (without a "this_ptr") // Option (1) has "this_ptr" for "this", option (2) needs it as // first parameter // NOTE: possible we ignore this_ptr as a param for native constructor if (native_constructor) { if (native_constructor==NATIVE_CONSTRUCTOR) Printf(f->code, "/* NATIVE Constructor */\nint self_constructor=1;\n"); else Printf(f->code, "/* ALTERNATIVE Constructor */\n"); } if (mvr && ! mvrset) { Wrapper_add_local(f, "_return_value", "zval _return_value"); Wrapper_add_local(f, "return_value", "zval *return_value=&_return_value"); }; // only let this_ptr count as arg[-1] if we are not a constructor // if we are a constructor and this_ptr is null we are called as a class // method and can make one of us if (! mvr && native_constructor==0) Printf(f->code, "if (this_ptr && this_ptr->type==IS_OBJECT) {\n" " /* fake this_ptr as first arg (till we can work out how to do it better */\n" " argbase++;\n" "}\n"); // I'd like to write out: //" //args[argbase++]=&this_ptr;\n" // but zend_get_parameters_array_ex can't then be told to leave // the first slot alone, so we have to check whether or not to access // this_ptr explicitly in each case where we normally just read args[] if(numopt > 0) { // membervariable wrappers do not have optional args Wrapper_add_local(f, "arg_count", "int arg_count"); Printf(f->code, "arg_count = ZEND_NUM_ARGS();\n" "if(arg_count<(%d-argbase) || arg_count>(%d-argbase))\n" "\tWRONG_PARAM_COUNT;\n\n", num_required, num_arguments); /* Verified args, retrieve them... */ Printf(f->code, "if(zend_get_parameters_array_ex(arg_count-argbase,args)!=SUCCESS)" "\n\t\tWRONG_PARAM_COUNT;\n\n"); } else if (!mvr) { Printf(f->code, "if(((ZEND_NUM_ARGS() + argbase )!= %d) || (zend_get_parameters_array_ex(%d-argbase, args)" "!= SUCCESS)) {\n" "WRONG_PARAM_COUNT;\n}\n\n", num_arguments, num_arguments); } /* Now convert from php to C variables */ // At this point, argcount if used is the number of deliberatly passed args // not including this_ptr even if it is used. // It means error messages may be out by argbase with error // reports. We can either take argbase into account when raising // errors, or find a better way of dealing with _thisptr // I would like, if objects are wrapped, to assume _thisptr is always // _this and the and not the first argument // This may mean looking at Lang::memberfunctionhandler for (i = 0, p = l; i < num_arguments; i++) { /* Skip ignored arguments */ //while (Getattr(p,"tmap:ignore")) { p = Getattr(p,"tmap:ignore:next");} while (checkAttribute(p,"tmap:in:numinputs","0")) { p = Getattr(p,"tmap:in:next"); } SwigType *pt = Getattr(p,"type"); if (mvr) { // do we assert that numargs=2, that i<2 if (i==0) sprintf(source,"&(property_reference->object)"); else sprintf(source,"&value"); } else { // Do we fake this_ptr as arg0, or just possibly shift other args by 1 if we did fake? if (i==0) sprintf(source, "((%d= (num_required)) Printf(f->code,"\tif(arg_count > %d) {\n", i); Setattr(p,"emit:input", source); if ((tm = Getattr(p,"tmap:in"))) { Replaceall(tm,"$target",target); Replaceall(tm,"$source",source); Replaceall(tm,"$input", source); Printf(f->code,"%s\n",tm); p = Getattr(p,"tmap:in:next"); if (i >= num_required) { Printf(f->code,"}\n"); } continue; } else { Printf(stderr,"%s : Line %d, Unable to use type %s as a function argument.\n", input_file, line_number, SwigType_str(pt,0)); } if (i>= num_required) Printf(f->code,"\t}\n"); } /* Insert constraint checking code */ for (p = l; p;) { if ((tm = Getattr(p,"tmap:check"))) { Replaceall(tm,"$target",Getattr(p,"lname")); Printv(f->code,tm,"\n",NIL); p = Getattr(p,"tmap:check:next"); } else { p = nextSibling(p); } } /* Insert cleanup code */ for (i = 0, p = l; p; i++) { if ((tm = Getattr(p,"tmap:freearg"))) { Replaceall(tm,"$source",Getattr(p,"lname")); Printv(cleanup,tm,"\n",NIL); p = Getattr(p,"tmap:freearg:next"); } else { p = nextSibling(p); } } /* Insert argument output code */ num_saved = 0; for (i=0,p = l; p;i++) { if ((tm = Getattr(p,"tmap:argout"))) { Replaceall(tm,"$source",Getattr(p,"lname")); Replaceall(tm,"$input",Getattr(p,"lname")); Replaceall(tm,"$target","return_value"); Replaceall(tm,"$result","return_value"); String *in = Getattr(p,"emit:input"); if (in) { sprintf(temp,"_saved[%d]", num_saved); Replaceall(tm,"$arg",temp); Printf(f->code,"_saved[%d] = %s;\n", num_saved, in); num_saved++; } Printv(outarg,tm,"\n",NIL); p = Getattr(p,"tmap:argout:next"); } else { p = nextSibling(p); } } // These are saved for argout again... if(num_saved) { sprintf(temp, "_saved[%d]",num_saved); // Used to be zval *, perhaps above we should use * %s Wrapper_add_localv(f,"_saved","zval **",temp,NIL); } /* emit function call*/ if (destructor) { // If it is a registered resource (and it always should be) // then destroy it the resource way Printf(f->code, "/*if ((*args[0])->type==IS_RESOURCE) { */\n" "/* Get zend list destructor to free it */\n" "/* zend_list_delete(Z_LVAL_PP(args[0])); */\n" "/* } else {*/ \n",name,name ); // but leave the old way in for as long as we accept strings as swig objects emit_action(n,f); Printf(f->code,"/*}*/\n"); } else { emit_action(n,f); } if((tm = Swig_typemap_lookup((char*)"out",d,iname,(char*)"result",(char*)"result",(char*)"return_value",0))) { Replaceall(tm, "$input", "result"); Replaceall(tm, "$source", "result"); Replaceall(tm, "$target", "return_value"); Replaceall(tm, "$result", "return_value"); Replaceall(tm,"$owner", newobject ? "1" : "0"); Printf(f->code, "%s\n", tm); // are we returning a wrapable object? // I don't know if this test is comlete, I nicked it if(is_shadow(d) && (SwigType_type(d) != T_ARRAY)) { Printf(f->code,"/* Wrap this return value */\n"); if (native_constructor==NATIVE_CONSTRUCTOR) { Printf(f->code, "if (this_ptr) {\n/* NATIVE Constructor, use this_ptr */\n"); Printf(f->code,"zval *_cPtr; MAKE_STD_ZVAL(_cPtr);\n" "*_cPtr = *return_value;\n" "INIT_ZVAL(*return_value);\n" "add_property_zval(this_ptr,\"_cPtr\",_cPtr);\n" "} else if (! this_ptr) ",shadow_classname); } { // THIS CODE only really needs writing out if the object to be returned // Is being shadow-wrap-thingied Printf(f->code, "{\n/* ALTERNATIVE Constructor, make an object wrapper */\n"); // Make object String *shadowrettype = NewString(""); SwigToPhpType(d, iname, shadowrettype, shadow); Printf(f->code, "zval *obj, *_cPtr;\n" "MAKE_STD_ZVAL(obj);\n" "MAKE_STD_ZVAL(_cPtr);\n" "*_cPtr = *return_value;\n" "INIT_ZVAL(*return_value);\n"); if (! shadow) { Printf(f->code, "*return_value=*_cPtr;\n"); } else { Printf(f->code, "object_init_ex(obj,ptr_ce_swig_%s);\n" "add_property_zval(obj,\"_cPtr\",_cPtr);\n" "*return_value=*obj;\n", shadowrettype); } Printf(f->code, "}\n"); } } // end of if-shadow lark } else { Printf(stderr,"%s: Line %d, Unable to use return type %s in function %s.\n", input_file, line_number, SwigType_str(d,0), name); } if(outarg) Printv(f->code,outarg,NIL); if(cleanup) Printv(f->code,cleanup,NIL); // Whats this bit for? if((tm = Swig_typemap_lookup((char*)"ret",d,iname,(char *)"result", (char*)"result",(char*)"",0))) { Printf(f->code,"%s\n", tm); } Replaceall(f->code,"$cleanup",cleanup); Replaceall(f->code,"$symname",iname); if (mvr) { if (! mvrset) Printf(f->code,"return _return_value;\n"); else Printf(f->code,"return SUCCESS;\n"); } Printf(f->code, "}\n"); Wrapper_print(f,s_wrappers); return SWIG_OK; } /* ------------------------------------------------------------ * variableWrapper() * ------------------------------------------------------------ */ virtual int OLDvariableWrapper(Node *n) { char *name = GetChar(n,"name"); char *iname = GetChar(n,"sym:name"); SwigType *t = Getattr(n,"type"); String *tm; if (!addSymbol(iname,n)) return SWIG_ERROR; SwigType_remember(t); /* First link C variables to PHP */ tm = Swig_typemap_lookup_new("varinit", n, name, 0); if(tm) { 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), name); } /* Now generate PHP -> C sync blocks */ tm = Swig_typemap_lookup_new("varin", n, name, 0); /* if(tm) { 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), name); } */ /* Now generate C -> PHP sync blocks */ /* if(!Getattr(n,"feature:immutable")) { tm = Swig_typemap_lookup_new("varout", n, name, 0); if(tm) { 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), name); } } */ return SWIG_OK; } /* ------------------------------------------------------------ * constantWrapper() * ------------------------------------------------------------ */ virtual int constantWrapper(Node *n) { char *name = GetChar(n,"name"); char *iname = GetChar(n,"sym:name"); SwigType *type = Getattr(n,"type"); char *value = GetChar(n,"value"); if (!addSymbol(iname,n)) return SWIG_ERROR; String *rval; String *tm; SwigType_remember(type); switch(SwigType_type(type)) { case T_STRING: rval = NewStringf("\"%s\"", value); break; case T_CHAR: rval = NewStringf("\'%s\'", value); break; default: rval = NewString(value); } if((tm = Swig_typemap_lookup_new("consttab", n, name, 0))) { Replaceall(tm, "$source", value); Replaceall(tm, "$target", name); Replaceall(tm, "$value", value); Printf(s_cinit, "%s\n", tm); } return SWIG_OK; } /* * PHP4::pragma() * * Pragma directive. * * %pragma(php4) code="String" # Includes a string in the .php file * %pragma(php4) include="file.pl" # Includes a file in the .php file */ virtual int pragmaDirective(Node *n) { if (!ImportMode) { String *lang = Getattr(n,"lang"); String *type = Getattr(n,"name"); String *value = Getattr(n,"value"); if (Strcmp(lang,"php4") == 0) { if (Strcmp(type, "code") == 0) { if (value) Printf(pragma_code, "%s\n", value); } else if (Strcmp(type, "include") == 0) { if (value) Printf(pragma_incl, "include \"%s\";\n", value); } else if (Strcmp(type, "phpinfo") == 0) { if (value) Printf(pragma_phpinfo, "%s\n", value); } else { Printf(stderr, "%s : Line %d. Unrecognized pragma.\n", input_file, line_number); } } } return Language::pragmaDirective(n); } /* ------------------------------------------------------------ * classDeclaration() * ------------------------------------------------------------ */ virtual int classDeclaration(Node *n) { String *symname = Getattr(n,"sym:name"); Setattr(n,"php:proxy",symname); return Language::classDeclaration(n); } /* ------------------------------------------------------------ * classHandler() * ------------------------------------------------------------ */ virtual int classHandler(Node *n) { constructors=0; //SwigType *t = Getattr(n, "classtype"); if(class_name) free(class_name); class_name = Swig_copy_string(GetChar(n, "name")); // String *use_class_name=SwigType_manglestr(SwigType_ltype(t)); if(shadow) { char *rename = GetChar(n, "sym:name"); if (!addSymbol(rename,n)) return SWIG_ERROR; shadow_classname = Swig_copy_string(rename); cs_entry = NewString(""); Printf(cs_entry,"/* Function entries for %s */\n" "static zend_function_entry %s_functions[] = {\n" ,shadow_classname, shadow_classname); if(Strcmp(shadow_classname, module) == 0) { Printf(stderr, "class name cannot be equal to module name: %s\n", shadow_classname); SWIG_exit(1); } Clear(shadow_classdef); Clear(shadow_code); have_default_constructor = 0; shadow_enum_code = NewString(""); this_shadow_baseclass = NewString(""); this_shadow_multinherit = NewString(""); this_shadow_extra_code = NewString(""); this_shadow_import = NewString(""); shadow_get_vars = NewHash(); shadow_set_vars = NewHash(); /* Deal with inheritance */ List *baselist = Getattr(n, "bases"); if(baselist) { int class_count = 0; Iterator base = First(baselist); while(base.item && Getattr(base.item,"feature:ignore")) base = Next(base); if (base.item && is_shadow(Getattr(base.item, "name"))) { class_count++; Printf(this_shadow_baseclass, "%s", Getattr(base.item, "name")); } if (base.item) for(base = Next(base); base.item; base = Next(base)) { if (Getattr(base.item,"feature:ignore")) continue; if(is_shadow(Getattr(base.item, "name"))) { class_count++; Printf(this_shadow_multinherit, "%s ", Getattr(base.item, "name")); } } if(class_count > 1) Printf(stderr, "Error: %s inherits from multiple base classes(%s %s). Multiple inheritance is not directly supported by PHP4, SWIG may support it at some point in the future.\n", shadow_classname, base.item, this_shadow_multinherit); } /* Write out class init code */ Printf(s_vdecl,"static zend_class_entry ce_swig_%s;\n",shadow_classname); Printf(s_vdecl,"static zend_class_entry* ptr_ce_swig_%s=NULL;\n",shadow_classname); } classnode=n; Language::classHandler(n); classnode=0; if(shadow) { DOH *key; int gcount, scount; String *s_propget=NewString(""); String *s_propset=NewString(""); List *baselist = Getattr(n, "bases"); Iterator ki, base; // If no constructor was generated (abstract class) we had better // generate a constructor that raises an error about instantiating // abstract classes if (! constructors || Getattr(n,"abstract")) { // have to write out fake constructor which raises an error when called abstractConstructorHandler(n); } Printf(s_oinit,"/* Define class %s */\n" "INIT_OVERLOADED_CLASS_ENTRY(ce_swig_%s,\"%(lower)s\",%s_functions," "NULL,_wrap_propget_%s,_wrap_propset_%s);\n", shadow_classname,shadow_classname,shadow_classname, shadow_classname,shadow_classname,shadow_classname); // ******** Write property SET handlers Printf(s_header,"static int _wrap_propset_%s(zend_property_reference *property_reference, pval *value);\n", shadow_classname); Printf(s_propset,"static int _wrap_propset_%s(zend_property_reference *property_reference, pval *value) { \n" " zval * _value;\n" " zend_llist_element *element = property_reference->elements_list->head;\n" " zend_overloaded_element *property=(zend_overloaded_element *)element->data;\n" " if (_propset_%s(property_reference, value)==SUCCESS) return SUCCESS;\n" " /* set it ourselves as it is %s */\n" " MAKE_STD_ZVAL(_value);\n" " *_value=*value;\n" " INIT_PZVAL(_value);\n" " zval_copy_ctor(_value);\n" " return add_property_zval_ex(property_reference->object,Z_STRVAL_P(&(property->element)),1+Z_STRLEN_P(&(property->element)),_value);\n" "}\n", shadow_classname, shadow_classname,shadow_classname); Printf(s_header,"static int _propset_%s(zend_property_reference *property_reference, pval *value);\n", shadow_classname); Printf(s_propset,"static int _propset_%s(zend_property_reference *property_reference, pval *value) {\n", shadow_classname); if (baselist) base=First(baselist); else base.item = NULL; while(base.item && Getattr(base.item,"feature:ignore")) base = Next(base); ki = First(shadow_set_vars); key = ki.key; // Print function header; we only need to find property name if there // are properties for this class to look up... if (key || ! base.item) { // or if we are base class and set it ourselves Printf(s_propset," /* get the property name */\n" " zend_llist_element *element = property_reference->elements_list->head;\n" " zend_overloaded_element *property=(zend_overloaded_element *)element->data;\n" " char *propname=Z_STRVAL_P(&(property->element));\n"); } else { if (base.item) { Printf(s_propset," /* No extra properties for subclass %s */\n",shadow_classname); } else { Printf(s_propset," /* No properties for base class %s */\n",shadow_classname); } } scount=0; while (ki.key) { key = ki.key; if (scount++) Printf(s_propset," else"); Printf(s_propset," if (strcmp(propname,\"%s\")==0) {\n" " return _wrap_%s(property_reference, value);\n" " }",Getattr(shadow_set_vars,key),key); ki=Next(ki); } if (scount) Printf(s_propset," else"); // If there is a base class then chain it's handler else set directly // try each base class handler, else set directly... if (base.item) { Printf(s_propset, " {\n /* chain to base class */\n"); while(base.item) { Printf(s_propset," if (_propset_%s(property_reference, value)==SUCCESS) return SUCCESS;\n", GetChar(base.item, "sym:name")); base=Next(base); while (base.item && Getattr(base.item,"feature:ignore")) base=Next(base); } Printf(s_propset," }\n"); } Printf(s_propset," return FAILURE;\n}\n\n"); // ******** Write property GET handlers Printf(s_header,"static pval _wrap_propget_%s(zend_property_reference *property_reference);\n", shadow_classname); Printf(s_propget,"static pval _wrap_propget_%s(zend_property_reference *property_reference) {\n" " pval result;\n" " pval **_result;\n" " zend_llist_element *element = property_reference->elements_list->head;\n" " zend_overloaded_element *property=(zend_overloaded_element *)element->data;\n" " result.type = IS_NULL;\n" " if (_propget_%s(property_reference, &result)==SUCCESS) return result;\n" " /* return it ourselves */\n" " if (zend_hash_find(Z_OBJPROP_P(property_reference->object),Z_STRVAL_P(&(property->element)),1+Z_STRLEN_P(&(property->element)),(void**)&_result)==SUCCESS) {\n" " zval *_value;\n" " MAKE_STD_ZVAL(_value);" " *_value=**_result;\n" " INIT_PZVAL(_value);\n" " zval_copy_ctor(_value);\n" " return *_value;\n" " }\n" " result.type = IS_NULL;\n" " return result;\n" "}\n", shadow_classname, shadow_classname); Printf(s_header,"static int _propget_%s(zend_property_reference *property_reference, pval *value);\n", shadow_classname); Printf(s_propget,"static int _propget_%s(zend_property_reference *property_reference, pval *value) {\n", shadow_classname); if (baselist) base=First(baselist); else base.item=NULL; while(base.item && Getattr(base.item,"feature:ignore")) base = Next(base); ki = First(shadow_get_vars); key = ki.key; // Print function header; we only need to find property name if there // are properties for this class to look up... if (key || !base.item ) { // or if we are base class... Printf(s_propget," /* get the property name */\n" " zend_llist_element *element = property_reference->elements_list->head;\n" " zend_overloaded_element *property=(zend_overloaded_element *)element->data;\n" " char *propname=Z_STRVAL_P(&(property->element));\n"); } else { if (base.item) { Printf(s_propget," /* No extra properties for subclass %s */\n",shadow_classname); } else { Printf(s_propget," /* No properties for base class %s */\n",shadow_classname); } } gcount=0; while (ki.key) { key = ki.key; if (gcount++) Printf(s_propget," else"); Printf(s_propget," if (strcmp(propname,\"%s\")==0) {\n" " *value=_wrap_%s(property_reference);\n" " return SUCCESS;\n" " }",Getattr(shadow_get_vars,key),key); ki=Next(ki); } if (gcount) Printf(s_propget," else"); // If there is a base class then chain it's handler else return null if (base.item) { Printf(s_propget, " {\n /* chain to base class */\n"); while(base.item) { Printf(s_propget," if (_propget_%s(property_reference, value)==SUCCESS) return SUCCESS;\n", GetChar(base.item, "sym:name")); base=Next(base); while (base.item && Getattr(base.item,"feature:ignore")) base=Next(base); } Printf(s_propget," }\n"); } Printf(s_propget," return FAILURE;\n}\n\n"); // wrappers generated now... // add wrappers to output code Printf(s_wrappers,"/* property handler for class %s */\n",shadow_classname); Printv(s_wrappers,s_propget,s_propset,NIL); // Save class in class table if (baselist) base=First(baselist); else base.item=NULL; while(base.item && Getattr(base.item,"feature:ignore")) base = Next(base); if (base.item) { Printf(s_oinit,"if (! (ptr_ce_swig_%s=zend_register_internal_class_ex(&ce_swig_%s,&ce_swig_%s,NULL))) zend_error(E_ERROR,\"Error registering wrapper for class %s\");\n", shadow_classname,shadow_classname,GetChar(base.item, "sym:name"), shadow_classname); } else { Printf(s_oinit,"if (! (ptr_ce_swig_%s=zend_register_internal_class_ex(&ce_swig_%s,NULL,NULL))) zend_error(E_ERROR,\"Error registering wrapper for class %s\");\n", shadow_classname,shadow_classname, shadow_classname); } Printf(s_oinit,"\n"); Printv(f_phpcode, shadow_classdef, shadow_code, NIL); // Write the enum initialisation code in a static block // These are all the enums defined withing the c++ class. // PHP Needs to handle shadow enums properly still if(strlen(Char(shadow_enum_code)) != 0 ) Printv(f_phpcode, "{\n /* enum */\n", shadow_enum_code, " }\n", NIL); free(shadow_classname); shadow_classname = NULL; Delete(shadow_enum_code); shadow_enum_code = NULL; Delete(this_shadow_baseclass); this_shadow_baseclass = NULL; Delete(this_shadow_extra_code); this_shadow_extra_code = NULL; Delete(this_shadow_import); this_shadow_import = NULL; Delete(shadow_set_vars); shadow_set_vars = NULL; Delete(shadow_get_vars); shadow_get_vars = NULL; Delete(this_shadow_multinherit); this_shadow_multinherit = NULL; Printf(all_cs_entry,"%s { NULL, NULL, NULL}\n};\n",cs_entry); //??delete cs_entry; cs_entry=NULL; } return SWIG_OK; } /* ------------------------------------------------------------ * memberfunctionHandler() * ------------------------------------------------------------ */ virtual int memberfunctionHandler(Node *n) { char *name = GetChar(n, "name"); char *iname = GetChar(n, "sym:name"); ParmList *l = Getattr(n, "parms"); this->Language::memberfunctionHandler(n); if(shadow) { char *realname = iname ? iname : name; String *php_function_name = Swig_name_member(shadow_classname, realname); cpp_func(l, realname, php_function_name); } return SWIG_OK; } /* ------------------------------------------------------------ * membervariableHandler() * ------------------------------------------------------------ */ virtual int membervariableHandler(Node *n) { wrapping_member = 1; variable_wrapper_flag = 1; Language::membervariableHandler(n); wrapping_member = 0; variable_wrapper_flag = 0; return SWIG_OK; } /* ------------------------------------------------------------ * staticmemberfunctionHandler() * ------------------------------------------------------------ */ virtual int staticmemberfunctionHandler(Node *n) { char *name = GetChar(n, "name"); char *iname = GetChar(n, "sym:name"); Language::staticmemberfunctionHandler(n); if(shadow) { String *symname = Getattr(n, "sym:name"); static_flag = 1; char *realname = iname ? iname : name; String *php_function_name = Swig_name_member(shadow_classname, realname); cpp_func(Getattr(n, "parms"), symname, php_function_name); static_flag = 0; } return SWIG_OK; } /* ------------------------------------------------------------ * staticmembervariableHandler() * ------------------------------------------------------------ */ virtual int staticmembervariableHandler(Node *n) { SwigType *d = Getattr(n, "type"); char *iname = GetChar(n, "sym:name"); char *name = GetChar(n, "name"); String *static_name = NewStringf("%s::%s", class_name, name); // String *use_class_name=SwigType_manglestr(SwigType_ltype(t)); Wrapper *f; /* A temporary(!) hack for static member variables. * Php currently supports class functions, but not class variables. * Until it does, we convert a class variable to a class function * that returns the current value of the variable. E.g. * * class Example { * public: * static int ncount; * }; * * would be available in php as Example::ncount() */ static_flag = 1; if(Getattr(n,"feature:immutable")) { const_flag = 1; } cpp_func(0, iname); static_flag = 0; create_command(iname, Char(Swig_name_wrapper(iname))); f = NewWrapper(); Printv(f->def, "ZEND_NAMED_FUNCTION(", Swig_name_wrapper(iname), ") {\n", NIL); /* If a argument is given we set the variable. Then we return * the current value */ Printf(f->code, "zval **args[1];\n" "int argcount;\n\n" "argcount = ZEND_NUM_ARGS();\n" "if(argcount > %d) WRONG_PARAM_COUNT;\n\n", (const_flag? 0 : 1)); if(!const_flag) { Printf(f->code, "if(argcount) {\n"); Printf(f->code, "if(zend_get_parameters_array_ex(argcount, args) != SUCCESS) WRONG_PARAM_COUNT;\n"); switch(SwigType_type(d)) { case T_BOOL: case T_INT: case T_SHORT: case T_LONG: case T_SCHAR: case T_UINT: case T_USHORT: case T_ULONG: case T_UCHAR: Printf(f->code, "convert_to_long_ex(args[0]);\n" "%s = Z_LVAL_PP(args[0]);\n", static_name); break; case T_CHAR: Printf(f->code, "convert_to_string_ex(args[0]);\n" "%s = estrdup(Z_STRVAL(args[0]));\n", static_name); break; case T_DOUBLE: case T_FLOAT: Printf(f->code, "convert_to_double_ex(args[0]);\n" "%s = Z_DVAL_PP(args[0]);\n", static_name); break; case T_VOID: break; case T_USER: Printf(f->code, "convert_to_string_ex(args[0]);\n"); get_pointer(Char(iname), (char*)"variable", (char*)"args[0]", Char(static_name), d, f->code, (char *)"RETURN_FALSE"); break; case T_POINTER: case T_ARRAY: case T_REFERENCE: Printf(f->code, "convert_to_string_ex(args[0]);\n"); get_pointer(Char(iname), (char*)"variable", (char*)"args[0]", Char(static_name), d, f->code, (char*)"RETURN_FALSE"); break; default: Printf(stderr,"%s : Line %d, Unable to use type %s as a class variable.\n", input_file, line_number, SwigType_str(d,0)); break; } Printf(f->code, "}\n\n"); } /* end of const_flag */ switch(SwigType_type(d)) { case T_BOOL: case T_INT: case T_SHORT: case T_LONG: case T_SCHAR: case T_UINT: case T_USHORT: case T_ULONG: case T_UCHAR: Printf(f->code, "RETURN_LONG(%s);\n", static_name); break; case T_DOUBLE: case T_FLOAT: Printf(f->code, "RETURN_DOUBLE(%s);\n", static_name); break; case T_CHAR: Printf(f->code, "{\nchar ctemp[2];\n" "ctemp[0] = %s;\n" "ctemp[1] = 0;\n" "RETURN_STRING(ctemp, 1);\n}\n", static_name); break; case T_USER: case T_POINTER: Printf(f->code, "SWIG_SetPointerZval(return_value, (void *)%s, " "SWIGTYPE%s);\n", static_name, SwigType_manglestr(d)); break; case T_STRING: Printf(f->code, "RETURN_STRING(%s, 1);\n", static_name); break; } Printf(f->code, "}\n"); const_flag = 0; Wrapper_print(f, s_wrappers); return SWIG_OK; } void SwigToPhpType(SwigType *t, String_or_char *pname, String* php_type, int shadow_flag) { char *ptype = 0; if(shadow_flag) ptype = PhpTypeFromTypemap((char*)"pstype", t, pname,(char*)""); if(!ptype) ptype = PhpTypeFromTypemap((char*)"ptype",t,pname,(char*)""); if(ptype) { Printf(php_type, ptype); free(ptype); } else { /* Map type here */ switch(SwigType_type(t)) { case T_CHAR: case T_SCHAR: case T_UCHAR: case T_SHORT: case T_USHORT: case T_INT: case T_UINT: case T_LONG: case T_ULONG: case T_FLOAT: case T_DOUBLE: case T_BOOL: case T_STRING: case T_VOID: Printf(php_type, ""); break; case T_POINTER: case T_REFERENCE: case T_USER: if(shadow_flag && is_shadow(t)) Printf(php_type, Char(is_shadow(t))); else Printf(php_type, ""); break; case T_ARRAY: /* TODO */ break; default: Printf(stderr, "SwigToPhpType: unhandled data type: %s\n", SwigType_str(t,0)); break; } } } char *PhpTypeFromTypemap(char *op, SwigType *t, String_or_char *pname, String_or_char *lname) { String *tms; char bigbuf[1024]; char *tm; char *c = bigbuf; if(!(tms = Swig_typemap_lookup(op, t, pname, lname, (char*)"", (char*)"", NULL))) return NULL; tm = Char(tms); while(*tm && (isspace(*tm) || *tm == '{')) tm++; while(*tm && *tm != '}') *c++ = *tm++; *c='\0'; return Swig_copy_string(bigbuf); } int abstractConstructorHandler(Node *n) { char *iname = GetChar(n, "sym:name"); if (shadow) { Wrapper *f; f = NewWrapper(); // constructor header if (cs_entry) Printf(cs_entry, " ZEND_NAMED_FE(%(lower)s,\n" " _wrap_new_%s, NULL)\n", iname,iname); // now constructor body Printf(f_h, "ZEND_NAMED_FUNCTION(_wrap_new_%s);\n",iname); Printf(f->def, "ZEND_NAMED_FUNCTION(_wrap_new_%s) {\n" "zend_error(E_ERROR,\"Cannot create swig object type: %s as the underlying object is abstract\");\n" "}\n\n", iname, iname); Wrapper_print(f,s_wrappers); DelWrapper(f); } return SWIG_OK; } /* ------------------------------------------------------------ * constructorHandler() * ------------------------------------------------------------ */ virtual int constructorHandler(Node *n) { char *iname = GetChar(n, "sym:name"); if (shadow) native_constructor = (strcmp(iname, shadow_classname) == 0)?\ NATIVE_CONSTRUCTOR:ALTERNATIVE_CONSTRUCTOR; else native_constructor=0; constructors++; Language::constructorHandler(n); if(shadow) { // But we also need one per wrapped-class if (cs_entry) Printf(cs_entry, " ZEND_NAMED_FE(%(lower)s,\n" " _wrap_new_%s, NULL)\n", iname,iname); } native_constructor = 0; return SWIG_OK; } /* ------------------------------------------------------------ * destructorHandler() * ------------------------------------------------------------ */ virtual int destructorHandler(Node *n) { char *iname = GetChar(n, "sym:name"); destructor=1; Language::destructorHandler(n); destructor=0; // we don't give user access to destructors, they have to unset var // and let php dispose instead if(0 && shadow) { // But we also need one per wrapped-class if (cs_entry) Printf(cs_entry, " ZEND_NAMED_FE(_destroy_%(lower)s,\n" " _wrap_delete_%s, NULL)\n", iname,iname); } return SWIG_OK; } /* ------------------------------------------------------------ * memberconstantHandler() * ------------------------------------------------------------ */ virtual int memberconstantHandler(Node *n) { wrapping_member = 1; Language::memberconstantHandler(n); wrapping_member = 0; return SWIG_OK; } // This method is quite stale and ought to be factored out void cpp_func(ParmList *l, String *php_function_name, String *handler_name = NULL) { if(!shadow) return; // if they didn't provide a handler name, use the realname if (! handler_name) handler_name=php_function_name; if(l) { if(SwigType_type(Getattr(l, "type")) == T_VOID) { l = nextSibling(l); } } // But we also need one per wrapped-class // Printf(f_h, "x ZEND_NAMED_FUNCTION(%s);\n", Swig_name_wrapper(handler_name)); if (cs_entry && !(variable_wrapper_flag && shadow)) Printf(cs_entry, " ZEND_NAMED_FE(%(lower)s,\n" " %s, NULL)\n", php_function_name,Swig_name_wrapper(handler_name)); if(variable_wrapper_flag) { return; } /* Workaround to overcome Getignore(p) not working - p does not always * have the Getignore attribute set. Noticeable when cpp_func is called * from cpp_member_func() */ Wrapper *f = NewWrapper(); emit_args(NULL, l, f); DelWrapper(f); /*Workaround end */ } }; /* class PHP4 */ /* ----------------------------------------------------------------------------- * swig_php() - Instantiate module * ----------------------------------------------------------------------------- */ static PHP4 *maininstance=0; // We use this function to be able to write out zend_register_list_destructor_ex // lines for most things in the type table // NOTE: it's a function NOT A PHP4::METHOD extern "C" void typetrace(SwigType *ty, String *mangled, String *clientdata) { Node *class_node; if (!zend_types) { zend_types=NewHash(); } // we want to know if the type which reduced to this has a constructor if ((class_node=maininstance->classLookup(ty))) { if (! Getattr(zend_types,mangled)) { // OK it may have been set before by a different SwigType but it would // have had the same underlying class node I think // - it is certainly required not to have different originating class // nodes for the same SwigType Setattr(zend_types,mangled,class_node); } } else { // a non-class pointer Setattr(zend_types,mangled,NOTCLASS); } if (r_prevtracefunc) (*r_prevtracefunc)(ty, mangled, (String *) clientdata); } static Language * new_swig_php() { maininstance=new PHP4(); if (! r_prevtracefunc) { r_prevtracefunc=SwigType_remember_trace(typetrace); } else { Printf(stderr,"php4 Typetrace vector already saved!\n"); assert(0); } return maininstance; } extern "C" Language * swig_php(void) { return new_swig_php(); } cableswig-0.1.0+git20150808.orig/SWIG/Source/Modules/pike.cxx0000644000175000000620000006360612561312227022135 0ustar stevestaff/*********************************************************************** * Pike language module for SWIG * * Notes: * * - The current approach used for "out" typemaps is inconsistent with * how "out" typemaps are handled by other language modules. Instead * of converting the C/C++ type ($1) to a Pike object type (e.g. a * struct svalue), we're just calling the appropriate push_XXX * (e.g. push_int) to push the return value onto the stack. * * - Pike classes can't have static member functions or data, so we need * to find some other appropriate mapping for C++ static member functions * and data. * * - Pike doesn't seem to provide any default way to print the memory * address, etc. for extension objects. Should we do something here? * ***********************************************************************/ char cvsroot_pike_cxx[] = "/cvsroot/SWIG/Source/Modules/pike.cxx,v 1.11 2004/01/22 22:42:16 cheetah Exp"; #include "swigmod.h" #include // for isalnum() static const char *usage = (char *)"\ Pike Options (available with -pike)\n\ -ldflags - Print runtime libraries to link with\n\ \n"; class PIKE : public Language { private: File *f_runtime; File *f_header; File *f_wrappers; File *f_init; File *f_classInit; String *PrefixPlusUnderscore; int current; // Wrap modes enum { NO_CPP, MEMBER_FUNC, CONSTRUCTOR, DESTRUCTOR, MEMBER_VAR, CLASS_CONST, STATIC_FUNC, STATIC_VAR }; public: /* --------------------------------------------------------------------- * PIKE() * * Initialize member data * --------------------------------------------------------------------- */ PIKE() { f_runtime = 0; f_header = 0; f_wrappers = 0; f_init = 0; f_classInit = 0; PrefixPlusUnderscore = 0; current = NO_CPP; } /* --------------------------------------------------------------------- * main() * * Parse command line options and initializes variables. * --------------------------------------------------------------------- */ virtual void main(int argc, char *argv[]) { /* Set location of SWIG library */ SWIG_library_directory("pike"); /* Look for certain command line options */ for (int i = 1; i < argc; i++) { if (argv[i]) { if (strcmp(argv[i],"-help") == 0) { fputs(usage,stderr); } else if (strcmp (argv[i], "-ldflags") == 0) { printf("%s\n", SWIG_PIKE_RUNTIME); SWIG_exit(EXIT_SUCCESS); } } } /* Add a symbol to the parser for conditional compilation */ Preprocessor_define("SWIGPIKE 1", 0); /* Set language-specific configuration file */ SWIG_config_file("pike.swg"); /* Set typemap language */ SWIG_typemap_lang("pike"); /* Enable overloaded methods support */ allow_overloading(); } /* --------------------------------------------------------------------- * top() * --------------------------------------------------------------------- */ virtual int top(Node *n) { /* Get the module name */ String *module = Getattr(n, "name"); /* Get the output file name */ String *outfile = Getattr(n, "outfile"); /* Open the output file */ f_runtime = NewFile(outfile, "w"); if (!f_runtime) { Printf(stderr, "*** Can't open '%s'\n", outfile); SWIG_exit(EXIT_FAILURE); } f_init = NewString(""); f_classInit = NewString(""); f_header = NewString(""); f_wrappers = NewString(""); /* Register file targets with the SWIG file handler */ Swig_register_filebyname("header", f_header); Swig_register_filebyname("wrapper", f_wrappers); Swig_register_filebyname("runtime", f_runtime); Swig_register_filebyname("init", f_init); Swig_register_filebyname("classInit", f_classInit); /* Standard stuff for the SWIG runtime section */ Swig_banner(f_runtime); if (NoInclude) { Printf(f_runtime, "#define SWIG_NOINCLUDE\n"); } Printf(f_header, "#define SWIG_init pike_module_init\n"); 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"); /* Current wrap type */ current = NO_CPP; /* Emit code for children */ Language::top(n); /* Close the initialization function */ Printf(f_init, "}\n"); SwigType_emit_type_table(f_runtime, f_wrappers); /* Close all of the files */ Dump(f_header, f_runtime); Dump(f_wrappers, f_runtime); Wrapper_pretty_print(f_init, f_runtime); Delete(f_header); Delete(f_wrappers); Delete(f_init); Delete(f_classInit); Close(f_runtime); Delete(f_runtime); /* Done */ return SWIG_OK; } /* ------------------------------------------------------------ * validIdentifier() * ------------------------------------------------------------ */ virtual int validIdentifier(String *s) { char *c = Char(s); const char *c0 = c; const char *c1 = c0 + 1; while (*c) { if (*c == '`' && c == c0) { c++; continue; } if ((*c == '+' || *c == '-' || *c == '*' || *c == '/') && c == c1) { c++; continue; } if (!(isalnum(*c) || (*c == '_'))) return 0; c++; } return 1; } /* ------------------------------------------------------------ * importDirective() * ------------------------------------------------------------ */ virtual int importDirective(Node *n) { String *modname = Getattr(n,"module"); if (modname) { Printf(f_init,"pike_require(\"%s\");\n", modname); } return Language::importDirective(n); } /* ------------------------------------------------------------ * strip() * * For names that begin with the current class prefix plus an * underscore (e.g. "Foo_enum_test"), return the base function * name (i.e. "enum_test"). * ------------------------------------------------------------ */ String *strip(const DOHString_or_char *name) { String *s = Copy(name); if (Strncmp(name, PrefixPlusUnderscore, Len(PrefixPlusUnderscore)) != 0) { return s; } Replaceall(s, PrefixPlusUnderscore, ""); return s; } /* ------------------------------------------------------------ * add_method() * ------------------------------------------------------------ */ void add_method(const DOHString_or_char *name, const DOHString_or_char *function, const DOHString_or_char *description) { String *rename = NULL; switch (current) { case NO_CPP: rename = NewString(name); Printf(f_init, "ADD_FUNCTION(\"%s\", %s, tFunc(%s), 0);\n", rename, function, description); break; case STATIC_FUNC: case STATIC_VAR: rename = NewString(name); Printf(f_init, "ADD_FUNCTION(\"%s\", %s, tFunc(%s), 0);\n", rename, function, description); break; case CONSTRUCTOR: case DESTRUCTOR: case MEMBER_FUNC: case MEMBER_VAR: rename = strip(name); Printf(f_classInit, "ADD_FUNCTION(\"%s\", %s, tFunc(%s), 0);\n", rename, function, description); break; case CLASS_CONST: assert(false); // shouldn't have gotten here for CLASS_CONST nodes default: assert(false); // what is this? } Delete(rename); } /* --------------------------------------------------------------------- * functionWrapper() * * Create a function declaration and register it with the interpreter. * --------------------------------------------------------------------- */ virtual int functionWrapper(Node *n) { String *name = Getattr(n,"name"); String *iname = Getattr(n,"sym:name"); SwigType *d = Getattr(n,"type"); ParmList *l = Getattr(n,"parms"); Parm *p; String *tm; int i; String *overname = 0; if (Getattr(n,"sym:overloaded")) { overname = Getattr(n,"sym:overname"); } else { if (!addSymbol(iname,n)) return SWIG_ERROR; } Wrapper *f = NewWrapper(); /* Write code to extract function parameters. */ emit_args(d, l, f); /* Attach the standard typemaps */ emit_attach_parmmaps(l,f); Setattr(n,"wrap:parms",l); /* Get number of required and total arguments */ int num_arguments = emit_num_arguments(l); int varargs = emit_isvarargs(l); /* Which input argument to start with? */ int start = (current == MEMBER_FUNC || current == MEMBER_VAR || current == DESTRUCTOR) ? 1 : 0; /* Offset to skip over the attribute name */ // int offset = (current == MEMBER_VAR) ? 1 : 0; int offset = 0; String *wname = Swig_name_wrapper(iname); if (overname) { Append(wname,overname); } Printv(f->def, "static void ", wname, "(INT32 args) {", NIL); /* Generate code for argument marshalling */ String *description = NewString(""); char source[64]; for (i = 0, p = l; i < num_arguments; i++) { while (checkAttribute(p,"tmap:in:numinputs","0")) { p = Getattr(p,"tmap:in:next"); } SwigType *pt = Getattr(p,"type"); String *ln = Getattr(p,"lname"); if (i < start) { String *lstr = SwigType_lstr(pt,0); Printf(f->code, "%s = (%s) THIS;\n", ln, lstr); Delete(lstr); } else { /* Look for an input typemap */ sprintf(source, "Pike_sp[%d-args]", i-start+offset); if ((tm = Getattr(p,"tmap:in"))) { Replaceall(tm, "$source", source); Replaceall(tm, "$target", ln); Replaceall(tm, "$input", source); Setattr(p, "emit:input", source); Printf(f->code, "%s\n", tm); String *pikedesc = Getattr(p, "tmap:in:pikedesc"); if (pikedesc) { Printv(description, pikedesc, " ", NIL); } p = Getattr(p,"tmap:in:next"); continue; } else { Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n",SwigType_str(pt,0)); break; } } p = nextSibling(p); } /* Check for trailing varargs */ if (varargs) { if (p && (tm = Getattr(p,"tmap:in"))) { Replaceall(tm,"$input", "varargs"); Printv(f->code,tm,"\n",NIL); } } /* Insert constraint checking code */ for (p = l; p;) { if ((tm = Getattr(p,"tmap:check"))) { Replaceall(tm,"$target",Getattr(p,"lname")); Printv(f->code,tm,"\n",NIL); p = Getattr(p,"tmap:check:next"); } else { p = nextSibling(p); } } /* Insert cleanup code */ String *cleanup = NewString(""); for (p = l; p;) { if ((tm = Getattr(p,"tmap:freearg"))) { Replaceall(tm,"$source",Getattr(p,"lname")); Printv(cleanup,tm,"\n",NIL); p = Getattr(p,"tmap:freearg:next"); } else { p = nextSibling(p); } } /* Insert argument output code */ String *outarg = NewString(""); for (p = l; p;) { if ((tm = Getattr(p,"tmap:argout"))) { Replaceall(tm,"$source",Getattr(p,"lname")); Replaceall(tm,"$target","resultobj"); Replaceall(tm,"$arg",Getattr(p,"emit:input")); Replaceall(tm,"$input",Getattr(p,"emit:input")); Printv(outarg,tm,"\n",NIL); p = Getattr(p,"tmap:argout:next"); } else { p = nextSibling(p); } } /* Emit the function call */ emit_action(n,f); /* Clear the return stack */ Printf(f->code, "pop_n_elems(args);\n"); /* Return the function value */ if (current == CONSTRUCTOR) { Printv(f->code, "THIS = (void *) result;\n", NIL); Printv(description, ", tVoid", NIL); } else if (current == DESTRUCTOR) { Printv(description, ", tVoid", NIL); } else { // Wrapper_add_local(f, "resultobj", "struct object *resultobj"); Printv(description, ", ", NIL); if ((tm = Swig_typemap_lookup_new("out",n,"result",0))) { Replaceall(tm,"$source", "result"); Replaceall(tm,"$target", "resultobj"); Replaceall(tm,"$result", "resultobj"); if (Getattr(n,"feature:new")) { Replaceall(tm,"$owner","1"); } else { Replaceall(tm,"$owner","0"); } String *pikedesc = Getattr(n, "tmap:out:pikedesc"); if (pikedesc) { Printv(description, pikedesc, NIL); } Printf(f->code,"%s\n", tm); } else { Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d,0), name); } } /* Output argument output code */ Printv(f->code,outarg,NIL); /* Output cleanup code */ Printv(f->code,cleanup,NIL); /* Look to see if there is any newfree cleanup code */ if (Getattr(n,"feature:new")) { if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) { Replaceall(tm,"$source","result"); Printf(f->code,"%s\n",tm); } } /* See if there is any return cleanup code */ if ((tm = Swig_typemap_lookup_new("ret", n, "result", 0))) { Replaceall(tm,"$source","result"); Printf(f->code,"%s\n",tm); } /* Close the function */ Printf(f->code, "}\n"); /* Substitute the cleanup code */ Replaceall(f->code,"$cleanup",cleanup); /* Substitute the function name */ Replaceall(f->code,"$symname",iname); Replaceall(f->code,"$result","resultobj"); /* Dump the function out */ Wrapper_print(f,f_wrappers); /* Now register the function with the interpreter. */ if (!Getattr(n,"sym:overloaded")) { add_method(iname, wname, description); } else { Setattr(n,"wrap:name", wname); if (!Getattr(n,"sym:nextSibling")) { dispatchFunction(n); } } Delete(cleanup); Delete(outarg); Delete(description); Delete(wname); DelWrapper(f); return SWIG_OK; } /* ------------------------------------------------------------ * dispatchFunction() * * Emit overloading dispatch function * ------------------------------------------------------------ */ void dispatchFunction(Node *n) { /* Last node in overloaded chain */ int maxargs; String *tmp = NewString(""); String *dispatch = Swig_overload_dispatch(n, "%s(args); return;", &maxargs); /* Generate a dispatch wrapper for all overloaded functions */ Wrapper *f = NewWrapper(); String *symname = Getattr(n,"sym:name"); String *wname = Swig_name_wrapper(symname); Printf(f->def, "static void %s(INT32 args) {", wname); Wrapper_add_local(f, "argc", "INT32 argc"); Printf(tmp, "struct svalue argv[%d]", maxargs); Wrapper_add_local(f, "argv", tmp); Wrapper_add_local(f, "ii", "INT32 ii"); Printf(f->code, "argc = args;\n"); Printf(f->code, "for (ii = 0; (ii < argc) && (ii < %d); ii++) {\n", maxargs); Printf(f->code, "argv[ii] = Pike_sp[ii-args];\n"); Printf(f->code, "}\n"); Replaceall(dispatch, "$args", "self, args"); Printv(f->code, dispatch, "\n", NIL); Printf(f->code, "Pike_error(\"No matching function for overloaded '%s'.\");\n", symname); Printv(f->code, "}\n", NIL); Wrapper_print(f, f_wrappers); String *description = NewString(""); Printf(description, "tAny,"); if (current == CONSTRUCTOR || current == DESTRUCTOR) { Printf(description, " tVoid"); } else { String *pd = Getattr(n, "tmap:out:pikedesc"); if (pd) Printf(description, " %s", pd); } add_method(symname, wname, description); Delete(description); DelWrapper(f); Delete(dispatch); Delete(tmp); Delete(wname); } /* ------------------------------------------------------------ * variableWrapper() * ------------------------------------------------------------ */ virtual int variableWrapper(Node *n) { return Language::variableWrapper(n); } /* ------------------------------------------------------------ * constantWrapper() * ------------------------------------------------------------ */ virtual int constantWrapper(Node *n) { Swig_require("constantWrapper",n, "*sym:name", "type", "value", NIL); String *symname = Getattr(n, "sym:name"); SwigType *type = Getattr(n, "type"); String *value = Getattr(n, "value"); /* Special hook for member pointer */ if (SwigType_type(type) == T_MPOINTER) { String *wname = Swig_name_wrapper(symname); Printf(f_header, "static %s = %s;\n", SwigType_str(type, wname), value); value = wname; } /* Perform constant typemap substitution */ String *tm = Swig_typemap_lookup_new("constant", n, value, 0); if (tm) { Replaceall(tm, "$source", value); Replaceall(tm, "$target", symname); Replaceall(tm, "$symname", symname); Replaceall(tm, "$value", value); Printf(f_init, "%s\n", tm); } else { Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value %s = %s\n", SwigType_str(type, 0), value); } Swig_restore(n); return SWIG_OK; } /* ------------------------------------------------------------ * nativeWrapper() * ------------------------------------------------------------ */ virtual int nativeWrapper(Node *n) { // return Language::nativeWrapper(n); String *name = Getattr(n,"sym:name"); String *wrapname = Getattr(n,"wrap:name"); if (!addSymbol(wrapname,n)) return SWIG_ERROR; add_method(name, wrapname,0); return SWIG_OK; } /* ------------------------------------------------------------ * enumDeclaration() * ------------------------------------------------------------ */ virtual int enumDeclaration(Node *n) { return Language::enumDeclaration(n); } /* ------------------------------------------------------------ * enumvalueDeclaration() * ------------------------------------------------------------ */ virtual int enumvalueDeclaration(Node *n) { return Language::enumvalueDeclaration(n); } /* ------------------------------------------------------------ * classDeclaration() * ------------------------------------------------------------ */ virtual int classDeclaration(Node *n) { return Language::classDeclaration(n); } /* ------------------------------------------------------------ * classHandler() * ------------------------------------------------------------ */ virtual int classHandler(Node *n) { String *symname = Getattr(n, "sym:name"); if (!addSymbol(symname, n)) return SWIG_ERROR; PrefixPlusUnderscore = NewStringf("%s_", getClassPrefix()); Printf(f_classInit, "start_new_program();\n"); /* Handle inheritance */ List *baselist = Getattr(n,"bases"); if (baselist && Len(baselist) > 0) { Iterator base = First(baselist); while (base.item) { String *basename = Getattr(base.item,"name"); SwigType *basetype = NewString(basename); SwigType_add_pointer(basetype); SwigType_remember(basetype); String *basemangle = SwigType_manglestr(basetype); Printf(f_classInit, "low_inherit((struct program *) SWIGTYPE%s->clientdata, 0, 0, 0, 0, 0);\n", basemangle); Delete(basemangle); Delete(basetype); base = Next(base); } } else { Printf(f_classInit, "ADD_STORAGE(swig_object_wrapper);\n"); } Language::classHandler(n); /* Accessors for member variables */ /* List *membervariables = Getattr(n,"membervariables"); if (membervariables && Len(membervariables) > 0) { membervariableAccessors(membervariables); } */ /* Done, close the class and dump its definition to the init function */ Printf(f_classInit, "add_program_constant(\"%s\", pr = end_program(), 0);\n", symname); Dump(f_classInit, f_init); Clear(f_classInit); SwigType *tt = NewString(symname); SwigType_add_pointer(tt); SwigType_remember(tt); String *tm = SwigType_manglestr(tt); Printf(f_init, "SWIG_TypeClientData(SWIGTYPE%s, (void *) pr);\n", tm); Delete(tm); Delete(tt); Delete(PrefixPlusUnderscore); PrefixPlusUnderscore = 0; return SWIG_OK; } /* ------------------------------------------------------------ * memberfunctionHandler() * * Method for adding C++ member function * ------------------------------------------------------------ */ virtual int memberfunctionHandler(Node *n) { current = MEMBER_FUNC; Language::memberfunctionHandler(n); current = NO_CPP; return SWIG_OK; } /* ------------------------------------------------------------ * constructorHandler() * * Method for adding C++ member constructor * ------------------------------------------------------------ */ virtual int constructorHandler(Node *n) { current = CONSTRUCTOR; Language::constructorHandler(n); current = NO_CPP; return SWIG_OK; } /* ------------------------------------------------------------ * destructorHandler() * ------------------------------------------------------------ */ virtual int destructorHandler(Node *n) { current = DESTRUCTOR; Language::destructorHandler(n); current = NO_CPP; return SWIG_OK; } /* ------------------------------------------------------------ * membervariableAccessors() * ------------------------------------------------------------ */ void membervariableAccessors(List *membervariables) { String *name; Iterator i; bool need_setter; String *funcname; /* If at least one of them is mutable, we need a setter */ need_setter = false; i = First(membervariables); while (i.item) { if (!Getattr(i.item, "feature:immutable")) { need_setter = true; break; } i = Next(i); } /* Create a function to set the values of the (mutable) variables */ if (need_setter) { Wrapper *wrapper = NewWrapper(); String *setter = Swig_name_member(getClassPrefix(), (char *) "`->="); 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"); i = First(membervariables); while (i.item) { if (!Getattr(i.item, "feature:immutable")) { name = Getattr(i.item, "name"); funcname = Swig_name_wrapper(Swig_name_set(Swig_name_member(getClassPrefix(), name))); Printf(wrapper->code, "if (!strcmp(name, \"%s\")) {\n", name); Printf(wrapper->code, "%s(args);\n", funcname); Printf(wrapper->code, "return;\n"); Printf(wrapper->code, "}\n"); Delete(funcname); } i = Next(i); } /* Close the function */ Printf(wrapper->code, "pop_n_elems(args);\n"); Printf(wrapper->code, "}\n"); /* Dump wrapper code to the output file */ Wrapper_print(wrapper, f_wrappers); /* Register it with Pike */ String *description = NewString("tStr tFloat, tVoid"); add_method("`->=", wname, description); Delete(description); /* Clean up */ Delete(wname); Delete(setter); DelWrapper(wrapper); } /* Create a function to get the values of the (mutable) variables */ Wrapper *wrapper = NewWrapper(); String *getter = Swig_name_member(getClassPrefix(), (char *) "`->"); 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"); i = First(membervariables); while (i.item) { name = Getattr(i.item, "name"); funcname = Swig_name_wrapper(Swig_name_get(Swig_name_member(getClassPrefix(), name))); Printf(wrapper->code, "if (!strcmp(name, \"%s\")) {\n", name); Printf(wrapper->code, "%s(args);\n", funcname); Printf(wrapper->code, "return;\n"); Printf(wrapper->code, "}\n"); Delete(funcname); i = Next(i); } /* Close the function */ Printf(wrapper->code, "pop_n_elems(args);\n"); Printf(wrapper->code, "}\n"); /* Dump wrapper code to the output file */ Wrapper_print(wrapper, f_wrappers); /* Register it with Pike */ String *description = NewString("tStr, tMix"); add_method("`->", wname, description); Delete(description); /* Clean up */ Delete(wname); Delete(getter); DelWrapper(wrapper); } /* ------------------------------------------------------------ * membervariableHandler() * ------------------------------------------------------------ */ virtual int membervariableHandler(Node *n) { List *membervariables = Getattr(getCurrentClass(),"membervariables"); if (!membervariables) { membervariables = NewList(); Setattr(getCurrentClass(),"membervariables",membervariables); } Append(membervariables,n); current = MEMBER_VAR; Language::membervariableHandler(n); current = NO_CPP; return SWIG_OK; } /* ----------------------------------------------------------------------- * staticmemberfunctionHandler() * * Wrap a static C++ function * ---------------------------------------------------------------------- */ virtual int staticmemberfunctionHandler(Node *n) { current = STATIC_FUNC; Language::staticmemberfunctionHandler(n); current = NO_CPP; return SWIG_OK; } /* ------------------------------------------------------------ * memberconstantHandler() * * Create a C++ constant * ------------------------------------------------------------ */ virtual int memberconstantHandler(Node *n) { current = CLASS_CONST; constantWrapper(n); current = NO_CPP; return SWIG_OK; } /* --------------------------------------------------------------------- * staticmembervariableHandler() * --------------------------------------------------------------------- */ virtual int staticmembervariableHandler(Node *n) { current = STATIC_VAR; Language::staticmembervariableHandler(n); current = NO_CPP; return SWIG_OK; } }; /* ----------------------------------------------------------------------------- * swig_pike() - Instantiate module * ----------------------------------------------------------------------------- */ static Language * new_swig_pike() { return new PIKE(); } extern "C" Language * swig_pike(void) { return new_swig_pike(); } cableswig-0.1.0+git20150808.orig/SWIG/Source/Modules/browser.cxx0000644000175000000620000002553612561312227022670 0ustar stevestaff/* ----------------------------------------------------------------------------- * browser.cxx * * A web-base parse tree browser using SWILL. This is an optional * feature that's normally disabled. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 2002. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_browser_cxx[] = "/cvsroot/SWIG/Source/Modules/browser.cxx,v 1.6 2004/01/22 22:42:14 cheetah Exp"; #include "swigmod.h" #ifdef SWIG_SWILL extern "C" { #include "swill.h" } static FILE *out = 0; static Node *view_top = 0; class Browser : public Dispatcher { void show_checkbox(Node *t, Node *n) { int v = 0; if (Getmeta(n,"visible")) { v = 1; } if (v) { Printf(out,"[-] ", n, t, n,n); } else { Printf(out,"[+] ", n, t, n,n); } } void show_attributes(Node *obj) { if (!Getmeta(obj,"visible")) return; String *os = NewString(""); String *k; Iterator ki; ki = First(obj); while (ki.key) { k = ki.key; if ((Cmp(k,"nodeType") == 0) || (Cmp(k,"firstChild") == 0) || (Cmp(k,"lastChild") == 0) || (Cmp(k,"parentNode") == 0) || (Cmp(k,"nextSibling") == 0) || (Cmp(k,"previousSibling") == 0) || (*(Char(k)) == '$')) { /* Do nothing */ } else if (Cmp(k,"parms") == 0) { String *o = NewString(""); Printf(o,"%s", ParmList_protostr(Getattr(obj,k))); Replaceall(o,"&","&"); Replaceall(o,"<","<"); Replaceall(o,">",">"); Printf(os,"? %-12s - %s\n", Getattr(obj,k), k, o); Delete(o); } else { DOH *o; char *trunc = ""; if (DohIsString(Getattr(obj,k))) { o = Str(Getattr(obj,k)); if (Len(o) > 70) { trunc = "..."; } Replaceall(o,"&","&"); Replaceall(o,"<","<"); Printf(os,"? %-12s - \"%(escape)-0.70s%s\"\n", Getattr(obj,k), k, o, trunc); Delete(o); } else { Printf(os,"? %-12s - 0x%x\n", Getattr(obj,k), k, Getattr(obj,k)); } } ki = Next(ki); } Printf(out,"
\n%s
\n", Char(os)); Delete(os); } public: virtual int emit_one(Node *n) { char *tag = Char(nodeType(n)); char *file = Char(Getfile(n)); int line = Getline(n); char *name = GetChar(n,"name"); show_checkbox(view_top, n); Printf(out,"%s", n, tag); if (name) { Printf(out," (%s)", name); } Printf(out,". %s:%d\n", file, line); Printf(out,"
"); Dispatcher::emit_one(n); return SWIG_OK; } virtual int emit_children(Node *n) { if (Getmeta(n,"visible")) { Printf(out,"
\n"); Dispatcher::emit_children(n); Printf(out,"
\n"); } return SWIG_OK; } virtual int defaultHandler(Node *n) { show_attributes(n); return SWIG_OK; } virtual int top(Node *n) { show_attributes(n); emit_children(n); return SWIG_OK; } virtual int includeDirective(Node *n) { show_attributes(n); emit_children(n); return SWIG_OK; } virtual int importDirective(Node *n) { show_attributes(n); emit_children(n); return SWIG_OK; } virtual int extendDirective(Node *n) { show_attributes(n); emit_children(n); return SWIG_OK; } virtual int classDeclaration(Node *n) { show_attributes(n); emit_children(n); return SWIG_OK; } virtual int templateDeclaration(Node *n) { show_attributes(n); emit_children(n); return SWIG_OK; } virtual int enumDeclaration(Node *n) { show_attributes(n); emit_children(n); return SWIG_OK; } virtual int typemapDirective(Node *n) { show_attributes(n); emit_children(n); return SWIG_OK; } virtual int namespaceDeclaration(Node *n) { show_attributes(n); emit_children(n); return SWIG_OK; } virtual int usingDeclaration(Node *n) { show_attributes(n); emit_children(n); return SWIG_OK; } }; static int browser_exit = 0; static Node *tree_top = 0; static Browser *browse = 0; /* ---------------------------------------------------------------------- * exit_handler() - Force the browser to exit * ---------------------------------------------------------------------- */ void exit_handler(FILE *f) { browser_exit = 1; Printf(f,"Terminated.\n"); } /* ---------------------------------------------------------------------- * node_handler() - Generate information about a specific node * ---------------------------------------------------------------------- */ static void display(FILE *f, Node *n) { /* Print standard HTML header */ Printf(f,"SWIG-%s\n", PACKAGE_VERSION); Printf(f,"SWIG-%s
\n", PACKAGE_VERSION); Printf(f,"[ Exit ]"); Printf(f," [ Top ]", tree_top); if (n != tree_top) { Printf(f," [ Up ]", parentNode(n)); } Printf(f," [ Symbols ]"); Printf(f,"

\n"); out = f; browse->emit_one(n); /* Print standard footer */ Printf(f,"


\n"); } void node_handler(FILE *f) { Node *n = 0; if (!swill_getargs("p(node)", &n)) { n = tree_top; } view_top = n; display(f,n); } /* ---------------------------------------------------------------------- * hide_handler() - Hide a node * ---------------------------------------------------------------------- */ void hide_handler(FILE *f) { Node *n = 0; if (!swill_getargs("p(hn)", &n)) { n = 0; } if (n) { Delmeta(n,"visible"); } node_handler(f); } void show_handler(FILE *f) { Node *n = 0; if (!swill_getargs("p(hn)", &n)) { n = 0; } if (n) { Setmeta(n,"visible","1"); } node_handler(f); } void raw_data(FILE *out, Node *obj) { if (!obj) return; if (DohIsMapping(obj)) { String *k; Iterator ki; String *os = NewString(""); Printf(os,"Hash {\n"); ki = First(obj); while (ki.key) { k = ki.key; DOH *o; const char *trunc = ""; if (DohIsString(Getattr(obj,k))) { o = Str(Getattr(obj,k)); if (Len(o) > 70) { trunc = "..."; } Replaceall(o,"<","<"); Printf(os," ? %-12s - \"%(escape)-0.70s%s\"\n", Getattr(obj,k), k, o, trunc); Delete(o); } else { Printf(os," ? %-12s - 0x%x\n", Getattr(obj,k), k, Getattr(obj,k)); } ki = Next(ki); } Printf(os,"}\n"); Printf(out,"
\n%s
\n", Char(os)); Delete(os); } else if (DohIsString(obj)) { String *o = Str(obj); Replaceall(o,"<","<"); Printf(out,"
\n%s
\n", Char(o)); Delete(o); } else if (DohIsSequence(obj)) { int i; String *os = NewString(""); Printf(os,"List [\n"); for (i = 0; i < Len(obj); i++) { DOH *o = Getitem(obj,i); const char *trunc = ""; if (DohIsString(o)) { String *s = Str(o); if (Len(s) > 70) { trunc = "..."; } Replaceall(o,"<","<"); Printf(os," ? [%d] - \"%(escape)-0.70s%s\"\n", o,i,s, trunc); Delete(s); } else { Printf(os," ? [%d] - 0x%x\n", o, i, o); } } Printf(os,"\n]\n"); Printf(out,"
\n%s
\n", Char(os)); Delete(os); } } void data_handler(FILE *f) { DOH *n = 0; if (!swill_getargs("p(n)", &n)) { n = 0; } Printf(f,"SWIG-%s\n", PACKAGE_VERSION); Printf(f,"SWIG-%s
\n", PACKAGE_VERSION); Printf(f,"[ Exit ]"); Printf(f," [ Top ]", tree_top); Printf(f,"

\n"); if (n) { raw_data(f,n); } /* Print standard footer */ Printf(f,"


\n"); } void symbol_handler(FILE *f) { Symtab *sym; char *name = 0; Printf(f,"SWIG-%s\n", PACKAGE_VERSION); Printf(f,"SWIG-%s
\n", PACKAGE_VERSION); Printf(f,"[ Exit ]"); Printf(f," [ Top ]", tree_top); Printf(f," [ Symbols ]"); Printf(f,"

\n"); if (!swill_getargs("p(sym)|s(name)", &sym, &name)) { sym = Swig_symbol_getscope(""); name = 0; } if (!sym) { Printf(f,"No symbol table specified!\n"); return; } { String *q = Swig_symbol_qualifiedscopename(sym); if (!Len(q)) { Printf(f,"Symbol table: :: (global)
\n"); } else { Printf(f,"Symbol table: %s
\n", q); } Delete(q); } fprintf(f,"

\n"); fprintf(f,"Symbol lookup:
\n"); fprintf(f,"\n", sym); fprintf(f,"Submit : \n"); fprintf(f,"
"); if (name) { Node *n = Swig_symbol_clookup(name,sym); Printf(f,"Symbol '%s':\n", name); Printf(f,"
\n"); if (!n) { Printf(f,"Not defined!\n"); } else { raw_data(f,n); } Printf(f,"
\n"); } Printf(f,"

Nested scopes
\n"); Printf(f,"

\n");
  {
    Hash   *h;
    h = firstChild(sym);
    while (h) {
      Printf(f,"%s\n", h, Getattr(h,"name"));
      h = nextSibling(h);
    }
  }
  Printf(f,"
\n"); Printf(f,"

Symbol table contents
\n"); raw_data(f,Getattr(sym,"symtab")); Printf(f,"


\n"); } #endif void Swig_browser(Node *top, int port) { #ifdef SWIG_SWILL int sport; browser_exit = 0; /* Initialize the server */ sport = swill_init(port); if (sport < 0) { Printf(stderr,"Couldn't open socket on port %d. Sorry.\n", port); return; } browse = new Browser(); Setmeta(top,"visible","1"); tree_top = top; Printf(stderr,"SWIG: Tree browser listening on port %d\n", sport); swill_handle("exit.html", exit_handler,0); swill_handle("index.html", node_handler, 0); swill_handle("hide.html", hide_handler,0); swill_handle("show.html", show_handler,0); swill_handle("data.html", data_handler,0); swill_handle("symbol.html", symbol_handler, 0); swill_netscape("index.html"); while (!browser_exit) { swill_serve(); } Printf(stderr,"Browser terminated.\n"); swill_close(); delete browse; return; #else (void)top; (void)port; #endif } cableswig-0.1.0+git20150808.orig/SWIG/Source/Modules/overload.cxx0000644000175000000620000003456712561312227023024 0ustar stevestaff/* ----------------------------------------------------------------------------- * overload.cxx * * This file is used to analyze overloaded functions and methods. * It looks at signatures and tries to gather information for * building a dispatch function. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_overload_cxx[] = "/cvsroot/SWIG/Source/Modules/overload.cxx,v 1.6 2004/02/12 21:48:55 cheetah Exp"; #include "swigmod.h" #define MAX_OVERLOAD 256 /* Overload "argc" and "argv" */ String *argv_template_string; String *argc_template_string; struct Overloaded { Node *n; /* Node */ int argc; /* Argument count */ ParmList *parms; /* Parameters used for overload check */ int error; /* Ambiguity error */ }; /* ----------------------------------------------------------------------------- * Swig_overload_rank() * * This function takes an overloaded declaration and creates a list that ranks * all overloaded methods in an order that can be used to generate a dispatch * function. * Slight difference in the way this function is used by scripting languages and * statically typed languages. The script languages call this method via * Swig_overload_dispatch() - where wrappers for all overloaded methods are generated, * however sometimes the code can never be executed. The non-scripting languages * call this method via Swig_overload_check() for each overloaded method in order * to determine whether or not the method should be wrapped. Note the slight * difference when overloading methods that differ by const only. The * scripting languages will ignore the const method, whereas the non-scripting * languages ignore the first method parsed. * ----------------------------------------------------------------------------- */ static List * Swig_overload_rank(Node *n, bool script_lang_wrapping) { Overloaded nodes[MAX_OVERLOAD]; int nnodes = 0; Node *o = Getattr(n,"sym:overloaded"); Node *c; if (!o) return 0; c = o; while (c) { if (Getattr(c,"error")) { c = Getattr(c,"sym:nextSibling"); continue; } /* if (SmartPointer && Getattr(c,"cplus:staticbase")) { c = Getattr(c,"sym:nextSibling"); continue; } */ if (Getattr(c,"wrap:name")) { nodes[nnodes].n = c; nodes[nnodes].parms = Getattr(c,"wrap:parms"); nodes[nnodes].argc = emit_num_required(nodes[nnodes].parms); nodes[nnodes].error = 0; nnodes++; } c = Getattr(c,"sym:nextSibling"); } /* Sort the declarations by required argument count */ { int i,j; for (i = 0; i < nnodes; i++) { for (j = i+1; j < nnodes; j++) { if (nodes[i].argc > nodes[j].argc) { Overloaded t = nodes[i]; nodes[i] = nodes[j]; nodes[j] = t; } } } } /* Sort the declarations by argument types */ { int i,j; for (i = 0; i < nnodes-1; i++) { if (nodes[i].argc == nodes[i+1].argc) { for (j = i+1; (j < nnodes) && (nodes[j].argc == nodes[i].argc); j++) { Parm *p1 = nodes[i].parms; Parm *p2 = nodes[j].parms; int differ = 0; int num_checked = 0; while (p1 && p2 && (num_checked < nodes[i].argc)) { // Printf(stdout,"p1 = '%s', p2 = '%s'\n", Getattr(p1,"type"), Getattr(p2,"type")); if (checkAttribute(p1,"tmap:in:numinputs","0")) { p1 = Getattr(p1,"tmap:in:next"); continue; } if (checkAttribute(p2,"tmap:in:numinputs","0")) { p2 = Getattr(p2,"tmap:in:next"); continue; } String *t1 = Getattr(p1,"tmap:typecheck:precedence"); String *t2 = Getattr(p2,"tmap:typecheck:precedence"); if ((!t1) && (!nodes[i].error)) { Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[i].n), Getline(nodes[i].n), "Overloaded %s(%s) not supported (no type checking rule for '%s').\n", Getattr(nodes[i].n,"name"),ParmList_str(Getattr(nodes[i].n,"parms")), SwigType_str(Getattr(p1,"type"),0)); nodes[i].error = 1; } else if ((!t2) && (!nodes[j].error)) { Swig_warning(WARN_TYPEMAP_TYPECHECK, Getfile(nodes[j].n), Getline(nodes[j].n), "Overloaded %s(%s) not supported (no type checking rule for '%s').\n", Getattr(nodes[j].n,"name"),ParmList_str(Getattr(nodes[j].n,"parms")), SwigType_str(Getattr(p2,"type"),0)); nodes[j].error = 1; } if (t1 && t2) { int t1v, t2v; t1v = atoi(Char(t1)); t2v = atoi(Char(t2)); differ = t1v-t2v; } else if (!t1 && t2) differ = 1; else if (t2 && !t1) differ = -1; else if (!t1 && !t2) differ = -1; num_checked++; if (differ > 0) { Overloaded t = nodes[i]; nodes[i] = nodes[j]; nodes[j] = t; break; } else if ((differ == 0) && (Strcmp(t1,"0") == 0)) { t1 = Getattr(p1,"ltype"); if (!t1) { t1 = SwigType_ltype(Getattr(p1,"type")); if (Getattr(p1,"tmap:typecheck:SWIGTYPE")) { SwigType_add_pointer(t1); } Setattr(p1,"ltype",t1); } t2 = Getattr(p2,"ltype"); if (!t2) { t2 = SwigType_ltype(Getattr(p2,"type")); if (Getattr(p2,"tmap:typecheck:SWIGTYPE")) { SwigType_add_pointer(t2); } Setattr(p2,"ltype",t2); } /* Need subtype check here. If t2 is a subtype of t1, then we need to change the order */ if (SwigType_issubtype(t2,t1)) { Overloaded t = nodes[i]; nodes[i] = nodes[j]; nodes[j] = t; } if (Strcmp(t1,t2) != 0) { differ = 1; break; } } else if (differ) { break; } if (Getattr(p1,"tmap:in:next")) { p1 = Getattr(p1,"tmap:in:next"); } else { p1 = nextSibling(p1); } if (Getattr(p2,"tmap:in:next")) { p2 = Getattr(p2,"tmap:in:next"); } else { p2 = nextSibling(p2); } } if (!differ) { /* See if declarations differ by const only */ String *d1 = Getattr(nodes[i].n,"decl"); String *d2 = Getattr(nodes[j].n,"decl"); if (d1 && d2) { String *dq1 = Copy(d1); String *dq2 = Copy(d2); if (SwigType_isconst(d1)) { SwigType_pop(dq1); } if (SwigType_isconst(d2)) { SwigType_pop(dq2); } if (Strcmp(dq1,dq2) == 0) { if (SwigType_isconst(d1) && !SwigType_isconst(d2)) { if (script_lang_wrapping) { // Swap nodes so that the const method gets ignored (shadowed by the non-const method) Overloaded t = nodes[i]; nodes[i] = nodes[j]; nodes[j] = t; } differ = 1; if (!nodes[j].error) { if (script_lang_wrapping) { Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n), "Overloaded %s(%s) const ignored. Non-const method at %s:%d used.\n", Getattr(nodes[j].n,"name"), ParmList_protostr(nodes[j].parms), Getfile(nodes[i].n), Getline(nodes[i].n)); } else { if (!Getattr(nodes[j].n, "overload:ignore")) Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), "Overloaded method %s(%s) ignored. Method %s(%s) const at %s:%d used.\n", Getattr(nodes[j].n,"name"), ParmList_protostr(nodes[j].parms), Getattr(nodes[i].n,"name"), ParmList_protostr(nodes[i].parms), Getfile(nodes[i].n), Getline(nodes[i].n)); } } nodes[j].error = 1; } else if (!SwigType_isconst(d1) && SwigType_isconst(d2)) { differ = 1; if (!nodes[j].error) { if (script_lang_wrapping) { Swig_warning(WARN_LANG_OVERLOAD_CONST, Getfile(nodes[j].n), Getline(nodes[j].n), "Overloaded %s(%s) const ignored. Non-const method at %s:%d used.\n", Getattr(nodes[j].n,"name"), ParmList_protostr(nodes[j].parms), Getfile(nodes[i].n), Getline(nodes[i].n)); } else { if (!Getattr(nodes[j].n, "overload:ignore")) Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), "Overloaded method %s(%s) const ignored. Method %s(%s) at %s:%d used.\n", Getattr(nodes[j].n,"name"), ParmList_protostr(nodes[j].parms), Getattr(nodes[i].n,"name"), ParmList_protostr(nodes[i].parms), Getfile(nodes[i].n), Getline(nodes[i].n)); } } nodes[j].error = 1; } } Delete(dq1); Delete(dq2); } } if (!differ) { if (!nodes[j].error) { if (script_lang_wrapping) { Swig_warning(WARN_LANG_OVERLOAD_SHADOW, Getfile(nodes[j].n), Getline(nodes[j].n), "Overloaded %s(%s)%s is shadowed by %s(%s)%s at %s:%d.\n", Getattr(nodes[j].n,"name"), ParmList_protostr(nodes[j].parms), SwigType_isconst(Getattr(nodes[j].n,"decl")) ? " const" : "", Getattr(nodes[i].n,"name"), ParmList_protostr(nodes[i].parms), SwigType_isconst(Getattr(nodes[i].n,"decl")) ? " const" : "", Getfile(nodes[i].n),Getline(nodes[i].n)); } else { if (!Getattr(nodes[j].n, "overload:ignore")) Swig_warning(WARN_LANG_OVERLOAD_IGNORED, Getfile(nodes[j].n), Getline(nodes[j].n), "Overloaded method %s(%s)%s ignored. Method %s(%s)%s at %s:%d used.\n", Getattr(nodes[j].n,"name"), ParmList_protostr(nodes[j].parms), SwigType_isconst(Getattr(nodes[j].n,"decl")) ? " const" : "", Getattr(nodes[i].n,"name"), ParmList_protostr(nodes[i].parms), SwigType_isconst(Getattr(nodes[i].n,"decl")) ? " const" : "", Getfile(nodes[i].n),Getline(nodes[i].n)); } nodes[j].error = 1; } } } } } } List *result = NewList(); { int i; for (i = 0; i < nnodes; i++) { if (nodes[i].error) Setattr(nodes[i].n, "overload:ignore", "1"); Append(result,nodes[i].n); // Printf(stdout,"[ %d ] %s\n", i, ParmList_protostr(nodes[i].parms)); // Swig_print_node(nodes[i].n); } } return result; } /* ----------------------------------------------------------------------------- * print_typecheck() * ----------------------------------------------------------------------------- */ static bool print_typecheck(String *f, int j, Parm *pj) { char tmp[256]; sprintf(tmp,Char(argv_template_string),j); String *tm = Getattr(pj,"tmap:typecheck"); if (tm) { Replaceid(tm,Getattr(pj,"lname"),"_v"); Replaceall(tm,"$input", tmp); Printv(f,tm,"\n",NIL); return true; } else return false; } /* ----------------------------------------------------------------------------- * ReplaceFormat() * ----------------------------------------------------------------------------- */ static String * ReplaceFormat (const String_or_char *fmt, int j) { String *lfmt = NewString (fmt); char buf[50]; sprintf (buf, "%d", j); Replaceall (lfmt, "$numargs", buf); int i; String *commaargs = NewString (""); for (i=0; i < j; i++) { Printv (commaargs, ", ", NIL); Printf (commaargs, Char(argv_template_string), i); } Replaceall (lfmt, "$commaargs", commaargs); return lfmt; }; /* ----------------------------------------------------------------------------- * Swig_overload_dispatch() * * Generate a dispatch function. argc is assumed to hold the argument count. * argv is the argument vector. * * Note that for C++ class member functions, Swig_overload_dispatch() assumes * that argc includes the "self" argument and that the first element of argv[] * is the "self" argument. So for a member function: * * Foo::bar(int x, int y, int z); * * the argc should be 4 (not 3!) and the first element of argv[] would be * the appropriate scripting language reference to "self". For regular * functions (and static class functions) the argc and argv only include * the regular function arguments. * ----------------------------------------------------------------------------- */ String * Swig_overload_dispatch(Node *n, const String_or_char *fmt, int *maxargs) { int i,j; *maxargs = 1; String *f = NewString(""); /* Get a list of methods ranked by precedence values and argument count */ List *dispatch = Swig_overload_rank(n, true); int nfunc = Len(dispatch); /* Loop over the functions */ for (i = 0; i < nfunc; i++) { Node *ni = Getitem(dispatch,i); Parm *pi = Getattr(ni,"wrap:parms"); int num_required = emit_num_required(pi); int num_arguments = emit_num_arguments(pi); if (num_arguments > *maxargs) *maxargs = num_arguments; int varargs = emit_isvarargs(pi); if (!varargs) { if (num_required == num_arguments) { Printf(f,"if (%s == %d) {\n", argc_template_string, num_required); } else { Printf(f,"if ((%s >= %d) && (%s <= %d)) {\n", argc_template_string, num_required, argc_template_string, num_arguments); } } else { Printf(f,"if (%s >= %d) {\n", argc_template_string, num_required); } if (num_arguments) { Printf(f,"int _v;\n"); } int num_braces = 0; j = 0; Parm *pj = pi; while (pj) { if (checkAttribute(pj,"tmap:in:numinputs","0")) { pj = Getattr(pj,"tmap:in:next"); continue; } if (j >= num_required) { String *lfmt = ReplaceFormat (fmt, num_arguments); Printf(f, "if (%s <= %d) {\n", argc_template_string, j); Printf(f, Char(lfmt),Getattr(ni,"wrap:name")); Printf(f, "}\n"); Delete (lfmt); } if (print_typecheck(f, j, pj)) { Printf(f, "if (_v) {\n"); num_braces++; } Parm *pk = Getattr(pj,"tmap:in:next"); if (pk) pj = pk; else pj = nextSibling(pj); j++; } String *lfmt = ReplaceFormat (fmt, num_arguments); Printf(f, Char(lfmt),Getattr(ni,"wrap:name")); Delete (lfmt); /* close braces */ for (/* empty */; num_braces > 0; num_braces--) Printf(f, "}\n"); Printf(f,"}\n"); /* braces closes "if" for this method */ } Delete(dispatch); return f; } /* ----------------------------------------------------------------------------- * Swig_overload_check() * ----------------------------------------------------------------------------- */ void Swig_overload_check(Node *n) { Swig_overload_rank(n, false); } cableswig-0.1.0+git20150808.orig/SWIG/Source/Modules/s-exp.cxx0000644000175000000620000002307412561312227022234 0ustar stevestaff/* ----------------------------------------------------------------------------- * s-exp.cxx * * A parse tree represented as Lisp s-expressions. * * Author(s) : Matthias Koeppe (mkoeppe@mail.math.uni-magdeburg.de) * * Copyright (C) 2002. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ /* Derived from xml.cxx 1.1.2.2 */ char cvsroot_s_exp_cxx[] = "/cvsroot/SWIG/Source/Modules/s-exp.cxx,v 1.13 2004/01/22 22:42:17 cheetah Exp"; static const char *usage = "\ S-Exp Options (available with -sexp)\n\ -typemaplang - Typemap language\n\n"; #include "swigmod.h" #include "dohint.h" //static Node *view_top = 0; static File *out = 0; class Sexp : public Language { public: int indent_level; Sexp() : indent_level( 0 ) {} virtual ~Sexp() {} virtual void main(int argc, char *argv[]) { SWIG_typemap_lang("sexp"); for( int iX = 0; iX < argc; iX++ ) { if( strcmp( argv[iX], "-typemaplang" ) == 0 ) { Swig_mark_arg (iX); iX++; SWIG_typemap_lang(argv[iX]); Swig_mark_arg (iX); continue; } if( strcmp( argv[iX], "-help" ) == 0 ) { fputs( usage, stderr ); } } // Add a symbol to the parser for conditional compilation Preprocessor_define("SWIGSEXP 1",0); } DOHHash *print_circle_hash; int print_circle_count; int hanging_parens; bool need_whitespace; bool need_newline; /* Top of the parse tree */ virtual int top(Node *n) { if( out == 0 ) { String *outfile = Getattr(n,"outfile"); Replaceall(outfile,"_wrap.cxx", ".lisp"); Replaceall(outfile,"_wrap.c", ".lisp"); out = NewFile(outfile,"w"); if (!out) { Printf(stderr,"*** Can't open '%s'\n", outfile); SWIG_exit(EXIT_FAILURE); } } Language::top(n); Printf( out, ";;; Lisp parse tree produced by SWIG\n" ); print_circle_hash = DohNewHash(); print_circle_count = 0; hanging_parens = 0; need_whitespace = 0; need_newline = 0; Sexp_print_node(n); flush_parens(); return SWIG_OK; } void print_indent() { int i; for (i = 0; i < indent_level; i++) { Printf(out, " "); } } void open_paren(const String *oper) { flush_parens(); Printf(out, "("); if (oper) Printf(out, "%s ", oper); indent_level += 2; } void close_paren(bool neednewline = false) { hanging_parens++; if (neednewline) print_lazy_whitespace(); indent_level -= 2; } void flush_parens() { int i; if (hanging_parens) { for (i = 0; iobjname, "List") == 0) { int i; open_paren(NIL); for (i = 0; i", ObjType(obj)->objname, obj); } } } } void Sexp_print_as_keyword(const DOH *k) { /* Print key, replacing ":" with "-" because : is CL's package prefix */ flush_parens(); String *key = NewString(k); Replaceall(key, ":", "-"); Replaceall(key, "_", "-"); Printf(out,":%s ", key); Delete(key); } void Sexp_print_plist_noparens(DOH *obj) { /* attributes map names to objects */ Iterator k; bool first; for (k = First(obj), first = true; k.key; k = Next(k), first=false) { if (!internal_key_p(k.key)) { DOH *value = Getattr(obj, k.key); flush_parens(); if (!first) { Printf(out, " "); } Sexp_print_as_keyword(k.key); /* Print value */ Sexp_print_value_of_key(value, k.key); } } } void Sexp_print_plist(DOH *obj) { flush_parens(); if (print_circle(obj, true)) { open_paren(NIL); Sexp_print_plist_noparens(obj); close_paren(); } } void Sexp_print_attributes(Node * obj) { Sexp_print_plist_noparens(obj); } void Sexp_print_node(Node *obj) { Node *cobj; open_paren(nodeType(obj)); /* A node has an attribute list... */ Sexp_print_attributes(obj); /* ... and child nodes. */ cobj = firstChild(obj); if (cobj) { print_lazy_newline(); flush_parens(); Sexp_print_as_keyword("children"); open_paren(NIL); for (; cobj; cobj = nextSibling(cobj)) { Sexp_print_node(cobj); } close_paren(); } close_paren(); } virtual int functionWrapper(Node *n) { ParmList *l = Getattr(n,"parms"); Wrapper *f = NewWrapper(); emit_attach_parmmaps(l,f); Setattr(n,"wrap:parms",l); return SWIG_OK; } }; static Language * new_swig_sexp() { return new Sexp(); } extern "C" Language * swig_sexp( void ) { return new_swig_sexp(); } cableswig-0.1.0+git20150808.orig/SWIG/Source/Modules/.cvsignore0000644000175000000620000000002012561312227022436 0ustar stevestaff.deps .dirstamp cableswig-0.1.0+git20150808.orig/SWIG/Source/Modules/main.cxx0000644000175000000620000005675212561312227022135 0ustar stevestaff/* ----------------------------------------------------------------------------- * main.cxx * * Main entry point to the SWIG core. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1998-2000. The University of Chicago * Copyright (C) 1995-1998. The University of Utah and The Regents of the * University of California. * * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_main_cxx[] = "/cvsroot/SWIG/Source/Modules/main.cxx,v 1.33 2004/01/22 22:42:15 cheetah Exp"; #if defined(_WIN32) #define WIN32_LEAN_AND_MEAN #include #endif #include "swigmod.h" #include "swigwarn.h" #include "cparse.h" #include // Global variables char LibDir[512]; // Library directory Language *lang; // Language method int CPlusPlus = 0; int Extend = 0; // Extend flag int ForceExtern = 0; // Force extern mode int GenerateDefault = 1; // Generate default constructors char *Config = 0; int NoInclude = 0; int Verbose = 0; int NoExtern = 0; int NoExcept = 0; char *SwigLib; extern "C" { extern String *ModuleName; } static const char *usage1 = (const char*)"\ \nGeneral Options\n\ -c++ - Enable C++ processing\n\ -co - Check a file out of the SWIG library\n\ -dirprot - Turn on wrapping of protected members for director classes\n\ -D - Define a symbol (for conditional compilation)\n\ -E - Preprocess only, does not generate wrapper code\n\ -fcompact - Compile in compact mode\n\ -fvirtual - Compile in virtual elimination mode\n\ -Fstandard - Display error/warning messages in commonly used format\n\ -Fmicrosoft - Display error/warning messages in Microsoft format\n\ -help - This output\n\ -I - Look for SWIG files in \n\ -ignoremissing - Ignore missing include files\n\ -importall - Follow all #include statements as imports\n\ -includeall - Follow all #include statements\n\ -l - Include SWIG library file \n\ -M - List all dependencies \n\ -MM - List dependencies, but omit files in SWIG library\n\ "; // usage string split in two otherwise string is too big for some compilers static const char *usage2 = (const char*)"\ -makedefault - Create default constructors/destructors (the default)\n\ -module - Set module name to \n\ -nocontract - Turn off contract checking \n\ -nodefault - Do not generate constructors/destructors\n\ -nodirprot - Do not wrap director protected members\n\ -noexcept - Do not wrap exception specifiers\n\ -noextern - Do not generate extern declarations\n\ -noruntime - Do not include SWIG runtime code\n\ -o - Set name of the output file to \n\ -outdir - Set language specific files output directory\n\ -runtime - Make the runtime support code globally visible.\n\ -small - Compile in virtual elimination & compact mode\n\ -swiglib - Report location of SWIG library and exit\n\ -v - Run in verbose mode\n\ -version - Print SWIG version number\n\ -Wall - Enable all warning messages\n\ -Wallkw - Enable keyword warnings for all the supported languages\n\ -Werror - Force to treat warnings as errors\n\ -w - Suppress/add warning messages by code. \n\ Use ',' as separator and the +/- signs as follows \n\ \n\ -w+321,401,-402 \n\ \n\ where code 321(+) is added, and 401(no sign) and 402(-) \n\ are suppressed. See documentation for code meanings.\n\ \n"; // Local variables static int freeze = 0; static String *lang_config = 0; static char *cpp_extension = (char *) "cxx"; static String *outdir = 0; // ----------------------------------------------------------------------------- // check_suffix(char *name) // // Checks the suffix of a file to see if we should emit extern declarations. // ----------------------------------------------------------------------------- static int check_suffix(char *name) { char *c; if (!name) return 0; c = Swig_file_suffix(name); if ((strcmp(c,".c") == 0) || (strcmp(c,".C") == 0) || (strcmp(c,".cc") == 0) || (strcmp(c,".cxx") == 0) || (strcmp(c,".c++") == 0) || (strcmp(c,".cpp") == 0)) { return 1; } return 0; } // ----------------------------------------------------------------------------- // install_opts(int argc, char *argv[]) // Install all command line options as preprocessor symbols // ----------------------------------------------------------------------------- static void install_opts(int argc, char *argv[]) { int i; int noopt = 0; char *c; for (i = 1; i < (argc-1); i++) { if (argv[i]) { if ((*argv[i] == '-') && (!isupper(*(argv[i]+1)))) { String *opt = NewStringf("SWIGOPT%(upper)s", argv[i]); Replaceall(opt,"-","_"); c = Char(opt); noopt = 0; while (*c) { if (!(isalnum(*c) || (*c == '_'))) { noopt = 1; break; } c++; } if (((i+1) < (argc-1)) && (argv[i+1]) && (*argv[i+1] != '-')) { Printf(opt," %s", argv[i+1]); i++; } else { Printf(opt," 1"); } if (!noopt) { /* Printf(stdout,"%s\n", opt); */ Preprocessor_define(opt, 0); } } } } } // ----------------------------------------------------------------------------- // Sets the output directory for language specific (proxy) files if not set and // adds trailing file separator if necessary. // ----------------------------------------------------------------------------- static void set_outdir(const String *c_wrapper_file_dir) { // Add file delimiter if not present in output directory name if (outdir && Len(outdir) != 0) { const char* outd = Char(outdir); if (strcmp(outd + strlen(outd) - strlen(SWIG_FILE_DELIMETER), SWIG_FILE_DELIMETER) != 0) Printv(outdir, SWIG_FILE_DELIMETER, 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); } //----------------------------------------------------------------- // main() // // Main program. Initializes the files and starts the parser. //----------------------------------------------------------------- /* This function sets the name of the configuration file */ void SWIG_config_file(const String_or_char *filename) { lang_config = NewString(filename); } void SWIG_library_directory(const char *filename) { strcpy(LibDir,filename); } // Returns the directory for generating language specific files (non C/C++ files) const String *SWIG_output_directory() { assert(outdir); return outdir; } void SWIG_config_cppext(const char *ext) { cpp_extension = (char *) ext; } int SWIG_main(int argc, char *argv[], Language *l) { int i; char *c; char temp[512]; char *outfile_name = 0; int help = 0; int checkout = 0; int cpp_only = 0; int tm_debug = 0; char *includefiles[256]; int includecount = 0; int dump_tags = 0; int dump_tree = 0; int browse = 0; int dump_typedef = 0; int dump_classes = 0; int werror = 0; int depend = 0; int memory_debug = 0; int allkw = 0; DOH *libfiles = 0; DOH *cpps = 0 ; /* Initialize the SWIG core */ Swig_init(); /* Suppress warning messages for private inheritance, preprocessor evaluation, might be abstract, overloaded const, and ... WARN_PP_EVALUATION 202 WARN_PARSE_PRIVATE_INHERIT 309 WARN_TYPE_ABSTRACT 403 WARN_LANG_OVERLOAD_CONST 512 WARN_PARSE_BUILTIN_NAME 321 WARN_PARSE_REDUNDANT 322 */ Swig_warnfilter("202,309,403,512,321,322",1); // Initialize the preprocessor Preprocessor_init(); lang = l; // Set up some default symbols (available in both SWIG interface files // and C files) Preprocessor_define((DOH *) "SWIG 1", 0); Preprocessor_define((DOH *) "__STDC__", 0); #ifdef MACSWIG Preprocessor_define((DOH *) "SWIGMAC 1", 0); #endif #ifdef SWIGWIN32 Preprocessor_define((DOH *) "SWIGWIN32 1", 0); #endif // Set the SWIG version value in format 0xAABBCC from package version expected to be in format A.B.C String *package_version = NewString(PACKAGE_VERSION); char *token = strtok(Char(package_version), "."); String *vers = NewString("SWIG_VERSION 0x"); int count = 0; while (token) { int len = strlen(token); assert(len == 1 || len == 2); Printf(vers, "%s%s", (len == 1) ? "0" : "", token); token = strtok(NULL, "."); count++; } Delete(package_version); assert(count == 3); // Check version format is correct /* Turn on contracts */ Swig_contract_mode_set(1); Preprocessor_define(vers,0); /* Turn on director protected mode */ Wrapper_director_protected_mode_set(0); // Check for SWIG_LIB environment variable if ((c = getenv("SWIG_LIB")) == (char *) 0) { #if defined(_WIN32) char buf[MAX_PATH]; char *p; if (GetModuleFileName(0, buf, MAX_PATH) == 0 || (p = strrchr(buf, '\\')) == 0) { Printf(stderr, "Warning: Could not determine SWIG library location. Assuming " SWIG_LIB "\n"); sprintf(LibDir,"%s",SWIG_LIB); // Build up search paths } else { strcpy(p+1, "Lib"); strcpy(LibDir, buf); } #else sprintf(LibDir,"%s",SWIG_LIB); // Build up search paths #endif } else { strcpy(LibDir,c); } SwigLib = Swig_copy_string(LibDir); // Make a copy of the real library location libfiles = NewList(); /* Check for SWIG_FEATURES environment variable */ if ((c = getenv("SWIG_FEATURES"))) { while (*c!='\0') { while ((*c)==' ') { c++; } i = 0; while ((*c!='\0') && (*c!=' ')) { temp[i] = *c; c++; i++; } temp[i]='\0'; if (strcmp(temp, "-fcompact") == 0) { Wrapper_compact_print_mode_set(1); } else if (strcmp(temp, "-fvirtual") == 0) { Wrapper_virtual_elimination_mode_set(1); } else if (strcmp(temp,"-dirprot") == 0) { Wrapper_director_protected_mode_set(1); } else if (strcmp(temp,"-nodirprot") == 0) { Wrapper_director_protected_mode_set(0); } else if (strcmp(temp, "-small") == 0) { Wrapper_compact_print_mode_set(1); Wrapper_virtual_elimination_mode_set(1); } } } // Get options for (i = 1; i < argc; i++) { if (argv[i]) { if (strncmp(argv[i],"-I",2) == 0) { // Add a new directory search path includefiles[includecount++] = Swig_copy_string(argv[i]+2); Swig_mark_arg(i); } else if (strncmp(argv[i],"-D",2) == 0) { DOH *d = NewString(argv[i]+2); Replace(d,(char*)"=",(char*)" ", DOH_REPLACE_ANY | DOH_REPLACE_FIRST); Preprocessor_define((DOH *) d,0); // Create a symbol Swig_mark_arg(i); } else if (strcmp(argv[i],"-E") == 0) { cpp_only = 1; Swig_mark_arg(i); } else if ((strcmp(argv[i],"-verbose") == 0) || (strcmp(argv[i],"-v") == 0)) { Verbose = 1; Swig_mark_arg(i); } else if (strcmp(argv[i],"-c++") == 0) { CPlusPlus=1; Preprocessor_define((DOH *) "__cplusplus 1", 0); Swig_cparse_cplusplus(1); Swig_mark_arg(i); } else if (strcmp(argv[i],"-fcompact") == 0) { Wrapper_compact_print_mode_set(1); Swig_mark_arg(i); } else if (strcmp(argv[i],"-fvirtual") == 0) { Wrapper_virtual_elimination_mode_set(1); Swig_mark_arg(i); } else if (strcmp(argv[i],"-dirprot") == 0) { Wrapper_director_protected_mode_set(1); Swig_mark_arg(i); } else if (strcmp(argv[i],"-nodirprot") == 0) { Wrapper_director_protected_mode_set(0); Swig_mark_arg(i); } else if (strcmp(argv[i],"-small") == 0) { Wrapper_compact_print_mode_set(1); Wrapper_virtual_elimination_mode_set(1); Swig_mark_arg(i); } else if ((strcmp(argv[i],"-noruntime") == 0) || (strcmp(argv[i],"-c") == 0)) { NoInclude=1; Preprocessor_define((DOH *) "SWIG_NOINCLUDE 1", 0); Swig_mark_arg(i); if (strcmp(argv[i],"-c") == 0) { Swig_warning(WARN_DEPRECATED_OPTC, "SWIG",1, "-c command line option is deprecated. Use -noruntime instead.\n"); } } else if ((strcmp(argv[i],"-runtime") == 0)) { Preprocessor_define((String *) "SWIG_RUNTIME_MODE 1", 0); Swig_mark_arg(i); } else if ((strcmp(argv[i],"-make_default") == 0) || (strcmp(argv[i],"-makedefault") == 0)) { GenerateDefault = 1; Swig_mark_arg(i); } else if ((strcmp(argv[i],"-no_default") == 0) || (strcmp(argv[i],"-nodefault") == 0)) { GenerateDefault = 0; Swig_mark_arg(i); } else if (strcmp(argv[i],"-noexcept") == 0) { NoExcept = 1; Swig_mark_arg(i); } else if (strcmp(argv[i],"-noextern") == 0) { NoExtern = 1; Swig_mark_arg(i); } else if (strcmp(argv[i],"-show_templates") == 0) { Swig_cparse_debug_templates(1); Swig_mark_arg(i); } else if (strcmp(argv[i],"-swiglib") == 0) { printf("%s\n", LibDir); SWIG_exit (EXIT_SUCCESS); } else if (strcmp(argv[i],"-o") == 0) { Swig_mark_arg(i); if (argv[i+1]) { outfile_name = Swig_copy_string(argv[i+1]); Swig_mark_arg(i+1); i++; } else { Swig_arg_error(); } } else if (strcmp(argv[i],"-version") == 0) { fprintf(stderr,"\nSWIG Version %s\n", PACKAGE_VERSION); fprintf(stderr,"Copyright (c) 1995-1998\n"); fprintf(stderr,"University of Utah and the Regents of the University of California\n"); fprintf(stderr,"Copyright (c) 1998-2003\n"); fprintf(stderr,"University of Chicago\n"); fprintf(stderr,"Compiled with %s [%s]\n", SWIG_CXX, SWIG_PLATFORM); fprintf(stderr,"\nPlease see %s for reporting bugs and further information\n", PACKAGE_BUGREPORT); SWIG_exit (EXIT_SUCCESS); } else if (strncmp(argv[i],"-l",2) == 0) { // Add a new directory search path Append(libfiles,argv[i]+2); Swig_mark_arg(i); } else if (strcmp(argv[i],"-co") == 0) { checkout = 1; Swig_mark_arg(i); } else if (strcmp(argv[i],"-freeze") == 0) { freeze = 1; Swig_mark_arg(i); } else if (strcmp(argv[i],"-includeall") == 0) { Preprocessor_include_all(1); Swig_mark_arg(i); } else if (strcmp(argv[i],"-importall") == 0) { Preprocessor_import_all(1); Swig_mark_arg(i); } else if (strcmp(argv[i],"-ignoremissing") == 0) { Preprocessor_ignore_missing(1); Swig_mark_arg(i); } else if (strcmp(argv[i],"-tm_debug") == 0) { tm_debug = 1; Swig_mark_arg(i); } else if (strcmp(argv[i],"-module") == 0) { Swig_mark_arg(i); if (argv[i+1]) { ModuleName = NewString(argv[i+1]); Swig_mark_arg(i+1); } else { Swig_arg_error(); } } else if (strcmp(argv[i],"-M") == 0) { depend = 1; Swig_mark_arg(i); } else if (strcmp(argv[i],"-MM") == 0) { depend = 2; Swig_mark_arg(i); } else if (strcmp(argv[i],"-outdir") == 0) { Swig_mark_arg(i); if (argv[i+1]) { outdir = NewString(argv[i+1]); Swig_mark_arg(i+1); } else { Swig_arg_error(); } } else if (strcmp(argv[i],"-Wall") == 0) { Swig_mark_arg(i); Swig_warnall(); } else if (strcmp(argv[i],"-Wallkw") == 0) { allkw = 1; Swig_mark_arg(i); } else if (strcmp(argv[i],"-Werror") == 0) { werror = 1; Swig_mark_arg(i); } else if (strncmp(argv[i],"-w",2) == 0) { Swig_mark_arg(i); Swig_warnfilter(argv[i]+2,1); } else if (strcmp(argv[i],"-dump_tags") == 0) { dump_tags = 1; Swig_mark_arg(i); } else if (strcmp(argv[i],"-dump_tree") == 0) { dump_tree = 1; Swig_mark_arg(i); } else if (strcmp(argv[i],"-nocontract") == 0) { Swig_mark_arg(i); Swig_contract_mode_set(0); } else if (strcmp(argv[i],"-browse") == 0) { browse = 1; Swig_mark_arg(i); } else if (strcmp(argv[i],"-dump_typedef") == 0) { dump_typedef = 1; Swig_mark_arg(i); } else if (strcmp(argv[i],"-dump_classes") == 0) { dump_classes = 1; Swig_mark_arg(i); } else if (strcmp(argv[i],"-dump_memory") == 0) { memory_debug =1; Swig_mark_arg(i); } else if (strcmp(argv[i],"-Fstandard") == 0) { Swig_error_msg_format(EMF_STANDARD); Swig_mark_arg(i); } else if (strcmp(argv[i],"-Fmicrosoft") == 0) { Swig_error_msg_format(EMF_MICROSOFT); Swig_mark_arg(i); } else if (strcmp(argv[i],"-help") == 0) { fputs(usage1,stderr); fputs(usage2,stderr); Swig_mark_arg(i); help = 1; } } } for (i = 0; i < includecount; i++) { Swig_add_directory((DOH *) includefiles[i]); } // Define the __cplusplus symbol if (CPlusPlus) Preprocessor_define((DOH *) "__cplusplus 1", 0); // Parse language dependent options lang->main(argc,argv); if (help) { Printf(stderr,"\nNote: 'swig - -help' displays options for a specific target language.\n\n"); SWIG_exit (EXIT_SUCCESS); // Exit if we're in help mode } // Check all of the options to make sure we're cool. Swig_check_options(); install_opts(argc, argv); // Add language dependent directory to the search path { DOH *rl = NewString(""); Printf(rl,"%s%s%s", SwigLib, SWIG_FILE_DELIMETER, LibDir); Swig_add_directory(rl); rl = NewString(""); Printf(rl,".%sswig_lib%s%s", SWIG_FILE_DELIMETER, SWIG_FILE_DELIMETER, LibDir); Swig_add_directory(rl); } sprintf(temp,"%s%sconfig", SwigLib, SWIG_FILE_DELIMETER); Swig_add_directory((DOH *) temp); Swig_add_directory((DOH *) "." SWIG_FILE_DELIMETER "swig_lib" SWIG_FILE_DELIMETER "config"); Swig_add_directory((DOH *) SwigLib); Swig_add_directory((DOH *) "." SWIG_FILE_DELIMETER "swig_lib"); if (Verbose) { printf ("LibDir: %s\n", LibDir); List *sp = Swig_search_path(); Iterator s; for (s = First(sp); s.item; s = Next(s)) { Printf(stdout," %s\n", s.item); } } // If we made it this far, looks good. go for it.... input_file = argv[argc-1]; // If the user has requested to check out a file, handle that if (checkout) { DOH *s; char *outfile = input_file; if (outfile_name) outfile = outfile_name; if (Verbose) printf ("Handling checkout...\n"); s = Swig_include(input_file); if (!s) { fprintf(stderr,"Unable to locate '%s' in the SWIG library.\n", input_file); } else { FILE *f = fopen(outfile,"r"); if (f) { fclose(f); fprintf(stderr,"File '%s' already exists. Checkout aborted.\n", outfile); } else { f = fopen(outfile,"w"); if (!f) { fprintf(stderr,"Unable to create file '%s'\n", outfile); } else { fprintf(stderr,"'%s' checked out from the SWIG library.\n", input_file); fputs(Char(s),f); fclose(f); } } } } else { // Check the suffix for a .c file. If so, we're going to // declare everything we see as "extern" ForceExtern = check_suffix(input_file); // Run the preprocessor if (Verbose) printf ("Preprocessing...\n"); { int i; String *fs = NewString(""); FILE *df = Swig_open(input_file); if (!df) { Printf(stderr,"Unable to find '%s'\n", input_file); SWIG_exit (EXIT_FAILURE); } fclose(df); Printf(fs,"%%include \"swig.swg\"\n"); if (allkw) { Printf(fs,"%%include \"allkw.swg\"\n"); } if (lang_config) { Printf(fs,"\n%%include \"%s\"\n", lang_config); } Printf(fs,"%%include \"%s\"\n", Swig_last_file()); for (i = 0; i < Len(libfiles); i++) { Printf(fs,"\n%%include \"%s\"\n", Getitem(libfiles,i)); } Seek(fs,0,SEEK_SET); cpps = Preprocessor_parse(fs); if (Swig_error_count()) { SWIG_exit(EXIT_FAILURE); } if (cpp_only) { Printf(stdout,"%s", cpps); while (freeze); SWIG_exit (EXIT_SUCCESS); } if (depend) { String *outfile; if (!outfile_name) { if (CPlusPlus) { outfile = NewStringf("%s_wrap.%s", Swig_file_basename(input_file),cpp_extension); } else { outfile = NewStringf("%s_wrap.c", Swig_file_basename(input_file)); } } else { outfile = NewString(outfile_name); } Printf(stdout,"%s: ", outfile); List *files = Preprocessor_depend(); for (int i = 0; i < Len(files); i++) { if ((depend != 2) || ((depend == 2) && (Strncmp(Getitem(files,i),SwigLib, Len(SwigLib)) != 0))) { Printf(stdout,"\\\n %s ", Getitem(files,i)); } } Printf(stdout,"\n"); SWIG_exit(EXIT_SUCCESS); } Seek(cpps, 0, SEEK_SET); } /* Register a null file with the file handler */ Swig_register_filebyname("null", NewString("")); // Pass control over to the specific language interpreter if (Verbose) { fprintf (stdout, "Starting language-specific parse...\n"); fflush (stdout); } Node *top = Swig_cparse(cpps); if (Verbose) { Printf(stdout,"Processing types...\n"); } Swig_process_types(top); if (Verbose) { Printf(stdout,"C++ analysis...\n"); } Swig_default_allocators(top); if (Verbose) { Printf(stdout,"Generating wrappers...\n"); } if (dump_classes) { Hash *classes = Getattr(top,"classes"); if (classes) { Printf(stdout,"Classes\n"); Printf(stdout,"------------\n"); Iterator ki; for (ki = First(classes); ki.key; ki = Next(ki)) { Printf(stdout,"%s\n", ki.key); } } } if (dump_typedef) { SwigType_print_scope(0); } if (dump_tags) { Swig_print_tags(top,0); } if (top) { if (!Getattr(top,"name")) { Printf(stderr,"*** No module name specified using %%module or -module.\n"); SWIG_exit(EXIT_FAILURE); } else { /* Set some filename information on the object */ Setattr(top,"infile", input_file); if (!outfile_name) { if (CPlusPlus) { Setattr(top,"outfile", NewStringf("%s_wrap.%s", Swig_file_basename(input_file),cpp_extension)); } else { Setattr(top,"outfile", NewStringf("%s_wrap.c", Swig_file_basename(input_file))); } Setattr(top,"outfile_h", NewStringf("%s_wrap.h", Swig_file_basename(input_file))); } else { char *ext = strrchr(outfile_name, '.'); String *basename = ext ? NewStringWithSize(outfile_name,ext-outfile_name) : NewString(outfile_name); Setattr(top,"outfile", outfile_name); Setattr(top,"outfile_h", NewStringf("%s.h", basename)); Delete(basename); } set_outdir(Swig_file_dirname(Getattr(top,"outfile"))); if (Swig_contract_mode_get()) { Swig_contracts(top); } lang->top(top); if (browse) { Swig_browser(top,0); } } } if (dump_tree) { Swig_print_tree(top); } } if (tm_debug) Swig_typemap_debug(); if (memory_debug) DohMemoryDebug(); while (freeze); if ((werror) && (Swig_warn_count())) { return Swig_warn_count(); } return Swig_error_count(); } // -------------------------------------------------------------------------- // SWIG_exit(int exit_code) // // Cleanup and either freeze or exit // -------------------------------------------------------------------------- void SWIG_exit(int exit_code) { while (freeze); exit (exit_code); } cableswig-0.1.0+git20150808.orig/SWIG/Source/Modules/tcl8.cxx0000644000175000000620000012002512561312227022044 0ustar stevestaff/* ----------------------------------------------------------------------------- * tcl8.cxx * * Tcl8.0 wrapper module. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * * Incr Tcl 3.x support by Alexey Dyachenko (dyachenko@fromru.com) * * Based on * itcl.cxx * Author: Bob Techentin * based on tcl8 and python modules by David Beazley * * Module for creating Incr Tcl 3.x shadow classes * and Tcl 8.x native wrapper functions. * * ----------------------------------------------------------------------------- */ char cvsroot_tcl8_cxx[] = "/cvsroot/SWIG/Source/Modules/tcl8.cxx,v 1.10 2004/01/22 22:42:17 cheetah Exp"; #include "swigmod.h" static const char *usage = (const char*)"\ Tcl 8 Options (available with -tcl)\n\ -itcl - Enable ITcl support\n\ -ldflags - Print runtime libraries to link with\n\ -nosafe - Leave out SafeInit module function.\n\ -prefix - Set a prefix to be prepended to all names\n\ -namespace - Build module into a Tcl 8 namespace\n\ -pkgversion - Set package version\n\n"; static String *cmd_tab = NULL; /* Table of command names */ static String *var_tab = NULL; /* Table of global variables */ static String *const_tab = NULL; /* Constant table */ static String *methods_tab = NULL; /* Methods table */ static String *attr_tab = NULL; /* Attribute table */ static String *prefix = NULL; static String *module = NULL; static int nspace = 0; static String *init_name = NULL; static String *ns_name = NULL; static int have_constructor; static int have_destructor; static int have_base_classes; static String *destructor_action = NULL; static String *version = NULL;//"0.0"; static String *class_name = NULL; static int have_attributes; static int have_methods; static int nosafe = 0; static File *f_header = NULL; static File *f_wrappers = NULL; static File *f_init = NULL; static File *f_runtime = NULL; // Itcl support static int itcl = 0; static File *f_shadow = NULL; static File *f_shadow_stubs = NULL; static String *constructor = NULL; //static String *destructor = 0; static String *base_classes = NULL; static String *base_class_init = NULL; //static String *methods = 0; static String *imethods = NULL; static String *attributes = NULL; static String *attribute_traces = NULL; //static String *iattribute_traces = 0; class TCL8 : public Language { public: /* ------------------------------------------------------------ * TCL8::main() * ------------------------------------------------------------ */ virtual void main(int argc, char *argv[]) { SWIG_library_directory("tcl"); for (int i = 1; i < argc; i++) { if (argv[i]) { if (strcmp(argv[i],"-prefix") == 0) { if (argv[i+1]) { prefix = NewString(argv[i+1]); Swig_mark_arg(i); Swig_mark_arg(i+1); i++; } else Swig_arg_error(); } else if (strcmp(argv[i],"-pkgversion") == 0) { if (argv[i+1]) { version = NewString(argv[i+1]); Swig_mark_arg(i); Swig_mark_arg(i+1); i++; } } else if (strcmp(argv[i],"-namespace") == 0) { nspace = 1; Swig_mark_arg(i); } else if (strcmp(argv[i],"-itcl") == 0) { itcl = 1; Swig_mark_arg(i); } else if (strcmp(argv[i],"-nosafe") == 0) { nosafe = 1; Swig_mark_arg(i); } else if (strcmp(argv[i],"-help") == 0) { fputs(usage,stderr); } else if (strcmp (argv[i], "-ldflags") == 0) { printf("%s\n", SWIG_TCL_RUNTIME); SWIG_exit (EXIT_SUCCESS); } } } Preprocessor_define("SWIGTCL 1",0); Preprocessor_define("SWIGTCL8 1", 0); SWIG_typemap_lang("tcl8"); SWIG_config_file("tcl8.swg"); allow_overloading(); } /* ------------------------------------------------------------ * top() * ------------------------------------------------------------ */ virtual int top(Node *n) { /* Initialize all of the output files */ String *outfile = Getattr(n,"outfile"); f_runtime = NewFile(outfile,"w"); if (!f_runtime) { Printf(stderr,"*** Can't open '%s'\n", outfile); SWIG_exit(EXIT_FAILURE); } f_init = NewString(""); f_header = NewString(""); f_wrappers = NewString(""); /* Register file targets with the SWIG file handler */ Swig_register_filebyname("header",f_header); Swig_register_filebyname("wrapper",f_wrappers); Swig_register_filebyname("runtime",f_runtime); Swig_register_filebyname("init",f_init); /* Initialize some variables for the object interface */ cmd_tab = NewString(""); var_tab = NewString(""); methods_tab = NewString(""); const_tab = NewString(""); Swig_banner(f_runtime); /* Include a Tcl configuration file */ if (NoInclude) { Printf(f_runtime,"#define SWIG_NOINCLUDE\n"); } /* Set the module name, namespace, and prefix */ module = NewStringf("%(lower)s", Getattr(n,"name")); init_name = NewStringf("%(title)s_Init",module); ns_name = prefix ? Copy(prefix) : Copy(module); if (prefix) Append(prefix,"_"); /* If shadow classing is enabled, we're going to change the module name to "_module" */ if (itcl) { char filen[256]; sprintf(filen,"%s%s.itcl", Swig_file_dirname(outfile), Char(module)); Insert( module,0,"_" ); if ((f_shadow = NewFile(filen,"w")) == 0) { Printf(stderr,"Unable to open %s\n", filen); SWIG_exit (EXIT_FAILURE); } f_shadow_stubs = NewString(""); Swig_register_filebyname("shadow",f_shadow); Swig_register_filebyname("itcl",f_shadow); Printv(f_shadow, "# This file was created automatically by SWIG.\n", "# Don't modify this file, modify the SWIG interface instead.\n", "# This file is compatible with both classic and new-style classes.\n", NIL); Printv(f_shadow,"\npackage require Itcl\n\n", NIL); }; /* Generate some macros used throughout code generation */ Printf(f_header,"#define SWIG_init %s\n", init_name); Printf(f_header,"#define SWIG_name \"%s\"\n", module); if (nspace) { Printf(f_header,"#define SWIG_prefix \"%s::\"\n", ns_name); Printf(f_header,"#define SWIG_namespace \"%s\"\n\n", ns_name); } else { Printf(f_header,"#define SWIG_prefix \"%s\"\n", prefix); } if(version == NULL) { Printf(f_header,"#define SWIG_version \"%s\"\n", "0.0"); } else { Printf(f_header,"#define SWIG_version \"%s\"\n", version); } Printf(cmd_tab, "\nstatic swig_command_info swig_commands[] = {\n"); Printf(var_tab, "\nstatic swig_var_info swig_variables[] = {\n"); Printf(const_tab, "\nstatic swig_const_info swig_constants[] = {\n"); Printf(f_wrappers,"#ifdef __cplusplus\nextern \"C\" {\n#endif\n"); /* Start emitting code */ Language::top(n); /* Done. Close up the module */ Printv(cmd_tab, tab4, "{0, 0, 0}\n", "};\n",NIL); Printv(var_tab, tab4, "{0,0,0,0}\n", "};\n",NIL); Printv(const_tab, tab4, "{0,0,0,0,0,0}\n", "};\n", NIL); Printv(f_wrappers, cmd_tab, var_tab, const_tab,NIL); /* Dump the pointer equivalency table */ SwigType_emit_type_table(f_runtime, f_wrappers); Printf(f_wrappers,"#ifdef __cplusplus\n}\n#endif\n"); /* Close the init function and quit */ Printf(f_init,"return TCL_OK;\n}\n"); if (!nosafe) { Printf(f_init,"SWIGEXPORT(int) %(title)s_SafeInit(Tcl_Interp *interp) {\n", module ); Printf(f_init," return SWIG_init(interp);\n"); Printf(f_init,"}\n"); } if (itcl) { Printv(f_shadow, f_shadow_stubs, "\n",NIL); Close(f_shadow); Delete(f_shadow); } /* Close all of the files */ Printv(f_runtime, f_header, f_wrappers,NIL); Wrapper_pretty_print(f_init,f_runtime); Delete(f_header); Delete(f_wrappers); Delete(f_init); Close(f_runtime); return SWIG_OK; } /* ------------------------------------------------------------ * functionWrapper() * ------------------------------------------------------------ */ virtual int functionWrapper(Node *n) { String *name = Getattr(n,"name"); /* Like to get rid of this */ String *iname = Getattr(n,"sym:name"); SwigType *type = Getattr(n,"type"); ParmList *parms = Getattr(n,"parms"); String *overname = 0; Parm *p; int i; String *tm; Wrapper *f; String *incode, *cleanup, *outarg, *argstr, *args; int num_arguments = 0; int num_required = 0; int varargs = 0; char source[64]; if (Getattr(n,"sym:overloaded")) { overname = Getattr(n,"sym:overname"); } else { if (!addSymbol(iname,n)) return SWIG_ERROR; } incode = NewString(""); cleanup = NewString(""); outarg = NewString(""); argstr = NewString("\""); args = NewString(""); f = NewWrapper(); String *wname = Swig_name_wrapper(iname); if (overname) { Append(wname, overname); } Setattr(n,"wrap:name",wname); Printv(f->def, "static int\n ", wname, "(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {\n" "(void)clientData; (void)interp; (void)objc; (void)objv;", NIL); /* Print out variables for storing arguments. */ emit_args(type,parms, f); /* Attach standard typemaps */ emit_attach_parmmaps(parms,f); Setattr(n,"wrap:parms",parms); /* Get number of require and total arguments */ num_arguments = emit_num_arguments(parms); num_required = emit_num_required(parms); varargs = emit_isvarargs(parms); /* Unmarshal parameters */ for (i = 0, p = parms; i < num_arguments; i++) { /* Skip ignored arguments */ while (checkAttribute(p,"tmap:in:numinputs","0")) { p = Getattr(p,"tmap:in:next"); } SwigType *pt = Getattr(p,"type"); String *ln = Getattr(p,"lname"); /* Produce string representations of the source and target arguments */ sprintf(source,"objv[%d]",i+1); if (i == num_required) Putc('|',argstr); if ((tm = Getattr(p,"tmap:in"))) { String *parse = Getattr(p,"tmap:in:parse"); if (!parse) { Replaceall(tm,"$target",ln); Replaceall(tm,"$source",source); Replaceall(tm,"$input",source); Setattr(p,"emit:input",source); if (Getattr(p,"wrap:disown") || (Getattr(p,"tmap:in:disown"))) { Replaceall(tm,"$disown","SWIG_POINTER_DISOWN"); } else { Replaceall(tm,"$disown","0"); } Putc('o',argstr); Printf(args,",0"); if (i >= num_required) { Printf(incode, "if (objc > %d) {\n", i+1); } Printf(incode,"%s\n", tm); if (i >= num_required) { Printf(incode, "}\n"); } } else { Printf(argstr,"%s",parse); Printf(args,",&%s",ln); if (Strcmp(parse,"p") == 0) { SwigType *lt = SwigType_ltype(pt); SwigType_remember(pt); if (Cmp(lt,"p.void") == 0) { Printf(args,",0"); } else { Printf(args,",SWIGTYPE%s", SwigType_manglestr(pt)); } Delete(lt); } } p = Getattr(p,"tmap:in:next"); continue; } else { Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt,0)); } p = nextSibling(p); } if (!varargs) { Putc(':',argstr); } else { Putc(';',argstr); /* If variable length arguments we need to emit the in typemap here */ if (p && (tm = Getattr(p,"tmap:in"))) { sprintf(source,"objv[%d]", i+1); Printf(incode,"if (objc > %d) {\n", i); Replaceall(tm,"$input",source); Printv(incode,tm,"\n", NIL); Printf(incode,"}\n"); } } Printf(argstr,"%s\"",usage_string(Char(iname),type,parms)); Printv(f->code, "if (SWIG_GetArgs(interp, objc, objv,", argstr, args, ") == TCL_ERROR) SWIG_fail;\n", NIL); Printv(f->code,incode,NIL); /* Insert constraint checking code */ for (p = parms; p;) { if ((tm = Getattr(p,"tmap:check"))) { Replaceall(tm,"$target",Getattr(p,"lname")); Printv(f->code,tm,"\n",NIL); p = Getattr(p,"tmap:check:next"); } else { p = nextSibling(p); } } /* Insert cleanup code */ for (i = 0, p = parms; p; i++) { if ((tm = Getattr(p,"tmap:freearg"))) { Replaceall(tm,"$source",Getattr(p,"lname")); Printv(cleanup,tm,"\n",NIL); p = Getattr(p,"tmap:freearg:next"); } else { p = nextSibling(p); } } /* Insert argument output code */ for (i=0,p = parms; p;i++) { if ((tm = Getattr(p,"tmap:argout"))) { Replaceall(tm,"$source",Getattr(p,"lname")); Replaceall(tm,"$target","(Tcl_GetObjResult(interp))"); Replaceall(tm,"$result","(Tcl_GetObjResult(interp))"); Replaceall(tm,"$arg",Getattr(p,"emit:input")); Replaceall(tm,"$input",Getattr(p,"emit:input")); Printv(outarg,tm,"\n",NIL); p = Getattr(p,"tmap:argout:next"); } else { p = nextSibling(p); } } /* Now write code to make the function call */ emit_action(n,f); /* Need to redo all of this code (eventually) */ /* Return value if necessary */ if ((tm = Swig_typemap_lookup_new("out",n,"result",0))) { Replaceall(tm,"$source", "result"); Replaceall(tm,"$target", "Tcl_GetObjResult(interp)"); Replaceall(tm,"$result", "Tcl_GetObjResult(interp)"); Printf(f->code,"%s\n", tm); } else { Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(type,0), name); } /* Dump output argument code */ Printv(f->code,outarg,NIL); /* Dump the argument cleanup code */ Printv(f->code,cleanup,NIL); /* Look for any remaining cleanup */ if (Getattr(n,"feature:new")) { if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) { Replaceall(tm,"$source","result"); Printf(f->code,"%s\n", tm); } } if ((tm = Swig_typemap_lookup_new("ret",n,"result",0))) { Replaceall(tm,"$source","result"); Printf(f->code,"%s\n", tm); } Printv(f->code, "return TCL_OK;\n", NIL); Printv(f->code, "fail:\n", cleanup, "return TCL_ERROR;\n", NIL); Printv(f->code,"}\n", NIL); /* Substitute the cleanup code */ Replaceall(f->code,"$cleanup",cleanup); Replaceall(f->code,"$symname", iname); /* Dump out the function */ Wrapper_print(f,f_wrappers); if (!Getattr(n,"sym:overloaded")) { /* Register the function with Tcl */ Printv(cmd_tab, tab4, "{ SWIG_prefix \"", iname, "\", (swig_wrapper_func) ", Swig_name_wrapper(iname), ", NULL},\n", NIL); } else { if (!Getattr(n,"sym:nextSibling")) { /* Emit overloading dispatch function */ int maxargs; String *dispatch = Swig_overload_dispatch(n,"return %s(clientData, interp, objc, objv);",&maxargs); /* Generate a dispatch wrapper for all overloaded functions */ Wrapper *df = NewWrapper(); String *dname = Swig_name_wrapper(iname); Printv(df->def, "static int\n", dname, "(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {\n" "(void)clientData; (void)interp; (void)objc; (void)objv;", NIL); Printf(df->code,"Tcl_Obj *CONST *argv = objv+1; (void)argv;\n"); Printf(df->code,"int argc = objc-1; (void)argc;\n"); Printv(df->code,dispatch,"\n",NIL); Printf(df->code,"Tcl_SetObjResult(interp, Tcl_NewStringObj(\"No matching function for overloaded '%s'\", -1));\n", iname); Printf(df->code,"return TCL_ERROR;\n"); Printv(df->code,"}\n",NIL); Wrapper_print(df,f_wrappers); Printv(cmd_tab, tab4, "{ SWIG_prefix \"", iname, "\", (swig_wrapper_func) ", dname, ", NULL},\n", NIL); DelWrapper(df); Delete(dispatch); Delete(dname); } } Delete(incode); Delete(cleanup); Delete(outarg); Delete(argstr); Delete(args); DelWrapper(f); return SWIG_OK; } /* ------------------------------------------------------------ * variableWrapper() * ------------------------------------------------------------ */ virtual int variableWrapper(Node *n) { String *name = Getattr(n,"name"); String *iname = Getattr(n,"sym:name"); SwigType *t = Getattr(n,"type"); String *setname = 0; String *getname = 0; Wrapper *setf = 0, *getf = 0; int readonly = 0; String *tm; if (!addSymbol(iname,n)) return SWIG_ERROR; /* Create a function for getting a variable */ getf = NewWrapper(); getname = Swig_name_wrapper(Swig_name_get(iname)); Printv(getf->def,"static char *",getname,"(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags) {",NIL); Wrapper_add_local(getf,"value", "Tcl_Obj *value = 0"); if ((tm = Swig_typemap_lookup_new("varout",n,name,0))) { Replaceall(tm,"$source", name); Replaceall(tm,"$target","value"); Replaceall(tm,"$result", "value"); Printf(getf->code, "%s\n",tm); Printf(getf->code, "if (value) {\n"); Printf(getf->code, "Tcl_SetVar2(interp,name1,name2,Tcl_GetStringFromObj(value,NULL), flags);\n"); Printf(getf->code, "Tcl_DecrRefCount(value);\n"); Printf(getf->code, "}\n"); Printf(getf->code, "return NULL;\n"); Printf(getf->code,"}\n"); Wrapper_print(getf,f_wrappers); } else { Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t,0)); DelWrapper(getf); return SWIG_NOWRAP; } DelWrapper(getf); /* Try to create a function setting a variable */ if (!Getattr(n,"feature:immutable")) { setf = NewWrapper(); setname = Swig_name_wrapper(Swig_name_set(iname)); Printv(setf->def,"static char *",setname, "(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags) {",NIL); Wrapper_add_local(setf,"value", "Tcl_Obj *value = 0"); Wrapper_add_local(setf,"name1o", "Tcl_Obj *name1o = 0"); if ((tm = Swig_typemap_lookup_new("varin", n, name, 0))) { Replaceall(tm,"$source","value"); Replaceall(tm,"$target",name); Replaceall(tm,"$input", "value"); Printf(setf->code,"name1o = Tcl_NewStringObj(name1,-1);\n"); Printf(setf->code,"value = Tcl_ObjGetVar2(interp, name1o, 0, flags);\n"); Printf(setf->code,"Tcl_DecrRefCount(name1o);\n"); Printf(setf->code,"if (!value) return NULL;\n"); Printf(setf->code,"%s\n", tm); Printf(setf->code,"return NULL;\n"); Printf(setf->code,"}\n"); if (setf) Wrapper_print(setf,f_wrappers); } else { Swig_warning(WARN_TYPEMAP_VARIN_UNDEF,input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t,0)); readonly = 1; } DelWrapper(setf); } Printv(var_tab, tab4,"{ SWIG_prefix \"", iname, "\", 0, (swig_variable_func) ", getname, ",", NIL); if (readonly || Getattr(n,"feature:immutable")) { static int readonlywrap = 0; if (!readonlywrap) { Wrapper *ro = NewWrapper(); Printf(ro->def, "static const char *swig_readonly(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags) {"); Printv(ro->code, "return \"Variable is read-only\";\n", "}\n", NIL); Wrapper_print(ro,f_wrappers); readonlywrap = 1; DelWrapper(ro); } Printf(var_tab, "(swig_variable_func) swig_readonly},\n"); } else { Printv(var_tab, "(swig_variable_func) ", setname, "},\n",NIL); } Delete(setname); Delete(getname); return SWIG_OK; } /* ------------------------------------------------------------ * constantWrapper() * ------------------------------------------------------------ */ virtual int constantWrapper(Node *n) { String *name = Getattr(n,"name"); String *iname = Getattr(n,"sym:name"); SwigType *type = Getattr(n,"type"); String *value = Getattr(n,"value"); String *tm; if (!addSymbol(iname,n)) return SWIG_ERROR; /* Special hook for member pointer */ if (SwigType_type(type) == T_MPOINTER) { String *wname = Swig_name_wrapper(iname); Printf(f_wrappers, "static %s = %s;\n", SwigType_str(type,wname), value); value = Char(wname); } if ((tm = Swig_typemap_lookup_new("consttab",n,name,0))) { Replaceall(tm,"$source",value); Replaceall(tm,"$target",name); Replaceall(tm,"$value",value); Printf(const_tab,"%s,\n", tm); } else if ((tm = Swig_typemap_lookup_new("constcode", n, name, 0))) { Replaceall(tm,"$source", value); Replaceall(tm,"$target", name); Replaceall(tm,"$value",value); Printf(f_init, "%s\n", tm); } else { Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n"); return SWIG_NOWRAP; } return SWIG_OK; } /* ------------------------------------------------------------ * nativeWrapper() * ------------------------------------------------------------ */ virtual int nativeWrapper(Node *n) { String *name = Getattr(n,"sym:name"); String *funcname = Getattr(n,"wrap:name"); if (!addSymbol(funcname,n)) return SWIG_ERROR; Printf(f_init,"\t Tcl_CreateObjCommand(interp, SWIG_prefix \"%s\", (swig_wrapper_func) %s, (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);\n",name, funcname); return SWIG_OK; } /* ------------------------------------------------------------ * classHandler() * ------------------------------------------------------------ */ virtual int classHandler(Node *n) { String *mangled_classname = 0; String *real_classname = 0; have_constructor = 0; have_destructor = 0; destructor_action = 0; if (itcl) { constructor = NewString(""); //destructor = NewString(""); base_classes = NewString(""); base_class_init = NewString(""); //methods = NewString(""); imethods = NewString(""); attributes = NewString(""); attribute_traces = NewString(""); //iattribute_traces = NewString(""); have_base_classes = 0; have_methods = 0; have_attributes = 0; } class_name = Getattr(n,"sym:name"); if (!addSymbol(class_name,n)) return SWIG_ERROR; real_classname = Getattr(n,"name"); mangled_classname = Swig_name_mangle(real_classname); attr_tab = NewString(""); Printf(attr_tab, "static swig_attribute swig_"); Printv(attr_tab, mangled_classname, "_attributes[] = {\n", NIL); methods_tab = NewStringf(""); Printf(methods_tab,"static swig_method swig_"); Printv(methods_tab, mangled_classname, "_methods[] = {\n", NIL); /* Generate normal wrappers */ Language::classHandler(n); SwigType *t = Copy(Getattr(n,"name")); SwigType_add_pointer(t); // Catch all: eg. a class with only static functions and/or variables will not have 'remembered' // SwigType_remember(t); String *wrap_class = NewStringf("&_wrap_class_%s", mangled_classname); SwigType_remember_clientdata(t,wrap_class); // t = Copy(Getattr(n,"classtype")); // SwigType_add_pointer(t); String *rt = Copy(Getattr(n,"classtype")); SwigType_add_pointer(rt); // Register the class structure with the type checker /* Printf(f_init,"SWIG_TypeClientData(SWIGTYPE%s, (void *) &_wrap_class_%s);\n", SwigType_manglestr(t), mangled_classname); */ if (have_destructor) { Printv(f_wrappers, "static void swig_delete_", class_name, "(void *obj) {\n", NIL); if (destructor_action) { Printv(f_wrappers, SwigType_str(rt,"arg1"), " = (", SwigType_str(rt,0), ") obj;\n", NIL); Printv(f_wrappers, destructor_action, NIL); } else { if (CPlusPlus) { Printv(f_wrappers," delete (", SwigType_str(rt,0), ") obj;\n",NIL); } else { Printv(f_wrappers," free(obj);\n",NIL); } } Printf(f_wrappers,"}\n"); } Printf(methods_tab, " {0,0}\n};\n"); Printv(f_wrappers,methods_tab,NIL); Printf(attr_tab, " {0,0,0}\n};\n"); Printv(f_wrappers,attr_tab,NIL); /* Handle inheritance */ String *base_class = NewString(""); if( itcl ) { base_classes = NewString(""); } List *baselist = Getattr(n,"bases"); if (baselist && Len(baselist)) { Iterator b; int index = 0; b = First(baselist); while (b.item) { String *bname = Getattr(b.item, "name"); if ((!bname) || Getattr(b.item,"feature:ignore") || (!Getattr(b.item,"module"))) { b = Next(b); continue; } if( itcl ) { have_base_classes = 1; Printv( base_classes, bname, " ", NIL ); Printv( base_class_init , " ", bname, "Ptr::constructor $ptr\n", NIL ); } String *bmangle = Swig_name_mangle(bname); // Printv(f_wrappers,"extern swig_class _wrap_class_", bmangle, ";\n", NIL); // Printf(base_class,"&_wrap_class_%s",bmangle); Printf(base_class,"0"); /* Put code to register base classes in init function */ Printf(f_init,"/* Register base : %s */\n", bmangle); Printf(f_init,"swig_%s_bases[%d] = \"%s *\";\n", mangled_classname, index, SwigType_namestr(bname)); b = Next(b); index++; Putc(',',base_class); Delete(bmangle); } } if( itcl ) { String *ptrclass = NewString(""); // First, build the pointer base class Printv( ptrclass, "itcl::class ", class_name,"Ptr {\n", NIL ); if( have_base_classes ) Printv( ptrclass, " inherit ", base_classes, "\n", NIL ); // Define protected variables for SWIG object pointer Printv( ptrclass, " protected variable swigobj\n", " protected variable thisown\n", NIL ); // Define public variables if ( have_attributes ) { Printv( ptrclass, attributes, NIL ); // base class swig_getset was being called for complex inheritance trees if ( nspace ) { Printv( ptrclass, " protected method ", class_name, "_swig_getset {var name1 name2 op} {\n" , NIL ); Printv( ptrclass, " switch -exact -- $op {\n", " r {set $var [", ns_name, "::", class_name, "_[set var]_get $swigobj]}\n", " w {", ns_name, "::", class_name, "_${var}_set $swigobj [set $var]}\n", " }\n", " }\n" , NIL ); } else { Printv( ptrclass, " protected method ", class_name, "_swig_getset {var name1 name2 op} {\n", " switch -exact -- $op {\n", " r {set $var [", class_name, "_[set var]_get $swigobj]}\n", " w {", class_name, "_${var}_set $swigobj [set $var]}\n", " }\n", " }\n", NIL ); } } // Add the constructor, which may include // calls to base class class constructors Printv( ptrclass, " constructor { ptr } {\n", NIL ); if( have_base_classes ) { Printv( ptrclass, base_class_init, NIL ); Printv( ptrclass, " } {\n", NIL ); } Printv( ptrclass, " set swigobj $ptr\n", " set thisown 0\n", NIL ); if( have_attributes ) { Printv( ptrclass, attribute_traces, NIL ); } Printv( ptrclass, " }\n", NIL ); // Add destructor Printv( ptrclass, " destructor {\n", " set d_func delete_", class_name, "\n", " if { $thisown && ([info command $d_func] != \"\") } {\n" " $d_func $swigobj\n", " }\n", " }\n", NIL ); // Add methods if( have_methods ) { Printv( ptrclass, imethods, NIL ); }; // Close out the pointer class Printv( ptrclass, "}\n\n", NIL ); Printv( f_shadow, ptrclass, NIL ); // pointer class end // Create the "real" class. Printv( f_shadow, "itcl::class ", class_name," {\n", NIL ); Printv( f_shadow, " inherit ", class_name,"Ptr\n", NIL ); // If we have a constructor, then use it. // If not, then we must have an abstract class without // any constructor. So we create a class constructor // which will fail for this class (but not for inherited // classes). Note that the constructor must fail before // calling the ptrclass constructor. if ( have_constructor ) { Printv( f_shadow, constructor, NIL ); } else { Printv( f_shadow, " constructor { } {\n", NIL ); Printv( f_shadow, " # This constructor will fail if called directly\n", NIL ); Printv( f_shadow, " if { [info class] == \"::", class_name, "\" } {\n", NIL ); Printv( f_shadow, " error \"No constructor for class ", class_name, "\"\n", NIL ); Printv( f_shadow, " }\n", NIL ); Printv( f_shadow, " }\n", NIL ); } Printv( f_shadow, "}\n\n", NIL ); }; Printv(f_wrappers,"static const char *swig_",mangled_classname,"_bases[] = {", base_class,"0};\n", NIL); Delete(base_class); Printv(f_wrappers, "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(class_name))); } else { Printf(f_wrappers,"0"); } if (have_destructor) { Printv(f_wrappers, ", swig_delete_", class_name,NIL); } else { Printf(f_wrappers,",0"); } Printv(f_wrappers, ", swig_", mangled_classname, "_methods, swig_", mangled_classname, "_attributes, swig_", mangled_classname,"_bases };\n", NIL); if( !itcl ) { Printv(cmd_tab, tab4, "{ SWIG_prefix \"", class_name, "\", (swig_wrapper_func) SWIG_ObjectConstructor, &_wrap_class_", mangled_classname, "},\n", NIL); }; Delete(t); Delete(mangled_classname); return SWIG_OK; } /* ------------------------------------------------------------ * memberfunctionHandler() * ------------------------------------------------------------ */ virtual int memberfunctionHandler(Node *n) { String *name = Getattr(n,"name"); String *iname = GetChar(n,"sym:name"); String *realname, *rname; Language::memberfunctionHandler(n); realname = iname ? iname : name; rname = Swig_name_wrapper(Swig_name_member(class_name, realname)); if (!Getattr(n,"sym:nextSibling")) { Printv(methods_tab, tab4, "{\"", realname, "\", ", rname, "}, \n", NIL); } if( itcl ) { ParmList *l = Getattr(n,"parms"); Parm *p = 0; String *pname = NewString(""); // Add this member to our class handler function Printv( imethods, tab2, "method ", realname, " [list ", NIL ); int pnum = 0; for (p = l; p; p = nextSibling(p)) { String *pn = Getattr(p,"name"); String *dv = Getattr(p,"value"); SwigType *pt = Getattr(p,"type"); Printv( pname, ",(", pt, ")", NIL ); Clear( pname ); /* Only print an argument if not void */ if (Cmp(pt,"void") != 0) { if( Len( pn ) > 0 ) { Printv( pname, pn, NIL ); } else { Printf( pname, "p%d", pnum ); } if( Len( dv ) > 0 ) { String *defval = NewString( dv ); if( nspace ) { Insert( defval, 0, "::"); Insert( defval, 0, ns_name ); } if( Strncmp( dv, "(", 1 ) == 0 ) { Insert( defval, 0, "$"); Replaceall( defval, "(", ""); Replaceall( defval, ")", ""); } Printv( imethods, "[list ", pname, " ", defval, "] ", NIL ); } else { Printv( imethods, pname, " ", NIL ); } } ++pnum; } Printv( imethods, "] ", NIL ); if( nspace ) { Printv( imethods,"{ ", ns_name, "::", class_name, "_", realname, " $swigobj" , NIL ); } else { Printv( imethods,"{ ", class_name, "_", realname, " $swigobj" , NIL ); }; pnum = 0; for (p = l; p; p = nextSibling(p)) { String *pn = Getattr(p,"name"); SwigType *pt = Getattr(p,"type"); Clear( pname ); /* Only print an argument if not void */ if (Cmp(pt,"void") != 0) { if( Len( pn ) > 0 ) { Printv( pname, pn, NIL ); } else { Printf( pname, "p%d", pnum ); } Printv( imethods, " $", pname, NIL ); } ++pnum; } Printv( imethods, " }\n", NIL ); have_methods = 1; } Delete(rname); return SWIG_OK; } /* ------------------------------------------------------------ * membervariableHandler() * ------------------------------------------------------------ */ virtual int membervariableHandler(Node *n) { String *symname = Getattr(n,"sym:name"); String *rname; Language::membervariableHandler(n); Printv(attr_tab, tab4, "{ \"-", symname, "\",", NIL); rname = Swig_name_wrapper(Swig_name_get(Swig_name_member(class_name,symname))); Printv(attr_tab, rname, ", ", NIL); Delete(rname); if (!Getattr(n,"feature:immutable")) { rname = Swig_name_wrapper(Swig_name_set(Swig_name_member(class_name,symname))); Printv(attr_tab, rname, "},\n",NIL); Delete(rname); } else { Printf(attr_tab, "0 },\n"); } if( itcl ) { Printv( attributes, " public variable ", symname, "\n", NIL ); Printv( attribute_traces, " trace variable ", symname, " rw [list ", class_name, "_swig_getset ", symname, "]\n", NIL ); Printv( attribute_traces, " set ", symname, "\n", NIL ); have_attributes = 1; } return SWIG_OK; } /* ------------------------------------------------------------ * constructorHandler() * ------------------------------------------------------------ */ virtual int constructorHandler(Node *n) { Language::constructorHandler(n); if( itcl ) { String *name = Getattr(n,"name"); String *iname = GetChar(n,"sym:name"); String *realname; ParmList *l = Getattr(n,"parms"); Parm *p = 0; String *pname = NewString(""); realname = iname ? iname : name; if( !have_constructor ) { // Add this member to our class handler function Printf( constructor, " constructor { " ); // Add parameter list int pnum = 0; for (p = l; p; p = nextSibling(p)) { SwigType *pt = Getattr(p,"type"); String *pn = Getattr(p,"name"); String *dv = Getattr(p,"value"); Clear( pname ); /* Only print an argument if not void */ if (Cmp(pt,"void") != 0) { if( Len( pn ) > 0 ) { Printv( pname, pn, NIL ); } else { Printf( pname, "p%d", pnum ); } if( Len( dv ) > 0 ) { Printv( constructor, "{", pname, " {", dv, "} } ", NIL ); } else { Printv( constructor, pname, " ", NIL ); } } ++pnum; } Printf( constructor, "} { \n" ); // [BRE] 08/17/00 Added test to see if we are instantiating this object // type, or, if this constructor is being called as part of the itcl // inheritance heirarchy. // In the former case, we need to call the C++ constructor, in the // latter we don't, or we end up with two C++ objects. // Check to see if we are instantiating a 'realname' or something // derived from it. // Printv( constructor, " if { [string equal -nocase \"", realname, "\" \"[namespace tail [info class]]\" ] } {\n", NIL ); // Call to constructor wrapper and parent Ptr class // [BRE] add -namespace/-prefix support if( nspace ) { Printv( constructor, " ", realname, "Ptr::constructor [", ns_name, "::new_", realname, NIL ); } else { Printv( constructor, " ", realname, "Ptr::constructor [new_", realname, NIL ); } pnum = 0; for (p = l; p; p = nextSibling(p)) { SwigType *pt = Getattr(p,"type"); String *pn = Getattr(p,"name"); Clear( pname ); /* Only print an argument if not void */ if (Cmp(pt,"void") != 0) { if( Len( pn ) > 0 ) { Printv( pname, pn, NIL ); } else { Printf( pname, "p%d", pnum ); } Printv( constructor, " $", pname, NIL ); } ++pnum; } Printv( constructor, "]\n", " }\n", " } {\n", " set thisown 1\n", " }\n", NIL ); } } have_constructor = 1; return SWIG_OK; } /* ------------------------------------------------------------ * destructorHandler() * ------------------------------------------------------------ */ virtual int destructorHandler(Node *n) { Language::destructorHandler(n); have_destructor = 1; destructor_action = Getattr(n,"wrap:action"); return SWIG_OK; } /* ------------------------------------------------------------ * validIdentifier() * ------------------------------------------------------------ */ virtual int validIdentifier(String *s) { if (Strchr(s,' ')) return 0; return 1; } /* ------------------------------------------------------------ * usage_string() * ------------------------------------------------------------ */ char * usage_string(char *iname, SwigType *, ParmList *l) { static String *temp = 0; Parm *p; int i, numopt,pcount; if (!temp) temp = NewString(""); Clear(temp); if (nspace) { Printf(temp,"%s::%s", ns_name,iname); } else { Printf(temp,"%s ", iname); } /* Now go through and print parameters */ i = 0; pcount = emit_num_arguments(l); numopt = pcount - emit_num_required(l); for (p = l; p; p = nextSibling(p)) { SwigType *pt = Getattr(p,"type"); String *pn = Getattr(p,"name"); /* Only print an argument if not ignored */ if (!checkAttribute(p,"tmap:in:numinputs","0")) { if (i >= (pcount-numopt)) Putc('?',temp); if (Len(pn) > 0) { Printf(temp, "%s",pn); } else { Printf(temp,"%s", SwigType_str(pt,0)); } if (i >= (pcount-numopt)) Putc('?',temp); Putc(' ',temp); i++; } } return Char(temp); } }; /* ---------------------------------------------------------------------- * swig_tcl() - Instantiate module * ---------------------------------------------------------------------- */ static Language * new_swig_tcl() { return new TCL8(); } extern "C" Language * swig_tcl(void) { return new_swig_tcl(); } cableswig-0.1.0+git20150808.orig/SWIG/Source/Modules/swigmod.h0000644000175000000620000002424312561312227022275 0ustar stevestaff/* ----------------------------------------------------------------------------- * swigmod.h * * Main header file for SWIG modules * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1998-2000. The University of Chicago * Copyright (C) 1995-1998. The University of Utah and The Regents of the * University of California. * * See the file LICENSE for information on usage and redistribution. * * /cvsroot/SWIG/Source/Modules/swigmod.h,v 1.20 2004/02/12 21:48:55 cheetah Exp * ----------------------------------------------------------------------------- */ #ifndef SWIGMOD_H_ #define SWIGMOD_H_ #include #include #include #include "swig.h" #include "preprocessor.h" #include "swigwarn.h" #define NOT_VIRTUAL 0 #define PLAIN_VIRTUAL 1 #define PURE_VIRTUAL 2 extern char *input_file; extern int line_number; extern int start_line; extern int CPlusPlus; // C++ mode extern int Extend; // Extend mode extern int NoInclude; // NoInclude flag extern int Verbose; extern int IsVirtual; extern int ImportMode; extern int NoExcept; // -no_except option extern int Abstract; // abstract base class extern int SmartPointer; // smart pointer methods being emitted /* Overload "argc" and "argv" */ extern String *argv_template_string; extern String *argc_template_string; /* Miscellaneous stuff */ #define tab2 " " #define tab4 " " #define tab8 " " class Dispatcher { public: virtual ~Dispatcher(); virtual int emit_one(Node *n); virtual int emit_children(Node *n); virtual int defaultHandler(Node *n); /* Top of the parse tree */ virtual int top(Node *n) = 0; /* SWIG directives */ virtual int applyDirective(Node *n); virtual int clearDirective(Node *n); virtual int constantDirective(Node *n); virtual int extendDirective(Node *n); virtual int fragmentDirective(Node *n); virtual int importDirective(Node *n); virtual int includeDirective(Node *n); virtual int insertDirective(Node *n); virtual int moduleDirective(Node *n); virtual int nativeDirective(Node *n); virtual int pragmaDirective(Node *n); virtual int typemapDirective(Node *n); virtual int typemapitemDirective(Node *n); virtual int typemapcopyDirective(Node *n); virtual int typesDirective(Node *n); /* C/C++ parsing */ virtual int cDeclaration(Node *n); virtual int externDeclaration(Node *n); virtual int enumDeclaration(Node *n); virtual int enumvalueDeclaration(Node *n); virtual int classDeclaration(Node *n); virtual int classforwardDeclaration(Node *n); virtual int constructorDeclaration(Node *n); virtual int destructorDeclaration(Node *n); virtual int accessDeclaration(Node *n); virtual int usingDeclaration(Node *n); virtual int namespaceDeclaration(Node *n); virtual int templateDeclaration(Node *n); }; /************************************************************************ * class language: * * This class defines the functions that need to be supported by the * scripting language being used. The translator calls these virtual * functions to output different types of code for different languages. *************************************************************************/ class Language : public Dispatcher { public: Language(); virtual ~Language(); virtual int emit_one(Node *n); /* Parse command line options */ virtual void main(int argc, char *argv[]); /* Top of the parse tree */ virtual int top(Node *n); /* SWIG directives */ virtual int applyDirective(Node *n); virtual int clearDirective(Node *n); virtual int constantDirective(Node *n); virtual int extendDirective(Node *n); virtual int fragmentDirective(Node *n); virtual int importDirective(Node *n); virtual int includeDirective(Node *n); virtual int insertDirective(Node *n); virtual int moduleDirective(Node *n); virtual int nativeDirective(Node *n); virtual int pragmaDirective(Node *n); virtual int typemapDirective(Node *n); virtual int typemapcopyDirective(Node *n); virtual int typesDirective(Node *n); /* C/C++ parsing */ virtual int cDeclaration(Node *n); virtual int externDeclaration(Node *n); virtual int enumDeclaration(Node *n); virtual int enumvalueDeclaration(Node *n); virtual int classDeclaration(Node *n); virtual int classforwardDeclaration(Node *n); virtual int constructorDeclaration(Node *n); virtual int destructorDeclaration(Node *n); virtual int accessDeclaration(Node *n); virtual int namespaceDeclaration(Node *n); virtual int usingDeclaration(Node *n); /* Function handlers */ virtual int functionHandler(Node *n); virtual int globalfunctionHandler(Node *n); virtual int memberfunctionHandler(Node *n); virtual int staticmemberfunctionHandler(Node *n); virtual int callbackfunctionHandler(Node *n); /* Variable handlers */ virtual int variableHandler(Node *n); virtual int globalvariableHandler(Node *n); virtual int membervariableHandler(Node *n); virtual int staticmembervariableHandler(Node *n); /* C++ handlers */ virtual int memberconstantHandler(Node *n); virtual int constructorHandler(Node *n); virtual int copyconstructorHandler(Node *n); virtual int destructorHandler(Node *n); virtual int classHandler(Node *n); /* Miscellaneous */ virtual int typedefHandler(Node *n); /* Low-level code generation */ virtual int constantWrapper(Node *n); virtual int variableWrapper(Node *n); virtual int functionWrapper(Node *n); virtual int nativeWrapper(Node *n); /* C++ director class generation */ virtual int classDirector(Node *n); virtual int classDirectorInit(Node *n); virtual int classDirectorEnd(Node *n); virtual int unrollVirtualMethods(Node *n, Node *parent, Hash *vm, int default_director, int &virtual_destructor); virtual int classDirectorConstructor(Node *n); virtual int classDirectorDefaultConstructor(Node *n); virtual int classDirectorMethod(Node *n, Node *parent, String *super); virtual int classDirectorConstructors(Node *n); virtual int classDirectorMethods(Node *n); virtual int classDirectorDisown(Node *n); /* Miscellaneous */ virtual int validIdentifier(String *s); /* valid identifier? */ virtual int addSymbol(String *s, Node *n); /* Add symbol */ virtual Node *symbolLookup(String *s); /* Symbol lookup */ virtual Node *classLookup(SwigType *s); /* Class lookup */ virtual int abstractClassTest(Node *n); /* Is class really abstract? */ /* Allow director related code generation */ void allow_directors(int val = 1); /* Return true if directors are enabled */ int directorsEnabled() const; /* Allow director protected members related code generation */ void allow_dirprot(int val = 1); /* Returns the dirprot mode */ int dirprot_mode() const; /* Set none comparison string */ void setSubclassInstanceCheck(String *s); /* Set overload variable templates argc and argv */ void setOverloadResolutionTemplates(String *argc, String *argv); protected: /* Patch C++ pass-by-value */ static void patch_parms(Parm *p); /* Allow multiple-input typemaps */ void allow_multiple_input(int val = 1); /* Allow overloaded functions */ void allow_overloading(int val = 1); /* Wrapping class query */ int is_wrapping_class(); /* Return the node for the current class */ Node *getCurrentClass() const; /* Return the real name of the current class */ String *getClassName() const; /* Return the current class prefix */ String *getClassPrefix() const; /* Fully qualified type name to use */ String *getClassType() const; /* Return true if the current method is part of a smart-pointer */ int is_smart_pointer() const; /* Director subclass comparison test */ String *none_comparison; /* Director constructor "template" code */ String *director_ctor_code; private: Hash *symbols; Hash *classtypes; int overloading; int multiinput; int directors; }; int SWIG_main(int, char **, Language *); void emit_args(SwigType *, ParmList *, Wrapper *f); void SWIG_exit(int); /* use EXIT_{SUCCESS,FAILURE} */ void SWIG_config_file(const String_or_char *); const String *SWIG_output_directory(); void SWIG_config_cppext(const char *ext); void SWIG_library_directory(const char *); int emit_num_arguments(ParmList *); int emit_num_required(ParmList *); int emit_isvarargs(ParmList *); void emit_attach_parmmaps(ParmList *, Wrapper *f); void emit_mark_varargs(ParmList *l); void emit_action(Node *n, Wrapper *f); void Swig_overload_check(Node *n); String *Swig_overload_dispatch(Node *n, const String_or_char *fmt, int *); SwigType *cplus_value_type(SwigType *t); /* directors.cxx start */ String *Swig_csuperclass_call(String* base, String* method, ParmList* l); String *Swig_class_declaration(Node *n, String *name); String *Swig_class_name(Node *n); String *Swig_method_call(String_or_char *name, ParmList *parms); String *Swig_method_decl(SwigType *s, const String_or_char *id, List *args, int strip, int values); String *Swig_director_declaration(Node *n); /* directors.cxx end */ extern "C" { void SWIG_typemap_lang(const char *); typedef Language *(*ModuleFactory)(void); } void Swig_register_module(const char *name, ModuleFactory fac); ModuleFactory Swig_find_module(const char *name); /* Utilities */ int is_public(Node* n); int is_private(Node* n); int is_protected(Node* n); int is_member_director(Node* parentnode, Node* member); int is_member_director(Node* member); void Wrapper_virtual_elimination_mode_set(int); void Wrapper_director_protected_mode_set(int); /* Contracts */ void Swig_contracts(Node *n); void Swig_contract_mode_set(int flag); int Swig_contract_mode_get(); /* Browser */ void Swig_browser(Node *n, int); void Swig_default_allocators(Node *n); void Swig_process_types(Node *n); #endif cableswig-0.1.0+git20150808.orig/SWIG/Source/Modules/swigmain.cxx0000644000175000000620000001036312561312227023013 0ustar stevestaff/******************************************************************************* * Simplified Wrapper and Interface Generator (SWIG) * * swigmain.cxx * * This file is the main entry point to SWIG. It collects the command * line options, registers built-in language modules, and instantiates * a module for code generation. If adding new language modules * to SWIG, you would modify this file. * * Author : David Beazley * * Department of Computer Science * University of Chicago * 1100 E 58th Street * Chicago, IL 60637 * beazley@cs.uchicago.edu * * Please read the file LICENSE for the copyright and terms by which SWIG * can be used and distributed. *******************************************************************************/ char cvsroot_swigmain_cxx[] = "/cvsroot/SWIG/Source/Modules/swigmain.cxx,v 1.9 2004/01/22 22:42:17 cheetah Exp"; #include "swigmod.h" /* Module factories. These functions are used to instantiate the built-in language modules. If adding a new language module to SWIG, place a similar function here. Make sure the function has "C" linkage. This is required so that modules can be dynamically loaded in future versions. */ extern "C" { Language *swig_tcl(void); Language *swig_python(void); Language *swig_perl5(void); Language *swig_ruby(void); Language *swig_guile(void); Language *swig_mzscheme(void); Language *swig_java(void); Language *swig_php(void); Language *swig_ocaml(void); Language *swig_pike(void); Language *swig_sexp(void); Language *swig_xml(void); Language *swig_chicken(void); Language *swig_csharp(void); } struct swig_module { const char *name; ModuleFactory fac; const char *help; }; /* Association of command line options to language modules. Place an entry for new language modules here, keeping the list sorted alphabetically. */ swig_module modules[] = { {"-chicken", swig_chicken, "CHICKEN"}, {"-csharp", swig_csharp, "C#"}, {"-guile", swig_guile, "Guile"}, {"-java", swig_java, "Java"}, {"-mzscheme", swig_mzscheme, "Mzscheme"}, {"-ocaml", swig_ocaml, "Ocaml"}, {"-perl", swig_perl5, "Perl"}, {"-perl5", swig_perl5, 0}, {"-php", swig_php, "PHP"}, {"-php4", swig_php, 0}, {"-pike", swig_pike, "Pike"}, {"-python", swig_python, "Python"}, {"-ruby", swig_ruby, "Ruby"}, {"-sexp", swig_sexp, "Lisp S-Expressions"}, {"-tcl", swig_tcl, "Tcl"}, {"-tcl8", swig_tcl, 0}, {"-xml", swig_xml, "XML"}, {NULL, NULL, NULL} }; #ifdef MACSWIG #include #include #endif #ifndef SWIG_LANG #define SWIG_LANG "-python" #endif //----------------------------------------------------------------- // main() // // Main program. Initializes the files and starts the parser. //----------------------------------------------------------------- int main(int argc, char **argv) { int i; Language *dl = 0; ModuleFactory fac = 0; #ifdef MACSWIG SIOUXSettings.asktosaveonclose = false; argc = ccommand(&argv); #endif /* Register built-in modules */ for (i = 0; modules[i].name; i++) { Swig_register_module(modules[i].name, modules[i].fac); } Swig_init_args(argc,argv); /* Get options */ for (i = 1; i < argc; i++) { if (argv[i]) { fac = Swig_find_module(argv[i]); if (fac) { dl = (fac)(); Swig_mark_arg(i); } else if (strcmp(argv[i],"-nolang") == 0) { dl = new Language; Swig_mark_arg(i); } else if ((strcmp(argv[i],"-dnone") == 0) || (strcmp(argv[i],"-dhtml") == 0) || (strcmp(argv[i],"-dlatex") == 0) || (strcmp(argv[i],"-dascii") == 0) || (strcmp(argv[i],"-stat") == 0)) { Printf(stderr,"swig: Warning. %s option deprecated.\n",argv[i]); Swig_mark_arg(i); } else if (strcmp(argv[i],"-help") == 0) { Printf(stderr,"Target Language Options:\n"); for (int j = 0; modules[j].name; j++) { if (modules[j].help) { Printf(stderr," %-15s - Generate %s wrappers\n", modules[j].name, modules[j].help); } } Swig_mark_arg(i); } } } if (!dl) { fac = Swig_find_module(SWIG_LANG); if (fac) { dl = (fac)(); } } return SWIG_main(argc,argv,dl); } cableswig-0.1.0+git20150808.orig/SWIG/Source/Modules/lang.cxx0000644000175000000620000021640212561312227022120 0ustar stevestaff/* ----------------------------------------------------------------------------- * lang.cxx * * Language base class functions. Default C++ handling is also implemented here. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1998-2000. The University of Chicago * Copyright (C) 1995-1998. The University of Utah and The Regents of the * University of California. * * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_lang_cxx[] = "/cvsroot/SWIG/Source/Modules/lang.cxx,v 1.58 2004/02/03 21:19:19 cheetah Exp"; #include "swigmod.h" #include "cparse.h" #include static int director_protected_mode = 0; /* set to 0 on default */ /* Set director_protected_mode */ void Wrapper_director_protected_mode_set(int flag) { director_protected_mode = flag; } extern "C" { int Swig_need_protected() { return director_protected_mode; } } /* Some status variables used during parsing */ static int InClass = 0; /* Parsing C++ or not */ static String *ClassName = 0; /* This is the real name of the current class */ static String *ClassPrefix = 0; /* Class prefix */ static String *ClassType = 0; /* Fully qualified type name to use */ int Abstract = 0; int ImportMode = 0; int IsVirtual = 0; static String *AttributeFunctionGet = 0; static String *AttributeFunctionSet = 0; static int cplus_mode = 0; static Node *CurrentClass = 0; int line_number = 0; char *input_file = 0; int SmartPointer = 0; extern int GenerateDefault; extern int ForceExtern; extern int NoExtern; /* import modes */ #define IMPORT_MODE 1 #define IMPORT_MODULE 2 /* C++ access modes */ #define CPLUS_PUBLIC 0 #define CPLUS_PROTECTED 1 #define CPLUS_PRIVATE 2 Dispatcher::~Dispatcher() { } /* ---------------------------------------------------------------------- * Dispatcher::emit_one() * * Dispatch a single node * ---------------------------------------------------------------------- */ int Dispatcher::emit_one(Node *n) { String *wrn; int ret = SWIG_OK; char *tag = Char(nodeType(n)); if (!tag) { Printf(stderr,"SWIG: Fatal internal error. Malformed parse tree node!\n"); return SWIG_ERROR; } /* Do not proceed if marked with an error */ if (Getattr(n,"error")) return SWIG_OK; /* Look for warnings */ wrn = Getattr(n,"feature:warnfilter"); if (wrn) { Swig_warnfilter(wrn,1); } /* ============================================================ * C/C++ parsing * ============================================================ */ if (strcmp(tag,"extern") == 0) { ret = externDeclaration(n); } else if (strcmp(tag,"cdecl") == 0) { ret = cDeclaration(n); } else if (strcmp(tag,"enum") == 0) { ret = enumDeclaration(n); } else if (strcmp(tag,"enumitem") == 0) { ret = enumvalueDeclaration(n); } else if (strcmp(tag,"class") == 0) { ret = classDeclaration(n); } else if (strcmp(tag,"classforward") == 0) { ret = classforwardDeclaration(n); } else if (strcmp(tag,"constructor") == 0) { ret = constructorDeclaration(n); } else if (strcmp(tag,"destructor") == 0) { ret = destructorDeclaration(n); } else if (strcmp(tag,"access") == 0) { ret = accessDeclaration(n); } else if (strcmp(tag,"using") == 0) { ret = usingDeclaration(n); } else if (strcmp(tag,"namespace") == 0) { ret = namespaceDeclaration(n); } else if (strcmp(tag,"template") == 0) { ret = templateDeclaration(n); } /* =============================================================== * SWIG directives * =============================================================== */ else if (strcmp(tag,"top") == 0) { ret = top(n); } else if (strcmp(tag,"extend") == 0) { ret = extendDirective(n); } else if (strcmp(tag,"apply") == 0) { ret = applyDirective(n); } else if (strcmp(tag,"clear") == 0) { ret = clearDirective(n); } else if (strcmp(tag,"constant") == 0) { ret = constantDirective(n); } else if (strcmp(tag,"fragment") == 0) { ret = fragmentDirective(n); } else if (strcmp(tag,"import") == 0) { ret = importDirective(n); } else if (strcmp(tag,"include") == 0) { ret = includeDirective(n); } else if (strcmp(tag,"insert") == 0) { ret = insertDirective(n); } else if (strcmp(tag,"module") == 0) { ret = moduleDirective(n); } else if (strcmp(tag,"native") == 0) { ret = nativeDirective(n); } else if (strcmp(tag,"pragma") == 0) { ret = pragmaDirective(n); } else if (strcmp(tag,"typemap") == 0) { ret = typemapDirective(n); } else if (strcmp(tag,"typemapcopy") == 0) { ret = typemapcopyDirective(n); } else if (strcmp(tag,"typemapitem") == 0) { ret = typemapitemDirective(n); } else if (strcmp(tag,"types") == 0) { ret = typesDirective(n); } else { Printf(stderr,"%s:%d. Unrecognized parse tree node type '%s'\n", input_file, line_number, tag); ret = SWIG_ERROR; } if (wrn) { Swig_warnfilter(wrn,0); } return ret; } /* ---------------------------------------------------------------------- * Dispatcher::emit_children() * * Emit all children. * ---------------------------------------------------------------------- */ int Dispatcher::emit_children(Node *n) { Node *c; for (c = firstChild(n); c; c = nextSibling(c)) { emit_one(c); } return SWIG_OK; } /* Stubs for dispatcher class. We don't do anything by default---up to derived class to fill in traversal code */ int Dispatcher::defaultHandler(Node *) { return SWIG_OK; } int Dispatcher::extendDirective(Node *n) { return defaultHandler(n); } int Dispatcher::applyDirective(Node *n) { return defaultHandler(n); } int Dispatcher::clearDirective(Node *n) { return defaultHandler(n); } int Dispatcher::constantDirective(Node *n) { return defaultHandler(n); } int Dispatcher::fragmentDirective(Node *n) { return defaultHandler(n); } int Dispatcher::importDirective(Node *n) { return defaultHandler(n); } int Dispatcher::includeDirective(Node *n) { return defaultHandler(n); } int Dispatcher::insertDirective(Node *n) { return defaultHandler(n); } int Dispatcher::moduleDirective(Node *n) { return defaultHandler(n); } int Dispatcher::nativeDirective(Node *n) { return defaultHandler(n); } int Dispatcher::pragmaDirective(Node *n) { return defaultHandler(n); } int Dispatcher::typemapDirective(Node *n) { return defaultHandler(n); } int Dispatcher::typemapitemDirective(Node *n) { return defaultHandler(n); } int Dispatcher::typemapcopyDirective(Node *n) { return defaultHandler(n); } int Dispatcher::typesDirective(Node *n) { return defaultHandler(n); } int Dispatcher::cDeclaration(Node *n) { return defaultHandler(n); } int Dispatcher::externDeclaration(Node *n) { return defaultHandler(n); } int Dispatcher::enumDeclaration(Node *n) { return defaultHandler(n); } int Dispatcher::enumvalueDeclaration(Node *n) { return defaultHandler(n); } int Dispatcher::classDeclaration(Node *n) { return defaultHandler(n); } int Dispatcher::templateDeclaration(Node *n) { return defaultHandler(n); } int Dispatcher::classforwardDeclaration(Node *n) { return defaultHandler(n); } int Dispatcher::constructorDeclaration(Node *n) { return defaultHandler(n); } int Dispatcher::destructorDeclaration(Node *n) { return defaultHandler(n); } int Dispatcher::accessDeclaration(Node *n) { return defaultHandler(n); } int Dispatcher::usingDeclaration(Node *n) { return defaultHandler(n); } int Dispatcher::namespaceDeclaration(Node *n) { return defaultHandler(n); } /* Allocators */ Language::Language() { symbols = NewHash(); classtypes = NewHash(); none_comparison = NewString("$arg != 0"); argc_template_string = NewString("argc"); argv_template_string = NewString("argv[%d]"); director_ctor_code = NewString(""); /* Default director constructor code, passed to Swig_ConstructorToFunction */ Printv(director_ctor_code, "if ( $comparison ) { /* subclassed */\n", " $director_new \n", "} else {\n", " $nondirector_new \n", "}\n", NIL); overloading = 0; multiinput = 0; directors = 0; } Language::~Language() { Delete(symbols); Delete(classtypes); } /* ---------------------------------------------------------------------- emit_one() ---------------------------------------------------------------------- */ int Language::emit_one(Node *n) { int ret; int oldext; if (!n) return SWIG_OK; if (Getattr(n,"feature:ignore")) return SWIG_OK; oldext = Extend; if (Getattr(n,"feature:extend")) Extend = 1; line_number = Getline(n); input_file = Char(Getfile(n)); /* symtab = Getattr(n,"symtab"); if (symtab) { symtab = Swig_symbol_setscope(symtab); } */ ret = Dispatcher::emit_one(n); /* if (symtab) { Swig_symbol_setscope(symtab); } */ Extend = oldext; return ret; } static Parm *nonvoid_parms(Parm *p) { if (p) { SwigType *t = Getattr(p,"type"); if (SwigType_type(t) == T_VOID) return 0; } return p; } /* This is a hack */ SwigType *cplus_value_type(SwigType *t) { Node *n; if (!CPlusPlus) return 0; if (SwigType_isclass(t)) { SwigType *ftd = SwigType_typedef_resolve_all(t); SwigType *td = SwigType_strip_qualifiers(ftd); Delete(ftd); if ((n = Swig_symbol_clookup(td,0))) { if ((Strcmp(nodeType(n),"class") == 0) && (!Getattr(n,"allocate:default_constructor") || (Getattr(n,"allocate:noassign")))) { String *s = NewStringf("SwigValueWrapper< %s >",SwigType_str(td,0)); Delete(td); return s; } else { return 0; } } if (SwigType_issimple(td) && SwigType_istemplate(td)) { String *s = NewStringf("SwigValueWrapper< %s >",SwigType_str(td,0)); Delete(td); return s; } Delete(td); } return 0; } /* Patch C++ pass-by-value */ void Language::patch_parms(Parm *p) { while (p) { SwigType *t = Getattr(p,"type"); SwigType *s = cplus_value_type(t); if (s) { Setattr(p,"alttype",s); Delete(s); } p = nextSibling(p); } } static Node *first_nontemplate(Node *n) { while (n) { if (Strcmp(nodeType(n),"template") != 0) return n; n = Getattr(n,"sym:nextSibling"); } return n; } /* -------------------------------------------------------------------------- * swig_pragma() * * Handle swig pragma directives. * -------------------------------------------------------------------------- */ void swig_pragma(char *lang, char *name, char *value) { if (strcmp(lang,"swig") == 0) { if ((strcmp(name,"make_default") == 0) || ((strcmp(name,"makedefault") == 0))) { GenerateDefault = 1; } else if ((strcmp(name,"no_default") == 0) || ((strcmp(name,"nodefault") == 0))) { GenerateDefault = 0; } else if (strcmp(name,"attributefunction") == 0) { String *nvalue = NewString(value); char *s = strchr(Char(nvalue),':'); if (!s) { Swig_error(input_file, line_number, "Bad value for attributefunction. Expected \"fmtget:fmtset\".\n"); } else { *s = 0; AttributeFunctionGet = NewString(Char(nvalue)); AttributeFunctionSet = NewString(s+1); } Delete(nvalue); } else if (strcmp(name,"noattributefunction") == 0) { AttributeFunctionGet = 0; AttributeFunctionSet = 0; } } } /* ---------------------------------------------------------------------- * Language::top() - Top of parsing tree * ---------------------------------------------------------------------- */ int Language::top(Node *n) { return emit_children(n); } /* ---------------------------------------------------------------------- * Language::extendDirective() * ---------------------------------------------------------------------- */ int Language::extendDirective(Node *n) { int oldam = Extend; int oldmode = cplus_mode; Extend = CWRAP_EXTEND; cplus_mode = CPLUS_PUBLIC; emit_children(n); Extend = oldam; cplus_mode = oldmode; return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::applyDirective() * ---------------------------------------------------------------------- */ int Language::applyDirective(Node *n) { Parm *pattern = Getattr(n,"pattern"); Node *c = firstChild(n); while (c) { Parm *apattern = Getattr(c,"pattern"); if (ParmList_len(pattern) != ParmList_len(apattern)) { Swig_error(input_file, line_number, "Can't apply (%s) to (%s). Number of arguments don't match.\n", ParmList_str(pattern), ParmList_str(apattern)); } else { if (!Swig_typemap_apply(pattern,apattern)) { Swig_warning(WARN_TYPEMAP_APPLY_UNDEF,input_file,line_number,"Can't apply (%s). No typemaps are defined.\n", ParmList_str(pattern)); } } c = nextSibling(c); } return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::clearDirective() * ---------------------------------------------------------------------- */ int Language::clearDirective(Node *n) { Node *p; for (p = firstChild(n); p; p = nextSibling(p)) { ParmList *pattern = Getattr(p,"pattern"); Swig_typemap_clear_apply(pattern); } return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::constantDirective() * ---------------------------------------------------------------------- */ int Language::constantDirective(Node *n) { if (CurrentClass && (cplus_mode != CPLUS_PUBLIC)) return SWIG_NOWRAP; if (!ImportMode) { Swig_require("constantDirective",n,"name", "?value",NIL); String *name = Getattr(n,"name"); String *value = Getattr(n,"value"); if (!value) { value = Copy(name); } else { /* if (checkAttribute(n,"type","char")) { value = NewString(value); } else { value = NewStringf("%(escape)s", value); } */ Setattr(n,"rawvalue",value); value = NewStringf("%(escape)s", value); if (!Len(value)) Append(value,"\\0"); /* Printf(stdout,"'%s' = '%s'\n", name, value); */ } Setattr(n,"value", value); this->constantWrapper(n); Swig_restore(n); return SWIG_OK; } return SWIG_NOWRAP; } /* ---------------------------------------------------------------------- * Language::fragmentDirective() * ---------------------------------------------------------------------- */ int Language::fragmentDirective(Node *n) { Swig_fragment_register(n); return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::importDirective() * ---------------------------------------------------------------------- */ int Language::importDirective(Node *n) { int oldim = ImportMode; ImportMode = IMPORT_MODE; emit_children(n); ImportMode = oldim; return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::includeDirective() * ---------------------------------------------------------------------- */ int Language::includeDirective(Node *n) { emit_children(n); return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::insertDirective() * ---------------------------------------------------------------------- */ int Language::insertDirective(Node *n) { /* %insert directive */ if ((!ImportMode) || Getattr(n,"generated")) { String *code = Getattr(n,"code"); String *section = Getattr(n,"section"); File *f = 0; if (!section) { /* %{ ... %} */ f = Swig_filebyname("header"); } else { f = Swig_filebyname(section); } if (f) { Printf(f,"%s\n",code); } else { Swig_error(input_file,line_number,"Unknown target '%s' for %%insert directive.\n", section); } return SWIG_OK; } else { return SWIG_NOWRAP; } } /* ---------------------------------------------------------------------- * Language::moduleDirective() * ---------------------------------------------------------------------- */ int Language::moduleDirective(Node *n) { (void)n; /* %module directive */ return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::nativeDirective() * ---------------------------------------------------------------------- */ int Language::nativeDirective(Node *n) { if (!ImportMode) { return nativeWrapper(n); } else { return SWIG_NOWRAP; } } /* ---------------------------------------------------------------------- * Language::pragmaDirective() * ---------------------------------------------------------------------- */ int Language::pragmaDirective(Node *n) { /* %pragma directive */ if (!ImportMode) { String *lan = Getattr(n,"lang"); String *name = Getattr(n,"name"); String *value = Getattr(n,"value"); swig_pragma(Char(lan),Char(name),Char(value)); /* pragma(Char(lan),Char(name),Char(value)); */ return SWIG_OK; } return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::typemapDirective() * ---------------------------------------------------------------------- */ int Language::typemapDirective(Node *n) { /* %typemap directive */ String *method = Getattr(n,"method"); String *code = Getattr(n,"code"); Parm *kwargs = Getattr(n,"kwargs"); Node *items = firstChild(n); static int namewarn = 0; if (code && (Strstr(code,"$source") || (Strstr(code,"$target")))) { Swig_warning(WARN_TYPEMAP_SOURCETARGET,Getfile(n),Getline(n),"Deprecated typemap feature ($source/$target).\n"); if (!namewarn) { Swig_warning(WARN_TYPEMAP_SOURCETARGET, Getfile(n), Getline(n), "The use of $source and $target in a typemap declaration is deprecated.\n\ For typemaps related to argument input (in,ignore,default,arginit,check), replace\n\ $source by $input and $target by $1. For typemaps related to return values (out,\n\ argout,ret,except), replace $source by $1 and $target by $result. See the file\n\ Doc/Manual/Typemaps.html for complete details.\n"); namewarn = 1; } } if (Strcmp(method,"except") == 0) { Swig_warning(WARN_DEPRECATED_EXCEPT_TM, Getfile(n), Getline(n), "%%typemap(except) is deprecated. Use the %%exception directive.\n"); } if (Strcmp(method,"in") == 0) { Hash *k; k = kwargs; while (k) { if (checkAttribute(k,"name","numinputs")) { if (!multiinput && (GetInt(k,"value") > 1)) { Swig_error(Getfile(n),Getline(n),"Multiple-input typemaps (numinputs > 1) not supported by this target language module.\n"); return SWIG_ERROR; } break; } k = nextSibling(k); } if (!k) { k = NewHash(); Setattr(k,"name","numinputs"); Setattr(k,"value","1"); set_nextSibling(k,kwargs); Setattr(n,"kwargs",k); kwargs = k; } } if (Strcmp(method,"ignore") == 0) { Swig_warning(WARN_DEPRECATED_IGNORE_TM, Getfile(n), Getline(n), "%%typemap(ignore) has been replaced by %%typemap(in,numinputs=0).\n"); Clear(method); Append(method,"in"); Hash *k = NewHash(); Setattr(k,"name","numinputs"); Setattr(k,"value","0"); set_nextSibling(k,kwargs); Setattr(n,"kwargs",k); kwargs = k; } /* Replace $descriptor() macros */ if (code) { Setfile(code,Getfile(n)); Setline(code,Getline(n)); Swig_cparse_replace_descriptor(code); } while (items) { Parm *pattern = Getattr(items,"pattern"); Parm *parms = Getattr(items,"parms"); if (code) { Swig_typemap_register(method,pattern,code,parms,kwargs); } else { Swig_typemap_clear(method,pattern); } items = nextSibling(items); } return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::typemapcopyDirective() * ---------------------------------------------------------------------- */ int Language::typemapcopyDirective(Node *n) { String *method = Getattr(n,"method"); Parm *pattern = Getattr(n,"pattern"); Node *items = firstChild(n); int nsrc = 0; nsrc = ParmList_len(pattern); while (items) { ParmList *npattern = Getattr(items,"pattern"); if (nsrc != ParmList_len(npattern)) { Swig_error(input_file,line_number,"Can't copy typemap. Number of types differ.\n"); } else { if (Swig_typemap_copy(method,pattern,npattern) < 0) { Swig_error(input_file, line_number, "Can't copy typemap.\n"); } } items = nextSibling(items); } return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::typesDirective() * ---------------------------------------------------------------------- */ int Language::typesDirective(Node *n) { Parm *parms = Getattr(n,"parms"); while (parms) { SwigType *t = Getattr(parms,"type"); String *v = Getattr(parms,"value"); if (!v) { SwigType_remember(t); } else { if (SwigType_issimple(t)) { SwigType_inherit(t,v,0); } } parms = nextSibling(parms); } return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::cDeclaration() * ---------------------------------------------------------------------- */ int Language::cDeclaration(Node *n) { String *name = Getattr(n,"name"); String *symname = Getattr(n,"sym:name"); SwigType *type = Getattr(n,"type"); SwigType *decl = Getattr(n,"decl"); String *storage = Getattr(n,"storage"); Node *over; File *f_header = 0; SwigType *ty, *fullty; /* discarts nodes following the access control rules */ if (cplus_mode != CPLUS_PUBLIC) { /* except for friends, they are not affected by access control */ int isfriend = storage && (Cmp(storage,"friend") == 0); if (!isfriend) { if (cplus_mode == CPLUS_PRIVATE) { return SWIG_NOWRAP; } else { /* and for protected members, we check what director needs */ if (!(dirprot_mode() && is_member_director(CurrentClass,n))) return SWIG_NOWRAP; } } } if (Cmp(storage,"typedef") == 0) { Swig_save("cDeclaration",n,"type",NIL); SwigType *t = Copy(type); if (t) { SwigType_push(t,decl); Setattr(n,"type",t); typedefHandler(n); } Swig_restore(n); return SWIG_OK; } /* If in import mode, we proceed no further */ if (ImportMode) return SWIG_NOWRAP; /* If we're in extend mode and there is code, replace the $descriptor macros */ if (Getattr(n,"feature:extend")) { String *code = Getattr(n,"code"); if (code) { Setfile(code,Getfile(n)); Setline(code,Getline(n)); Swig_cparse_replace_descriptor(code); } } /* Overloaded symbol check */ over = Swig_symbol_isoverloaded(n); if (!overloading) { if (over) over = first_nontemplate(over); if (over && (over != n)) { SwigType *tc = Copy(decl); SwigType *td = SwigType_pop_function(tc); String *oname; String *cname; if (CurrentClass) { oname = NewStringf("%s::%s",ClassName,name); cname = NewStringf("%s::%s",ClassName,Getattr(over,"name")); } else { oname = NewString(name); cname = NewString(Getattr(over,"name")); } SwigType *tc2 = Copy(Getattr(over,"decl")); SwigType *td2 = SwigType_pop_function(tc2); Swig_warning(WARN_LANG_OVERLOAD_DECL, input_file, line_number, "Overloaded declaration ignored. %s\n", SwigType_str(td,SwigType_namestr(oname))); Swig_warning(WARN_LANG_OVERLOAD_DECL, Getfile(over), Getline(over),"Previous declaration is %s\n", SwigType_str(td2,SwigType_namestr(cname))); Delete(tc2); Delete(td2); Delete(tc); Delete(td); Delete(oname); Delete(cname); return SWIG_NOWRAP; } } if (symname && !validIdentifier(symname)) { Swig_warning(WARN_LANG_IDENTIFIER,input_file, line_number, "Can't wrap '%s' unless renamed to a valid identifier.\n", symname); return SWIG_NOWRAP; } ty = NewString(type); SwigType_push(ty,decl); fullty = SwigType_typedef_resolve_all(ty); if (SwigType_isfunction(fullty)) { if (!SwigType_isfunction(ty)) { Delete(ty); ty = fullty; fullty = 0; ParmList *parms = SwigType_function_parms(ty); Setattr(n,"parms",parms); } /* Transform the node into a 'function' node and emit */ if (!CurrentClass) { f_header = Swig_filebyname("header"); if (!NoExtern) { if (f_header) { if ((Cmp(storage,"extern") == 0) || (ForceExtern && !storage)) { Printf(f_header,"extern %s", SwigType_str(ty,name)); { DOH *t = Getattr(n,"throws"); if (t) { Printf(f_header,"throw("); while (t) { Printf(f_header,"%s", Getattr(t,"type")); t = nextSibling(t); if (t) Printf(f_header,","); } Printf(f_header,")"); } } Printf(f_header,";\n"); } else if (Cmp(storage,"externc") == 0) { Printf(f_header,"extern \"C\" %s;\n", SwigType_str(ty,name)); } } } } /* This needs to check qualifiers */ if (SwigType_isqualifier(ty)) { Setattr(n,"qualifier", SwigType_pop(ty)); } Delete(SwigType_pop_function(ty)); DohIncref(type); Setattr(n,"type",ty); functionHandler(n); Setattr(n,"type",type); Delete(ty); Delete(type); return SWIG_OK; } else { /* Some kind of variable declaration */ Delattr(n,"decl"); if (Getattr(n,"nested")) Setattr(n,"feature:immutable","1"); if (!CurrentClass) { if ((Cmp(storage,"extern") == 0) || ForceExtern) { f_header = Swig_filebyname("header"); if (!NoExtern) { if (f_header) { Printf(f_header,"extern %s;\n", SwigType_str(ty,name)); } } } } if (!SwigType_ismutable(ty)) { Setattr(n,"feature:immutable","1"); } /* If an array and elements are const, then read-only */ if (SwigType_isarray(ty)) { SwigType *tya = SwigType_array_type(ty); if (SwigType_isconst(tya)) { Setattr(n,"feature:immutable","1"); } } DohIncref(type); Setattr(n,"type",ty); variableHandler(n); Setattr(n,"type",type); Setattr(n,"decl",decl); Delete(ty); Delete(type); Delete(fullty); return SWIG_OK; } } /* ---------------------------------------------------------------------- * Language::functionHandler() * ---------------------------------------------------------------------- */ int Language::functionHandler(Node *n) { Parm *p; p = Getattr(n,"parms"); if (CPlusPlus) patch_parms(p); if (!CurrentClass) { globalfunctionHandler(n); } else { String *storage = Getattr(n,"storage"); if (Cmp(storage,"static") == 0) { staticmemberfunctionHandler(n); } else if (Cmp(storage,"friend") == 0) { globalfunctionHandler(n); } else { memberfunctionHandler(n); } } return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::globalfunctionHandler() * ---------------------------------------------------------------------- */ int Language::globalfunctionHandler(Node *n) { Swig_require("globalfunctionHandler",n,"name","sym:name","type","?parms",NIL); String *name = Getattr(n,"name"); String *symname = Getattr(n,"sym:name"); SwigType *type = Getattr(n,"type"); String *storage = Getattr(n,"storage"); ParmList *parms = Getattr(n,"parms"); if (0 && (Cmp(storage,"static") == 0)) { Swig_restore(n); return SWIG_NOWRAP; /* Can't wrap static functions */ } else { /* Check for callback mode */ String *cb = Getattr(n,"feature:callback"); if (cb) { String *cbname = NewStringf(cb,symname); callbackfunctionHandler(n); if (Cmp(cbname, symname) == 0) { Delete(cbname); Swig_restore(n); return SWIG_NOWRAP; } Delete(cbname); } Setattr(n,"parms",nonvoid_parms(parms)); Setattr(n,"wrap:action", Swig_cresult(type,"result", Swig_cfunction_call(name,parms))); functionWrapper(n); } Swig_restore(n); return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::callbackfunctionHandler() * ---------------------------------------------------------------------- */ int Language::callbackfunctionHandler(Node *n) { Swig_require("callbackfunctionHandler",n,"name","*sym:name","*type","?value",NIL); String *symname = Getattr(n,"sym:name"); String *type = Getattr(n,"type"); String *name = Getattr(n,"name"); String *parms = Getattr(n,"parms"); String *cb = Getattr(n,"feature:callback"); String *cbname = NewStringf(cb,symname); SwigType *cbty = Copy(type); SwigType_add_function(cbty,parms); SwigType_add_pointer(cbty); Setattr(n,"sym:name", cbname); Setattr(n,"type", cbty); Setattr(n,"value", name); constantWrapper(n); Delete(cbname); Delete(cbty); Swig_restore(n); return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::memberfunctionHandler() * ---------------------------------------------------------------------- */ int Language::memberfunctionHandler(Node *n) { Swig_require("memberfunctionHandler",n,"*name","*sym:name","*type","?parms","?value",NIL); String *storage = Getattr(n,"storage"); String *name = Getattr(n,"name"); String *symname = Getattr(n,"sym:name"); SwigType *type = Getattr(n,"type"); String *value = Getattr(n,"value"); ParmList *parms = Getattr(n,"parms"); String *cb; if (Cmp(storage,"virtual") == 0) { if (Cmp(value,"0") == 0) { IsVirtual = PURE_VIRTUAL; } else { IsVirtual = PLAIN_VIRTUAL; } } else { IsVirtual = 0; } cb = Getattr(n,"feature:callback"); if (cb) { Node *cb = NewHash(); String *cbname = NewStringf(cb,symname); String *cbvalue; SwigType *cbty = Copy(type); SwigType_add_function(cbty,parms); SwigType_add_memberpointer(cbty,ClassName); cbvalue = NewStringf("&%s::%s",ClassName,name); Setattr(cb,"sym:name", cbname); Setattr(cb,"type", cbty); Setattr(cb,"value", cbvalue); Setattr(cb,"name", name); memberconstantHandler(n); Delete(cb); Delete(cbvalue); Delete(cbty); Delete(cbname); if (Cmp(cbname,symname) == 0) { Swig_restore(n); return SWIG_NOWRAP; } } String *fname = Swig_name_member(ClassPrefix, symname); /* Transformation */ Swig_MethodToFunction(n,ClassType, Getattr(n,"template") ? 0 : Extend | SmartPointer); Setattr(n,"sym:name",fname); functionWrapper(n); /* DelWrapper(w);*/ Delete(fname); Swig_restore(n); return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::staticmemberfunctionHandler() * ---------------------------------------------------------------------- */ int Language::staticmemberfunctionHandler(Node *n) { Swig_require("staticmemberfunctionHandler",n,"*name","*sym:name","*type",NIL); Swig_save("staticmemberfunctionHandler",n,"storage",NIL); String *name = Getattr(n,"name"); String *symname = Getattr(n,"sym:name"); SwigType *type = Getattr(n,"type"); ParmList *parms = Getattr(n,"parms"); String *code = Getattr(n,"code"); String *cname, *mrename; if (!Extend) { String *sname = Getattr(Getattr(n,"cplus:staticbase"),"name"); if (sname) { cname = NewStringf("%s::%s",sname,name); } else { cname = NewStringf("%s::%s",ClassName,name); } } else { cname = Copy(Swig_name_member(ClassPrefix,name)); } mrename = Swig_name_member(ClassPrefix, symname); Setattr(n,"name",cname); Setattr(n,"sym:name",mrename); if ((Extend) && (code)) { /* Hmmm. An added static member. We have to create a little wrapper for this */ String *tmp = NewStringf("%s(%s)", cname, ParmList_str(parms)); String *wrap = SwigType_str(type,tmp); Printv(wrap,code,"\n",NIL); Setattr(n,"wrap:code",wrap); Delete(tmp); Delete(wrap); } Delattr(n,"storage"); globalfunctionHandler(n); Delete(cname); Delete(mrename); Swig_restore(n); return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::variableHandler() * ---------------------------------------------------------------------- */ int Language::variableHandler(Node *n) { if (!CurrentClass) { globalvariableHandler(n); } else { String *storage = Getattr(n,"storage"); if ((Cmp(storage,"static") == 0)) { if (!SmartPointer) { staticmembervariableHandler(n); } } else { Swig_save("variableHandler",n,"feature:immutable",NIL); /* If a smart-pointer and it's a constant access, we have to set immutable */ if (SmartPointer) { if (Getattr(CurrentClass,"allocate:smartpointerconst")) { Setattr(n,"feature:immutable","1"); } } membervariableHandler(n); Swig_restore(n); } } return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::globalvariableHandler() * ---------------------------------------------------------------------- */ int Language::globalvariableHandler(Node *n) { String *storage = Getattr(n,"storage"); if (0 && (Cmp(storage,"static") == 0)) return SWIG_NOWRAP; variableWrapper(n); return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::membervariableHandler() * ---------------------------------------------------------------------- */ int Language::membervariableHandler(Node *n) { Swig_require("membervariableHandler",n,"*name","*sym:name","*type",NIL); Swig_save("membervariableHandler",n,"parms",NIL); String *name = Getattr(n,"name"); String *symname = Getattr(n,"sym:name"); SwigType *type = Getattr(n,"type"); /* If not a smart-pointer access or added method. We clear feature:except. There is no way C++ or C would throw an exception merely for accessing a member data. Caveat: Some compilers seem to route attribute access through methods which can generate exceptions. The feature:allowexcept allows this. */ if (!(Extend | SmartPointer) && (!Getattr(n,"feature:allowexcept"))) { Delattr(n,"feature:except"); } if (!AttributeFunctionGet) { String *mrename_get, *mrename_set; mrename_get = Swig_name_get(Swig_name_member(ClassPrefix, symname)); mrename_set = Swig_name_set(Swig_name_member(ClassPrefix, symname)); /* Create a function to set the value of the variable */ if (!Getattr(n,"feature:immutable")) { int make_wrapper = 1; String *tm = 0; String *target = 0; if (!Extend) { target = NewStringf("%s->%s", Swig_cparm_name(0,0),name); tm = Swig_typemap_lookup_new("memberin",n,target,0); } Swig_MembersetToFunction(n,ClassType,Extend | SmartPointer); if (!Extend) { /* Check for a member in typemap here */ if (!tm) { if (SwigType_isarray(type)) { Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(type,0)); make_wrapper = 0; } } else { Replace(tm,"$source", Swig_cparm_name(0,1), DOH_REPLACE_ANY); Replace(tm,"$target", target, DOH_REPLACE_ANY); Replace(tm,"$input",Swig_cparm_name(0,1),DOH_REPLACE_ANY); Replace(tm,"$self",Swig_cparm_name(0,0),DOH_REPLACE_ANY); Setattr(n,"wrap:action", tm); Delete(tm); } Delete(target); } if (make_wrapper) { Setattr(n,"sym:name", mrename_set); functionWrapper(n); } else { Setattr(n,"feature:immutable","1"); } /* Restore parameters */ Setattr(n,"type",type); Setattr(n,"name",name); Setattr(n,"sym:name",symname); } /* Emit get function */ { Swig_MembergetToFunction(n,ClassType,Extend | SmartPointer); Setattr(n,"sym:name", mrename_get); functionWrapper(n); } Delete(mrename_get); Delete(mrename_set); } else { /* This code is used to support the attributefunction directive where member variables are converted automagically to accessor functions */ #if 0 Parm *p; String *gname; SwigType *vty; p = NewParm(type,0); gname = NewStringf(AttributeFunctionGet,symname); if (!Extend) { ActionFunc = Copy(Swig_cmemberget_call(name,type)); cpp_member_func(Char(gname),Char(gname),type,0); Delete(ActionFunc); } else { String *cname = Copy(Swig_name_get(name)); cpp_member_func(Char(cname),Char(gname),type,0); Delete(cname); } Delete(gname); if (!Getattr(n,"feature:immutable")) { gname = NewStringf(AttributeFunctionSet,symname); vty = NewString("void"); if (!Extend) { ActionFunc = Copy(Swig_cmemberset_call(name,type)); cpp_member_func(Char(gname),Char(gname),vty,p); Delete(ActionFunc); } else { String *cname = Copy(Swig_name_set(name)); cpp_member_func(Char(cname),Char(gname),vty,p); Delete(cname); } Delete(gname); } ActionFunc = 0; #endif } Swig_restore(n); return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::staticmembervariableHandler() * ---------------------------------------------------------------------- */ int Language::staticmembervariableHandler(Node *n) { Swig_require("staticmembervariableHandler",n,"*name","*sym:name","*type", "?value", NIL); String *value = Getattr(n,"value"); SwigType *type = SwigType_typedef_resolve_all(Getattr(n,"type")); if (!value || !(SwigType_isconst(type))) { String *name = Getattr(n,"name"); String *symname = Getattr(n,"sym:name"); String *cname, *mrename; /* Create the variable name */ mrename = Swig_name_member(ClassPrefix, symname); cname = NewStringf("%s::%s", ClassName,name); Setattr(n,"sym:name",mrename); Setattr(n,"name", cname); /* Wrap as an ordinary global variable */ variableWrapper(n); Delete(mrename); Delete(cname); } else { /* This is a C++ static member declaration with an initializer and it's const. Certain C++ compilers optimize this out so that there is no linkage to a memory address. Example: class Foo { public: static const int x = 3; }; Some discussion of this in section 9.4 of the C++ draft standard. */ String *name = Getattr(n,"name"); String *cname = NewStringf("%s::%s", ClassName,name); String* value = SwigType_namestr(cname); Setattr(n, "value", value); SwigType *t1 = SwigType_typedef_resolve_all(Getattr(n,"type")); SwigType *t2 = SwigType_strip_qualifiers(t1); Setattr(n, "type", t2); Delete(t1); Delete(t2); memberconstantHandler(n); Delete(cname); } Delete(type); Swig_restore(n); return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::externDeclaration() * ---------------------------------------------------------------------- */ int Language::externDeclaration(Node *n) { return emit_children(n); } /* ---------------------------------------------------------------------- * Language::enumDeclaration() * ---------------------------------------------------------------------- */ int Language::enumDeclaration(Node *n) { if (!ImportMode) { emit_children(n); } return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::enumvalueDeclaration() * ---------------------------------------------------------------------- */ int Language::enumvalueDeclaration(Node *n) { if (CurrentClass && (cplus_mode != CPLUS_PUBLIC)) return SWIG_NOWRAP; Swig_require("enumvalueDeclaratuon",n,"*name", "?value",NIL); String *value = Getattr(n,"value"); String *name = Getattr(n,"name"); String *tmpValue; if (value) tmpValue = NewString(value); else tmpValue = NewString(name); Setattr(n, "value", tmpValue); if (!CurrentClass) { Setattr(n,"name",tmpValue); /* for wrapping of enums in a namespace when emit_action is used */ constantWrapper(n); } else { memberconstantHandler(n); } Delete(tmpValue); Swig_restore(n); return SWIG_OK; } /* ----------------------------------------------------------------------------- * Language::memberconstantHandler() * ----------------------------------------------------------------------------- */ int Language::memberconstantHandler(Node *n) { Swig_require("memberconstantHandler",n,"*name","*sym:name","*value",NIL); String *name = Getattr(n,"name"); String *symname = Getattr(n,"sym:name"); String *value = Getattr(n,"value"); String *mrename; String *new_value; mrename = Swig_name_member(ClassPrefix, symname); /* Fixed by namespace-enum patch if ((!value) || (Cmp(value,name) == 0)) { new_value = NewStringf("%s::%s",ClassName,name); } else { new_value = NewString(value); } */ new_value = Copy(value); Setattr(n,"sym:name", mrename); Setattr(n,"value", new_value); Setattr(n,"name", NewStringf("%s::%s", ClassName,name)); constantWrapper(n); Delete(mrename); Delete(new_value); Swig_restore(n); return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::typedefHandler() * ---------------------------------------------------------------------- */ int Language::typedefHandler(Node *) { return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::classDirectorMethod() * ---------------------------------------------------------------------- */ int Language::classDirectorMethod(Node *n, Node *parent, String* super) { (void)n; (void)parent; (void)super; return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::classDirectorConstructor() * ---------------------------------------------------------------------- */ int Language::classDirectorConstructor(Node *n) { (void)n; return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::classDirectorDefaultConstructor() * ---------------------------------------------------------------------- */ int Language::classDirectorDefaultConstructor(Node *n) { (void)n; return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::unrollVirtualMethods() * ---------------------------------------------------------------------- */ int Language::unrollVirtualMethods(Node *n, Node *parent, Hash *vm, int default_director, int &virtual_destructor) { Node *ni; String *nodeType; String *classname; String *decl; // recurse through all base classes to build the vtable List* bl = Getattr(n, "bases"); if (bl) { Iterator bi; for (bi = First(bl); bi.item; bi = Next(bi)) { unrollVirtualMethods(bi.item, parent, vm, default_director, virtual_destructor); } } // find the methods that need directors classname = Getattr(n, "name"); for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) { /* we only need to check the virtual members */ if (!checkAttribute(ni, "storage", "virtual")) continue; nodeType = Getattr(ni, "nodeType"); /* we need to add only the methods(cdecl), no destructors */ if ((Cmp(nodeType, "cdecl") == 0)) { decl = Getattr(ni, "decl"); /* extra check for function type and proper access */ if (SwigType_isfunction(decl) && (is_public(ni) || (dirprot_mode() && is_protected(ni)))) { String *name = Getattr(ni, "name"); String *local_decl = SwigType_typedef_resolve_all(decl); Node *method_id = NewStringf("%s|%s", name, local_decl); /* Make sure that the new method overwrites the existing: */ Hash *exists_item = Getattr(vm, method_id); if (exists_item) { /* maybe we should check for precedence here, ie, only delete the previous method if 'n' is derived from the previous method parent node. This is almost always true, so by now, we just delete the entry. */ Delattr(vm, method_id); } /* filling a new method item */ String *fqname = NewStringf("%s::%s", classname, name); Hash *item = NewHash(); Setattr(item, "fqName", fqname); Setattr(item, "methodNode", Copy(ni)); Setattr(vm, method_id, item); Delete(fqname); Delete(item); Delete(method_id); Delete(local_decl); } } else if (Cmp(nodeType, "destructor") == 0) { virtual_destructor = 1; } } /* We delete all the nodirector methods. This prevents the generation of 'empty' director classes. But this has to be done outside the previous 'for' an the recursive loop!. */ if (n == parent) { Iterator k; for (k = First(vm); k.key; k = Next(k)) { Node *m = Getattr(k.item, "methodNode"); /* retrieve the director features */ int mdir = checkAttribute(m, "feature:director", "1"); int mndir = checkAttribute(m, "feature:nodirector", "1"); /* 'nodirector' has precedence over 'director' */ int dir = (mdir || mndir) ? (mdir && !mndir) : 1; /* check if the method was found only in a base class */ Node *p = Getattr(m, "parentNode"); if (p != n) { /* check for my own features to take precedence, ie, if I only found Base::method(), look for MySelf::method() features. The problem is that MySelf::method() is not declared in the MySelf class, and appears here through derivation: %feature("nodirector") Base::method(); %feature("director") MySelf::method(); struct Base { virtual ~Base(); virtual int method(); }; struct MySelf : Base { }; *** Ask David, this is not working now!!! ***** This is now just giving back the Base::method() features, maybe we need to look directly in the feature hash table?... */ Node *c = Copy(m); Setattr(c, "parentNode", n); int cdir = checkAttribute(c, "feature:director", "1"); int cndir = checkAttribute(c, "feature:nodirector", "1"); dir = (cdir || cndir) ? (cdir && !cndir) : dir; Delete(c); } if (dir) { /* be sure the 'nodirector' feature is disabled */ if (mndir) Delattr(m, "feature:nodirector"); } else { /* or just delete from the vm, since is not a director method */ Delattr(vm, k.key); } } } return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::classDirectorDisown() * ---------------------------------------------------------------------- */ int Language::classDirectorDisown(Node *n) { Node *disown = NewHash(); String *mrename; String *symname = Getattr(n,"sym:name"); mrename = Swig_name_disown(symname); //Getattr(n, "name")); String *type = NewString(ClassType); String *name = NewString("self"); SwigType_add_pointer(type); Parm *p = NewParm(type, name); Delete(name); 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); Setattr(disown, "wrap:action", action); Setattr(disown,"name", mrename); Setattr(disown,"sym:name", mrename); Setattr(disown,"type",type); Setattr(disown,"parms", p); Delete(action); Delete(mrename); Delete(type); Delete(p); functionWrapper(disown); Delete(disown); return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::classDirectorConstructors() * ---------------------------------------------------------------------- */ int Language::classDirectorConstructors(Node *n) { Node *ni; String *nodeType; int constructor = 0; for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) { nodeType = Getattr(ni, "nodeType"); if (!Cmp(nodeType, "constructor")) { if (is_public(ni)) { classDirectorConstructor(ni); constructor = 1; } } } if (!constructor) { classDirectorDefaultConstructor(n); } return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::classDirectorMethods() * ---------------------------------------------------------------------- */ int Language::classDirectorMethods(Node *n) { Node *vtable = Getattr(n, "vtable"); Node *item; Iterator k; for (k = First(vtable); k.key; k = Next(k)) { item = k.item; String *method = Getattr(item, "methodNode"); String *fqname = Getattr(item, "fqName"); if (!Cmp(Getattr(method, "feature:nodirector"), "1")) continue; if (classDirectorMethod(method, n, fqname) == SWIG_OK) { Setattr(item, "director", "1"); } } return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::classDirectorInit() * ---------------------------------------------------------------------- */ int Language::classDirectorInit(Node *n) { (void)n; return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::classDirectorEnd() * ---------------------------------------------------------------------- */ int Language::classDirectorEnd(Node *n) { (void)n; return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::classDirector() * ---------------------------------------------------------------------- */ int Language::classDirector(Node *n) { Node *module = Getattr(n,"module"); String *classtype = Getattr(n, "classtype"); Hash *directormap = 0; if (module) { directormap = Getattr(module, "wrap:directormap"); if (directormap == 0) { directormap = NewHash(); Setattr(module, "wrap:directormap", directormap); } } Hash* vtable = NewHash(); int virtual_destructor = 0; unrollVirtualMethods(n, n, vtable, 0, virtual_destructor); if (Len(vtable) > 0) { if (!virtual_destructor) { String *classtype = Getattr(n, "classtype"); Swig_warning(WARN_LANG_DIRECTOR_VDESTRUCT, input_file, line_number, "Director base class %s has no virtual destructor.\n", classtype); } Setattr(n, "vtable", vtable); classDirectorInit(n); classDirectorConstructors(n); classDirectorMethods(n); classDirectorEnd(n); if (directormap != 0) { Setattr(directormap, classtype, n); } } Delete(vtable); return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::classDeclaration() * ---------------------------------------------------------------------- */ int Language::classDeclaration(Node *n) { String *kind = Getattr(n,"kind"); String *name = Getattr(n,"name"); String *tdname = Getattr(n,"tdname"); String *symname = Getattr(n,"sym:name"); char *classname = tdname ? Char(tdname) : Char(name); char *iname = Char(symname); int strip = (tdname || CPlusPlus) ? 1 : 0; if (!classname) { Swig_warning(WARN_LANG_CLASS_UNNAMED, input_file, line_number, "Can't generate wrappers for unnamed struct/class.\n"); return SWIG_NOWRAP; } /* Check symbol name for template. If not renamed. Issue a warning */ /* Printf(stdout,"sym:name = %s\n", symname); */ if (!validIdentifier(symname)) { Swig_warning(WARN_LANG_IDENTIFIER, input_file, line_number, "Can't wrap class %s unless renamed to a valid identifier.\n", SwigType_namestr(symname)); return SWIG_NOWRAP; } Swig_save("classDeclaration",n,"name",NIL); Setattr(n,"name",classname); if (Cmp(kind,"class") == 0) { cplus_mode = CPLUS_PRIVATE; } else { cplus_mode = CPLUS_PUBLIC; } ClassName = NewString(classname); ClassPrefix = NewString(iname); if (strip) { ClassType = NewString(classname); } else { ClassType = NewStringf("%s %s", kind, classname); } Setattr(n,"classtypeobj", Copy(ClassType)); Setattr(n,"classtype", SwigType_namestr(ClassType)); InClass = 1; CurrentClass = n; Abstract = abstractClassTest(n); /* Call classHandler() here */ if (!ImportMode) { if (directorsEnabled() && Getattr(n, "feature:director")) { classDirector(n); } classHandler(n); } else { Language::classHandler(n); } InClass = 0; CurrentClass = 0; Delete(ClassType); ClassType = 0; Delete(ClassPrefix); ClassPrefix = 0; Delete(ClassName); ClassName = 0; Swig_restore(n); return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::classHandler() * ---------------------------------------------------------------------- */ int Language::classHandler(Node *n) { bool hasDirector = Swig_directorclass(n) ? true : false; /* Emit all of the class members */ emit_children(n); /* Look for smart pointer handling */ if (Getattr(n,"allocate:smartpointer")) { List *methods = Getattr(n,"allocate:smartpointer"); cplus_mode = CPLUS_PUBLIC; SmartPointer = CWRAP_SMART_POINTER; Iterator c; for (c = First(methods); c.item; c= Next(c)) { emit_one(c.item); } SmartPointer = 0; } cplus_mode = CPLUS_PUBLIC; if (!ImportMode && (GenerateDefault && !Getattr(n,"feature:nodefault"))) { if (!Getattr(n,"has_constructor") && !Getattr(n,"allocate:has_constructor") && (Getattr(n,"allocate:default_constructor"))) { /* Note: will need to change this to support different kinds of classes */ if (!Abstract || hasDirector) { Setattr(CurrentClass,"feature:new","1"); constructorHandler(CurrentClass); Delattr(CurrentClass,"feature:new"); } } if (!Getattr(n,"has_destructor") && (!Getattr(n,"allocate:has_destructor")) && (Getattr(n,"allocate:default_destructor"))) { destructorHandler(CurrentClass); } } /* emit director disown method */ if (hasDirector) { classDirectorDisown(n); /* emit all the protected virtual members as needed */ if (dirprot_mode()) { Node *vtable = Getattr(n, "vtable"); String* symname = Getattr(n, "sym:name"); Node *item; Iterator k; int old_mode = cplus_mode; cplus_mode = CPLUS_PROTECTED; for (k = First(vtable); k.key; k = Next(k)) { item = k.item; String* director = Getattr(item,"director"); Node *method = Getattr(item, "methodNode"); Node* parentnode = Getattr(method, "parentNode"); String* methodname = Getattr(method,"sym:name"); String* wrapname = NewStringf("%s_%s", symname,methodname); if (!Getattr(symbols,wrapname) && !Cmp(director,"1") && (n != parentnode) && is_protected(method)) { Node* m = Copy(method); String* mdecl = Getattr(m,"decl"); Setattr(m,"parentNode", n); /* ugly trick, to avoid an uglier one later on emit. We take the 'const' out from calling method to avoid the ugly const casting latter. The casting from 'non-const' to 'const' is not needed here, but it prevents the simple replacement of arg1 by darg on emit.cxx. */ if (Strncmp(mdecl, "q(const).", 9)== 0) Replace(mdecl,"q(const).","", DOH_REPLACE_FIRST); cDeclaration(m); Delete(m); } Delete(wrapname); } cplus_mode = old_mode; } } return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::classforwardDeclaration() * ---------------------------------------------------------------------- */ int Language::classforwardDeclaration(Node *n) { (void)n; return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::constructorDeclaration() * ---------------------------------------------------------------------- */ int Language::constructorDeclaration(Node *n) { String *name = Getattr(n,"name"); String *symname = Getattr(n,"sym:name"); if (!CurrentClass) return SWIG_NOWRAP; if (cplus_mode != CPLUS_PUBLIC) return SWIG_NOWRAP; if (ImportMode) return SWIG_NOWRAP; /* Name adjustment for %name */ Swig_save("constructorDeclaration",n,"sym:name",NIL); { String *base = Swig_scopename_last(name); if ((Strcmp(base,symname) == 0) && (Strcmp(symname, ClassPrefix) != 0)) { Setattr(n,"sym:name", ClassPrefix); } Delete(base); } /* Only create a constructor if the class is not abstract */ if (!Abstract) { Node *over; over = Swig_symbol_isoverloaded(n); if (over) over = first_nontemplate(over); if ((over) && (!overloading)) { /* If the symbol is overloaded. We check to see if it is a copy constructor. If so, we invoke copyconstructorHandler() as a special case. */ if (Getattr(n,"copy_constructor") && (!Getattr(CurrentClass,"has_copy_constructor"))) { copyconstructorHandler(n); Setattr(CurrentClass,"has_copy_constructor","1"); } else { if (Getattr(over,"copy_constructor")) over = Getattr(over,"sym:nextSibling"); if (over != n) { String *oname = NewStringf("%s::%s", ClassName, Swig_scopename_last(SwigType_namestr(name))); String *cname = NewStringf("%s::%s", ClassName, Swig_scopename_last(SwigType_namestr(Getattr(over,"name")))); SwigType *decl = Getattr(n,"decl"); Swig_warning(WARN_LANG_OVERLOAD_CONSTRUCT, input_file, line_number, "Overloaded constructor ignored. %s\n", SwigType_str(decl,SwigType_namestr(oname))); Swig_warning(WARN_LANG_OVERLOAD_CONSTRUCT, Getfile(over), Getline(over), "Previous declaration is %s\n", SwigType_str(Getattr(over,"decl"),SwigType_namestr(cname))); Delete(oname); Delete(cname); } else { constructorHandler(n); } } } else { if (name && (Cmp(Swig_scopename_last(name),Swig_scopename_last(ClassName))) && !(Getattr(n,"template"))) { Printf(stdout,"name = '%s', ClassName='%s'\n", name, ClassName); Swig_warning(WARN_LANG_RETURN_TYPE, input_file,line_number,"Function %s must have a return type.\n", name); Swig_restore(n); return SWIG_NOWRAP; } constructorHandler(n); } } Setattr(CurrentClass,"has_constructor","1"); Swig_restore(n); return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::constructorHandler() * ---------------------------------------------------------------------- */ int Language::constructorHandler(Node *n) { Swig_require("constructorHandler",n,"?name","*sym:name","?type","?parms",NIL); String *symname = Getattr(n,"sym:name"); String *mrename; Parm *parms = Getattr(n,"parms"); mrename = Swig_name_construct(symname); if (CPlusPlus) patch_parms(parms); Swig_ConstructorToFunction(n, ClassType, none_comparison, director_ctor_code, CPlusPlus, Getattr(n, "template") ? 0 :Extend); Setattr(n,"sym:name", mrename); functionWrapper(n); Delete(mrename); Swig_restore(n); return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::copyconstructorHandler() * ---------------------------------------------------------------------- */ int Language::copyconstructorHandler(Node *n) { Swig_require("copyconstructorHandler",n,"?name","*sym:name","?type","?parms", NIL); String *symname = Getattr(n,"sym:name"); String *mrename; Parm *parms = Getattr(n,"parms"); if (CPlusPlus) patch_parms(parms); mrename = Swig_name_copyconstructor(symname); Swig_ConstructorToFunction(n,ClassType, none_comparison, director_ctor_code, CPlusPlus, Getattr(n,"template") ? 0 : Extend); Setattr(n,"sym:name", mrename); functionWrapper(n); Delete(mrename); Swig_restore(n); return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::destructorDeclaration() * ---------------------------------------------------------------------- */ int Language::destructorDeclaration(Node *n) { if (!CurrentClass) return SWIG_NOWRAP; if (cplus_mode != CPLUS_PUBLIC) return SWIG_NOWRAP; if (ImportMode) return SWIG_NOWRAP; Swig_save("destructorDeclaration",n,"name", "sym:name",NIL); char *c = GetChar(n,"name"); if (c && (*c == '~')) Setattr(n,"name",c+1); c = GetChar(n,"sym:name"); if (c && (*c == '~')) Setattr(n,"sym:name",c+1); /* Name adjustment for %name */ String *name = Getattr(n,"name"); String *symname = Getattr(n,"sym:name"); if ((Strcmp(name,symname) == 0) || (Strcmp(symname,ClassPrefix) != 0)) { Setattr(n,"sym:name", ClassPrefix); } destructorHandler(n); Setattr(CurrentClass,"has_destructor","1"); Swig_restore(n); return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::destructorHandler() * ---------------------------------------------------------------------- */ int Language::destructorHandler(Node *n) { Swig_require("destructorHandler",n,"?name","*sym:name",NIL); Swig_save("destructorHandler",n,"type","parms",NIL); String *symname = Getattr(n,"sym:name"); String *mrename; char *csymname = Char(symname); if (csymname && (*csymname == '~')) csymname +=1; mrename = Swig_name_destroy(csymname); Swig_DestructorToFunction(n,ClassType,CPlusPlus,Extend); Setattr(n,"sym:name", mrename); functionWrapper(n); Delete(mrename); Swig_restore(n); return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::accessDeclaration() * ---------------------------------------------------------------------- */ int Language::accessDeclaration(Node *n) { String *kind = Getattr(n,"kind"); if (Cmp(kind,"public") == 0) { cplus_mode = CPLUS_PUBLIC; } else if (Cmp(kind,"private") == 0) { cplus_mode = CPLUS_PRIVATE; } else if (Cmp(kind,"protected") == 0) { cplus_mode = CPLUS_PROTECTED; } return SWIG_OK; } /* ----------------------------------------------------------------------------- * Language::namespaceDeclaration() * ----------------------------------------------------------------------------- */ int Language::namespaceDeclaration(Node *n) { if (Getattr(n,"alias")) return SWIG_OK; emit_children(n); return SWIG_OK; } int Language::validIdentifier(String *s) { char *c = Char(s); while (*c) { if (!(isalnum(*c) || (*c == '_'))) return 0; c++; } return 1; } /* ----------------------------------------------------------------------------- * Language::usingDeclaration() * ----------------------------------------------------------------------------- */ int Language::usingDeclaration(Node *n) { if ((cplus_mode == CPLUS_PUBLIC)) { Node* np = Copy(n); Node *c; for (c = firstChild(np); c; c = nextSibling(c)) { if (!is_public(c)) Setattr(c, "access", "public"); /* it seems for some cases this is needed, like A* A::boo() */ if (CurrentClass) Setattr(c, "parentNode", CurrentClass); emit_one(c); } Delete(np); } return SWIG_OK; } /* Stubs. Language modules need to implement these */ /* ---------------------------------------------------------------------- * Language::constantWrapper() * ---------------------------------------------------------------------- */ int Language::constantWrapper(Node *n) { String *name = Getattr(n,"sym:name"); SwigType *type = Getattr(n,"type"); String *value = Getattr(n,"value"); Printf(stdout,"constantWrapper : %s = %s\n", SwigType_str(type,name), value); return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::variableWrapper() * ---------------------------------------------------------------------- */ int Language::variableWrapper(Node *n) { Swig_require("variableWrapper",n,"*name","*sym:name","*type","?parms",NIL); String *symname = Getattr(n,"sym:name"); SwigType *type = Getattr(n,"type"); String *name = Getattr(n,"name"); /* If no way to set variables. We simply create functions */ if (!Getattr(n,"feature:immutable")) { int make_wrapper = 1; String *tm = Swig_typemap_lookup_new("globalin", n, name, 0); Swig_VarsetToFunction(n); Setattr(n,"sym:name", Swig_name_set(symname)); /* String *tm = Swig_typemap_lookup((char *) "globalin",type,name,name,Swig_cparm_name(0,0),name,0);*/ if (!tm) { if (SwigType_isarray(type)) { Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(type,0)); make_wrapper = 0; } } else { Replace(tm,"$source", Swig_cparm_name(0,0), DOH_REPLACE_ANY); Replace(tm,"$target", name, DOH_REPLACE_ANY); Replace(tm,"$input",Swig_cparm_name(0,0),DOH_REPLACE_ANY); Setattr(n,"wrap:action", tm); Delete(tm); } if (make_wrapper) { functionWrapper(n); } Setattr(n,"sym:name",symname); Setattr(n,"type",type); Setattr(n,"name",name); } Swig_VargetToFunction(n); Setattr(n,"sym:name", Swig_name_get(symname)); functionWrapper(n); Swig_restore(n); return SWIG_OK; } /* ---------------------------------------------------------------------- * Language::functionWrapper() * ---------------------------------------------------------------------- */ int Language::functionWrapper(Node *n) { String *name = Getattr(n,"sym:name"); SwigType *type = Getattr(n,"type"); ParmList *parms = Getattr(n,"parms"); Printf(stdout,"functionWrapper : %s\n", SwigType_str(type, NewStringf("%s(%s)", name, ParmList_str(parms)))); Printf(stdout," action : %s\n", Getattr(n,"wrap:action")); return SWIG_OK; } /* ----------------------------------------------------------------------------- * Language::nativeWrapper() * ----------------------------------------------------------------------------- */ int Language::nativeWrapper(Node *n) { (void)n; return SWIG_OK; } void Language::main(int argc, char *argv[]) { (void)argc; (void)argv; } /* ----------------------------------------------------------------------------- * Language::addSymbol() * * Adds a symbol entry. Returns 1 if the symbol is added successfully. * Prints an error message and returns 0 if a conflict occurs. * ----------------------------------------------------------------------------- */ int Language::addSymbol(String *s, Node *n) { Node *c = Getattr(symbols,s); if (c && (c != n)) { Swig_error(input_file, line_number, "'%s' is multiply defined in the generated module.\n", s); Swig_error(Getfile(c),Getline(c), "Previous declaration of '%s'\n", s); return 0; } Setattr(symbols,s,n); return 1; } /* ----------------------------------------------------------------------------- * Language::symbolLookup() * ----------------------------------------------------------------------------- */ Node * Language::symbolLookup(String *s) { return Getattr(symbols,s); } /* ----------------------------------------------------------------------------- * Language::classLookup() * * Tries to locate a class from a type definition * ----------------------------------------------------------------------------- */ Node * Language::classLookup(SwigType *s) { Node *n = 0; SwigType *lt, *ty1,*ty2; String *base; String *prefix; Symtab *stab = 0; /* Look in hash of cached values */ n = Getattr(classtypes,s); if (!n) { lt = SwigType_ltype(s); ty1 = SwigType_typedef_resolve_all(lt); ty2 = SwigType_strip_qualifiers(ty1); Delete(lt); Delete(ty1); base = SwigType_base(ty2); Replaceall(base,"class ",""); Replaceall(base,"struct ",""); Replaceall(base,"union ",""); prefix = SwigType_prefix(ty2); /* Do a symbol table search on the base type */ while (!n) { Hash *nstab; n = Swig_symbol_clookup(base,stab); if (!n) break; if (Strcmp(nodeType(n),"class") == 0) break; n = parentNode(n); if (!n) break; nstab = Getattr(n,"sym:symtab"); n = 0; if ((!nstab) || (nstab == stab)) { break; } stab = nstab; } if (n) { /* Found a match. Look at the prefix. We only allow a few cases: pointers, references, and simple */ if ((Len(prefix) == 0) || /* Simple type */ (Strcmp(prefix,"p.") == 0) || /* pointer */ (Strcmp(prefix,"r.") == 0)) { /* reference */ Setattr(classtypes,Copy(s),n); } else { n = 0; } } Delete(ty2); Delete(base); Delete(prefix); } if (n && (Getattr(n,"feature:ignore"))) { n = 0; } return n; } /* ----------------------------------------------------------------------------- * Language::allow_overloading() * ----------------------------------------------------------------------------- */ void Language::allow_overloading(int val) { overloading = val; } /* ----------------------------------------------------------------------------- * Language::allow_multiple_input() * ----------------------------------------------------------------------------- */ void Language::allow_multiple_input(int val) { multiinput = val; } /* ----------------------------------------------------------------------------- * Language::allow_directors() * ----------------------------------------------------------------------------- */ void Language::allow_directors(int val) { directors = val; } /* ----------------------------------------------------------------------------- * Language::directorsEnabled() * ----------------------------------------------------------------------------- */ int Language::directorsEnabled() const { return directors && CPlusPlus; } /* ----------------------------------------------------------------------------- * Language::allow_dirprot() * ----------------------------------------------------------------------------- */ void Language::allow_dirprot(int val) { director_protected_mode = val; } /* ----------------------------------------------------------------------------- * Language::dirprot_mode() * ----------------------------------------------------------------------------- */ int Language::dirprot_mode() const { return directorsEnabled() ? director_protected_mode : 0; } /* ----------------------------------------------------------------------------- * Language::is_smart_pointer() * ----------------------------------------------------------------------------- */ int Language::is_smart_pointer() const { return SmartPointer; } /* ----------------------------------------------------------------------------- * Language::is_wrapping_class() * ----------------------------------------------------------------------------- */ int Language::is_wrapping_class() { return InClass; } /* ----------------------------------------------------------------------------- * Language::getCurrentClass() * ----------------------------------------------------------------------------- */ Node * Language::getCurrentClass() const { return CurrentClass; } /* ----------------------------------------------------------------------------- * Language::getClassName() * ----------------------------------------------------------------------------- */ String * Language::getClassName() const { return ClassName; } /* ----------------------------------------------------------------------------- * Language::getClassPrefix() * ----------------------------------------------------------------------------- */ String * Language::getClassPrefix() const { return ClassPrefix; } /* ----------------------------------------------------------------------------- * Language::getClassType() * ----------------------------------------------------------------------------- */ String * Language::getClassType() const { return ClassType; } /* ----------------------------------------------------------------------------- * Language::abstractClassTest() * ----------------------------------------------------------------------------- */ int Language::abstractClassTest(Node *n) { return (Getattr(n,"abstract") ? 1 : 0); } void Language::setSubclassInstanceCheck(String *nc) { none_comparison = nc; } void Language::setOverloadResolutionTemplates(String *argc, String *argv) { Delete(argc_template_string); argc_template_string = Copy(argc); Delete(argv_template_string); argv_template_string = Copy(argv); } cableswig-0.1.0+git20150808.orig/SWIG/Source/Modules/directors.cxx0000644000175000000620000001433612561312227023177 0ustar stevestaff/* ----------------------------------------------------------------------------- * directors.cxx * * Director support functions. * * Not all of these may be necessary, and some may duplicate existing functionality * in SWIG. --MR * * Author(s) : Mark Rose * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_directors_cxx[] = "$Header"; #include "swigmod.h" /* Swig_csuperclass_call() * * Generates a fully qualified method call, including the full parameter list. * e.g. "base::method(i, j)" * */ String *Swig_csuperclass_call(String* base, String* method, ParmList* l) { String *call = NewString(""); Parm *p; if (base) { Printf(call, "%s::", base); } Printf(call, "%s(", method); for (p=l; p; p = nextSibling(p)) { String *pname = Getattr(p, "name"); if (p != l) Printf(call, ", "); Printv(call, pname, NIL); } Printf(call, ")"); return call; } /* Swig_class_declaration() * * Generate the start of a class/struct declaration. * e.g. "class myclass" * */ String *Swig_class_declaration(Node *n, String *name) { if (!name) { name = Getattr(n, "sym:name"); } String *result = NewString(""); String *kind = Getattr(n, "kind"); Printf(result, "%s %s", kind, name); return result; } String *Swig_class_name(Node *n) { String *name; name = Copy(Getattr(n, "sym:name")); return name; } /* Swig_director_declaration() * * Generate the full director class declaration, complete with base classes. * e.g. "class SwigDirector_myclass : public myclass, public Swig::Director {" * */ String *Swig_director_declaration(Node *n) { String* classname = Swig_class_name(n); String *directorname = NewStringf("SwigDirector_%s", classname); String *base = Getattr(n, "classtype"); String *declaration = Swig_class_declaration(n, directorname); Printf(declaration, " : public %s, public Swig::Director {\n", base); Delete(classname); Delete(directorname); return declaration; } String *Swig_method_call(String_or_char *name, ParmList *parms) { String *func; int i = 0; int comma = 0; Parm *p = parms; SwigType *pt; String *nname; func = NewString(""); nname = SwigType_namestr(name); Printf(func,"%s(", nname); while (p) { String *pname; pt = Getattr(p,"type"); if ((SwigType_type(pt) != T_VOID)) { if (comma) Printf(func,","); pname = Getattr(p, "name"); Printf(func,"%s", pname); comma = 1; i++; } p = nextSibling(p); } Printf(func,")"); return func; } /* Swig_method_decl * * Misnamed and misappropriated! Taken from SWIG's type string manipulation utilities * and modified to generate full (or partial) type qualifiers for method declarations, * local variable declarations, and return value casting. More importantly, it merges * parameter type information with actual parameter names to produce a complete method * declaration that fully mirrors the original method declaration. * * There is almost certainly a saner way to do this. * * This function needs to be cleaned up and possibly split into several smaller * functions. For instance, attaching default names to parameters should be done in a * separate function. * */ String *Swig_method_decl(SwigType *s, const String_or_char *id, List *args, int strip, int values) { String *result; List *elements; String *element = 0, *nextelement; int is_const = 0; int nelements, i; int is_func = 0; int arg_idx = 0; if (id) { result = NewString(Char(id)); } else { result = NewString(""); } elements = SwigType_split(s); nelements = Len(elements); if (nelements > 0) { element = Getitem(elements, 0); } for (i = 0; i < nelements; i++) { if (i < (nelements - 1)) { nextelement = Getitem(elements, i+1); } else { nextelement = 0; } if (SwigType_isqualifier(element)) { int skip = 0; DOH *q = 0; if (!strip) { q = SwigType_parm(element); if (!Cmp(q, "const")) { is_const = 1; is_func = SwigType_isfunction(nextelement); if (is_func) skip = 1; skip = 1; } if (!skip) { Insert(result,0," "); Insert(result,0,q); } Delete(q); } } else if (SwigType_ispointer(element)) { Insert(result,0,"*"); if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) { Insert(result,0,"("); Append(result,")"); } } else if (SwigType_ismemberpointer(element)) { String *q; q = SwigType_parm(element); Insert(result,0,"::*"); Insert(result,0,q); if ((nextelement) && ((SwigType_isfunction(nextelement) || (SwigType_isarray(nextelement))))) { Insert(result,0,"("); Append(result,")"); } Delete(q); } else if (SwigType_isreference(element)) { Insert(result,0,"&"); } else if (SwigType_isarray(element)) { DOH *size; Append(result,"["); size = SwigType_parm(element); Append(result,size); Append(result,"]"); Delete(size); } else if (SwigType_isfunction(element)) { Parm *parm; String *p; Append(result,"("); parm = args; while (parm != 0) { String *type = Getattr(parm, "type"); String* name = Getattr(parm, "name"); if (!name && Cmp(type, "void")) { name = NewString(""); Printf(name, "arg%d", arg_idx++); Setattr(parm, "name", name); } if (!name) { name = NewString(""); } p = SwigType_str(type, name); Append(result,p); String* value = Getattr(parm, "value"); if (values && (value != 0)) { Printf(result, " = %s", value); } parm = nextSibling(parm); if (parm != 0) Append(result,", "); } Append(result,")"); } else { if (Strcmp(element,"v(...)") == 0) { Insert(result,0,"..."); } else { String *bs = SwigType_namestr(element); Insert(result,0," "); Insert(result,0,bs); Delete(bs); } } element = nextelement; } Delete(elements); if (is_const) { if (is_func) { Append(result, " "); Append(result, "const"); } else { Insert(result, 0, "const "); } } Chop(result); return result; } cableswig-0.1.0+git20150808.orig/SWIG/Source/Modules/ruby.cxx0000644000175000000620000022716112561312227022164 0ustar stevestaff/******************************************************************** * Ruby module for SWIG * * /cvsroot/SWIG/Source/Modules/ruby.cxx,v 1.51 2004/01/24 00:28:54 mmatus Exp * * Copyright (C) 2000 Network Applied Communication Laboratory, Inc. * Copyright (C) 2000 Information-technology Promotion Agency, Japan * * Masaki Fukushima * ********************************************************************/ char cvsroot_ruby_cxx[] = "/cvsroot/SWIG/Source/Modules/ruby.cxx,v 1.51 2004/01/24 00:28:54 mmatus Exp"; #include "swigmod.h" #define SWIG_PROTECTED_TARGET_METHODS 1 #include #include #include /* for INT_MAX */ class RClass { private: String *temp; public: String *name; /* class name (renamed) */ String *cname; /* original C class/struct name */ String *mname; /* Mangled name */ /** * The C variable name used in the SWIG-generated wrapper code to refer to * this class; usually it is of the form "cClassName.klass", where cClassName * is a swig_class struct instance and klass is a member of that struct. */ String *vname; /** * The C variable name used in the SWIG-generated wrapper code to refer to * the module that implements this class's methods (when we're trying to * support C++ multiple inheritance). Usually it is of the form * "cClassName.mImpl", where cClassName is a swig_class struct instance * and mImpl is a member of that struct. */ String *mImpl; String *type; String *prefix; String *header; String *init; int constructor_defined; int destructor_defined; RClass() { temp = NewString(""); name = NewString(""); cname = NewString(""); mname = NewString(""); vname = NewString(""); mImpl = NewString(""); type = NewString(""); prefix = NewString(""); header = NewString(""); init = NewString(""); constructor_defined = 0; destructor_defined = 0; } ~RClass() { Delete(name); Delete(cname); Delete(vname); Delete(mImpl); Delete(mname); Delete(type); Delete(prefix); Delete(header); Delete(init); Delete(temp); } void set_name(const String_or_char *cn, const String_or_char *rn, const String_or_char *valn) { /* Original C/C++ class (or struct) name */ Clear(cname); Append(cname,cn); /* Mangled name */ Delete(mname); mname = Swig_name_mangle(cname); /* Renamed class name */ Clear(name); Append(name,valn); /* Variable name for the VALUE that refers to the Ruby Class object */ Clear(vname); Printf(vname, "c%s.klass", name); /* Variable name for the VALUE that refers to the Ruby Class object */ Clear(mImpl); Printf(mImpl, "c%s.mImpl", name); /* Prefix */ Clear(prefix); Printv(prefix,(rn ? rn : cn), "_", NIL); } char *strip(const String_or_char *s) { Clear(temp); Append(temp, s); if (Strncmp(s, prefix, Len(prefix)) == 0) { Replaceall(temp,prefix,""); } return Char(temp); } }; static const char * usage = "\ Ruby Options (available with -ruby)\n\ -ldflags - Print runtime libraries to link with\n\ -globalmodule - Wrap everything into the global module\n\ -minherit - Attempt to support multiple inheritance\n\ -feature - Set feature name to (used by `require')\n"; #define RCLASS(hash, name) (RClass*)(Getattr(hash, name) ? Data(Getattr(hash, name)) : 0) #define SET_RCLASS(hash, name, klass) Setattr(hash, name, NewVoid(klass, 0)) class RUBY : public Language { private: String *module; String *modvar; String *feature; int current; Hash *classes; /* key=cname val=RClass */ RClass *klass; /* Currently processing class */ Hash *special_methods; /* Python style special method name table */ File *f_directors; File *f_directors_h; File *f_runtime; File *f_runtime_h; File *f_header; File *f_wrappers; File *f_init; bool use_kw; bool useGlobalModule; bool multipleInheritance; // Wrap modes enum { NO_CPP, MEMBER_FUNC, CONSTRUCTOR_ALLOCATE, CONSTRUCTOR_INITIALIZE, DESTRUCTOR, MEMBER_VAR, CLASS_CONST, STATIC_FUNC, STATIC_VAR }; public: /* --------------------------------------------------------------------- * RUBY() * * Initialize member data * --------------------------------------------------------------------- */ RUBY() { module = 0; modvar = 0; feature = 0; current = NO_CPP; classes = 0; klass = 0; special_methods = 0; f_runtime = 0; f_header = 0; f_wrappers = 0; f_init = 0; use_kw = false; useGlobalModule = false; multipleInheritance = false; } /* --------------------------------------------------------------------- * main() * * Parse command line options and initializes variables. * --------------------------------------------------------------------- */ virtual void main(int argc, char *argv[]) { /* Set location of SWIG library */ SWIG_library_directory("ruby"); /* Look for certain command line options */ for (int i = 1; i < argc; i++) { if (argv[i]) { if (strcmp(argv[i],"-feature") == 0) { if (argv[i+1]) { char *name = argv[i+1]; feature = NewString(name); Swig_mark_arg(i); Swig_mark_arg(i+1); i++; } else { Swig_arg_error(); } } else if (strcmp(argv[i],"-globalmodule") == 0) { useGlobalModule = true; Swig_mark_arg(i); } else if (strcmp(argv[i],"-minherit") == 0) { multipleInheritance = true; Swig_mark_arg(i); } else if (strcmp(argv[i],"-help") == 0) { Printf(stderr,"%s\n", usage); } else if (strcmp (argv[i],"-ldflags") == 0) { printf("%s\n", SWIG_RUBY_RUNTIME); SWIG_exit (EXIT_SUCCESS); } } } /* Add a symbol to the parser for conditional compilation */ Preprocessor_define("SWIGRUBY 1", 0); /* Add typemap definitions */ SWIG_typemap_lang("ruby"); SWIG_config_file("ruby.swg"); allow_overloading(); } /** * Generate initialization code to define the Ruby module(s), * accounting for nested modules as necessary. */ void defineRubyModule() { List *modules = Split(module,':',INT_MAX); if (modules != 0 && Len(modules) > 0) { String *mv = 0; Iterator m; m = First(modules); while (m.item) { if (Len(m.item) > 0) { if (mv != 0) { Printv(f_init, tab4, modvar, " = rb_define_module_under(", modvar, ", \"", m.item, "\");\n", NIL); } else { Printv(f_init, tab4, modvar, " = rb_define_module(\"", m.item, "\");\n", NIL); mv = NewString(modvar); } } m = Next(m); } Delete(mv); Delete(modules); } } void registerMagicMethods() { special_methods = NewHash(); /* Python style special method name. */ /* Basic */ Setattr(special_methods, "__repr__", "inspect"); Setattr(special_methods, "__str__", "to_s"); Setattr(special_methods, "__cmp__", "<=>"); Setattr(special_methods, "__hash__", "hash"); Setattr(special_methods, "__nonzero__", "nonzero?"); /* Callable */ Setattr(special_methods, "__call__", "call"); /* Collection */ Setattr(special_methods, "__len__", "length"); Setattr(special_methods, "__getitem__", "[]"); Setattr(special_methods, "__setitem__", "[]="); /* Operators */ Setattr(special_methods, "__add__", "+"); Setattr(special_methods, "__pos__", "+@"); Setattr(special_methods, "__sub__", "-"); Setattr(special_methods, "__neg__", "-@"); Setattr(special_methods, "__mul__", "*"); Setattr(special_methods, "__div__", "/"); Setattr(special_methods, "__mod__", "%"); Setattr(special_methods, "__lshift__", "<<"); Setattr(special_methods, "__rshift__", ">>"); Setattr(special_methods, "__and__", "&"); Setattr(special_methods, "__or__", "|"); Setattr(special_methods, "__xor__", "^"); Setattr(special_methods, "__invert__", "~"); Setattr(special_methods, "__lt__", "<"); Setattr(special_methods, "__le__", "<="); Setattr(special_methods, "__gt__", ">"); Setattr(special_methods, "__ge__", ">="); Setattr(special_methods, "__eq__", "=="); /* Other numeric */ Setattr(special_methods, "__divmod__", "divmod"); Setattr(special_methods, "__pow__", "**"); Setattr(special_methods, "__abs__", "abs"); Setattr(special_methods, "__int__", "to_i"); Setattr(special_methods, "__float__", "to_f"); Setattr(special_methods, "__coerce__", "coerce"); } /* --------------------------------------------------------------------- * top() * --------------------------------------------------------------------- */ virtual int top(Node *n) { /** * See if any Ruby module options have been specified as options * to the %module directive. */ Node *swigModule = Getattr(n, "module"); if (swigModule) { Node *options = Getattr(swigModule, "options"); if (options) { if (Getattr(options, "directors")) { allow_directors(); } if (Getattr(options, "dirprot")) { allow_dirprot(); } if (Getattr(options, "ruby_globalmodule")) { useGlobalModule = true; } if (Getattr(options, "ruby_minherit")) { multipleInheritance = true; } } } /* Set comparison with none for ConstructorToFunction */ setSubclassInstanceCheck(NewString("CLASS_OF(self) != Qnil")); // FIXME // setSubclassInstanceCheck(NewString("CLASS_OF(self) != cFoo.klass")); /* Initialize all of the output files */ String *outfile = Getattr(n,"outfile"); String *outfile_h = Getattr(n, "outfile_h"); f_runtime = NewFile(outfile,"w"); if (!f_runtime) { Printf(stderr,"*** Can't open '%s'\n", outfile); SWIG_exit(EXIT_FAILURE); } if (directorsEnabled()) { f_runtime_h = NewFile(outfile_h,"w"); if (!f_runtime_h) { Printf(stderr,"*** Can't open '%s'\n", outfile_h); SWIG_exit(EXIT_FAILURE); } } f_init = NewString(""); f_header = NewString(""); f_wrappers = NewString(""); f_directors_h = NewString(""); f_directors = NewString(""); /* Register file targets with the SWIG file handler */ Swig_register_filebyname("header",f_header); Swig_register_filebyname("wrapper",f_wrappers); Swig_register_filebyname("runtime",f_runtime); Swig_register_filebyname("init",f_init); Swig_register_filebyname("director",f_directors); Swig_register_filebyname("director_h",f_directors_h); modvar = 0; current = NO_CPP; klass = 0; classes = NewHash(); registerMagicMethods(); Swig_banner(f_runtime); if (NoInclude) { Printf(f_runtime, "#define SWIG_NOINCLUDE\n"); } if (directorsEnabled()) { Printf(f_runtime,"#define SWIG_DIRECTORS\n"); } /* typedef void *VALUE */ SwigType *value = NewSwigType(T_VOID); SwigType_add_pointer(value); SwigType_typedef(value,(char*)"VALUE"); Delete(value); /* Set module name */ set_module(Char(Getattr(n,"name"))); if (directorsEnabled()) { Swig_banner(f_directors_h); Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", module); Printf(f_directors_h, "#define SWIG_%s_WRAP_H_\n\n", module); Printf(f_directors_h, "class Swig::Director;\n\n"); Swig_insert_file("director.swg", f_directors); Printf(f_directors, "\n\n"); Printf(f_directors, "/* ---------------------------------------------------\n"); Printf(f_directors, " * C++ director class methods\n"); Printf(f_directors, " * --------------------------------------------------- */\n\n"); Printf(f_directors, "#include \"%s\"\n\n", Swig_file_filename(outfile_h)); } Printf(f_header,"#define SWIG_init Init_%s\n", feature); Printf(f_header,"#define SWIG_name \"%s\"\n\n", module); Printf(f_header,"static VALUE %s;\n", modvar); /* Start generating the initialization function */ Printv(f_init, "\n", "#ifdef __cplusplus\n", "extern \"C\"\n", "#endif\n", "SWIGEXPORT(void) Init_", feature, "(void) {\n", "int i;\n", "\n", NIL); Printv(f_init, tab4, "SWIG_InitRuntime();\n", NIL); if (!useGlobalModule) defineRubyModule(); Printv(f_init, "\n", "for (i = 0; swig_types_initial[i]; i++) {\n", "swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]);\n", "SWIG_define_class(swig_types[i]);\n", "}\n", NIL); Printf(f_init,"\n"); Language::top(n); /* Finish off our init function */ Printf(f_init,"}\n"); SwigType_emit_type_table(f_runtime,f_wrappers); /* Close all of the files */ Dump(f_header,f_runtime); if (directorsEnabled()) { Dump(f_directors, f_runtime); Dump(f_directors_h, f_runtime_h); Printf(f_runtime_h, "\n"); Printf(f_runtime_h, "#endif\n"); Close(f_runtime_h); } Dump(f_wrappers,f_runtime); Wrapper_pretty_print(f_init,f_runtime); Delete(f_header); Delete(f_wrappers); Delete(f_init); Close(f_runtime); Delete(f_runtime); return SWIG_OK; } /* ----------------------------------------------------------------------------- * importDirective() * ----------------------------------------------------------------------------- */ virtual int importDirective(Node *n) { String *modname = Getattr(n,"module"); if (modname) { Printf(f_init,"rb_require(\"%s\");\n", modname); } return Language::importDirective(n); } /* --------------------------------------------------------------------- * set_module(const char *mod_name) * * Sets the module name. Does nothing if it's already set (so it can * be overridden as a command line option). *---------------------------------------------------------------------- */ void set_module(const char *s) { String *mod_name = NewString(s); if (module == 0) { /* Start with the empty string */ module = NewString(""); /* Account for nested modules */ List *modules = Split(mod_name,':',INT_MAX); if (modules != 0 && Len(modules) > 0) { String *last = 0; Iterator m = First(modules); while (m.item) { if (Len(m.item) > 0) { String *cap = NewString(m.item); (Char(cap))[0] = toupper((Char(cap))[0]); if (last != 0) { Append(module, "::"); } Append(module, cap); last = m.item; } m = Next(m); } if (feature == 0) { feature = Copy(last); } (Char(last))[0] = toupper((Char(last))[0]); modvar = NewStringf("m%s", last); Delete(modules); } } Delete(mod_name); } /* -------------------------------------------------------------------------- * nativeWrapper() * -------------------------------------------------------------------------- */ virtual int nativeWrapper(Node *n) { String *funcname = Getattr(n,"wrap:name"); Swig_warning(WARN_LANG_NATIVE_UNIMPL, input_file, line_number, "Adding native function %s not supported (ignored).\n", funcname); return SWIG_NOWRAP; } /** * Process the comma-separated list of aliases (if any). */ void defineAliases(Node *n, const String_or_char *iname) { String *aliasv = Getattr(n,"feature:alias"); if (aliasv) { List *aliases = Split(aliasv,',',INT_MAX); if (aliases && Len(aliases) > 0) { Iterator alias = First(aliases); while (alias.item) { if (Len(alias.item) > 0) { Printv(klass->init, tab4, "rb_define_alias(", klass->vname, ", \"", alias.item, "\", \"", iname, "\");\n", NIL); } alias = Next(alias); } } Delete(aliases); } } /* --------------------------------------------------------------------- * create_command(Node *n, char *iname) * * Creates a new command from a C function. * iname = Name of function in scripting language * * A note about what "protected" and "private" mean in Ruby: * * A private method is accessible only within the class or its subclasses, * and it is callable only in "function form", with 'self' (implicit or * explicit) as a receiver. * * A protected method is callable only from within its class, but unlike * a private method, it can be called with a receiver other than self, such * as another instance of the same class. * --------------------------------------------------------------------- */ void create_command(Node *n, const String_or_char *iname) { String *alloc_func = Swig_name_wrapper(iname); String *wname = Swig_name_wrapper(iname); if (CPlusPlus) { Insert(wname,0,"VALUEFUNC("); Append(wname,")"); } if (current != NO_CPP) iname = klass->strip(iname); if (Getattr(special_methods, iname)) { iname = GetChar(special_methods, iname); } String *s = NewString(""); String *temp = NewString(""); switch (current) { case MEMBER_FUNC: { #ifdef SWIG_PROTECTED_TARGET_METHODS const char* rb_define_method = is_protected(n) ? "rb_define_protected_method" : "rb_define_method"; #else const char* rb_define_method = "rb_define_method"; #endif if (multipleInheritance) { Printv(klass->init, tab4, rb_define_method,"(", klass->mImpl, ", \"", iname, "\", ", wname, ", -1);\n", NIL); } else { Printv(klass->init, tab4, rb_define_method, "(", klass->vname, ", \"", iname, "\", ", wname, ", -1);\n", NIL); } } break; case CONSTRUCTOR_ALLOCATE: Printv(s, tab4, "rb_define_alloc_func(", klass->vname, ", ", alloc_func, ");\n", NIL); Replaceall(klass->init,"$allocator", s); break; case CONSTRUCTOR_INITIALIZE: Printv(s, tab4, "rb_define_method(", klass->vname, ", \"initialize\", ", wname, ", -1);\n", NIL); Replaceall(klass->init,"$initializer", s); break; case MEMBER_VAR: Append(temp,iname); Replaceall(temp,"_set", "="); Replaceall(temp,"_get", ""); if (multipleInheritance) { Printv(klass->init, tab4, "rb_define_method(", klass->mImpl, ", \"", temp, "\", ", wname, ", -1);\n", NIL); } else { Printv(klass->init, tab4, "rb_define_method(", klass->vname, ", \"", temp, "\", ", wname, ", -1);\n", NIL); } break; case STATIC_FUNC: Printv(klass->init, tab4, "rb_define_singleton_method(", klass->vname, ", \"", iname, "\", ", wname, ", -1);\n", NIL); break; case NO_CPP: if (!useGlobalModule) { Printv(s, tab4, "rb_define_module_function(", modvar, ", \"", iname, "\", ", wname, ", -1);\n",NIL); Printv(f_init,s,NIL); } else { Printv(s, tab4, "rb_define_global_function(\"", iname, "\", ", wname, ", -1);\n",NIL); Printv(f_init,s,NIL); } break; case DESTRUCTOR: case CLASS_CONST: case STATIC_VAR: assert(false); // Should not have gotten here for these types default: assert(false); } defineAliases(n, iname); Delete(temp); Delete(s); Delete(wname); Delete(alloc_func); } /* --------------------------------------------------------------------- * applyInputTypemap() * * Look up the appropriate "in" typemap for this parameter (p), * substitute the correct strings for the $target and $input typemap * parameters, and dump the resulting code to the wrapper file. * --------------------------------------------------------------------- */ Parm *applyInputTypemap(Parm *p, String *ln, String *source, Wrapper *f) { String *tm; SwigType *pt = Getattr(p,"type"); if ((tm = Getattr(p,"tmap:in"))) { Replaceall(tm,"$target",ln); Replaceall(tm,"$source",source); Replaceall(tm,"$input",source); Setattr(p,"emit:input",Copy(source)); Printf(f->code,"%s\n", tm); p = Getattr(p,"tmap:in:next"); } else { Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt,0)); p = nextSibling(p); } return p; } Parm *skipIgnoredArgs(Parm *p) { while (checkAttribute(p,"tmap:in:numinputs","0")) { p = Getattr(p,"tmap:in:next"); } return p; } /* --------------------------------------------------------------------- * marshalInputArgs() * * Process all of the arguments passed into the scripting language * method and convert them into C/C++ function arguments using the * supplied typemaps. * --------------------------------------------------------------------- */ void marshalInputArgs(Node *n, ParmList *l, int numarg, int numreq, String *kwargs, bool allow_kwargs, Wrapper *f) { int i; Parm *p; String *tm; String *source; String *target; source = NewString(""); target = NewString(""); bool use_director = (current == CONSTRUCTOR_INITIALIZE && Swig_directorclass(n)); /** * The 'start' value indicates which of the C/C++ function arguments * produced here corresponds to the first value in Ruby's argv[] array. * The value of start is either zero or one. If start is zero, then * the first argument (with name arg1) is based on the value of argv[0]. * If start is one, then arg1 is based on the value of argv[1]. */ int start = (current == MEMBER_FUNC || current == MEMBER_VAR || use_director) ? 1 : 0; int varargs = emit_isvarargs(l); Printf(kwargs,"{ "); for (i = 0, p = l; i < numarg; i++) { p = skipIgnoredArgs(p); String *pn = Getattr(p,"name"); String *ln = Getattr(p,"lname"); /* Produce string representation of source argument */ Clear(source); /* First argument is a special case */ if (i == 0) { Printv(source, (start == 0) ? "argv[0]" : "self", NIL); } else { Printf(source,"argv[%d]",i-start); } /* Produce string representation of target argument */ Clear(target); Printf(target,"%s",Char(ln)); if (i >= (numreq)) { /* Check if parsing an optional argument */ Printf(f->code," if (argc > %d) {\n", i - start); } /* Record argument name for keyword argument handling */ if (Len(pn)) { Printf(kwargs,"\"%s\",", pn); } else { Printf(kwargs,"\"arg%d\",", i+1); } /* Look for an input typemap */ p = applyInputTypemap(p, ln, source, f); if (i >= numreq) { Printf(f->code,"}\n"); } } /* Finish argument marshalling */ Printf(kwargs," NULL }"); if (allow_kwargs) { Printv(f->locals, tab4, "char *kwnames[] = ", kwargs, ";\n", NIL); } /* Trailing varargs */ if (varargs) { if (p && (tm = Getattr(p,"tmap:in"))) { Clear(source); Printf(source,"argv[%d]",i-start); Replaceall(tm,"$input",source); Setattr(p,"emit:input",Copy(source)); Printf(f->code,"if (argc > %d) {\n", i-start); Printv(f->code,tm,"\n",NIL); Printf(f->code,"}\n"); } } Delete(source); Delete(target); } /* --------------------------------------------------------------------- * insertConstraintCheckingCode(ParmList *l, Wrapper *f) * * Checks each of the parameters in the parameter list for a "check" * typemap and (if it finds one) inserts the typemapping code into * the function wrapper. * --------------------------------------------------------------------- */ void insertConstraintCheckingCode(ParmList *l, Wrapper *f) { Parm *p; String *tm; for (p = l; p;) { if ((tm = Getattr(p,"tmap:check"))) { Replaceall(tm,"$target",Getattr(p,"lname")); Printv(f->code,tm,"\n",NIL); p = Getattr(p,"tmap:check:next"); } else { p = nextSibling(p); } } } /* --------------------------------------------------------------------- * insertCleanupCode(ParmList *l, String *cleanup) * * Checks each of the parameters in the parameter list for a "freearg" * typemap and (if it finds one) inserts the typemapping code into * the function wrapper. * --------------------------------------------------------------------- */ void insertCleanupCode(ParmList *l, String *cleanup) { String *tm; for (Parm *p = l; p; ) { if ((tm = Getattr(p,"tmap:freearg"))) { Replaceall(tm,"$source",Getattr(p,"lname")); Printv(cleanup,tm,"\n",NIL); p = Getattr(p,"tmap:freearg:next"); } else { p = nextSibling(p); } } } /* --------------------------------------------------------------------- * insertArgOutputCode(ParmList *l, String *outarg, int& need_result) * * Checks each of the parameters in the parameter list for a "argout" * typemap and (if it finds one) inserts the typemapping code into * the function wrapper. * --------------------------------------------------------------------- */ void insertArgOutputCode(ParmList *l, String *outarg, int& need_result) { String *tm; for (Parm *p = l; p; ) { if ((tm = Getattr(p,"tmap:argout"))) { Replaceall(tm,"$source",Getattr(p,"lname")); Replaceall(tm,"$target","vresult"); Replaceall(tm,"$result","vresult"); Replaceall(tm,"$arg",Getattr(p,"emit:input")); Replaceall(tm,"$input",Getattr(p,"emit:input")); Printv(outarg,tm,"\n",NIL); need_result = 1; p = Getattr(p,"tmap:argout:next"); } else { p = nextSibling(p); } } } /* --------------------------------------------------------------------- * validIdentifier() * * Is this a valid identifier in the scripting language? * Ruby method names can include any combination of letters, numbers * and underscores. A Ruby method name may optionally end with * a question mark ("?"), exclamation point ("!") or equals sign ("="). * * Methods whose names end with question marks are, by convention, * predicate methods that return true or false (e.g. Array#empty?). * * Methods whose names end with exclamation points are, by convention, * "mutators" that modify the instance in place (e.g. Array#sort!). * * Methods whose names end with an equals sign are attribute setters * (e.g. Thread#critical=). * --------------------------------------------------------------------- */ virtual int validIdentifier(String *s) { char *c = Char(s); while (*c) { if ( !( isalnum(*c) || (*c == '_') || (*c == '?') || (*c == '!') || (*c == '=') ) ) return 0; c++; } return 1; } /* --------------------------------------------------------------------- * functionWrapper() * * Create a function declaration and register it with the interpreter. * --------------------------------------------------------------------- */ virtual int functionWrapper(Node *n) { String *nodeType; bool constructor; bool destructor; String *storage; bool isVirtual; String *symname = Copy(Getattr(n,"sym:name")); SwigType *t = Getattr(n,"type"); ParmList *l = Getattr(n,"parms"); Node *parent = Getattr(n,"parentNode"); String *tm; int need_result = 0; /* Ruby needs no destructor wrapper */ if (current == DESTRUCTOR) return SWIG_NOWRAP; nodeType = Getattr(n, "nodeType"); constructor = (!Cmp(nodeType, "constructor")); destructor = (!Cmp(nodeType, "destructor")); storage = Getattr(n, "storage"); isVirtual = (Cmp(storage, "virtual") == 0); /* If the C++ class constructor is overloaded, we only want to * write out the "new" singleton method once since it is always * the same. (It's the "initialize" method that will handle the * overloading). */ if (current == CONSTRUCTOR_ALLOCATE && Swig_symbol_isoverloaded(n) && Getattr(n, "sym:nextSibling") != 0) return SWIG_OK; String *overname = 0; if (Getattr(n, "sym:overloaded")) { overname = Getattr(n, "sym:overname"); } else { if (!addSymbol(symname, n)) return SWIG_ERROR; } String *cleanup = NewString(""); String *outarg = NewString(""); String *kwargs = NewString(""); Wrapper *f = NewWrapper(); /* Rename predicate methods */ if (Getattr(n, "feature:predicate")) { Append(symname, "?"); } /* Determine the name of the SWIG wrapper function */ String *wname = Swig_name_wrapper(symname); if (overname && current != CONSTRUCTOR_ALLOCATE) { Append(wname,overname); } /* Emit arguments */ if (current != CONSTRUCTOR_ALLOCATE) { emit_args(t,l,f); } /* Attach standard typemaps */ if (current != CONSTRUCTOR_ALLOCATE) { emit_attach_parmmaps(l, f); } Setattr(n, "wrap:parms", l); /* Get number of arguments */ int numarg = emit_num_arguments(l); int numreq = emit_num_required(l); int varargs = emit_isvarargs(l); bool allow_kwargs = use_kw || Getattr(n,"feature:kwargs"); bool use_director = (current == CONSTRUCTOR_INITIALIZE && Swig_directorclass(n)); int start = (current == MEMBER_FUNC || current == MEMBER_VAR || use_director) ? 1 : 0; /* Now write the wrapper function itself */ if (current == CONSTRUCTOR_ALLOCATE) { Printf(f->def, "#ifdef HAVE_RB_DEFINE_ALLOC_FUNC\n"); Printv(f->def, "static VALUE\n", wname, "(VALUE self) {", NIL); Printf(f->def, "#else\n"); Printv(f->def, "static VALUE\n", wname, "(int argc, VALUE *argv, VALUE self) {", NIL); Printf(f->def, "#endif\n"); } else if (current == CONSTRUCTOR_INITIALIZE) { Printv(f->def, "static VALUE\n", wname, "(int argc, VALUE *argv, VALUE self) {", NIL); if (!varargs) { Printf(f->code,"if ((argc < %d) || (argc > %d))\n", numreq-start, numarg-start); } else { Printf(f->code,"if (argc < %d)\n", numreq-start); } Printf(f->code,"rb_raise(rb_eArgError, \"wrong # of arguments(%%d for %d)\",argc);\n",numreq-start); } else { Printv(f->def, "static VALUE\n", wname, "(int argc, VALUE *argv, VALUE self) {", NIL); if (!varargs) { Printf(f->code,"if ((argc < %d) || (argc > %d))\n", numreq-start, numarg-start); } else { Printf(f->code,"if (argc < %d)\n", numreq-start); } Printf(f->code,"rb_raise(rb_eArgError, \"wrong # of arguments(%%d for %d)\",argc);\n",numreq-start); } /* Now walk the function parameter list and generate code */ /* to get arguments */ if (current != CONSTRUCTOR_ALLOCATE) { marshalInputArgs(n, l, numarg, numreq, kwargs, allow_kwargs, f); } // FIXME? if (use_director) { numarg--; numreq--; } /* Insert constraint checking code */ insertConstraintCheckingCode(l, f); /* Insert cleanup code */ insertCleanupCode(l, cleanup); /* Insert argument output code */ insertArgOutputCode(l, outarg, need_result); /* if the object is a director, and the method call originated from its * underlying python object, resolve the call by going up the c++ * inheritance chain. otherwise try to resolve the method in python. * without this check an infinite loop is set up between the director and * shadow class method calls. */ // NOTE: this code should only be inserted if this class is the // base class of a director class. however, in general we haven't // yet analyzed all classes derived from this one to see if they are // directors. furthermore, this class may be used as the base of // a director class defined in a completely different module at a // later time, so this test must be included whether or not directorbase // is true. we do skip this code if directors have not been enabled // at the command line to preserve source-level compatibility with // non-polymorphic swig. also, if this wrapper is for a smart-pointer // method, there is no need to perform the test since the calling object // (the smart-pointer) and the director object (the "pointee") are // distinct. if (directorsEnabled()) { if (!is_smart_pointer()) { if (/*directorbase &&*/ !constructor && !destructor && isVirtual) { Wrapper_add_local(f, "director", "Swig::Director *director = 0"); Printf(f->code, "director = dynamic_cast(arg1);\n"); Printf(f->code, "if (director && (director->swig_get_self() == self)) director->swig_set_up();\n"); } } } /* Now write code to make the function call */ if (current != CONSTRUCTOR_ALLOCATE) { if (current == CONSTRUCTOR_INITIALIZE) { String *action = Getattr(n,"wrap:action"); if (action) { Append(action,"DATA_PTR(self) = result;"); } } emit_action(n,f); } /* Return value if necessary */ if (SwigType_type(t) != T_VOID && current != CONSTRUCTOR_ALLOCATE && current != CONSTRUCTOR_INITIALIZE) { need_result = 1; if (Getattr(n, "feature:predicate")) { Printv(f->code, tab4, "vresult = (result ? Qtrue : Qfalse);\n", NIL); } else { tm = Swig_typemap_lookup_new("out",n,"result",0); if (tm) { Replaceall(tm,"$result","vresult"); Replaceall(tm,"$source","result"); Replaceall(tm,"$target","vresult"); if (Getattr(n, "feature:new")) Replaceall(tm,"$owner", "1"); else Replaceall(tm,"$owner", "0"); // FIXME: this will not try to unwrap directors returned as non-director // base class pointers! /* New addition to unwrap director return values so that the original * python object is returned instead. */ bool unwrap = false; String *decl = Getattr(n, "decl"); int is_pointer = SwigType_ispointer_return(decl); int is_reference = SwigType_isreference_return(decl); if (is_pointer || is_reference) { String *type = Getattr(n, "type"); Node *modname = Getattr(parent, "module"); Node *target = Swig_directormap(modname, type); if (target) unwrap = true; } if (unwrap) { Wrapper_add_local(f, "resultdirector", "Swig::Director *resultdirector = 0"); Printf(f->code, "resultdirector = dynamic_cast(result);\n"); Printf(f->code, "if (resultdirector) {\n"); Printf(f->code, " vresult = resultdirector->swig_get_self();\n"); Printf(f->code, "} else {\n"); Printf(f->code,"%s\n", tm); Printf(f->code, "}\n"); } else { Printf(f->code,"%s\n", tm); } } else { Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s.\n", SwigType_str(t,0)); } } } /* Extra code needed for new and initialize methods */ if (current == CONSTRUCTOR_ALLOCATE) { need_result = 1; Printf(f->code, "VALUE vresult = SWIG_NewClassInstance(self, SWIGTYPE%s);\n", Char(SwigType_manglestr(t))); Printf(f->code, "#ifndef HAVE_RB_DEFINE_ALLOC_FUNC\n"); Printf(f->code, "rb_obj_call_init(vresult, argc, argv);\n"); Printf(f->code, "#endif\n"); } else if (current == CONSTRUCTOR_INITIALIZE) { need_result = 1; // Printf(f->code, "DATA_PTR(self) = result;\n"); } /* Dump argument output code; */ Printv(f->code,outarg,NIL); /* Dump the argument cleanup code */ if (current != CONSTRUCTOR_ALLOCATE) Printv(f->code,cleanup,NIL); /* Look for any remaining cleanup. This processes the %new directive */ if (current != CONSTRUCTOR_ALLOCATE && Getattr(n, "feature:new")) { tm = Swig_typemap_lookup_new("newfree",n,"result",0); if (tm) { Replaceall(tm,"$source","result"); Printv(f->code,tm, "\n",NIL); } } /* Special processing on return value. */ tm = Swig_typemap_lookup_new("ret",n,"result",0); if (tm) { Replaceall(tm,"$source","result"); Printv(f->code,tm, NIL); } /* Wrap things up (in a manner of speaking) */ if (need_result) { if (current == CONSTRUCTOR_ALLOCATE) { Printv(f->code, tab4, "return vresult;\n", NIL); } else if (current == CONSTRUCTOR_INITIALIZE) { Printv(f->code, tab4, "return self;\n", NIL); } else { Wrapper_add_local(f,"vresult","VALUE vresult = Qnil"); Printv(f->code, tab4, "return vresult;\n", NIL); } } else { Printv(f->code, tab4, "return Qnil;\n", NIL); } /* Error handling code */ /* Printf(f->code,"fail:\n"); Printv(f->code,cleanup,NIL); Printv(f->code,"return Qnil;\n",NIL); */ Printf(f->code,"}\n"); /* Substitute the cleanup code */ Replaceall(f->code,"$cleanup",cleanup); /* Emit the function */ Wrapper_print(f, f_wrappers); /* Now register the function with the interpreter */ if (!Swig_symbol_isoverloaded(n)) { create_command(n, symname); } else { if (current == CONSTRUCTOR_ALLOCATE) { create_command(n, symname); } else { Setattr(n, "wrap:name", wname); if (!Getattr(n, "sym:nextSibling")) dispatchFunction(n); } } Delete(kwargs); Delete(cleanup); Delete(outarg); DelWrapper(f); Delete(symname); return SWIG_OK; } /* ------------------------------------------------------------ * dispatchFunction() * ------------------------------------------------------------ */ void dispatchFunction(Node *n) { /* Last node in overloaded chain */ int maxargs; String *tmp = NewString(""); String *dispatch = Swig_overload_dispatch(n, "return %s(nargs, args, self);", &maxargs); /* Generate a dispatch wrapper for all overloaded functions */ Wrapper *f = NewWrapper(); String *symname = Getattr(n, "sym:name"); String *wname = Swig_name_wrapper(symname); Printv(f->def, "static VALUE ", wname, "(int nargs, VALUE *args, VALUE self) {", NIL); Wrapper_add_local(f, "argc", "int argc"); if (current == MEMBER_FUNC || current == MEMBER_VAR) { Printf(tmp, "VALUE argv[%d]", maxargs+1); } else { Printf(tmp, "VALUE argv[%d]", maxargs); } Wrapper_add_local(f, "argv", tmp); Wrapper_add_local(f, "ii", "int ii"); if (current == MEMBER_FUNC || current == MEMBER_VAR) { Printf(f->code, "argc = nargs + 1;\n"); Printf(f->code, "argv[0] = self;\n"); Printf(f->code, "for (ii = 1; (ii < argc) && (ii < %d); ii++) {\n", maxargs); Printf(f->code, "argv[ii] = args[ii-1];\n"); Printf(f->code, "}\n"); } else { Printf(f->code, "argc = nargs;\n"); Printf(f->code, "for (ii = 0; (ii < argc) && (ii < %d); ii++) {\n", maxargs); Printf(f->code, "argv[ii] = args[ii];\n"); Printf(f->code, "}\n"); } Replaceall(dispatch, "$args", "nargs, args, self"); Printv(f->code, dispatch, "\n", NIL); Printf(f->code, "rb_raise(rb_eArgError, \"No matching function for overloaded '%s'\");\n", symname); Printf(f->code,"return Qnil;\n"); Printv(f->code, "}\n", NIL); Wrapper_print(f, f_wrappers); create_command(n, Char(symname)); DelWrapper(f); Delete(dispatch); Delete(tmp); Delete(wname); } /* --------------------------------------------------------------------- * variableWrapper() * --------------------------------------------------------------------- */ virtual int variableWrapper(Node *n) { char *name = GetChar(n,"name"); char *iname = GetChar(n,"sym:name"); SwigType *t = Getattr(n,"type"); String *tm; String *getfname, *setfname; Wrapper *getf, *setf; getf = NewWrapper(); setf = NewWrapper(); /* create getter */ getfname = NewString(Swig_name_get(iname)); Printv(getf->def, "static VALUE\n", getfname, "(", NIL); Printf(getf->def, "VALUE self"); Printf(getf->def, ") {"); Wrapper_add_local(getf,"_val","VALUE _val"); tm = Swig_typemap_lookup_new("varout",n, name, 0); if (tm) { Replaceall(tm,"$result","_val"); Replaceall(tm,"$target","_val"); Replaceall(tm,"$source",name); Printv(getf->code,tm, NIL); } else { Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t,0)); } Printv(getf->code, tab4, "return _val;\n}\n", NIL); Wrapper_print(getf,f_wrappers); if (Getattr(n,"feature:immutable")) { setfname = NewString("NULL"); } else { /* create setter */ setfname = NewString(Swig_name_set(iname)); Printv(setf->def, "static VALUE\n", setfname, "(VALUE self, ", NIL); Printf(setf->def, "VALUE _val) {"); tm = Swig_typemap_lookup_new("varin",n,name,0); if (tm) { Replaceall(tm,"$input","_val"); Replaceall(tm,"$source","_val"); Replaceall(tm,"$target",name); Printv(setf->code,tm,"\n",NIL); } else { Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s\n", SwigType_str(t,0)); } Printv(setf->code, tab4, "return _val;\n",NIL); Printf(setf->code,"}\n"); Wrapper_print(setf,f_wrappers); } /* define accessor method */ if (CPlusPlus) { Insert(getfname,0,"VALUEFUNC("); Append(getfname,")"); Insert(setfname,0,"VALUEFUNC("); Append(setfname,")"); } String *s = NewString(""); switch (current) { case STATIC_VAR: /* C++ class variable */ Printv(s, tab4, "rb_define_singleton_method(", klass->vname, ", \"", klass->strip(iname), "\", ", getfname, ", 0);\n", NIL); if (!Getattr(n,"feature:immutable")) { Printv(s, tab4, "rb_define_singleton_method(", klass->vname, ", \"", klass->strip(iname), "=\", ", setfname, ", 1);\n", NIL); } Printv(klass->init,s,NIL); break; default: /* C global variable */ /* wrapped in Ruby module attribute */ assert(current == NO_CPP); if (!useGlobalModule) { Printv(s, tab4, "rb_define_singleton_method(", modvar, ", \"", iname, "\", ", getfname, ", 0);\n", NIL); if (!Getattr(n,"feature:immutable")) { Printv(s, tab4, "rb_define_singleton_method(", modvar, ", \"", iname, "=\", ", setfname, ", 1);\n", NIL); } } else { Printv(s, tab4, "rb_define_global_method(\"", iname, "\", ", getfname, ", 0);\n", NIL); if (!Getattr(n,"feature:immutable")) { Printv(s, tab4, "rb_define_global_method(\"", iname, "=\", ", setfname, ", 1);\n", NIL); } } Printv(f_init,s,NIL); Delete(s); break; } Delete(getfname); Delete(setfname); DelWrapper(setf); DelWrapper(getf); return SWIG_OK; } /* --------------------------------------------------------------------- * validate_const_name(char *name) * * Validate constant name. * --------------------------------------------------------------------- */ char * validate_const_name(char *name, const char *reason) { if (!name || name[0] == '\0') return name; if (isupper(name[0])) return name; if (islower(name[0])) { name[0] = toupper(name[0]); Swig_warning(WARN_RUBY_WRONG_NAME, input_file, line_number, "Wrong %s name (corrected to `%s')\n", reason, name); return name; } Swig_warning(WARN_RUBY_WRONG_NAME, input_file, line_number, "Wrong %s name\n", reason); return name; } /* --------------------------------------------------------------------- * constantWrapper() * --------------------------------------------------------------------- */ virtual int constantWrapper(Node *n) { Swig_require("constantWrapper",n, "*sym:name", "type", "value", NIL); char *iname = GetChar(n,"sym:name"); SwigType *type = Getattr(n,"type"); char *value = GetChar(n,"value"); if (current == CLASS_CONST) { iname = klass->strip(iname); } validate_const_name(iname, "constant"); SetChar(n, "sym:name", iname); /* Special hook for member pointer */ if (SwigType_type(type) == T_MPOINTER) { String *wname = Swig_name_wrapper(iname); Printf(f_header, "static %s = %s;\n", SwigType_str(type, wname), value); value = Char(wname); } String *tm = Swig_typemap_lookup_new("constant", n, value, 0); if (tm) { Replaceall(tm, "$source", value); Replaceall(tm, "$target", iname); Replaceall(tm, "$symname", iname); Replaceall(tm, "$value", value); if (current == CLASS_CONST) { if (multipleInheritance) { Replaceall(tm, "$module", klass->mImpl); Printv(klass->init, tm, "\n", NIL); } else { Replaceall(tm, "$module", klass->vname); Printv(klass->init, tm, "\n", NIL); } } else { if (!useGlobalModule) { Replaceall(tm, "$module", modvar); } else { Replaceall(tm, "$module", "rb_cObject"); } Printf(f_init, "%s\n", tm); } } else { Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value %s = %s\n", SwigType_str(type, 0), value); } Swig_restore(n); return SWIG_OK; } /* ----------------------------------------------------------------------------- * classDeclaration() * * Records information about classes---even classes that might be defined in * other modules referenced by %import. * ----------------------------------------------------------------------------- */ virtual int classDeclaration(Node *n) { String *name = Getattr(n,"name"); String *symname = Getattr(n,"sym:name"); String *tdname = Getattr(n,"tdname"); name = tdname ? tdname : name; String *namestr = SwigType_namestr(name); klass = RCLASS(classes, Char(namestr)); if (!klass) { klass = new RClass(); String *valid_name = NewString(symname ? symname : namestr); validate_const_name(Char(valid_name), "class"); klass->set_name(namestr, symname, valid_name); SET_RCLASS(classes, Char(namestr), klass); Delete(valid_name); } Delete(namestr); return Language::classDeclaration(n); } /** * Process the comma-separated list of mixed-in module names (if any). */ void includeRubyModules(Node *n) { String *mixin = Getattr(n,"feature:mixin"); if (mixin) { List *modules = Split(mixin,',',INT_MAX); if (modules && Len(modules) > 0) { Iterator mod = First(modules); while (mod.item) { if (Len(mod.item) > 0) { Printf(klass->init, "rb_include_module(%s, rb_eval_string(\"%s\"));\n", klass->vname, mod.item); } mod = Next(mod); } } Delete(modules); } } void handleBaseClasses(Node *n) { List *baselist = Getattr(n,"bases"); if (baselist && Len(baselist)) { Iterator base = First(baselist); while (base.item) { String *basename = Getattr(base.item,"name"); String *basenamestr = SwigType_namestr(basename); RClass *super = RCLASS(classes, Char(basenamestr)); Delete(basenamestr); if (super) { SwigType *btype = NewString(basename); SwigType_add_pointer(btype); SwigType_remember(btype); if (multipleInheritance) { String *bmangle = SwigType_manglestr(btype); Insert(bmangle,0,"((swig_class *) SWIGTYPE"); Append(bmangle,"->clientdata)->mImpl"); Printv(klass->init, "rb_include_module(", klass->mImpl, ", ", bmangle, ");\n", NIL); Delete(bmangle); } else { String *bmangle = SwigType_manglestr(btype); Insert(bmangle,0,"((swig_class *) SWIGTYPE"); Append(bmangle,"->clientdata)->klass"); Replaceall(klass->init,"$super",bmangle); Delete(bmangle); } Delete(btype); } base = Next(base); if (!multipleInheritance) { /* Warn about multiple inheritance for additional base class(es) listed */ while (base.item) { basename = Getattr(n,"name"); Swig_warning(WARN_RUBY_MULTIPLE_INHERITANCE, input_file, line_number, "Warning for %s: Base %s ignored. Multiple inheritance is not supported in Ruby.\n", basename, basename); base = Next(base); } } } } } /** * Check to see if a %markfunc was specified. */ void handleMarkFuncDirective(Node *n) { String *markfunc = Getattr(n, "feature:markfunc"); if (markfunc) { Printf(klass->init, "c%s.mark = (void (*)(void *)) %s;\n", klass->name, markfunc); } else { Printf(klass->init, "c%s.mark = 0;\n", klass->name); } } /** * Check to see if a %freefunc was specified. */ void handleFreeFuncDirective(Node *n) { String *freefunc = Getattr(n, "feature:freefunc"); if (freefunc) { Printf(klass->init, "c%s.destroy = (void (*)(void *)) %s;\n", klass->name, freefunc); } else { if (klass->destructor_defined) { Printf(klass->init, "c%s.destroy = (void (*)(void *)) free_%s;\n", klass->name, klass->mname); } } Replaceall(klass->header,"$freeproto", ""); } /* ---------------------------------------------------------------------- * classHandler() * ---------------------------------------------------------------------- */ virtual int classHandler(Node *n) { String *name = Getattr(n,"name"); String *symname = Getattr(n,"sym:name"); String *namestr = SwigType_namestr(name); // does template expansion klass = RCLASS(classes, Char(namestr)); assert(klass != 0); Delete(namestr); String *valid_name = NewString(symname); validate_const_name(Char(valid_name), "class"); Clear(klass->type); Printv(klass->type, Getattr(n,"classtype"), NIL); Printv(klass->header, "\nswig_class c", valid_name, ";\n", NIL); Printv(klass->init, "\n", tab4, NIL); if (multipleInheritance) { if (!useGlobalModule) { Printv(klass->init, klass->vname, " = rb_define_class_under(", modvar, ", \"", klass->name, "\", rb_cObject);\n", NIL); } else { Printv(klass->init, klass->vname, " = rb_define_class(\"", klass->name, "\", rb_cObject);\n", NIL); } Printv(klass->init, klass->mImpl, " = rb_define_module_under(", klass->vname, ", \"Impl\");\n", NIL); } else { if (!useGlobalModule) { Printv(klass->init, klass->vname, " = rb_define_class_under(", modvar, ", \"", klass->name, "\", $super);\n", NIL); } else { Printv(klass->init, klass->vname, " = rb_define_class(\"", klass->name, "\", $super);\n", NIL); } } SwigType *tt = NewString(name); SwigType_add_pointer(tt); SwigType_remember(tt); String *tm = SwigType_manglestr(tt); Printf(klass->init, "SWIG_TypeClientData(SWIGTYPE%s, (void *) &c%s);\n", tm, valid_name); Delete(tm); Delete(tt); Delete(valid_name); includeRubyModules(n); Printv(klass->init, "$allocator",NIL); Printv(klass->init, "$initializer",NIL); Printv(klass->header, "$freeproto", NIL); Language::classHandler(n); handleBaseClasses(n); handleMarkFuncDirective(n); handleFreeFuncDirective(n); if (multipleInheritance) { Printv(klass->init, "rb_include_module(", klass->vname, ", ", klass->mImpl, ");\n", NIL); } Printv(f_header, klass->header,NIL); String *s = NewString(""); Printv(s, tab4, "rb_undef_alloc_func(", klass->vname, ");\n", NIL); Replaceall(klass->init,"$allocator", s); Replaceall(klass->init,"$initializer", ""); Replaceall(klass->init,"$super", "rb_cObject"); Delete(s); Printv(f_init,klass->init,NIL); klass = 0; return SWIG_OK; } /* ---------------------------------------------------------------------- * memberfunctionHandler() * * Method for adding C++ member function * * By default, we're going to create a function of the form : * * Foo_bar(this,args) * * Where Foo is the classname, bar is the member name and the this pointer * is explicitly attached to the beginning. * * The renaming only applies to the member function part, not the full * classname. * * --------------------------------------------------------------------- */ virtual int memberfunctionHandler(Node *n) { current = MEMBER_FUNC; Language::memberfunctionHandler(n); current = NO_CPP; return SWIG_OK; } /* --------------------------------------------------------------------- * constructorHandler() * * Method for adding C++ member constructor * -------------------------------------------------------------------- */ virtual int constructorHandler(Node *n) { int use_director = Swig_directorclass(n); /* First wrap the allocate method */ current = CONSTRUCTOR_ALLOCATE; Swig_name_register((String_or_char *) "construct", (String_or_char *) "%c_allocate"); Language::constructorHandler(n); /* * If we're wrapping the constructor of a C++ director class, prepend a new parameter * to receive the scripting language object (e.g. 'self') * */ Swig_save("ruby:constructorHandler",n,"parms",NIL); if (use_director) { Parm *parms = Getattr(n, "parms"); Parm *self; String *name = NewString("self"); String *type = NewString("VALUE"); self = NewParm(type, name); Delete(type); Delete(name); Setattr(self, "lname", "Qnil"); if (parms) set_nextSibling(self, parms); Setattr(n, "parms", self); Setattr(n, "wrap:self", "1"); Delete(self); } /* Now do the instance initialize method */ current = CONSTRUCTOR_INITIALIZE; Swig_name_register((String_or_char *) "construct", (String_or_char *) "new_%c"); Language::constructorHandler(n); /* Restore original parameter list */ Delattr(n, "wrap:self"); Swig_restore(n); /* Done */ Swig_name_unregister((String_or_char *) "construct"); current = NO_CPP; klass->constructor_defined = 1; return SWIG_OK; } /* --------------------------------------------------------------------- * destructorHandler() * -------------------------------------------------------------------- */ virtual int destructorHandler(Node *n) { current = DESTRUCTOR; Language::destructorHandler(n); String *freefunc = NewString(""); String *freeproto = NewString(""); String *freebody = NewString(""); Printv(freefunc, "free_", klass->mname, NIL); Printv(freeproto, "static void ", freefunc, "(", klass->type, " *);\n", NIL); Printv(freebody, "static void\n", freefunc, "(", klass->type, " *", Swig_cparm_name(0,0), ") {\n", tab4, NIL); if (Extend) { String *wrap = Getattr(n, "wrap:code"); if (wrap) { File *f_code = Swig_filebyname("header"); if (f_code) { Printv(f_code, wrap, NIL); } } /* Printv(freebody, Swig_name_destroy(name), "(", Swig_cparm_name(0,0), ")", NIL); */ Printv(freebody,Getattr(n,"wrap:action"), NIL); } else { String *action = Getattr(n,"wrap:action"); if (action) { Printv(freebody, action, NIL); } else { /* In the case swig emits no destroy function. */ if (CPlusPlus) Printf(freebody, "delete %s;\n", Swig_cparm_name(0,0)); else Printf(freebody, "free((char*) %s);\n", Swig_cparm_name(0,0)); } } Printv(freebody, "}\n", NIL); Replaceall(klass->header,"$freeproto", freeproto); Printv(f_wrappers, freebody, NIL); klass->destructor_defined = 1; current = NO_CPP; Delete(freefunc); Delete(freeproto); Delete(freebody); return SWIG_OK; } /* --------------------------------------------------------------------- * membervariableHandler() * * This creates a pair of functions to set/get the variable of a member. * -------------------------------------------------------------------- */ virtual int membervariableHandler(Node *n) { current = MEMBER_VAR; Language::membervariableHandler(n); current = NO_CPP; return SWIG_OK; } /* ----------------------------------------------------------------------- * staticmemberfunctionHandler() * * Wrap a static C++ function * ---------------------------------------------------------------------- */ virtual int staticmemberfunctionHandler(Node *n) { current = STATIC_FUNC; Language::staticmemberfunctionHandler(n); current = NO_CPP; return SWIG_OK; } /* ---------------------------------------------------------------------- * memberconstantHandler() * * Create a C++ constant * --------------------------------------------------------------------- */ virtual int memberconstantHandler(Node *n) { current = CLASS_CONST; Language::memberconstantHandler(n); current = NO_CPP; return SWIG_OK; } /* --------------------------------------------------------------------- * staticmembervariableHandler() * --------------------------------------------------------------------- */ virtual int staticmembervariableHandler(Node *n) { current = STATIC_VAR; Language::staticmembervariableHandler(n); current = NO_CPP; return SWIG_OK; } /* C++ director class generation */ virtual int classDirector(Node *n) { return Language::classDirector(n); } virtual int classDirectorInit(Node *n) { String *declaration; declaration = Swig_director_declaration(n); Printf(f_directors_h, "\n"); Printf(f_directors_h, "%s\n", declaration); Printf(f_directors_h, "public:\n"); Delete(declaration); return Language::classDirectorInit(n); } virtual int classDirectorEnd(Node *n) { Printf(f_directors_h, "};\n\n"); return Language::classDirectorEnd(n); } virtual int unrollVirtualMethods(Node *n, Node *parent, Hash *vm, int default_director, int &virtual_destructor) { return Language::unrollVirtualMethods(n, parent, vm, default_director, virtual_destructor); } /* ------------------------------------------------------------ * classDirectorConstructor() * ------------------------------------------------------------ */ virtual int classDirectorConstructor(Node *n) { Node *parent = Getattr(n, "parentNode"); String *sub = NewString(""); String *decl = Getattr(n, "decl"); String *supername = Swig_class_name(parent); String *classname = NewString(""); Printf(classname, "SwigDirector_%s", supername); /* insert self and disown parameters */ Parm *p, *ip; ParmList *superparms = Getattr(n, "parms"); ParmList *parms = CopyParmList(superparms); String *type = NewString("VALUE"); p = NewParm(type, NewString("self")); set_nextSibling(p, parms); parms = p; for (ip = parms; nextSibling(ip); ) ip = nextSibling(ip); p = NewParm(NewString("bool"), NewString("disown")); Setattr(p, "arg:byname", "1"); Setattr(n, "director:postfix_args", p); Setattr(p, "value", "0"); set_nextSibling(ip, p); /* constructor */ { Wrapper *w = NewWrapper(); String *call; String *basetype = Getattr(parent, "classtype"); String *target = Swig_method_decl(decl, classname, parms, 0, 0); call = Swig_csuperclass_call(0, basetype, superparms); Printf(w->def, "%s::%s: %s, Swig::Director(self, disown) { }", classname, target, call); Delete(target); Wrapper_print(w, f_directors); Delete(call); DelWrapper(w); } /* constructor header */ { String *target = Swig_method_decl(decl, classname, parms, 0, 1); Printf(f_directors_h, " %s;\n", target); Delete(target); } Delete(sub); Delete(classname); Delete(supername); Delete(parms); return Language::classDirectorConstructor(n); } virtual int classDirectorDefaultConstructor(Node *n) { String *classname; Wrapper *w; classname = Swig_class_name(n); w = NewWrapper(); Printf(w->def, "SwigDirector_%s::SwigDirector_%s(VALUE self, bool disown) : Swig::Director(self, disown) { }", classname, classname); Wrapper_print(w, f_directors); DelWrapper(w); Printf(f_directors_h, " SwigDirector_%s(VALUE self, bool disown = true);\n", classname); Delete(classname); return Language::classDirectorDefaultConstructor(n); } /* --------------------------------------------------------------- * classDirectorMethod() * * Emit a virtual director method to pass a method call on to the * underlying Ruby instance. * * --------------------------------------------------------------- */ void exceptionSafeMethodCall(String *className, Node *n, Wrapper *w, int argc, String *args) { Wrapper *body = NewWrapper(); Wrapper *rescue = NewWrapper(); String *methodName = Getattr(n, "sym:name"); String *bodyName = NewStringf("%s_%s_body", className, methodName); String *rescueName = NewStringf("%s_%s_rescue", className, methodName); String *depthCountName = NewStringf("%s_%s_call_depth", className, methodName); // Check for an exception typemap of some kind String *tm = Swig_typemap_lookup_new("director:except", n, "result", 0); if (!tm) { tm = Getattr(n, "feature:director:except"); } if ((tm != 0) && (Len(tm) > 0) && (Strcmp(tm, "1") != 0)) { // Declare a global to hold the depth count Printf(f_directors, "static int %s = 0;\n", depthCountName); // Function body Printf(body->def, "VALUE %s(VALUE data) {\n", bodyName); Wrapper_add_localv(body, "args", "Swig::body_args *", "args", "= reinterpret_cast(data)", NIL); Wrapper_add_localv(body, "result", "VALUE", "result", "= Qnil", NIL); Printf(body->code, "%s++;\n", depthCountName, NIL); Printv(body->code, "result = rb_funcall2(args->recv, args->id, args->argc, args->argv);\n", NIL); Printf(body->code, "%s--;\n", depthCountName, NIL); Printv(body->code, "return result;\n", NIL); Printv(body->code, "}", NIL); // Exception handler Printf(rescue->def, "VALUE %s(VALUE args, VALUE error) {\n", rescueName); Replaceall(tm, "$error", "error"); Printf(rescue->code, "if (%s == 0) ", depthCountName); Printv(rescue->code, Str(tm), "\n", NIL); Printf(rescue->code, "%s--;\n", depthCountName); Printv(rescue->code, "rb_exc_raise(error);\n", NIL); Printv(rescue->code, "}", NIL); // Main code Wrapper_add_localv(w, "args", "Swig::body_args", "args", NIL); Printv(w->code, "args.recv = swig_get_self();\n", NIL); Printf(w->code, "args.id = rb_intern(\"%s\");\n", methodName); Printf(w->code, "args.argc = %d;\n", argc); if (argc > 0) { Wrapper_add_localv(w, "i", "int", "i", NIL); Printf(w->code, "args.argv = new VALUE[%d];\n", argc); Printf(w->code, "for (i = 0; i < %d; i++) {\n", argc); Printv(w->code, "args.argv[i] = Qnil;\n", NIL); Printv(w->code, "}\n", NIL); } else { Printv(w->code, "args.argv = 0;\n", NIL); } Printf(w->code, "result = rb_rescue2((VALUE(*)(ANYARGS)) %s, reinterpret_cast(&args), (VALUE(*)(ANYARGS)) %s, reinterpret_cast(&args), rb_eStandardError, 0);\n", bodyName, rescueName); if (argc > 0) { Printv(w->code, "delete [] args.argv;\n", NIL); } // Dump wrapper code Wrapper_print(body, f_directors); Wrapper_print(rescue, f_directors); } else { if (argc > 0) { Printf(w->code, "result = rb_funcall(swig_get_self(), rb_intern(\"%s\"), %d%s);\n", methodName, argc, args); } else { Printf(w->code, "result = rb_funcall(swig_get_self(), rb_intern(\"%s\"), 0, NULL);\n", methodName); } } // Clean up Delete(bodyName); Delete(rescueName); Delete(depthCountName); DelWrapper(body); DelWrapper(rescue); } virtual int classDirectorMethod(Node *n, Node *parent, String *super) { int is_void = 0; int is_pointer = 0; String *decl; String *type; String *name; String *classname; String *declaration; ParmList *l; Wrapper *w; String *tm; String *wrap_args; String *return_type; Parm* p; String *value = Getattr(n, "value"); String *storage = Getattr(n,"storage"); bool pure_virtual = false; int status = SWIG_OK; int idx; if (Cmp(storage,"virtual") == 0) { if (Cmp(value,"0") == 0) { pure_virtual = true; } } classname = Getattr(parent, "sym:name"); type = Getattr(n, "type"); name = Getattr(n, "name"); w = NewWrapper(); declaration = NewString(""); /* determine if the method returns a pointer */ decl = Getattr(n, "decl"); is_pointer = SwigType_ispointer_return(decl); is_void = (!Cmp(type, "void") && !is_pointer); /* form complete return type */ return_type = Copy(type); { SwigType *t = Copy(decl); SwigType *f = 0; f = SwigType_pop_function(t); SwigType_push(return_type, t); Delete(f); Delete(t); } /* virtual method definition */ l = Getattr(n, "parms"); String *target; String *pclassname = NewStringf("SwigDirector_%s", classname); String *qualified_name = NewStringf("%s::%s", pclassname, name); target = Swig_method_decl(decl, qualified_name, l, 0, 0); String *rtype = SwigType_str(type, 0); Printf(w->def, "%s %s", rtype, target); Delete(qualified_name); Delete(target); /* header declaration */ target = Swig_method_decl(decl, name, l, 0, 1); Printf(declaration, " virtual %s %s", rtype, target); Delete(target); // Get any exception classes in the throws typemap ParmList *throw_parm_list = 0; if ((throw_parm_list = Getattr(n,"throws"))) { Parm *p; int gencomma = 0; Append(w->def, " throw("); Append(declaration, " throw("); Swig_typemap_attach_parms("throws", throw_parm_list, 0); for (p = throw_parm_list; p; p=nextSibling(p)) { if ((tm = Getattr(p,"tmap:throws"))) { if (gencomma++) { Append(w->def, ", "); Append(declaration, ", "); } Printf(w->def, "%s", SwigType_str(Getattr(p, "type"),0)); Printf(declaration, "%s", SwigType_str(Getattr(p, "type"),0)); } } Append(w->def, ")"); Append(declaration, ")"); } Append(w->def, " {"); Append(declaration, ";\n"); /* attach typemaps to arguments (C/C++ -> Ruby) */ String *arglist = NewString(""); /** * For each parameter to the C++ member function, copy the parameter name * to its "lname"; this ensures that Swig_typemap_attach_parms() will do * the right thing when it sees strings like "$1" in your "directorin" typemaps. * Not sure if it's OK to leave it like this, but seems OK so far. */ typemap_copy_pname_to_lname(l); Swig_typemap_attach_parms("in", l, w); Swig_typemap_attach_parms("directorin", l, w); Swig_typemap_attach_parms("directorout", l, w); Swig_typemap_attach_parms("directorargout", l, w); int num_arguments = emit_num_arguments(l); int i; char source[256]; wrap_args = NewString(""); int outputs = 0; if (!is_void) outputs++; /* build argument list and type conversion string */ for (i=0, idx=0, p = l; i < num_arguments; i++) { while (Getattr(p, "tmap:ignore")) { p = Getattr(p, "tmap:ignore:next"); } if (Getattr(p, "tmap:directorargout") != 0) outputs++; String* parameterName = Getattr(p, "name"); String* parameterType = Getattr(p, "type"); Putc(',',arglist); if ((tm = Getattr(p, "tmap:directorin")) != 0) { sprintf(source, "obj%d", idx++); Replaceall(tm, "$input", source); Replaceall(tm, "$owner", "0"); Printv(wrap_args, tm, "\n", NIL); Wrapper_add_localv(w, source, "VALUE", source, "= Qnil", NIL); Printv(arglist, source, NIL); p = Getattr(p, "tmap:directorin:next"); continue; } else if (Cmp(parameterType, "void")) { /** * Special handling for pointers to other C++ director classes. * Ideally this would be left to a typemap, but there is currently no * way to selectively apply the dynamic_cast<> to classes that have * directors. In other words, the type "SwigDirector_$1_lname" only exists * for classes with directors. We avoid the problem here by checking * module.wrap::directormap, but it's not clear how to get a typemap to * do something similar. Perhaps a new default typemap (in addition * to SWIGTYPE) called DIRECTORTYPE? */ if (SwigType_ispointer(parameterType) || SwigType_isreference(parameterType)) { Node *modname = Getattr(parent, "module"); Node *target = Swig_directormap(modname, parameterType); sprintf(source, "obj%d", idx++); String *nonconst = 0; /* strip pointer/reference --- should move to Swig/stype.c */ String *nptype = NewString(Char(parameterType)+2); /* name as pointer */ String *ppname = Copy(parameterName); if (SwigType_isreference(parameterType)) { Insert(ppname,0,"&"); } /* if necessary, cast away const since Ruby doesn't support it! */ if (SwigType_isconst(nptype)) { nonconst = NewStringf("nc_tmp_%s", parameterName); String *nonconst_i = NewStringf("= const_cast<%s>(%s)", SwigType_lstr(parameterType, 0), ppname); Wrapper_add_localv(w, nonconst, SwigType_lstr(parameterType, 0), nonconst, nonconst_i, NIL); Delete(nonconst_i); Swig_warning(WARN_LANG_DISCARD_CONST, input_file, line_number, "Target language argument '%s' discards const in director method %s::%s.\n", SwigType_str(parameterType, parameterName), classname, name); } else { nonconst = Copy(ppname); } Delete(nptype); Delete(ppname); String *mangle = SwigType_manglestr(parameterType); if (target) { String *director = NewStringf("director_%s", mangle); Wrapper_add_localv(w, director, "Swig::Director *", director, "= 0", NIL); Wrapper_add_localv(w, source, "VALUE", source, "= Qnil", NIL); Printf(wrap_args, "%s = dynamic_cast(%s);\n", director, nonconst); Printf(wrap_args, "if (!%s) {\n", director); Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle); Printf(wrap_args, "} else {\n"); Printf(wrap_args, "%s = %s->swig_get_self();\n", source, director); Printf(wrap_args, "}\n"); Delete(director); Printv(arglist, source, NIL); } else { Wrapper_add_localv(w, source, "VALUE", source, "= Qnil", NIL); Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle); //Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE_p_%s, 0);\n", // source, nonconst, base); Printv(arglist, source, NIL); } Delete(mangle); Delete(nonconst); } else { Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(parameterType, 0), classname, name); status = SWIG_NOWRAP; break; } } p = nextSibling(p); } /* declare method return value * if the return value is a reference or const reference, a specialized typemap must * handle it, including declaration of c_result ($result). */ if (!is_void) { Wrapper_add_localv(w, "c_result", SwigType_lstr(return_type, "c_result"), NIL); } /* declare Ruby return value */ Wrapper_add_local(w, "result", "VALUE result"); /* direct call to superclass if _up is set */ Printf(w->code, "if (swig_get_up()) {\n"); if (pure_virtual) { Printf(w->code, "throw Swig::DirectorPureVirtualException();\n"); } else { if (is_void) { Printf(w->code, "%s;\n", Swig_method_call(super,l)); Printf(w->code, "return;\n"); } else { Printf(w->code, "return %s;\n", Swig_method_call(super,l)); } } Printf(w->code, "}\n"); /* wrap complex arguments to VALUEs */ Printv(w->code, wrap_args, NIL); /* pass the method call on to the Ruby object */ exceptionSafeMethodCall(classname, n, w, idx, arglist); /* * Ruby method may return a simple object, or an Array of objects. * For in/out arguments, we have to extract the appropriate VALUEs from the Array, * then marshal everything back to C/C++ (return value and output arguments). */ /* Marshal return value and other outputs (if any) from VALUE to C/C++ type */ String* cleanup = NewString(""); String* outarg = NewString(""); if (outputs > 1) { Wrapper_add_local(w, "output", "VALUE output"); Printf(w->code, "if (TYPE(result) != T_ARRAY) {\n"); Printf(w->code, "throw Swig::DirectorTypeMismatchException(\"Ruby method failed to return an array.\");\n"); Printf(w->code, "}\n"); } idx = 0; /* Marshal return value */ if (!is_void) { /* This seems really silly. The node's type excludes qualifier/pointer/reference markers, * which have to be retrieved from the decl field to construct return_type. But the typemap * lookup routine uses the node's type, so we have to swap in and out the correct type. * It's not just me, similar silliness also occurs in Language::cDeclaration(). */ Setattr(n, "type", return_type); tm = Swig_typemap_lookup_new("directorout", n, "result", w); Setattr(n, "type", type); if (tm == 0) { String *name = NewString("result"); tm = Swig_typemap_search("directorout", return_type, name, NULL); Delete(name); } if (tm != 0) { if (outputs > 1) { Printf(w->code, "output = rb_ary_entry(result, %d);\n", idx++); Replaceall(tm, "$input", "output"); } else { Replaceall(tm, "$input", "result"); } /* TODO check this */ if (Getattr(n,"wrap:disown")) { Replaceall(tm,"$disown","SWIG_POINTER_DISOWN"); } else { Replaceall(tm,"$disown","0"); } Replaceall(tm, "$result", "c_result"); Printv(w->code, tm, "\n", NIL); } else { Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to return type %s in director method %s::%s (skipping method).\n", SwigType_str(return_type, 0), classname, name); status = SWIG_ERROR; } } /* Marshal outputs */ for (p = l; p; ) { if ((tm = Getattr(p, "tmap:directorargout")) != 0) { if (outputs > 1) { Printf(w->code, "output = rb_ary_entry(result, %d);\n", idx++); Replaceall(tm, "$input", "output"); } else { Replaceall(tm, "$input", "result"); } Replaceall(tm, "$result", Getattr(p, "name")); Printv(w->code, tm, "\n", NIL); p = Getattr(p, "tmap:directorargout:next"); } else { p = nextSibling(p); } } /* any existing helper functions to handle this? */ if (!is_void) { if (!SwigType_isreference(return_type)) { Printf(w->code, "return c_result;\n"); } else { Printf(w->code, "return *c_result;\n"); } } Printf(w->code, "}\n"); /* emit the director method */ if (status == SWIG_OK) { Wrapper_print(w, f_directors); Printv(f_directors_h, declaration, NIL); } /* clean up */ Delete(wrap_args); Delete(arglist); Delete(rtype); Delete(return_type); Delete(pclassname); Delete(cleanup); Delete(outarg); DelWrapper(w); return status; } virtual int classDirectorConstructors(Node *n) { return Language::classDirectorConstructors(n); } virtual int classDirectorMethods(Node *n) { return Language::classDirectorMethods(n); } virtual int classDirectorDisown(Node *n) { return Language::classDirectorDisown(n); } void typemap_copy_pname_to_lname(ParmList *parms) { Parm *p; String *pname; String *lname; p = parms; while (p) { pname = Getattr(p,"name"); lname = Copy(pname); Setattr(p,"lname",lname); p = nextSibling(p); } } }; /* class RUBY */ /* ----------------------------------------------------------------------------- * swig_ruby() - Instantiate module * ----------------------------------------------------------------------------- */ static Language * new_swig_ruby() { return new RUBY(); } extern "C" Language * swig_ruby(void) { return new_swig_ruby(); } /* * Local Variables: * c-basic-offset: 2 * End: */ cableswig-0.1.0+git20150808.orig/SWIG/Source/Modules/module.cxx0000644000175000000620000000311512561312227022457 0ustar stevestaff/* ----------------------------------------------------------------------------- * module.cxx * * This file is responsible for the module system. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_module_cxx[] = "/cvsroot/SWIG/Source/Modules/module.cxx,v 1.1 2002/12/03 20:33:33 beazley Exp"; #include "swigmod.h" struct Module { ModuleFactory fac; char *name; Module *next; Module(const char *n, ModuleFactory f) { fac = f; name = new char[strlen(n)+1]; strcpy(name, n); next = 0; } }; static Module *modules = 0; /* ----------------------------------------------------------------------------- * void Swig_register_module() * * Register a module. * ----------------------------------------------------------------------------- */ void Swig_register_module(const char *n, ModuleFactory f) { Module *m = new Module(n,f); m->next = modules; modules = m; } /* ----------------------------------------------------------------------------- * Language *Swig_find_module() * * Given a command line option, locates the factory function. * ----------------------------------------------------------------------------- */ ModuleFactory Swig_find_module(const char *name) { Module *m = modules; while (m) { if (strcmp(m->name,name) == 0) { return m->fac; } m = m->next; } return 0; } cableswig-0.1.0+git20150808.orig/SWIG/Source/Modules/typepass.cxx0000644000175000000620000006562512561312227023060 0ustar stevestaff/* ----------------------------------------------------------------------------- * typepass.cxx * * This module builds all of the internal type information by collecting * typedef declarations as well as registering classes, structures, and unions. * This information is needed to correctly handle shadow classes and other * advanced features. This phase of compilation is also used to perform * type-expansion. All types are fully qualified with namespace prefixes * and other information needed for compilation. * * This module also handles the %varargs directive by looking for * "feature:varargs" and substituting ... with an alternative set of * arguments. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1998-2002. The University of Chicago * Copyright (C) 1995-1998. The University of Utah and The Regents of the * University of California. * * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_typepass_cxx[] = "/cvsroot/SWIG/Source/Modules/typepass.cxx,v 1.10 2004/01/15 08:33:11 mmatus Exp"; #include "swigmod.h" struct normal_node { Symtab *symtab; Hash *typescope; List *normallist; normal_node *next; }; static normal_node *patch_list = 0; class TypePass : public Dispatcher { Node *inclass; Node *module; int importmode; String *nsname; Hash *classhash; List *normalize; /* Normalize a type. Replaces type with fully qualified version */ void normalize_type(SwigType *ty) { SwigType *qty; /*qty = Swig_symbol_type_qualify(ty,0);*/ /* if (SwigType_istemplate(ty)) { qty = Swig_symbol_type_qualify(ty,0); Clear(ty); Append(ty,qty); } */ if (CPlusPlus) { Replaceall(ty,"struct ",""); Replaceall(ty,"union ",""); Replaceall(ty,"class ",""); } qty = SwigType_typedef_qualified(ty); /* Printf(stdout,"%s --> %s\n", ty, qty); */ Clear(ty); Append(ty,qty); Delete(qty); } /* Normalize a parameter list */ void normalize_parms(ParmList *p) { while (p) { SwigType *ty = Getattr(p,"type"); normalize_type(ty); /* This is a check for a function type */ { SwigType *qty = SwigType_typedef_resolve_all(ty); if (SwigType_isfunction(qty)) { SwigType_add_pointer(ty); } Delete(qty); } String *value = Getattr(p,"value"); if (value) { Node *n = Swig_symbol_clookup(value,0); if (n) { String *q = Swig_symbol_qualified(n); if (q && Len(q)) { String *vb = Swig_scopename_last(value); Clear(value); Printf(value,"%s::%s", SwigType_namestr(q), vb); Delete(q); } } } if (value && SwigType_istemplate(value)) { String *nv = SwigType_namestr(value); Setattr(p,"value",nv); } p = nextSibling(p); } } void normalize_later(ParmList *p) { while (p) { SwigType *ty = Getattr(p,"type"); Append(normalize,ty); p = nextSibling(p); } } /* Walk through entries in normalize list and patch them up */ void normalize_list() { Hash *currentsym = Swig_symbol_current(); normal_node *nn = patch_list; normal_node *np; while (nn) { Swig_symbol_setscope(nn->symtab); SwigType_set_scope(nn->typescope); Iterator t; for (t = First(nn->normallist); t.item; t = Next(t)) { normalize_type(t.item); } Delete(nn->normallist); np = nn->next; delete(nn); nn = np; } Swig_symbol_setscope(currentsym); } /* generate C++ inheritance type-relationships */ void cplus_inherit_types(Node *first, Node *cls, String *clsname, String *cast = 0) { if (first == cls) return; /* The Marcelo check */ if (!cls) cls = first; List *ilist = Getattr(cls,"bases"); if (!ilist) { List *nlist = Getattr(cls,"baselist"); if (nlist) { int len = Len(nlist); int i; for (i = 0; i < len; i++) { Node *bcls = 0; int clsforward = 0; String *bname = Getitem(nlist,i); String *sname = bname; String *tname = 0; /* Try to locate the base class. We look in the symbol table and we chase typedef declarations to get to the base class if necessary */ Symtab *st = Getattr(cls,"sym:symtab"); if (SwigType_istemplate(bname)) { tname = SwigType_typedef_resolve_all(bname); sname = tname; } while (1) { String *qsname = SwigType_typedef_qualified(sname); bcls = Swig_symbol_clookup(qsname,st); Delete(qsname); if (bcls) { if (Strcmp(nodeType(bcls),"class") != 0) { /* Not a class. The symbol could be a typedef. */ if (checkAttribute(bcls,"storage","typedef")) { SwigType *decl = Getattr(bcls,"decl"); if (!decl || !(Len(decl))) { sname = Getattr(bcls,"type"); st = Getattr(bcls,"sym:symtab"); if (SwigType_istemplate(sname)) { if (tname) Delete(tname); tname = SwigType_typedef_resolve_all(sname); sname = tname; } continue; } } if (Strcmp(nodeType(bcls),"classforward") != 0) { Swig_error(Getfile(bname),Getline(bname),"'%s' is not a class. \n",bname); } else { Swig_warning(WARN_TYPE_INCOMPLETE,Getfile(bname),Getline(bname),"Base class '%s' is incomplete.\n", bname); clsforward = 1; } bcls = 0; } else { if (Getattr(bcls,"typepass:visit")) { if (!ilist) ilist = NewList(); Append(ilist,bcls); } else { Swig_error(Getfile(bcls),Getline(bcls),"class '%s' must be defined before it is used as a base class.\n", bname); } } } break; } if (tname) Delete(tname); if (!bcls) { if (!clsforward) { if (!Getmeta(bname,"already_warned")) { Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname),Getline(bname),"Nothing known about class '%s'. Ignored.\n", SwigType_namestr(bname)); if (Strchr(bname,'<')) { Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(bname), Getline(bname), "Maybe you forgot to instantiate '%s' using %%template.\n", SwigType_namestr(bname)); } Setmeta(bname,"already_warned","1"); } } SwigType_inherit(clsname,bname, cast); } } } if (ilist) { Setattr(cls,"bases",ilist); } } if (!ilist) return; int len = Len(ilist); int i; for (i = 0; i < len; i++) { Node *n = Getitem(ilist,i); String *bname = Getattr(n,"name"); Node *bclass = n; /* Getattr(n,"class"); */ Hash *scopes = Getattr(bclass,"typescope"); SwigType_inherit(clsname,bname, cast); if (!importmode) { String *btype = Copy(bname); SwigType_add_pointer(btype); SwigType_remember(btype); Delete(btype); } if (scopes) { SwigType_inherit_scope(scopes); } /* Set up inheritance in the symbol table */ Symtab *s = Swig_symbol_current(); Symtab *st = Getattr(cls,"symtab"); Swig_symbol_setscope(st); Swig_symbol_inherit(Getattr(bclass,"symtab")); Swig_symbol_setscope(s); /* Recursively hit base classes */ String *newcast = NewStringf("(%s *)%s", SwigType_namestr(Getattr(bclass,"name")), cast); cplus_inherit_types(first,bclass,clsname, newcast); Delete(newcast); } } /* Clean overloaded list. Removes templates, friends, ignored, and errors */ void clean_overloaded(Node *n) { Node *nn = Getattr(n,"sym:overloaded"); Node *first = 0; int cnt = 0; while (nn) { if ((Strcmp(nodeType(nn),"template") == 0) || (Getattr(nn,"feature:ignore")) || (Getattr(nn,"error")) || // (checkAttribute(nn,"storage","friend")) || ((Strcmp(nodeType(nn),"using") == 0) && !firstChild(nn))) { /* Remove from overloaded list */ Node *ps = Getattr(nn,"sym:previousSibling"); Node *ns = Getattr(nn,"sym:nextSibling"); if (ps) { Setattr(ps,"sym:nextSibling",ns); } if (ns) { Setattr(ns,"sym:previousSibling",ps); } Delattr(nn,"sym:previousSibling"); Delattr(nn,"sym:nextSibling"); Delattr(nn,"sym:overloaded"); nn = ns; continue; } else if ((Strcmp(nodeType(nn),"using") == 0)) { /* A possibly dangerous parse tree hack. We're going to cut the parse tree node out and stick in the resolved using declarations */ Node *ps = Getattr(nn,"sym:previousSibling"); Node *ns = Getattr(nn,"sym:nextSibling"); Node *un = firstChild(nn); Node *pn = un; if (!first) { first = un; } while (pn) { Node *ppn = Getattr(pn,"sym:nextSibling"); Setattr(pn,"sym:overloaded",first); Setattr(pn,"sym:overname", NewStringf("%s_%d", Getattr(nn,"sym:overname"), cnt++)); if (ppn) pn = ppn; else break; } if (ps) { Setattr(ps,"sym:nextSibling",un); Setattr(un,"sym:previousSibling",ps); } if (ns) { Setattr(ns,"sym:previousSibling", pn); Setattr(pn,"sym:nextSibling",ns); } if (!first) { first = un; Setattr(nn,"sym:overloaded",first); } } else { if (!first) first = nn; Setattr(nn,"sym:overloaded",first); } nn = Getattr(nn,"sym:nextSibling"); } if (!first || (first && !Getattr(first,"sym:nextSibling"))) { Delattr(n,"sym:overloaded"); } } public: /* ------------------------------------------------------------ * top() * ------------------------------------------------------------ */ virtual int top(Node *n) { importmode = 0; module = Getattr(n,"module"); inclass = 0; normalize = 0; nsname = 0; classhash = Getattr(n,"classes"); emit_children(n); normalize_list(); SwigType_set_scope(0); return SWIG_OK; } /* ------------------------------------------------------------ * moduleDirective() * ------------------------------------------------------------ */ virtual int moduleDirective(Node *n) { if (!module) { module = n; } return SWIG_OK; } /* ------------------------------------------------------------ * importDirective() * ------------------------------------------------------------ */ virtual int importDirective(Node *n) { String *oldmodule = module; int oldimport = importmode; importmode = 1; module = 0; emit_children(n); importmode = oldimport; module = oldmodule; return SWIG_OK; } /* ------------------------------------------------------------ * includeDirective() * externDirective() * extendDirective() * ------------------------------------------------------------ */ virtual int includeDirective(Node *n) { return emit_children(n); } virtual int externDeclaration(Node *n) { return emit_children(n); } virtual int extendDirective(Node *n) { return emit_children(n); } /* ------------------------------------------------------------ * classDeclaration() * ------------------------------------------------------------ */ virtual int classDeclaration(Node *n) { String *name = Getattr(n,"name"); String *tdname = Getattr(n,"tdname"); String *unnamed = Getattr(n,"unnamed"); String *storage = Getattr(n,"storage"); String *kind = Getattr(n,"kind"); Node *oldinclass = inclass; List *olist = normalize; Symtab *symtab; String *nname = 0; String *fname = 0; String *scopename = 0; normalize = NewList(); if (name) { if (SwigType_istemplate(name)) { // We need to fully resolve the name to make templates work correctly */ Node *cn; fname = SwigType_typedef_resolve_all(name); if (Strcmp(fname,name) != 0) { cn = Swig_symbol_clookup_local(fname,0); if ((!cn) || (Strcmp(nodeType(cn),"template") == 0)) { Swig_symbol_cadd(fname,n); SwigType_typedef_class(fname); scopename = Copy(fname); } else { Swig_warning(WARN_TYPE_REDEFINED,Getfile(n),Getline(n), "Template '%s' was already wrapped,\n", SwigType_namestr(name)); Swig_warning(WARN_TYPE_REDEFINED,Getfile(cn), Getline(cn), "previous wrap of '%s'.\n", SwigType_namestr(Getattr(cn,"name"))); scopename = 0; } } else { Swig_symbol_cadd(fname,n); SwigType_typedef_class(fname); scopename = Copy(fname); } } else { if ((CPlusPlus) || (unnamed)) { SwigType_typedef_class(name); } else { SwigType_typedef_class(NewStringf("%s %s", kind, name)); } scopename = Copy(name); } } else { scopename = 0; } Setattr(n,"typepass:visit","1"); /* Need to set up a typedef if unnamed */ if (unnamed && tdname && (Cmp(storage,"typedef") == 0)) { SwigType_typedef(unnamed,tdname); } if (nsname) { nname = NewStringf("%s::%s", nsname, name); String *tdname = Getattr(n,"tdname"); if (tdname) { tdname = NewStringf("%s::%s", nsname, tdname); Setattr(n,"tdname",tdname); } } SwigType_new_scope(scopename); SwigType_attach_symtab(Getattr(n,"symtab")); /* Inherit type definitions into the class */ if (name) { cplus_inherit_types(n, 0, nname ? nname : (fname ? fname : name)); } inclass = n; symtab = Swig_symbol_setscope(Getattr(n,"symtab")); emit_children(n); Swig_symbol_setscope(symtab); Hash *ts = SwigType_pop_scope(); Setattr(n,"typescope",ts); Setattr(n,"module",module); /* Normalize deferred types */ { normal_node *nn = new normal_node(); nn->normallist = normalize; nn->symtab = Getattr(n,"symtab"); nn->next = patch_list; nn->typescope = Getattr(n,"typescope"); patch_list = nn; } normalize = olist; inclass = oldinclass; /* If in a namespace, patch the class name */ if (nname) { Setattr(n,"name",nname); } return SWIG_OK; } /* ------------------------------------------------------------ * namespaceDeclaration() * ------------------------------------------------------------ */ virtual int templateDeclaration(Node *n) { String *name = Getattr(n,"name"); String *ttype = Getattr(n,"templatetype"); if (Strcmp(ttype,"class") == 0) { String *rname = SwigType_typedef_resolve_all(name); SwigType_typedef_class(rname); Delete(rname); } else if (Strcmp(ttype,"classforward") == 0) { String *rname = SwigType_typedef_resolve_all(name); SwigType_typedef_class(rname); Delete(rname); /* SwigType_typedef_class(name);*/ } return SWIG_OK; } /* ------------------------------------------------------------ * classforwardDeclaration() * ------------------------------------------------------------ */ virtual int classforwardDeclaration(Node *n) { /* Temporary hack. Can't do inside a class because it breaks C nested structure wrapping */ if ((!inclass) || (CPlusPlus)) { String *name = Getattr(n,"name"); String *nname; SwigType_typedef_class(name); if (nsname) { nname = NewStringf("%s::%s", nsname, name); Setattr(n,"name",nname); } } return SWIG_OK; } /* ------------------------------------------------------------ * namespaceDeclaration() * ------------------------------------------------------------ */ virtual int namespaceDeclaration(Node *n) { Symtab *symtab; String *name = Getattr(n,"name"); String *alias = Getattr(n,"alias"); List *olist = normalize; normalize = NewList(); if (alias) { Typetab *ts = Getattr(n,"typescope"); if (!ts) { Node *ns; /* Create a empty scope for the alias */ ns = Getattr(n,"namespace"); if (ns) { SwigType_scope_alias(name, Getattr(ns,"typescope")); } ts = Getattr(ns,"typescope"); Setattr(n,"typescope",ts); } /* Namespace alias */ return SWIG_OK; } else { if (name) { Node *nn = Swig_symbol_clookup(name,n); Hash *ts = Getattr(nn,"typescope"); if (!ts) { SwigType_new_scope(name); SwigType_attach_symtab(Getattr(n,"symtab")); } else { SwigType_set_scope(ts); } } String *oldnsname = nsname; nsname = Swig_symbol_qualified(Getattr(n,"symtab")); symtab = Swig_symbol_setscope(Getattr(n,"symtab")); emit_children(n); Swig_symbol_setscope(symtab); if (name) { Hash *ts = SwigType_pop_scope(); Setattr(n,"typescope",ts); } /* Normalize deferred types */ { normal_node *nn = new normal_node(); nn->normallist = normalize; nn->symtab = Getattr(n,"symtab"); nn->next = patch_list; nn->typescope = Getattr(n,"typescope"); patch_list = nn; } normalize = olist; Delete(nsname); nsname = oldnsname; return SWIG_OK; } } /* ------------------------------------------------------------ * cDeclaration() * ------------------------------------------------------------ */ virtual int cDeclaration(Node *n) { if (NoExcept) { Delattr(n,"throws"); } /* Search for var args */ if (Getattr(n,"feature:varargs")) { ParmList *v = Getattr(n,"feature:varargs"); Parm *p = Getattr(n,"parms"); Parm *pp = 0; while (p) { SwigType *t = Getattr(p,"type"); if (Strcmp(t,"v(...)") == 0) { if (pp) { set_nextSibling(pp,Copy(v)); } else { Setattr(n,"parms", Copy(v)); } break; } pp = p; p = nextSibling(p); } } /* Normalize types. */ SwigType *ty = Getattr(n,"type"); normalize_type(ty); SwigType *decl = Getattr(n,"decl"); if (decl) { normalize_type(decl); } normalize_parms(Getattr(n,"parms")); normalize_parms(Getattr(n,"throws")); if (checkAttribute(n,"storage","typedef")) { String *name = Getattr(n,"name"); ty = Getattr(n,"type"); decl = Getattr(n,"decl"); SwigType *t = Copy(ty); { /* If the typename is qualified, make sure the scopename is fully qualified when making a typedef */ if (Swig_scopename_check(t)) { String *base, *prefix, *qprefix; base = Swig_scopename_last(t); prefix = Swig_scopename_prefix(t); qprefix = SwigType_typedef_qualified(prefix); Delete(t); t = NewStringf("%s::%s", qprefix,base); Delete(base); Delete(prefix); Delete(qprefix); } } SwigType_push(t,decl); if (CPlusPlus) { Replaceall(t,"struct ",""); Replaceall(t,"union ",""); Replaceall(t,"class ",""); } SwigType_typedef(t,name); } /* If namespaces are active. We need to patch the name with a namespace prefix */ if (nsname && !inclass) { String *name = Getattr(n,"name"); if (name) { String *nname = NewStringf("%s::%s", nsname, name); Setattr(n,"name", nname); Delete(nname); } } clean_overloaded(n); return SWIG_OK; } /* ------------------------------------------------------------ * constructorDeclaration() * ------------------------------------------------------------ */ virtual int constructorDeclaration(Node *n) { if (NoExcept) { Delattr(n,"throws"); } /* Search for var args */ if (Getattr(n,"feature:varargs")) { ParmList *v = Getattr(n,"feature:varargs"); Parm *p = Getattr(n,"parms"); Parm *pp = 0; while (p) { SwigType *t = Getattr(p,"type"); if (Strcmp(t,"v(...)") == 0) { if (pp) { set_nextSibling(pp,Copy(v)); } else { Setattr(n,"parms", Copy(v)); } break; } pp = p; p = nextSibling(p); } } normalize_parms(Getattr(n,"parms")); normalize_parms(Getattr(n,"throws")); /* If in a namespace, patch the class name */ if (nsname) { String *nname = NewStringf("%s::%s", nsname, Getattr(n,"name")); Setattr(n,"name",nname); } clean_overloaded(n); return SWIG_OK; } /* ------------------------------------------------------------ * destructorDeclaration() * ------------------------------------------------------------ */ virtual int destructorDeclaration(Node *n) { /* If in a namespace, patch the class name */ if (nsname) { String *nname = NewStringf("%s::%s", nsname, Getattr(n,"name")); Setattr(n,"name",nname); } return SWIG_OK; } /* ------------------------------------------------------------ * constantDirective() * ------------------------------------------------------------ */ virtual int constantDirective(Node *n) { SwigType *ty = Getattr(n,"type"); if (ty) { Setattr(n,"type",SwigType_typedef_qualified(ty)); } return SWIG_OK; } /* ------------------------------------------------------------ * enumDeclaration() * ------------------------------------------------------------ */ virtual int enumDeclaration(Node *n) { String *name = Getattr(n,"name"); String *uname = Getattr(n,"unnamed"); if (name) { SwigType *t; if (uname) { t = NewStringf("enum %s", uname); if (checkAttribute(n,"storage","typedef")) { SwigType_typedef(t,name); } } else { t = NewStringf("enum %s", name); SwigType_typedef(t,name); } Delete(t); } emit_children(n); return SWIG_OK; } /* ------------------------------------------------------------ * enumvalueDeclaration() * ------------------------------------------------------------ */ virtual int enumvalueDeclaration(Node *n) { String *name = Getattr(n,"name"); String *value = Getattr(n,"value"); if (!value) value = name; if (Strcmp(value,name) == 0) { String *new_value; if ((nsname) || (inclass)) { new_value = NewStringf("%s::%s", SwigType_namestr(Swig_symbol_qualified(n)), value); } else { new_value = NewString(value); } Setattr(n,"value",new_value); Delete(new_value); } return SWIG_OK; } /* ------------------------------------------------------------ * usingDeclaration() * ------------------------------------------------------------ */ virtual int usingDeclaration(Node *n) { if (Getattr(n,"namespace")) { /* using namespace id */ /* For a namespace import. We set up inheritance in the type system */ Node *ns = Getattr(n,"node"); if (ns) { Typetab *ts = Getattr(ns,"typescope"); if (ts) { SwigType_using_scope(ts); } } return SWIG_OK; } else { Node *ns; /* using id */ if (Getattr(n,"sym:symtab")) { ns = Swig_symbol_clookup(Getattr(n,"uname"), Getattr(n,"sym:symtab")); } else { ns = 0; } if (!ns) { if (is_public(n)) { Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(n), Getline(n), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(n,"uname"))); } } else { /* Only a single symbol is being used. There are only a few symbols that we actually care about. These are typedef, class declarations, and enum */ String *ntype = nodeType(ns); if (Strcmp(ntype,"cdecl") == 0) { if (checkAttribute(ns,"storage","typedef")) { /* A typedef declaration */ String *uname = Getattr(n,"uname"); SwigType_typedef_using(uname); } else { /* A normal C declaration. */ if ((inclass) && (!Getattr(n,"feature:ignore")) && (Getattr(n,"sym:name"))) { Node *c = ns; Node *unodes = 0, *last_unodes = 0; int ccount = 0; String *symname = Getattr(n,"sym:name"); while (c) { if (Strcmp(nodeType(c),"cdecl") == 0) { if (!(checkAttribute(c,"storage","static") || checkAttribute(c,"storage","typedef") || checkAttribute(c,"storage","friend") || (Getattr(c,"feature:extend") && !Getattr(c,"code")) || Getattr(c,"feature:ignore"))) { String *csymname = Getattr(c,"sym:name"); if (!csymname || (Strcmp(csymname,symname) == 0)) { /* Check for existence in overload list already */ { String *decl = Getattr(c,"decl"); Node *over = Getattr(n,"sym:overloaded"); int match = 0; while (over) { String *odecl = Getattr(over,"decl"); if (Cmp(decl, odecl) == 0) { match = 1; break; } over = Getattr(over,"sym:nextSibling"); } if (match) { c = Getattr(c,"csym:nextSibling"); continue; } } Node *nn = copyNode(c); if (!Getattr(nn,"sym:name")) Setattr(nn,"sym:name", symname); if (!Getattr(nn,"feature:ignore")) { Setattr(nn,"parms",CopyParmList(Getattr(c,"parms"))); ccount++; if (!last_unodes) { last_unodes = nn; unodes = nn; } else { Setattr(nn,"previousSibling",last_unodes); Setattr(last_unodes,"nextSibling", nn); Setattr(nn,"sym:previousSibling", last_unodes); Setattr(last_unodes,"sym:nextSibling", nn); Setattr(nn,"sym:overloaded", unodes); Setattr(unodes,"sym:overloaded", unodes); last_unodes = nn; } } else { Delete(nn); } } } } c = Getattr(c,"csym:nextSibling"); } if (unodes) { set_firstChild(n,unodes); if (ccount > 1) { if (!Getattr(n,"sym:overloaded")) { Setattr(n,"sym:overloaded",n); Setattr(n,"sym:overname","_SWIG_0"); } } } } } } else if ((Strcmp(ntype,"class") == 0) || ((Strcmp(ntype,"classforward") == 0))) { /* We install the using class name as kind of a typedef back to the original class */ String *uname = Getattr(n,"uname"); /* Import into current type scope */ SwigType_typedef_using(uname); } else if (Strcmp(ntype,"enum") == 0) { SwigType_typedef_using(Getattr(n,"uname")); } } } return SWIG_OK; } /* ------------------------------------------------------------ * typemapDirective() * ------------------------------------------------------------ */ virtual int typemapDirective(Node *n) { if (inclass || nsname) { Node *items = firstChild(n); while (items) { Parm *pattern = Getattr(items,"pattern"); Parm *parms = Getattr(items,"parms"); normalize_later(pattern); normalize_later(parms); items = nextSibling(items); } } return SWIG_OK; } /* ------------------------------------------------------------ * typemapcopyDirective() * ------------------------------------------------------------ */ virtual int typemapcopyDirective(Node *n) { if (inclass || nsname) { Node *items = firstChild(n); ParmList *pattern = Getattr(n,"pattern"); normalize_later(pattern); while (items) { ParmList *npattern = Getattr(items,"pattern"); normalize_later(npattern); items = nextSibling(items); } } return SWIG_OK; } /* ------------------------------------------------------------ * applyDirective() * ------------------------------------------------------------ */ virtual int applyDirective(Node *n) { if (inclass || nsname) { ParmList *pattern = Getattr(n,"pattern"); normalize_later(pattern); Node *items = firstChild(n); while (items) { Parm *apattern = Getattr(items,"pattern"); normalize_later(apattern); items = nextSibling(items); } } return SWIG_OK; } /* ------------------------------------------------------------ * clearDirective() * ------------------------------------------------------------ */ virtual int clearDirective(Node *n) { if (inclass || nsname) { Node *p; for (p = firstChild(n); p; p = nextSibling(p)) { ParmList *pattern = Getattr(p,"pattern"); normalize_later(pattern); } } return SWIG_OK; } }; void Swig_process_types(Node *n) { if (!n) return; TypePass *t = new TypePass; t->top(n); delete t; } cableswig-0.1.0+git20150808.orig/SWIG/Source/Modules/csharp.cxx0000644000175000000620000022061212561312227022455 0ustar stevestaff/* ----------------------------------------------------------------------------- * csharp.cxx * * CSharp wrapper module. * * Author(s) : William Fulton * Neil Cawse * * Copyright (C) 1999-2002. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_csharp_cxx[] = "/cvsroot/SWIG/Source/Modules/csharp.cxx,v 1.36 2004/02/12 21:48:37 cheetah Exp"; #include // for INT_MAX #include "swigmod.h" #include class CSHARP : public Language { static const char *usage; const String *empty_string; const String *public_string; const String *protected_string; Hash *swig_types_hash; File *f_runtime; File *f_header; File *f_wrappers; File *f_init; bool proxy_flag; // Flag for generating proxy classes bool have_default_constructor_flag; bool native_function_flag; // Flag for when wrapping a native function bool enum_constant_flag; // Flag for when wrapping an enum or constant bool static_flag; // Flag for when wrapping a static functions or member variables bool variable_wrapper_flag; // Flag for when wrapping a nonstatic member variable bool wrapping_member_flag; // Flag for when wrapping a member variable/enum/const bool global_variable_flag; // Flag for when wrapping a global variable String *imclass_name; // intermediary class name String *module_class_name; // module class name String *imclass_class_code; // intermediary class code String *proxy_class_def; String *proxy_class_code; String *module_class_code; String *proxy_class_name; String *variable_name; //Name of a variable being wrapped String *proxy_class_constants_code; String *module_class_constants_code; String *package; // Package name String *imclass_imports; //intermediary class imports from %pragma String *module_imports; //module imports from %pragma String *imclass_baseclass; //inheritance for intermediary class class from %pragma String *module_baseclass; //inheritance for module class from %pragma String *imclass_interfaces; //interfaces for intermediary class class from %pragma String *module_interfaces; //interfaces for module class from %pragma String *imclass_class_modifiers; //class modifiers for intermediary class overriden by %pragma String *module_class_modifiers; //class modifiers for module class overriden by %pragma String *upcasts_code; //C++ casts for inheritance hierarchies C++ code String *imclass_cppcasts_code; //C++ casts up inheritance hierarchies intermediary class code String *destructor_call; //C++ destructor call if any enum type_additions {none, pointer, reference}; public: /* ----------------------------------------------------------------------------- * CSHARP() * ----------------------------------------------------------------------------- */ CSHARP() : empty_string(NewString("")), public_string(NewString("public")), protected_string(NewString("protected")), swig_types_hash(NULL), f_runtime(NULL), f_header(NULL), f_wrappers(NULL), f_init(NULL), proxy_flag(true), have_default_constructor_flag(false), native_function_flag(false), enum_constant_flag(false), static_flag(false), variable_wrapper_flag(false), wrapping_member_flag(false), global_variable_flag(false), imclass_name(NULL), module_class_name(NULL), imclass_class_code(NULL), proxy_class_def(NULL), proxy_class_code(NULL), module_class_code(NULL), proxy_class_name(NULL), variable_name(NULL), proxy_class_constants_code(NULL), module_class_constants_code(NULL), package(NULL), imclass_imports(NULL), module_imports(NULL), imclass_baseclass(NULL), module_baseclass(NULL), imclass_interfaces(NULL), module_interfaces(NULL), imclass_class_modifiers(NULL), module_class_modifiers(NULL), upcasts_code(NULL), imclass_cppcasts_code(NULL), destructor_call(NULL) { } /* ----------------------------------------------------------------------------- * getProxyName() * * Test to see if a type corresponds to something wrapped with a proxy class * Return NULL if not otherwise the proxy class name * ----------------------------------------------------------------------------- */ String *getProxyName(SwigType *t) { if (proxy_flag) { Node *n = classLookup(t); if (n) { return Getattr(n,"sym:name"); } } return NULL; } /* ------------------------------------------------------------ * main() * ------------------------------------------------------------ */ virtual void main(int argc, char *argv[]) { SWIG_library_directory("csharp"); // Look for certain command line options for (int i = 1; i < argc; i++) { if (argv[i]) { if (strcmp(argv[i],"-package") == 0) { if (argv[i+1]) { package = NewString(""); Printf(package, argv[i+1]); Swig_mark_arg(i); Swig_mark_arg(i+1); i++; } else { Swig_arg_error(); } } else if ((strcmp(argv[i],"-noproxy") == 0)) { Swig_mark_arg(i); proxy_flag = false; } else if (strcmp(argv[i],"-help") == 0) { Printf(stderr,"%s\n", usage); } } } // Add a symbol to the parser for conditional compilation Preprocessor_define("SWIGCSHARP 1",0); // Add typemap definitions SWIG_typemap_lang("csharp"); SWIG_config_file("csharp.swg"); allow_overloading(); } /* --------------------------------------------------------------------- * top() * --------------------------------------------------------------------- */ virtual int top(Node *n) { /* Initialize all of the output files */ String *outfile = Getattr(n,"outfile"); f_runtime = NewFile(outfile,"w"); if (!f_runtime) { Printf(stderr,"Unable to open %s\n", outfile); SWIG_exit(EXIT_FAILURE); } f_init = NewString(""); f_header = NewString(""); f_wrappers = NewString(""); /* Register file targets with the SWIG file handler */ Swig_register_filebyname("header",f_header); Swig_register_filebyname("wrapper",f_wrappers); Swig_register_filebyname("runtime",f_runtime); Swig_register_filebyname("init",f_init); swig_types_hash = NewHash(); // Make the intermediary class and module class names. The intermediary class name can be set in the module directive. Node* optionsnode = Getattr( Getattr(n,"module") ,"options"); if (optionsnode) if (Getattr(optionsnode,"imclassname")) imclass_name = Copy(Getattr(optionsnode,"imclassname")); if (!imclass_name) { imclass_name = NewStringf("%sPINVOKE", Getattr(n,"name")); module_class_name = Copy(Getattr(n,"name")); } else { // Rename the module name if it is the same as intermediary class name - a backwards compatibility solution if (Cmp(imclass_name, Getattr(n,"name")) == 0) module_class_name = NewStringf("%sModule", Getattr(n,"name")); else module_class_name = Copy(Getattr(n,"name")); } imclass_class_code = NewString(""); proxy_class_def = NewString(""); proxy_class_code = NewString(""); module_class_constants_code = NewString(""); imclass_baseclass = NewString(""); imclass_interfaces = NewString(""); imclass_class_modifiers = NewString(""); // package access only to the intermediary class by default module_class_code = NewString(""); module_baseclass = NewString(""); module_interfaces = NewString(""); module_imports = NewString(""); module_class_modifiers = NewString("public"); imclass_imports = NewString(""); imclass_cppcasts_code = NewString(""); upcasts_code = NewString(""); if (!package) package = NewString(""); Swig_banner(f_runtime); // Print the SWIG banner message if (NoInclude) { Printf(f_runtime,"#define SWIG_NOINCLUDE\n"); } String *wrapper_name = NewString(""); Printf(wrapper_name, "CSharp_%%f", imclass_name); Swig_name_register((char*)"wrapper", Char(wrapper_name)); Swig_name_register((char*)"set", (char*)"set_%v"); Swig_name_register((char*)"get", (char*)"get_%v"); Swig_name_register((char*)"member", (char*)"%c_%m"); Delete(wrapper_name); Printf(f_wrappers,"\n#ifdef __cplusplus\n"); Printf(f_wrappers,"extern \"C\" {\n"); Printf(f_wrappers,"#endif\n\n"); /* Emit code */ Language::top(n); // Generate the intermediary class { String *filen = NewStringf("%s%s.cs", SWIG_output_directory(), imclass_name); File *f_im = NewFile(filen,"w"); if(!f_im) { Printf(stderr,"Unable to open %s\n", filen); SWIG_exit(EXIT_FAILURE); } Delete(filen); filen = NULL; // Start writing out the intermediary class if(Len(package) > 0) Printf(f_im, "//package %s;\n\n", package); emitBanner(f_im); if(imclass_imports) Printf(f_im, "%s\n", imclass_imports); if (Len(imclass_class_modifiers) > 0) Printf(f_im, "%s ", imclass_class_modifiers); Printf(f_im, "class %s ", imclass_name); if (imclass_baseclass && *Char(imclass_baseclass)) Printf(f_im, ": %s ", imclass_baseclass); if (Len(imclass_interfaces) > 0) Printv(f_im, "implements ", imclass_interfaces, " ", NIL); Printf(f_im, "{\n"); // Add the intermediary class methods Replaceall(imclass_class_code,"$module", module_class_name); Printv(f_im, imclass_class_code, NIL); Printv(f_im, imclass_cppcasts_code, NIL); // Finish off the class Printf(f_im, "}\n"); Close(f_im); } // Generate the C# module class { String *filen = NewStringf("%s%s.cs", SWIG_output_directory(), module_class_name); File *f_module = NewFile(filen,"w"); if(!f_module) { Printf(stderr,"Unable to open %s\n", filen); SWIG_exit(EXIT_FAILURE); } Delete(filen); filen = NULL; // Start writing out the module class if(Len(package) > 0) Printf(f_module, "//package %s;\n\n", package); emitBanner(f_module); if(module_imports) Printf(f_module, "%s\n", module_imports); if (Len(module_class_modifiers) > 0) Printf(f_module, "%s ", module_class_modifiers); Printf(f_module, "class %s ", module_class_name); if (module_baseclass && *Char(module_baseclass)) Printf(f_module, ": %s ", module_baseclass); if (Len(module_interfaces) > 0) Printv(f_module, "implements ", module_interfaces, " ", NIL); Printf(f_module, "{\n"); // Add the wrapper methods Printv(f_module, module_class_code, NIL); // Write out all the enums constants if (Len(module_class_constants_code) != 0 ) Printv(f_module, " // enums and constants\n", module_class_constants_code, NIL); // Finish off the class Printf(f_module, "}\n"); Close(f_module); } if(upcasts_code) Printv(f_wrappers,upcasts_code,NIL); Printf(f_wrappers,"#ifdef __cplusplus\n"); Printf(f_wrappers,"}\n"); Printf(f_wrappers,"#endif\n"); // Output a C# type wrapper class for each SWIG type for (Iterator swig_type = First(swig_types_hash); swig_type.key; swig_type = Next(swig_type)) { emitTypeWrapperClass(swig_type.key, swig_type.item); } Delete(swig_types_hash); swig_types_hash = NULL; Delete(imclass_name); imclass_name = NULL; Delete(imclass_class_code); imclass_class_code = NULL; Delete(proxy_class_def); proxy_class_def = NULL; Delete(proxy_class_code); proxy_class_code = NULL; Delete(module_class_constants_code); module_class_constants_code = NULL; Delete(imclass_baseclass); imclass_baseclass = NULL; Delete(imclass_interfaces); imclass_interfaces = NULL; Delete(imclass_class_modifiers); imclass_class_modifiers = NULL; Delete(module_class_name); module_class_name = NULL; Delete(module_class_code); module_class_code = NULL; Delete(module_baseclass); module_baseclass = NULL; Delete(module_interfaces); module_interfaces = NULL; Delete(module_imports); module_imports = NULL; Delete(module_class_modifiers); module_class_modifiers = NULL; Delete(imclass_imports); imclass_imports = NULL; Delete(imclass_cppcasts_code); imclass_cppcasts_code = NULL; Delete(upcasts_code); upcasts_code = NULL; Delete(package); package = NULL; /* Close all of the files */ Dump(f_header,f_runtime); Dump(f_wrappers,f_runtime); Wrapper_pretty_print(f_init,f_runtime); Delete(f_header); Delete(f_wrappers); Delete(f_init); Close(f_runtime); Delete(f_runtime); return SWIG_OK; } /* ----------------------------------------------------------------------------- * emitBanner() * ----------------------------------------------------------------------------- */ void emitBanner(File *f) { Printf(f, "/* ----------------------------------------------------------------------------\n"); Printf(f, " * This file was automatically generated by SWIG (http://www.swig.org).\n"); Printf(f, " * Version: %s\n", PACKAGE_VERSION); Printf(f, " *\n"); Printf(f, " * Do not make changes to this file unless you know what you are doing--modify\n"); Printf(f, " * the SWIG interface file instead.\n"); Printf(f, " * ----------------------------------------------------------------------------- */\n\n"); } /* ---------------------------------------------------------------------- * nativeWrapper() * ---------------------------------------------------------------------- */ virtual int nativeWrapper(Node *n) { String *wrapname = Getattr(n,"wrap:name"); if (!addSymbol(wrapname,n)) return SWIG_ERROR; if (Getattr(n,"type")) { Swig_save("nativeWrapper",n,"name",NIL); Setattr(n,"name", wrapname); native_function_flag = true; functionWrapper(n); Swig_restore(n); native_function_flag = false; } else { Printf(stderr,"%s : Line %d. No return type for %%native method %s.\n", input_file, line_number, Getattr(n,"wrap:name")); } return SWIG_OK; } /* ---------------------------------------------------------------------- * functionWrapper() * ---------------------------------------------------------------------- */ virtual int functionWrapper(Node *n) { String *symname = Getattr(n,"sym:name"); SwigType *t = Getattr(n,"type"); ParmList *l = Getattr(n,"parms"); String *tm; Parm *p; int i; String *c_return_type = NewString(""); String *im_return_type = NewString(""); String *cleanup = NewString(""); String *outarg = NewString(""); String *body = NewString(""); int num_arguments = 0; int num_required = 0; bool is_void_return; String *overloaded_name = getOverloadedName(n); if (!Getattr(n,"sym:overloaded")) { if (!addSymbol(Getattr(n,"sym:name"),n)) return SWIG_ERROR; } /* * Generate the proxy class properties for public member variables. * Not for enums and constants. */ if(proxy_flag && wrapping_member_flag && !enum_constant_flag) { // Capitalize the first letter in the variable in the getter/setter function name bool getter_flag = Cmp(symname, Swig_name_set(Swig_name_member(proxy_class_name, variable_name))) != 0; String *getter_setter_name = NewString(""); if(!getter_flag) Printf(getter_setter_name,"set"); else Printf(getter_setter_name,"get"); Putc(toupper((int) *Char(variable_name)), getter_setter_name); Printf(getter_setter_name, "%s", Char(variable_name)+1); Setattr(n,"proxyfuncname", getter_setter_name); Setattr(n,"imfuncname", symname); proxyClassFunctionHandler(n); Delete(getter_setter_name); } /* The rest of this function deals with generating the intermediary class wrapper function (that wraps a c/c++ function) and generating the PInvoke c code. Each C# wrapper function has a matching PInvoke c function call. */ // A new wrapper function object Wrapper *f = NewWrapper(); // Make a wrapper name for this function String *wname = Swig_name_wrapper(overloaded_name); /* Attach the non-standard typemaps to the parameter list. */ Swig_typemap_attach_parms("ctype", l, f); Swig_typemap_attach_parms("imtype", l, f); /* Get return types */ if ((tm = Swig_typemap_lookup_new("ctype",n,"",0))) { Printf(c_return_type,"%s", tm); } else { Swig_warning(WARN_CSHARP_TYPEMAP_CTYPE_UNDEF, input_file, line_number, "No ctype typemap defined for %s\n", SwigType_str(t,0)); } if ((tm = Swig_typemap_lookup_new("imtype",n,"",0))) { Printf(im_return_type,"%s", tm); } else { Swig_warning(WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s\n", SwigType_str(t,0)); } is_void_return = (Cmp(c_return_type, "void") == 0); if (!is_void_return) Wrapper_add_localv(f,"jresult", c_return_type, "jresult = 0",NIL); Printv(f->def, " DllExport ", c_return_type, " SWIGSTDCALL ", wname, "(", NIL); // Emit all of the local variables for holding arguments. emit_args(t,l,f); /* Attach the standard typemaps */ emit_attach_parmmaps(l,f); // Parameter overloading Setattr(n,"wrap:parms",l); Setattr(n,"wrap:name", wname); // Wrappers not wanted for some methods where the parameters cannot be overloaded in C# if (Getattr(n,"sym:overloaded")) { // Emit warnings for the few cases that can't be overloaded in C# and give up on generating wrapper Swig_overload_check(n); if (Getattr(n, "overload:ignore")) return SWIG_OK; } Printv(imclass_class_code, "\n [DllImport(\"",module_class_name,"\", EntryPoint=\"CSharp_",overloaded_name,"\")]\n", NIL); Printf(imclass_class_code, " public static extern %s %s(", im_return_type, overloaded_name); /* Get number of required and total arguments */ num_arguments = emit_num_arguments(l); num_required = emit_num_required(l); int gencomma = 0; // Now walk the function parameter list and generate code to get arguments for (i = 0, p=l; i < num_arguments; i++) { while (checkAttribute(p,"tmap:in:numinputs","0")) { p = Getattr(p,"tmap:in:next"); } SwigType *pt = Getattr(p,"type"); String *ln = Getattr(p,"lname"); String *im_param_type = NewString(""); String *c_param_type = NewString(""); String *arg = NewString(""); Printf(arg,"j%s", ln); /* Get the ctype types of the parameter */ if ((tm = Getattr(p,"tmap:ctype"))) { Printv(c_param_type, tm, NIL); } else { Swig_warning(WARN_CSHARP_TYPEMAP_CTYPE_UNDEF, input_file, line_number, "No ctype typemap defined for %s\n", SwigType_str(pt,0)); } /* Get the intermediary class parameter types of the parameter */ if ((tm = Getattr(p,"tmap:imtype"))) { Printv(im_param_type, tm, NIL); } else { Swig_warning(WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s\n", SwigType_str(pt,0)); } /* Add parameter to intermediary class method */ if(gencomma) Printf(imclass_class_code, ", "); Printf(imclass_class_code, "%s %s", im_param_type, arg); // Add parameter to C function Printv(f->def, gencomma?", ":"", c_param_type, " ", arg, NIL); gencomma = 1; // Get typemap for this argument if ((tm = Getattr(p,"tmap:in"))) { addThrows(n, "tmap:in", p); Replaceall(tm,"$source",arg); /* deprecated */ Replaceall(tm,"$target",ln); /* deprecated */ Replaceall(tm,"$arg",arg); /* deprecated? */ Replaceall(tm,"$input", arg); Setattr(p,"emit:input", arg); Printf(f->code,"%s\n", tm); p = Getattr(p,"tmap:in:next"); } else { Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n",SwigType_str(pt,0)); p = nextSibling(p); } Delete(im_param_type); Delete(c_param_type); Delete(arg); } /* Insert constraint checking code */ for (p = l; p;) { if ((tm = Getattr(p,"tmap:check"))) { addThrows(n, "tmap:check", p); Replaceall(tm,"$target",Getattr(p,"lname")); /* deprecated */ Replaceall(tm,"$arg",Getattr(p,"emit:input")); /* deprecated? */ Replaceall(tm,"$input",Getattr(p,"emit:input")); Printv(f->code,tm,"\n",NIL); p = Getattr(p,"tmap:check:next"); } else { p = nextSibling(p); } } /* Insert cleanup code */ for (p = l; p;) { if ((tm = Getattr(p,"tmap:freearg"))) { addThrows(n, "tmap:freearg", p); Replaceall(tm,"$source",Getattr(p,"emit:input")); /* deprecated */ Replaceall(tm,"$arg",Getattr(p,"emit:input")); /* deprecated? */ Replaceall(tm,"$input",Getattr(p,"emit:input")); Printv(cleanup,tm,"\n",NIL); p = Getattr(p,"tmap:freearg:next"); } else { p = nextSibling(p); } } /* Insert argument output code */ for (p = l; p;) { if ((tm = Getattr(p,"tmap:argout"))) { addThrows(n, "tmap:argout", p); Replaceall(tm,"$source",Getattr(p,"emit:input")); /* deprecated */ Replaceall(tm,"$target",Getattr(p,"lname")); /* deprecated */ Replaceall(tm,"$arg",Getattr(p,"emit:input")); /* deprecated? */ Replaceall(tm,"$result","jresult"); Replaceall(tm,"$input",Getattr(p,"emit:input")); Printv(outarg,tm,"\n",NIL); p = Getattr(p,"tmap:argout:next"); } else { p = nextSibling(p); } } // Get any C# exception classes in the throws typemap ParmList *throw_parm_list = NULL; if ((throw_parm_list = Getattr(n,"throws"))) { Swig_typemap_attach_parms("throws", throw_parm_list, f); for (p = throw_parm_list; p; p=nextSibling(p)) { if ((tm = Getattr(p,"tmap:throws"))) { addThrows(n, "tmap:throws", p); } } } if (Cmp(nodeType(n), "constant") == 0) { // Wrapping a constant hack Swig_save("functionWrapper",n,"wrap:action",NIL); // below based on Swig_VargetToFunction() SwigType *ty = Swig_wrapped_var_type(Getattr(n,"type")); Setattr(n,"wrap:action", NewStringf("result = (%s) %s;\n", SwigType_lstr(ty,0), Getattr(n, "value"))); } // Now write code to make the function call if(!native_function_flag) emit_action(n,f); if (Cmp(nodeType(n), "constant") == 0) Swig_restore(n); /* Return value if necessary */ if(!native_function_flag) { if ((tm = Swig_typemap_lookup_new("out",n,"result",0))) { addThrows(n, "tmap:out", n); Replaceall(tm,"$source", "result"); /* deprecated */ Replaceall(tm,"$target", "jresult"); /* deprecated */ Replaceall(tm,"$result","jresult"); Printf(f->code,"%s", tm); if (Len(tm)) Printf(f->code,"\n"); } else { Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(t,0), Getattr(n,"name")); } } /* Output argument output code */ Printv(f->code,outarg,NIL); /* Output cleanup code */ Printv(f->code,cleanup,NIL); /* Look to see if there is any newfree cleanup code */ if (Getattr(n,"feature:new")) { if ((tm = Swig_typemap_lookup_new("newfree",n,"result",0))) { addThrows(n, "tmap:newfree", n); Replaceall(tm,"$source","result"); /* deprecated */ Printf(f->code,"%s\n",tm); } } /* See if there is any return cleanup code */ if(!native_function_flag) { if ((tm = Swig_typemap_lookup_new("ret", n, "result", 0))) { Replaceall(tm,"$source","result"); /* deprecated */ Printf(f->code,"%s\n",tm); } } /* Finish C function and intermediary class function definitions */ Printf(imclass_class_code, ")"); generateThrowsClause(n, imclass_class_code); Printf(imclass_class_code, ";\n"); Printf(f->def,") {"); if(!is_void_return) Printv(f->code, " return jresult;\n", NIL); Printf(f->code, "}\n"); /* Substitute the cleanup code */ Replaceall(f->code,"$cleanup",cleanup); /* Contract macro modification */ Replaceall(f->code, "SWIG_contract_assert(", "SWIG_contract_assert($null, "); if(!is_void_return) Replaceall(f->code,"$null","0"); else Replaceall(f->code,"$null",""); /* Dump the function out */ if(!native_function_flag) Wrapper_print(f,f_wrappers); if(!(proxy_flag && is_wrapping_class()) && !enum_constant_flag) { moduleClassFunctionHandler(n); } Delete(c_return_type); Delete(im_return_type); Delete(cleanup); Delete(outarg); Delete(body); Delete(overloaded_name); DelWrapper(f); return SWIG_OK; } /* ----------------------------------------------------------------------- * variableWrapper() * ----------------------------------------------------------------------- */ virtual int variableWrapper(Node *n) { Language::variableWrapper(n); return SWIG_OK; } /* ----------------------------------------------------------------------- * globalvariableHandler() * ------------------------------------------------------------------------ */ virtual int globalvariableHandler(Node *n) { SwigType *t = Getattr(n,"type"); String *tm; // Get the variable type if ((tm = Swig_typemap_lookup_new("cstype",n,"",0))) { substituteClassname(t, tm); } else { Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(t,0)); } // Output the property's field declaration and accessor methods Printf(module_class_code, " public static %s %s {", tm, Getattr(n, "sym:name")); variable_name = Getattr(n,"sym:name"); global_variable_flag = true; int ret = Language::globalvariableHandler(n); global_variable_flag = false; Printf(module_class_code, "\n }\n\n"); return ret; } /* ----------------------------------------------------------------------- * constantWrapper() * ------------------------------------------------------------------------ */ virtual int constantWrapper(Node *n) { String *symname = Getattr(n,"sym:name"); SwigType *t = Getattr(n,"type"); ParmList *l = Getattr(n,"parms"); String *tm; String *return_type = NewString(""); String *constants_code = NewString(""); SwigType *original_type = t; if (!addSymbol(symname,n)) return SWIG_ERROR; bool is_enum_item = (Cmp(nodeType(n), "enumitem") == 0); /* Adjust the enum type for the Swig_typemap_lookup. We want the same cstype typemap for all the enum items. * The type of each enum item depends on what value it is assigned, but is usually a C int. */ if (is_enum_item) { t = NewStringf("enum %s", Getattr(parentNode(n), "sym:name")); Setattr(n,"type", t); } /* Attach the non-standard typemaps to the parameter list. */ Swig_typemap_attach_parms("cstype", l, NULL); /* Get C# return types */ bool classname_substituted_flag = false; if ((tm = Swig_typemap_lookup_new("cstype",n,"",0))) { classname_substituted_flag = substituteClassname(t, tm); Printf(return_type, "%s", tm); } else { Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(t,0)); } // Add the stripped quotes back in String *new_value = NewString(""); Swig_save("constantWrapper",n,"value",NIL); if(SwigType_type(t) == T_STRING) { Printf(new_value, "\"%s\"", Copy(Getattr(n, "value"))); Setattr(n, "value", new_value); } else if(SwigType_type(t) == T_CHAR) { Printf(new_value, "\'%s\'", Copy(Getattr(n, "value"))); Setattr(n, "value", new_value); } // The %csconst feature determines how the constant value is obtained String *const_feature = Getattr(n,"feature:cs:const"); bool const_feature_flag = const_feature && Cmp(const_feature, "0") != 0; // enums are wrapped using a public final static int in C#. // Other constants are wrapped using a public final static [cstype] in C#. Printf(constants_code, " public %s %s %s = ", (const_feature_flag ? "const" : "static readonly"), return_type, ((proxy_flag && wrapping_member_flag) ? variable_name : symname)); if ((is_enum_item && Getattr(n,"enumvalue") == 0) || !const_feature_flag) { // Enums without value and default constant handling will work with any type of C constant and initialises the C# variable from C through a PInvoke call. if(classname_substituted_flag) // 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)); else Printf(constants_code, "%s.%s();\n", imclass_name, Swig_name_get(symname)); // Each constant and enum value is wrapped with a separate PInvoke function call enum_constant_flag = true; variableWrapper(n); enum_constant_flag = false; } else if (is_enum_item) { // Alternative enum item handling will use the explicit value of the enum item and hope that it compiles as C# code Printf(constants_code, "%s;\n", Getattr(n,"enumvalue")); } else { // Alternative constant handling will use the C syntax to make a true C# constant and hope that it compiles as C# code Printf(constants_code, "%s;\n", Getattr(n,"value")); } if(proxy_flag && wrapping_member_flag) Printv(proxy_class_constants_code, constants_code, NIL); else Printv(module_class_constants_code, constants_code, NIL); Swig_restore(n); if (is_enum_item) { Delete(Getattr(n,"type")); Setattr(n,"type", original_type); } Delete(new_value); Delete(return_type); Delete(constants_code); return SWIG_OK; } virtual int insertDirective(Node *n) { String *code = Getattr(n,"code"); Replaceall(code, "$module", module_class_name); return Language::insertDirective(n); } /* ----------------------------------------------------------------------------- * pragmaDirective() * * Valid Pragmas: * imclassbase - base (extends) for the intermediary class * imclassclassmodifiers - class modifiers for the intermediary class * imclasscode - text (C# code) is copied verbatim to the intermediary class * imclassimports - import statements for the intermediary class * imclassinterfaces - interface (implements) for the intermediary class * * modulebase - base (extends) for the module class * moduleclassmodifiers - class modifiers for the module class * modulecode - text (C# code) is copied verbatim to the module class * moduleimports - import statements for the module class * moduleinterfaces - interface (implements) for the module class * * ----------------------------------------------------------------------------- */ virtual int pragmaDirective(Node *n) { if (!ImportMode) { String *lang = Getattr(n,"lang"); String *code = Getattr(n,"name"); String *value = Getattr(n,"value"); if(Strcmp(lang, "csharp") == 0) { String *strvalue = NewString(value); Replaceall(strvalue,"\\\"", "\""); if(Strcmp(code, "imclassbase") == 0) { Delete(imclass_baseclass); imclass_baseclass = Copy(strvalue); } else if(Strcmp(code, "imclassclassmodifiers") == 0) { Delete(imclass_class_modifiers); imclass_class_modifiers = Copy(strvalue); } else if(Strcmp(code, "imclasscode") == 0) { Printf(imclass_class_code, "%s\n", strvalue); } else if(Strcmp(code, "imclassimports") == 0) { Delete(imclass_imports); imclass_imports = Copy(strvalue); } else if(Strcmp(code, "imclassinterfaces") == 0) { Delete(imclass_interfaces); imclass_interfaces = Copy(strvalue); } else if(Strcmp(code, "modulebase") == 0) { Delete(module_baseclass); module_baseclass = Copy(strvalue); } else if(Strcmp(code, "moduleclassmodifiers") == 0) { Delete(module_class_modifiers); module_class_modifiers = Copy(strvalue); } else if(Strcmp(code, "modulecode") == 0) { Printf(module_class_code, "%s\n", strvalue); } else if(Strcmp(code, "moduleimports") == 0) { Delete(module_imports); module_imports = Copy(strvalue); } else if(Strcmp(code, "moduleinterfaces") == 0) { Delete(module_interfaces); module_interfaces = Copy(strvalue); } else { Printf(stderr,"%s : Line %d. Unrecognized pragma.\n", input_file, line_number); } Delete(strvalue); } } return Language::pragmaDirective(n); } /* ----------------------------------------------------------------------------- * emitProxyClassDefAndCPPCasts() * ----------------------------------------------------------------------------- */ void emitProxyClassDefAndCPPCasts(Node *n) { String *c_classname = SwigType_namestr(Getattr(n,"name")); String *c_baseclass = NULL; String *baseclass = NULL; String *c_baseclassname = NULL; String *typemap_lookup_type = Getattr(n,"classtypeobj"); /* Deal with inheritance */ List *baselist = Getattr(n,"bases"); if (baselist) { Iterator base = First(baselist); c_baseclassname = Getattr(base.item,"name"); baseclass = Copy(getProxyName(c_baseclassname)); if (baseclass){ c_baseclass = SwigType_namestr(Getattr(base.item,"name")); } base = Next(base); if (base.item) { Swig_warning(WARN_CSHARP_MULTIPLE_INHERITANCE, input_file, line_number, "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in C#.\n", typemap_lookup_type, Getattr(base.item,"name")); } } bool derived = baseclass && getProxyName(c_baseclassname); if (!baseclass) baseclass = NewString(""); // Inheritance from pure C# classes const String *pure_baseclass = typemapLookup("csbase", typemap_lookup_type, WARN_NONE); if (Len(pure_baseclass) > 0 && Len(baseclass) > 0) { Swig_warning(WARN_CSHARP_MULTIPLE_INHERITANCE, input_file, line_number, "Warning for %s proxy: Base %s ignored. Multiple inheritance is not supported in C#.\n", typemap_lookup_type, pure_baseclass); } // Pure C# interfaces const String *pure_interfaces = typemapLookup(derived ? "csinterfaces_derived" : "csinterfaces", typemap_lookup_type, WARN_NONE); // Start writing the proxy class Printv(proxy_class_def, typemapLookup("csimports", typemap_lookup_type, WARN_NONE), // Import statements "\n", typemapLookup("csclassmodifiers", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers " class $csclassname", // Class name and bases (derived || *Char(pure_baseclass) || *Char(pure_interfaces)) ? " : " : "", baseclass, pure_baseclass, ((derived || *Char(pure_baseclass)) && *Char(pure_interfaces)) ? // Interfaces ", " : "", pure_interfaces, " {\n", " private IntPtr swigCPtr;\n", // Member variables for memory handling derived ? "" : " protected bool swigCMemOwn;\n", "\n", " ", typemapLookup("csptrconstructormodifiers", typemap_lookup_type, WARN_CSHARP_TYPEMAP_PTRCONSTMOD_UNDEF), // pointer constructor modifiers " $csclassname(IntPtr cPtr, bool cMemoryOwn) ", // Constructor used for wrapping pointers derived ? ": base($imclassname.$csclassnameTo$baseclass(cPtr), cMemoryOwn) {\n" : "{\n swigCMemOwn = cMemoryOwn;\n", " swigCPtr = cPtr;\n", " }\n", NIL); if(!have_default_constructor_flag) { // All proxy classes need a constructor Printv(proxy_class_def, "\n", " protected $csclassname() : this(IntPtr.Zero, false) {\n", " }\n", NIL); } // C++ destructor is wrapped by the Dispose method // Note that the method name is specified in a typemap attribute called methodname String *destruct = NewString(""); const String *tm = NULL; Node *attributes = NewHash(); String *destruct_methodname = NULL; if (derived) { tm = typemapLookup("csdestruct_derived", typemap_lookup_type, WARN_NONE, attributes); destruct_methodname = Getattr(attributes, "tmap:csdestruct_derived:methodname"); } else { tm = typemapLookup("csdestruct", typemap_lookup_type, WARN_NONE, attributes); destruct_methodname = Getattr(attributes, "tmap:csdestruct:methodname"); } if (!destruct_methodname) { Swig_error(input_file, line_number, "No methodname attribute defined in csdestruct%s typemap for %s\n", (derived ? "_derived" : ""), proxy_class_name); } // Emit the Finalize and Dispose methods if (tm) { // Finalize method if (*Char(destructor_call)) { Printv(proxy_class_def, typemapLookup("csfinalize", typemap_lookup_type, WARN_NONE), NIL); } // Dispose method Printv(destruct, tm, NIL); if (*Char(destructor_call)) Replaceall(destruct, "$imcall", destructor_call); else Replaceall(destruct, "$imcall", "throw new MethodAccessException(\"C++ destructor does not have public access\")"); if (*Char(destruct)) Printv(proxy_class_def, "\n public ", derived ? "override" : "virtual", " void ", destruct_methodname, "() ", destruct, "\n", NIL); } Delete(attributes); Delete(destruct); // Emit various other methods Printv(proxy_class_def, typemapLookup("csgetcptr", typemap_lookup_type, WARN_CSHARP_TYPEMAP_GETCPTR_UNDEF), // getCPtr method typemapLookup("cscode", typemap_lookup_type, WARN_NONE), // extra C# code "\n", NIL); // Substitute various strings into the above template Replaceall(proxy_class_code, "$csclassname", proxy_class_name); Replaceall(proxy_class_def, "$csclassname", proxy_class_name); Replaceall(proxy_class_def, "$baseclass", baseclass); Replaceall(proxy_class_code, "$baseclass", baseclass); 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,"\n [DllImport(\"", module_class_name, "\", EntryPoint=\"CSharp_", proxy_class_name ,"To", baseclass ,"\")]\n", NIL); Printv(imclass_cppcasts_code," public static extern IntPtr ", "$csclassnameTo$baseclass(IntPtr objectRef);\n", NIL); Replaceall(imclass_cppcasts_code, "$csclassname", proxy_class_name); Replaceall(imclass_cppcasts_code, "$baseclass", baseclass); Printv(upcasts_code, "DllExport $cbaseclass * SWIGSTDCALL CSharp_$imclazznameTo$imbaseclass", "($cclass *objectRef) {\n", " return ($cbaseclass *)objectRef;\n" "}\n", "\n", NIL); Replaceall(upcasts_code, "$imbaseclass", baseclass); Replaceall(upcasts_code, "$cbaseclass", c_baseclass); Replaceall(upcasts_code, "$imclazzname", proxy_class_name); Replaceall(upcasts_code, "$cclass", c_classname); } Delete(baseclass); } /* ---------------------------------------------------------------------- * classHandler() * ---------------------------------------------------------------------- */ virtual int classHandler(Node *n) { File *f_proxy = NULL; if (proxy_flag) { proxy_class_name = NewString(Getattr(n,"sym:name")); if (!addSymbol(proxy_class_name,n)) 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.cs", SWIG_output_directory(), proxy_class_name); f_proxy = NewFile(filen,"w"); if(!f_proxy) { Printf(stderr, "Unable to create proxy class file: %s\n", filen); SWIG_exit(EXIT_FAILURE); } Delete(filen); filen = NULL; emitBanner(f_proxy); if(Len(package) > 0) Printf(f_proxy, "//package %s;\n\n", package); Clear(proxy_class_def); Clear(proxy_class_code); have_default_constructor_flag = false; destructor_call = NewString(""); proxy_class_constants_code = NewString(""); } Language::classHandler(n); if (proxy_flag) { emitProxyClassDefAndCPPCasts(n); Printv(f_proxy, proxy_class_def, proxy_class_code, NIL); // Write out all the enums and constants if (Len(proxy_class_constants_code) != 0 ) Printv(f_proxy, " // enums and constants\n", proxy_class_constants_code, NIL); Printf(f_proxy, "}\n"); Close(f_proxy); f_proxy = NULL; Delete(proxy_class_name); proxy_class_name = NULL; Delete(destructor_call); destructor_call = NULL; Delete(proxy_class_constants_code); proxy_class_constants_code = NULL; } return SWIG_OK; } /* ---------------------------------------------------------------------- * memberfunctionHandler() * ---------------------------------------------------------------------- */ virtual int memberfunctionHandler(Node *n) { Language::memberfunctionHandler(n); if (proxy_flag) { String *overloaded_name = getOverloadedName(n); String *intermediary_function_name = Swig_name_member(proxy_class_name, overloaded_name); Setattr(n,"proxyfuncname", Getattr(n, "sym:name")); Setattr(n,"imfuncname", intermediary_function_name); proxyClassFunctionHandler(n); Delete(overloaded_name); } return SWIG_OK; } /* ---------------------------------------------------------------------- * staticmemberfunctionHandler() * ---------------------------------------------------------------------- */ virtual int staticmemberfunctionHandler(Node *n) { static_flag = true; Language::staticmemberfunctionHandler(n); if (proxy_flag) { String *overloaded_name = getOverloadedName(n); String *intermediary_function_name = Swig_name_member(proxy_class_name, overloaded_name); Setattr(n,"proxyfuncname", Getattr(n,"sym:name")); Setattr(n,"imfuncname", intermediary_function_name); proxyClassFunctionHandler(n); Delete(overloaded_name); } static_flag = false; return SWIG_OK; } /* ----------------------------------------------------------------------------- * proxyClassFunctionHandler() * * Function called for creating a C# wrapper function around a c++ function in the * proxy class. Used for both static and non-static C++ class functions. * C++ class static functions map to C# static functions. * Two extra attributes in the Node must be available. These are "proxyfuncname" - * the name of the C# class proxy function, which in turn will call "imfuncname" - * the intermediary (PInvoke) function name in the intermediary class. * ----------------------------------------------------------------------------- */ void proxyClassFunctionHandler(Node *n) { SwigType *t = Getattr(n,"type"); ParmList *l = Getattr(n,"parms"); String *intermediary_function_name = Getattr(n,"imfuncname"); String *proxy_function_name = Getattr(n,"proxyfuncname"); String *tm; Parm *p; int i; String *imcall = NewString(""); String *return_type = NewString(""); String *function_code = NewString(""); bool setter_flag = false; if(!proxy_flag) return; // Wrappers not wanted for some methods where the parameters cannot be overloaded in C# if (Getattr(n, "overload:ignore")) return; if (l) { if (SwigType_type(Getattr(l,"type")) == T_VOID) { l = nextSibling(l); } } /* Attach the non-standard typemaps to the parameter list */ Swig_typemap_attach_parms("in", l, NULL); Swig_typemap_attach_parms("cstype", l, NULL); Swig_typemap_attach_parms("csin", l, NULL); /* Get return types */ if ((tm = Swig_typemap_lookup_new("cstype",n,"",0))) { // Note that in the case of polymorphic (covariant) return types, the method's return type is changed to be the base of the C++ return type SwigType *virtualtype = Getattr(n,"virtual:type"); substituteClassname(virtualtype ? virtualtype : t, tm); Printf(return_type, "%s", tm); if (virtualtype) Swig_warning(WARN_CSHARP_COVARIANT_RET, input_file, line_number, "Covariant return types not supported in C#. Proxy method will return %s.\n", SwigType_str(virtualtype,0)); } else { Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(t,0)); } if(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))) == 0); } /* Start generating the proxy function */ const String *methodmods = Getattr(n,"feature:cs:methodmodifiers"); methodmods = methodmods ? methodmods : (is_protected(n) ? protected_string : public_string); Printf(function_code, " %s ", methodmods); if (static_flag) Printf(function_code, "static "); if (Getattr(n,"virtual:derived")) Printf(function_code, "override "); else if (checkAttribute(n, "storage", "virtual")) Printf(function_code, "virtual "); Printf(function_code, "%s %s(", return_type, proxy_function_name); Printv(imcall, imclass_name, ".", intermediary_function_name, "(", NIL); if (!static_flag) Printv(imcall, "swigCPtr", NIL); emit_mark_varargs(l); int gencomma = !static_flag; /* Output each parameter */ for (i = 0, p=l; p; i++) { /* Ignored varargs */ if (checkAttribute(p,"varargs:ignore","1")) { p = nextSibling(p); continue; } /* Ignored parameters */ if (checkAttribute(p,"tmap:in:numinputs","0")) { p = Getattr(p,"tmap:in:next"); continue; } /* Ignore the 'this' argument for variable wrappers */ if (!(variable_wrapper_flag && i==0)) { SwigType *pt = Getattr(p,"type"); String *param_type = NewString(""); /* Get the C# parameter type */ if ((tm = Getattr(p,"tmap:cstype"))) { substituteClassname(pt, tm); Printf(param_type, "%s", tm); } else { Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(pt,0)); } if (gencomma) Printf(imcall, ", "); String *arg = variable_wrapper_flag ? NewString("value") : makeParameterName(n, p, i); // Use typemaps to transform type used in C# wrapper function (in proxy class) to type used in PInvoke function (in intermediary class) if ((tm = Getattr(p,"tmap:csin"))) { addThrows(n, "tmap:csin", p); substituteClassname(pt, tm); Replaceall(tm, "$csinput", arg); Printv(imcall, tm, NIL); } else { Swig_warning(WARN_CSHARP_TYPEMAP_CSIN_UNDEF, input_file, line_number, "No csin typemap defined for %s\n", SwigType_str(pt,0)); } /* Add parameter to proxy function */ if (gencomma >= 2) Printf(function_code, ", "); gencomma = 2; Printf(function_code, "%s %s", param_type, arg); Delete(arg); Delete(param_type); } p = Getattr(p,"tmap:in:next"); } Printf(imcall, ")"); Printf(function_code, ")"); // Transform return type used in PInvoke function (in intermediary class) to type used in C# wrapper function (in proxy class) if ((tm = Swig_typemap_lookup_new("csout",n,"",0))) { addThrows(n, "tmap:csout", n); if (Getattr(n,"feature:new")) Replaceall(tm,"$owner","true"); else Replaceall(tm,"$owner","false"); substituteClassname(t, tm); Replaceall(tm, "$imcall", imcall); } else { Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csout typemap defined for %s\n", SwigType_str(t,0)); } generateThrowsClause(n, function_code); Printf(function_code, " %s\n\n", tm ? tm : empty_string); if(proxy_flag && wrapping_member_flag && !enum_constant_flag) { // Properties if(setter_flag) { // Setter method if ((tm = Swig_typemap_lookup_new("csvarin",n,"",0))) { if (Getattr(n,"feature:new")) Replaceall(tm,"$owner","true"); else Replaceall(tm,"$owner","false"); substituteClassname(t, tm); Replaceall(tm, "$imcall", imcall); Printf(proxy_class_code, "%s", tm); } else { Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csvarin typemap defined for %s\n", SwigType_str(t,0)); } } else { // Getter method if ((tm = Swig_typemap_lookup_new("csvarout",n,"",0))) { if (Getattr(n,"feature:new")) Replaceall(tm,"$owner","true"); else Replaceall(tm,"$owner","false"); substituteClassname(t, tm); Replaceall(tm, "$imcall", imcall); Printf(proxy_class_code, "%s", tm); } else { Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csvarout typemap defined for %s\n", SwigType_str(t,0)); } } } else { // Normal function call Printv(proxy_class_code, function_code, NIL); } Delete(function_code); Delete(return_type); Delete(imcall); } /* ---------------------------------------------------------------------- * constructorHandler() * ---------------------------------------------------------------------- */ virtual int constructorHandler(Node *n) { ParmList *l = Getattr(n,"parms"); String *tm; Parm *p; int i; Language::constructorHandler(n); // Wrappers not wanted for some methods where the parameters cannot be overloaded in C# if (Getattr(n, "overload:ignore")) return SWIG_OK; if(proxy_flag) { String *overloaded_name = getOverloadedName(n); String *imcall = NewString(""); const String *methodmods = Getattr(n,"feature:cs:methodmodifiers"); methodmods = methodmods ? methodmods : (is_protected(n) ? protected_string : public_string); methodmods = methodmods ? methodmods : public_string; Printf(proxy_class_code, " %s %s(", methodmods, proxy_class_name); Printv(imcall, " : this(", imclass_name, ".", Swig_name_construct(overloaded_name), "(", NIL); /* Attach the non-standard typemaps to the parameter list */ Swig_typemap_attach_parms("in", l, NULL); Swig_typemap_attach_parms("cstype", l, NULL); Swig_typemap_attach_parms("csin", l, NULL); emit_mark_varargs(l); int gencomma = 0; /* Output each parameter */ for (i = 0, p=l; p; i++) { /* Ignored varargs */ if (checkAttribute(p,"varargs:ignore","1")) { p = nextSibling(p); continue; } /* Ignored parameters */ if (checkAttribute(p,"tmap:in:numinputs","0")) { p = Getattr(p,"tmap:in:next"); continue; } SwigType *pt = Getattr(p,"type"); String *param_type = NewString(""); /* Get the C# parameter type */ if ((tm = Getattr(p,"tmap:cstype"))) { substituteClassname(pt, tm); Printf(param_type, "%s", tm); } else { Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(pt,0)); } if (gencomma) Printf(imcall, ", "); String *arg = makeParameterName(n, p, i); // Use typemaps to transform type used in C# wrapper function (in proxy class) to type used in PInvoke function (in intermediary class) if ((tm = Getattr(p,"tmap:csin"))) { addThrows(n, "tmap:csin", p); substituteClassname(pt, tm); Replaceall(tm, "$csinput", arg); Printv(imcall, tm, NIL); } else { Swig_warning(WARN_CSHARP_TYPEMAP_CSIN_UNDEF, input_file, line_number, "No csin typemap defined for %s\n", SwigType_str(pt,0)); } /* Add parameter to proxy function */ if(gencomma) Printf(proxy_class_code, ", "); Printf(proxy_class_code, "%s %s", param_type, arg); gencomma = 1; Delete(arg); Delete(param_type); p = Getattr(p,"tmap:in:next"); } Printf(imcall, "), true)"); Printf(proxy_class_code, ")"); Printf(proxy_class_code,"%s", imcall); generateThrowsClause(n, proxy_class_code); Printf(proxy_class_code, " {\n"); Printf(proxy_class_code, " }\n\n"); if(!gencomma) // We must have a default constructor have_default_constructor_flag = true; Delete(overloaded_name); Delete(imcall); } return SWIG_OK; } /* ---------------------------------------------------------------------- * destructorHandler() * ---------------------------------------------------------------------- */ virtual int destructorHandler(Node *n) { Language::destructorHandler(n); String *symname = Getattr(n,"sym:name"); if(proxy_flag) { Printv(destructor_call, imclass_name, ".", Swig_name_destroy(symname), "(swigCPtr)", NIL); } return SWIG_OK; } /* ---------------------------------------------------------------------- * membervariableHandler() * ---------------------------------------------------------------------- */ virtual int membervariableHandler(Node *n) { SwigType *t = Getattr(n,"type"); String *tm; // Get the variable type if ((tm = Swig_typemap_lookup_new("cstype",n,"",0))) { substituteClassname(t, tm); } else { Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(t,0)); } // Output the property's field declaration and accessor methods Printf(proxy_class_code, " public %s %s {", tm, Getattr(n, "sym:name")); variable_name = Getattr(n,"sym:name"); wrapping_member_flag = true; variable_wrapper_flag = true; Language::membervariableHandler(n); wrapping_member_flag = false; variable_wrapper_flag = false; Printf(proxy_class_code, "\n }\n\n"); return SWIG_OK; } /* ---------------------------------------------------------------------- * staticmembervariableHandler() * ---------------------------------------------------------------------- */ virtual int staticmembervariableHandler(Node *n) { bool static_const_member_flag = (Getattr(n, "value") == 0); if(static_const_member_flag) { SwigType *t = Getattr(n,"type"); String *tm; // Get the variable type if ((tm = Swig_typemap_lookup_new("cstype",n,"",0))) { substituteClassname(t, tm); } else { Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(t,0)); } // Output the property's field declaration and accessor methods Printf(proxy_class_code, " public static %s %s {", tm, Getattr(n, "sym:name")); } variable_name = Getattr(n,"sym:name"); wrapping_member_flag = true; static_flag = true; Language::staticmembervariableHandler(n); wrapping_member_flag = false; static_flag = false; if(static_const_member_flag) Printf(proxy_class_code, "\n }\n\n"); return SWIG_OK; } /* ---------------------------------------------------------------------- * memberconstantHandler() * ---------------------------------------------------------------------- */ virtual int memberconstantHandler(Node *n) { variable_name = Getattr(n,"sym:name"); wrapping_member_flag = true; Language::memberconstantHandler(n); wrapping_member_flag = false; return SWIG_OK; } /* ----------------------------------------------------------------------------- * getOverloadedName() * ----------------------------------------------------------------------------- */ String *getOverloadedName(Node *n) { /* Although PInvoke functions are designed to handle overloaded functions, a C# IntPtr is used for all classes in the SWIG * intermediary class. The intermediary class methods are thus mangled when overloaded to give a unique name. */ String *overloaded_name = NewStringf("%s", Getattr(n,"sym:name")); if (Getattr(n,"sym:overloaded")) { Printv(overloaded_name, Getattr(n,"sym:overname"), NIL); } return overloaded_name; } /* ----------------------------------------------------------------------------- * moduleClassFunctionHandler() * ----------------------------------------------------------------------------- */ void moduleClassFunctionHandler(Node *n) { SwigType *t = Getattr(n,"type"); ParmList *l = Getattr(n,"parms"); String *tm; Parm *p; int i; String *imcall = NewString(""); String *return_type = NewString(""); String *function_code = NewString(""); int num_arguments = 0; int num_required = 0; String *overloaded_name = getOverloadedName(n); String *func_name = NULL; bool setter_flag = false; if (l) { if (SwigType_type(Getattr(l,"type")) == T_VOID) { l = nextSibling(l); } } /* Attach the non-standard typemaps to the parameter list */ Swig_typemap_attach_parms("cstype", l, NULL); Swig_typemap_attach_parms("csin", l, NULL); /* Get return types */ if ((tm = Swig_typemap_lookup_new("cstype",n,"",0))) { substituteClassname(t, tm); Printf(return_type, "%s", tm); } else { Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(t,0)); } /* Change function name for global variables */ if (proxy_flag && global_variable_flag) { // Capitalize the first letter in the variable to create the getter/setter function name func_name = NewString(""); setter_flag = (Cmp(Getattr(n,"sym:name"), Swig_name_set(variable_name)) == 0); if(setter_flag) Printf(func_name,"set"); else Printf(func_name,"get"); Putc(toupper((int) *Char(variable_name)), func_name); Printf(func_name, "%s", Char(variable_name)+1); } else { func_name = Copy(Getattr(n,"sym:name")); } /* Start generating the function */ const String *methodmods = Getattr(n,"feature:cs:methodmodifiers"); methodmods = methodmods ? methodmods : (is_protected(n) ? protected_string : public_string); Printf(function_code, " %s static %s %s(", methodmods, return_type, func_name); Printv(imcall, imclass_name, ".", overloaded_name, "(", NIL); /* Get number of required and total arguments */ num_arguments = emit_num_arguments(l); num_required = emit_num_required(l); int gencomma = 0; /* Output each parameter */ for (i = 0, p=l; i < num_arguments; i++) { /* Ignored parameters */ while (checkAttribute(p,"tmap:in:numinputs","0")) { p = Getattr(p,"tmap:in:next"); } SwigType *pt = Getattr(p,"type"); String *param_type = NewString(""); /* Get the C# parameter type */ if ((tm = Getattr(p,"tmap:cstype"))) { substituteClassname(pt, tm); Printf(param_type, "%s", tm); } else { Swig_warning(WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF, input_file, line_number, "No cstype typemap defined for %s\n", SwigType_str(pt,0)); } if (gencomma) Printf(imcall, ", "); String *arg = makeParameterName(n, p, i); // Use typemaps to transform type used in C# wrapper function (in proxy class) to type used in PInvoke function (in intermediary class) if ((tm = Getattr(p,"tmap:csin"))) { addThrows(n, "tmap:csin", p); substituteClassname(pt, tm); Replaceall(tm, "$csinput", arg); Printv(imcall, tm, NIL); } else { Swig_warning(WARN_CSHARP_TYPEMAP_CSIN_UNDEF, input_file, line_number, "No csin typemap defined for %s\n", SwigType_str(pt,0)); } /* Add parameter to module class function */ if (gencomma >= 2) Printf(function_code, ", "); gencomma = 2; Printf(function_code, "%s %s", param_type, arg); p = Getattr(p,"tmap:in:next"); Delete(arg); Delete(param_type); } Printf(imcall, ")"); Printf(function_code, ")"); // Transform return type used in PInvoke function (in intermediary class) to type used in C# wrapper function (in module class) if ((tm = Swig_typemap_lookup_new("csout",n,"",0))) { addThrows(n, "tmap:csout", n); if (Getattr(n,"feature:new")) Replaceall(tm,"$owner","true"); else Replaceall(tm,"$owner","false"); substituteClassname(t, tm); Replaceall(tm, "$imcall", imcall); } else { Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csout typemap defined for %s\n", SwigType_str(t,0)); } generateThrowsClause(n, function_code); Printf(function_code, " %s\n\n", tm ? tm : empty_string); if (proxy_flag && global_variable_flag) { // Properties if(setter_flag) { // Setter method if ((tm = Swig_typemap_lookup_new("csvarin",n,"",0))) { if (Getattr(n,"feature:new")) Replaceall(tm,"$owner","true"); else Replaceall(tm,"$owner","false"); substituteClassname(t, tm); Replaceall(tm, "$imcall", imcall); Printf(module_class_code, "%s", tm); } else { Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csvarin typemap defined for %s\n", SwigType_str(t,0)); } } else { // Getter method if ((tm = Swig_typemap_lookup_new("csvarout",n,"",0))) { if (Getattr(n,"feature:new")) Replaceall(tm,"$owner","true"); else Replaceall(tm,"$owner","false"); substituteClassname(t, tm); Replaceall(tm, "$imcall", imcall); Printf(module_class_code, "%s", tm); } else { Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csvarout typemap defined for %s\n", SwigType_str(t,0)); } } } else { // Normal function call Printv(module_class_code, function_code, NIL); } Delete(function_code); Delete(return_type); Delete(imcall); Delete(func_name); } /* ----------------------------------------------------------------------------- * substituteClassname() * * Substitute $csclassname with the proxy class name for classes/structs/unions that SWIG knows about. * Otherwise use the $descriptor name for the C# class name. Note that the $&csclassname substitution * is the same as a $&descriptor substitution, ie one pointer added to descriptor name. * Inputs: * pt - parameter type * tm - cstype typemap * Outputs: * tm - cstype typemap with $csclassname substitution * Return: * substitution_performed - flag indicating if a substitution was performed * ----------------------------------------------------------------------------- */ bool substituteClassname(SwigType *pt, String *tm) { bool substitution_performed = false; if (Strstr(tm, "$csclassname") || Strstr(tm,"$&csclassname")) { String *classname = getProxyName(pt); if (classname) { Replaceall(tm,"$&csclassname", classname); // getProxyName() works for pointers to classes too Replaceall(tm,"$csclassname", classname); } else { // use $descriptor if SWIG does not know anything about this type. Note that any typedefs are resolved. String *descriptor = NULL; SwigType *type = Copy(SwigType_typedef_resolve_all(pt)); if (Strstr(tm, "$&csclassname")) { SwigType_add_pointer(type); descriptor = NewStringf("SWIGTYPE%s", SwigType_manglestr(type)); Replaceall(tm, "$&csclassname", descriptor); } else { // $csclassname descriptor = NewStringf("SWIGTYPE%s", SwigType_manglestr(type)); Replaceall(tm, "$csclassname", descriptor); } // Add to hash table so that the type wrapper classes can be created later Setattr(swig_types_hash, descriptor, type); Delete(descriptor); Delete(type); } substitution_performed = true; } return substitution_performed; } /* ----------------------------------------------------------------------------- * makeParameterName() * * Inputs: * n - Node * p - parameter node * arg_num - parameter argument number * Return: * arg - a unique parameter name * ----------------------------------------------------------------------------- */ String *makeParameterName(Node *n, Parm *p, int arg_num) { // Use C parameter name unless it is a duplicate or an empty parameter name String *pn = Getattr(p,"name"); int count = 0; ParmList *plist = Getattr(n,"parms"); while (plist) { if ((Cmp(pn, Getattr(plist,"name")) == 0)) count++; plist = nextSibling(plist); } String *arg = (!pn || (count > 1)) ? NewStringf("arg%d",arg_num) : Copy(Getattr(p,"name")); return arg; } /* ----------------------------------------------------------------------------- * emitTypeWrapperClass() * ----------------------------------------------------------------------------- */ void emitTypeWrapperClass(String *classname, SwigType *type) { String *swigtype = NewString(""); String *filen = NewStringf("%s%s.cs", SWIG_output_directory(), classname); File *f_swigtype = NewFile(filen,"w"); if(!f_swigtype) { Printf(stderr,"Unable to open %s\n", filen); SWIG_exit(EXIT_FAILURE); } Delete(filen); filen = NULL; // Emit banner and package name emitBanner(f_swigtype); if(Len(package) > 0) Printf(f_swigtype, "//package %s;\n\n", package); // Pure C# baseclass and interfaces const String *pure_baseclass = typemapLookup("csbase", type, WARN_NONE); const String *pure_interfaces = typemapLookup("csinterfaces", type, WARN_NONE); // Emit the class Printv(swigtype, typemapLookup("csimports", type, WARN_NONE), // Import statements "\n", typemapLookup("csclassmodifiers", type, WARN_CSHARP_TYPEMAP_CLASSMOD_UNDEF), // Class modifiers " class $csclassname", // Class name and bases *Char(pure_baseclass) ? " : " : "", pure_baseclass, *Char(pure_interfaces) ? // Interfaces " : " : "", pure_interfaces, " {\n", " private IntPtr swigCPtr;\n", "\n", " ", typemapLookup("csptrconstructormodifiers", type, WARN_CSHARP_TYPEMAP_PTRCONSTMOD_UNDEF), // pointer constructor modifiers " $csclassname(IntPtr cPtr, bool bFutureUse) {\n", // Constructor used for wrapping pointers " swigCPtr = cPtr;\n", " }\n", "\n", " protected $csclassname() {\n", // Default constructor " swigCPtr = IntPtr.Zero;\n", " }\n", typemapLookup("csgetcptr", type, WARN_CSHARP_TYPEMAP_GETCPTR_UNDEF), // getCPtr method typemapLookup("cscode", type, WARN_NONE), // extra C# code "}\n", "\n", NIL); Replaceall(swigtype, "$csclassname", classname); Printv(f_swigtype, swigtype, NIL); Close(f_swigtype); Delete(swigtype); } /* ----------------------------------------------------------------------------- * typemapLookup() * ----------------------------------------------------------------------------- */ const String *typemapLookup(const String *op, String *type, int warning, Node *typemap_attributes=NULL) { String *tm = NULL; const String *code = NULL; if((tm = Swig_typemap_search(op, type, NULL, NULL))) { code = Getattr(tm,"code"); if (typemap_attributes) Swig_typemap_attach_kwargs(tm,op,typemap_attributes); } if (!code) { code = empty_string; if (warning != WARN_NONE) Swig_warning(warning, input_file, line_number, "No %s typemap defined for %s\n", op, type); } return code ? code : empty_string; } /* ----------------------------------------------------------------------------- * addThrows() * ----------------------------------------------------------------------------- */ void addThrows(Node *n, const String *typemap, Node *parameter) { // Get the comma separated throws clause - held in "throws" attribute in the typemap passed in String *throws_attribute = NewStringf("%s:throws", typemap); String *throws = Getattr(parameter,throws_attribute); if (throws) { String *throws_list = Getattr(n,"csharp:throwslist"); if (!throws_list) { throws_list = NewList(); Setattr(n,"csharp:throwslist", throws_list); } // Put the exception classes in the throws clause into a temporary List List *temp_classes_list = Split(throws,',',INT_MAX); // Add the exception classes to the node throws list, but don't duplicate if already in list if (temp_classes_list && Len(temp_classes_list) > 0) { for (Iterator cls = First(temp_classes_list); cls.item; cls = Next(cls)) { String *exception_class = NewString(cls.item); Replaceall(exception_class," ",""); // remove spaces Replaceall(exception_class,"\t",""); // remove tabs if (Len(exception_class) > 0) { // $csclassname substitution SwigType *pt = Getattr(parameter,"type"); substituteClassname(pt, exception_class); // Don't duplicate the C# exception class in the throws clause bool found_flag = false; for (Iterator item = First(throws_list); item.item; item = Next(item)) { if (Strcmp(item.item, exception_class) == 0) found_flag = true; } if (!found_flag) Append(throws_list, exception_class); } Delete(exception_class); } } Delete(temp_classes_list); } Delete(throws_attribute); } /* ----------------------------------------------------------------------------- * generateThrowsClause() * ----------------------------------------------------------------------------- */ void generateThrowsClause(Node *n, String *code) { // Add the throws clause into code List *throws_list = Getattr(n,"csharp:throwslist"); if (throws_list) { Iterator cls = First(throws_list); Printf(code, " throws %s", cls.item); while ( (cls = Next(cls)).item) Printf(code, ", %s", cls.item); } } }; /* class CSHARP */ /* ----------------------------------------------------------------------------- * swig_csharp() - Instantiate module * ----------------------------------------------------------------------------- */ static Language * new_swig_csharp() { return new CSHARP(); } extern "C" Language * swig_csharp(void) { return new_swig_csharp(); } /* ----------------------------------------------------------------------------- * Static member variables * ----------------------------------------------------------------------------- */ const char *CSHARP::usage = (char*)"\ C# Options (available with -csharp)\n\ -package - set name of the assembly to \n\ -noproxy - Generate the low-level functional interface instead\n\ of proxy classes\n\ \n"; cableswig-0.1.0+git20150808.orig/SWIG/Source/Modules/utils.cxx0000644000175000000620000000173212561312227022335 0ustar stevestaff #include int is_public(Node* n) { String* access = Getattr(n, "access"); return !access || !Cmp(access, "public"); } int is_private(Node* n) { String* access = Getattr(n, "access"); return access && !Cmp(access, "private"); } int is_protected(Node* n) { String* access = Getattr(n, "access"); return access && !Cmp(access, "protected"); } int is_member_director(Node* parentnode, Node* member) { if (checkAttribute(member,"director","1")) return 1; if (parentnode && checkAttribute(member, "storage", "virtual")) { int parent_director = checkAttribute(parentnode,"feature:director","1"); int cdecl_director = parent_director || checkAttribute(member,"feature:director","1"); int cdecl_nodirector = checkAttribute(member,"feature:nodirector","1"); return cdecl_director && !cdecl_nodirector; } else { return 0; } } int is_member_director(Node* member) { return is_member_director(Getattr(member, "parentNode"), member); } cableswig-0.1.0+git20150808.orig/SWIG/Source/Modules/README0000644000175000000620000000047212561312227021331 0ustar stevestaff06/25/2002 This directory contains all of the SWIG language modules. Many of these modules contain code that dates back to SWIG1.0. The module API has changed a lot in the development releases so this is fairly messy. We're working on cleaning it up, but you'll have to bear with us until it's done. -- Dave cableswig-0.1.0+git20150808.orig/SWIG/Source/Modules/xml.cxx0000644000175000000620000001616712561312227022005 0ustar stevestaff/* ----------------------------------------------------------------------------- * Xml.cxx * * An Xml parse tree generator * Author(s) : Swig base: David Beazley (beazley@cs.uchicago.edu) * Xml module: Klaus Wiederaenders (kwconsulting@compuserve.com * * Copyright (C) 2002. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_xml_cxx[] = "/cvsroot/SWIG/Source/Modules/xml.cxx,v 1.10 2004/01/22 22:42:18 cheetah Exp"; static const char *usage = "\ XML Options (available with -xml)\n\ -xmllang - Typedef language\n\ -xmllite - More lightweight version of XML\n\ ------\n\ deprecated (use -o): -xml - Use as output file (extension .xml mandatory)\n"; #include "swigmod.h" //static Node *view_top = 0; static File *out = 0; static int xmllite = 0; class XML : public Language { public: int indent_level; long id; XML() : indent_level( 0 ) , id( 0 ) { } virtual ~XML() { } virtual void main(int argc, char *argv[]) { SWIG_typemap_lang("xml"); for( int iX = 0; iX < argc; iX++ ) { if( strcmp( argv[iX], "-xml" ) == 0 ) { char * extension = 0; if( iX + 1 >= argc ) continue; extension = argv[iX+1]+strlen(argv[iX+1])-4; if( strcmp( extension, ".xml" ) ) continue; iX++; Swig_mark_arg (iX); String * outfile = NewString( argv[iX] ); out = NewFile(outfile,"w"); if (!out) { Printf(stderr,"*** Can't open '%s'\n", outfile); SWIG_exit(EXIT_FAILURE); } continue; } if( strcmp( argv[iX], "-xmllang" ) == 0 ) { Swig_mark_arg (iX); iX++; SWIG_typemap_lang(argv[iX]); Swig_mark_arg (iX); continue; } if( strcmp( argv[iX], "-help" ) == 0 ) { fputs( usage, stderr ); } if( strcmp( argv[iX], "-xmllite" ) == 0 ) { Swig_mark_arg (iX); xmllite = 1; } } // Add a symbol to the parser for conditional compilation Preprocessor_define("SWIGXML 1",0); } /* Top of the parse tree */ virtual int top(Node *n) { if( out == 0 ) { String *outfile = Getattr(n,"outfile"); Replaceall(outfile,".cxx", ".xml"); Replaceall(outfile,".cpp", ".xml"); Replaceall(outfile,".c", ".xml"); out = NewFile(outfile,"w"); if (!out) { Printf(stderr,"*** Can't open '%s'\n", outfile); SWIG_exit(EXIT_FAILURE); } } Printf( out, " \n" ); Xml_print_tree(n); return SWIG_OK; } void print_indent(int l) { int i; for (i = 0; i < indent_level; i++) { Printf(out, " "); } if (l) { Printf(out, " "); } } void Xml_print_tree(DOH *obj) { while (obj) { Xml_print_node(obj); obj = nextSibling(obj); } } void Xml_print_attributes(Node * obj) { String *k; indent_level += 4; print_indent(0); Printf( out, "\n", ++id, obj ); indent_level += 4; Iterator ki; ki = First(obj); while (ki.key) { k = ki.key; if ((Cmp(k,"nodeType") == 0) || (Cmp(k,"firstChild") == 0) || (Cmp(k,"lastChild") == 0) || (Cmp(k,"parentNode") == 0) || (Cmp(k,"nextSibling") == 0) || (Cmp(k,"previousSibling") == 0) || (*(Char(k)) == '$')) { /* Do nothing */ } else if (Cmp(k,"module") == 0) { Xml_print_module( Getattr(obj,k) ); } else if (Cmp(k,"baselist") == 0) { Xml_print_baselist( Getattr(obj,k) ); } else if (!xmllite && Cmp(k,"typescope") == 0) { Xml_print_typescope( Getattr(obj,k) ); } else if (!xmllite && Cmp(k,"typetab") == 0) { Xml_print_typetab( Getattr(obj,k) ); } else if (Cmp(k,"kwargs") == 0) { Xml_print_kwargs( Getattr(obj,k) ); } else if (Cmp(k,"parms") == 0 || Cmp(k, "pattern") == 0 ) { Xml_print_parmlist( Getattr(obj,k) ); } else { DOH *o; print_indent(0); if (DohIsString(Getattr(obj,k))) { String *ck = NewString(k); o = Str(Getattr(obj,k)); Replaceall( ck, ":", "_" ); /* Do first to avoid aliasing errors. */ Replaceall( o, "&", "&" ); Replaceall( o, "<", "<" ); Replaceall( o, "\"", """ ); Replaceall( o, "\\", "\\\\" ); Printf(out,"\n", ck, o, ++id, o ); Delete(o); Delete(ck); } else { o = Getattr(obj,k); String *ck = NewString(k); Replaceall( ck, ":", "_" ); Printf(out,"\n", ck, o, ++id, o ); Delete(ck); } } ki = Next(ki); } indent_level -= 4; print_indent(0); Printf( out, "\n" ); indent_level -= 4; } void Xml_print_node(Node *obj) { Node *cobj; print_indent(0); Printf(out,"<%s id=\"%ld\" addr=\"%x\" >\n", nodeType(obj), ++id, obj); Xml_print_attributes( obj ); cobj = firstChild(obj); if (cobj) { indent_level += 4; Printf(out,"\n"); Xml_print_tree(cobj); indent_level -= 4; } else { print_indent(1); Printf(out,"\n"); } print_indent(0); Printf(out,"\n", nodeType(obj)); } void Xml_print_parmlist(ParmList *p) { print_indent(0); Printf( out, "\n", ++id, p ); indent_level += 4; while(p) { print_indent(0); Printf( out, "\n", ++id ); Xml_print_attributes( p ); print_indent(0); Printf( out, "\n" ); p = nextSibling(p); } indent_level -= 4; print_indent(0); Printf( out, "\n" ); } void Xml_print_baselist(List *p) { print_indent(0); Printf( out, "\n", ++id, p ); indent_level += 4; Iterator s; for (s = First(p); s.item; s = Next(s)) { print_indent(0); Printf( out, "\n", s.item, ++id, s.item ); } indent_level -= 4; print_indent(0); Printf( out, "\n" ); } void Xml_print_module(Node *p) { print_indent(0); Printf( out, "\n", Getattr( p, "name"), ++id, p ); } void Xml_print_kwargs(Hash *p) { Xml_print_hash( p, "kwargs" ); } void Xml_print_typescope(Hash *p) { Xml_print_hash( p, "typescope" ); } void Xml_print_typetab(Hash *p) { Xml_print_hash( p, "typetab" ); } void Xml_print_hash(Hash *p, const char * markup) { print_indent(0); Printf( out, "<%s id=\"%ld\" addr=\"%x\" >\n", markup, ++id, p ); Xml_print_attributes( p ); indent_level += 4; Iterator n = First(p); while(n.key) { print_indent(0); Printf( out, "<%ssitem id=\"%ld\" addr=\"%x\" >\n", markup, ++id, n.item ); Xml_print_attributes( n.item ); Printf( out, "\n", markup ); print_indent(0); Printf( out, " />\n" ); n = Next(n); } indent_level -= 4; print_indent(0); Printf( out, "\n", markup ); } }; static Language * new_swig_xml() { return new XML(); } extern "C" Language * swig_xml( void ) { return new_swig_xml(); } cableswig-0.1.0+git20150808.orig/SWIG/Source/CParse/0002755000175000000620000000000012561312227020215 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Source/CParse/templ.c0000644000175000000620000003470412561312227021510 0ustar stevestaff/* ----------------------------------------------------------------------------- * templ.c * * Expands a template into a specialized version. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_templ_c[] = "/cvsroot/SWIG/Source/CParse/templ.c,v 1.10 2004/01/15 08:33:10 mmatus Exp"; #include "swig.h" #include "cparse.h" static int template_debug = 0; static void add_parms(ParmList *p, List *patchlist, List *typelist) { while (p) { SwigType *ty = Getattr(p,"type"); SwigType *val = Getattr(p,"value"); Append(typelist,ty); Append(patchlist,val); p = nextSibling(p); } } void Swig_cparse_debug_templates(int x) { template_debug = x; } /* ----------------------------------------------------------------------------- * Swig_cparse_template_expand() * * Expands a template node into a specialized version. This is done by * patching typenames and other aspects of the node according to a list of * template parameters * ----------------------------------------------------------------------------- */ static int cparse_template_expand(Node *n, String *tname, String *rname, String *templateargs, List *patchlist, List *typelist, List *cpatchlist) { static int expanded = 0; int ret; if (!n) return 0; if (Getattr(n,"error")) return 0; if (Strcmp(nodeType(n),"template") == 0) { /* Change the node type back to normal */ if (!expanded) { expanded = 1; set_nodeType(n,Getattr(n,"templatetype")); ret = cparse_template_expand(n,tname, rname, templateargs, patchlist,typelist, cpatchlist); expanded = 0; return ret; } else { /* Called when template appears inside another template */ /* Member templates */ set_nodeType(n,Getattr(n,"templatetype")); ret = cparse_template_expand(n,tname, rname, templateargs, patchlist,typelist, cpatchlist); set_nodeType(n,"template"); return ret; } } else if (Strcmp(nodeType(n),"cdecl") == 0) { /* A simple C declaration */ SwigType *t, *v, *d; String *code; t = Getattr(n,"type"); v = Getattr(n,"value"); d = Getattr(n,"decl"); code = Getattr(n,"code"); Append(typelist,t); Append(typelist,d); Append(patchlist,v); Append(cpatchlist,code); if (Getattr(n,"conversion_operator")) { Append(cpatchlist, Getattr(n,"name")); if (Getattr(n,"sym:name")) { Append(cpatchlist, Getattr(n,"sym:name")); } } add_parms(Getattr(n,"parms"), cpatchlist, typelist); add_parms(Getattr(n,"throws"), cpatchlist, typelist); } else if (Strcmp(nodeType(n),"class") == 0) { /* Patch base classes */ { List *bases = Getattr(n,"baselist"); if (bases) { int i; for (i = 0; i < Len(bases); i++) { String *name = Copy(Getitem(bases,i)); Setitem(bases,i,name); Append(typelist,name); } } } /* Patch children */ { Node *cn = firstChild(n); while (cn) { cparse_template_expand(cn,tname, rname, templateargs, patchlist,typelist,cpatchlist); cn = nextSibling(cn); } } } else if (Strcmp(nodeType(n),"constructor") == 0) { String *name = Getattr(n,"name"); if (!(Getattr(n,"templatetype"))) { String *symname; String *stripped_name = SwigType_templateprefix(name); if (Strstr(tname,stripped_name)) { Replaceid(name,stripped_name,tname); } Delete(stripped_name); symname = Getattr(n,"sym:name"); if (symname) { stripped_name = SwigType_templateprefix(symname); if (Strstr(tname,stripped_name)) { Replaceid(symname,stripped_name,tname); } Delete(stripped_name); } if (Strstr(name,"<")) { Append(patchlist,Getattr(n,"name")); } else { Append(name,templateargs); } name = Getattr(n,"sym:name"); if (name && (Strstr(name,"<"))) { Clear(name); Append(name,rname); } else { Replace(name,tname,rname, DOH_REPLACE_ANY); } Setattr(n,"sym:name",name); } Append(cpatchlist,Getattr(n,"code")); Append(typelist, Getattr(n,"decl")); add_parms(Getattr(n,"parms"), cpatchlist, typelist); add_parms(Getattr(n,"throws"), cpatchlist, typelist); } else if (Strcmp(nodeType(n),"destructor") == 0) { String *name = Getattr(n,"name"); if (Strstr(name,"<")) { Append(patchlist,Getattr(n,"name")); } else { Append(name,templateargs); } name = Getattr(n,"sym:name"); if (name && Strstr(name,"<")) { Setattr(n,"sym:name", Copy(tname)); } else { Replace(name,tname,rname, DOH_REPLACE_ANY); } Setattr(n,"sym:name",name); Append(cpatchlist,Getattr(n,"code")); } else if (Strcmp(nodeType(n),"using") == 0) { String *uname = Getattr(n,"uname"); if (uname) { if (Strstr(uname,"<")) { Append(patchlist, uname); } } if (Getattr(n,"namespace")) { /* Namespace link. This is nasty. Is other namespace defined? */ } } else { /* Look for obvious parameters */ Node *cn; Append(cpatchlist,Getattr(n,"code")); Append(typelist, Getattr(n,"type")); Append(typelist, Getattr(n,"decl")); add_parms(Getattr(n,"parms"), cpatchlist, typelist); add_parms(Getattr(n,"pattern"), cpatchlist, typelist); add_parms(Getattr(n,"throws"), cpatchlist, typelist); cn = firstChild(n); while (cn) { cparse_template_expand(cn,tname, rname, templateargs, patchlist, typelist, cpatchlist); cn = nextSibling(cn); } } return 0; } static String *partial_arg(String *s, String *p) { char *c; String *prefix; String *newarg; /* Find the prefix on the partial argument */ c = Strstr(p,"$"); if (!c) { return NewString(s); } prefix = NewStringWithSize(Char(p),c-Char(p)); newarg = NewString(s); Replace(newarg,prefix,"",DOH_REPLACE_ANY | DOH_REPLACE_FIRST); Delete(prefix); return newarg; } int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms) { List *patchlist, *cpatchlist, *typelist; String *templateargs; String *tname; String *iname; String *tbase; patchlist = NewList(); cpatchlist = NewList(); typelist = NewList(); { String *tmp = NewString(""); if (tparms) { SwigType_add_template(tmp,tparms); } templateargs = Copy(tmp); Delete(tmp); } tname = Copy(Getattr(n,"name")); tbase = Swig_scopename_last(tname); /* Look for partial specialization matching */ if (Getattr(n,"partialargs")) { Parm *p, *tp; ParmList *ptargs = SwigType_function_parms(Getattr(n,"partialargs")); p = ptargs; tp = tparms; while (p && tp) { SwigType *ptype; SwigType *tptype; SwigType *partial_type; ptype = Getattr(p,"type"); tptype = Getattr(tp,"type"); if (ptype && tptype) { partial_type = partial_arg(tptype,ptype); /* Printf(stdout,"partial '%s' '%s' ---> '%s'\n", tptype, ptype, partial_type); */ Setattr(tp,"type",partial_type); } p = nextSibling(p); tp = nextSibling(tp); } assert(ParmList_len(ptargs) == ParmList_len(tparms)); } if (0) { Parm *p = tparms; while (p) { Printf(stdout,"tparm: '%s' '%s' '%s'\n", Getattr(p,"name"), Getattr(p,"type"), Getattr(p,"value")); p = nextSibling(p); } } /* Printf(stdout,"targs = '%s'\n", templateargs); Printf(stdout,"rname = '%s'\n", rname); Printf(stdout,"tname = '%s'\n", tname); */ cparse_template_expand(n,tname, rname, templateargs, patchlist, typelist, cpatchlist); /* Set the name */ { String *name = Getattr(n,"name"); if (name) { Append(name,templateargs); } iname = name; } /* Patch all of the types */ { Parm *tp = Getattr(n,"templateparms"); Parm *p = tparms; /* Printf(stdout,"%s\n", ParmList_str(tp)); */ if (tp) { while (p && tp) { String *name, *value, *valuestr, *tydef, *tmp, *tmpr; int sz, i; name = Getattr(tp,"name"); value = Getattr(p,"value"); tydef = Getattr(p,"typedef"); if (name) { if (!value) { value = Getattr(p,"type"); valuestr = SwigType_str(value,0); } else { valuestr = SwigType_namestr(value); } /* Printf(stdout,"valuestr = '%s'\n", valuestr); */ assert(value); /* Need to patch default arguments */ { Parm *rp = nextSibling(p); while (rp) { String *rvalue = Getattr(rp,"value"); if (rvalue) { Replace(rvalue,name,value, DOH_REPLACE_ID); } rp = nextSibling(rp); } } sz = Len(patchlist); for (i = 0; i < sz; i++) { String *s = Getitem(patchlist,i); Replace(s,name,value, DOH_REPLACE_ID); } sz = Len(typelist); for (i = 0; i < sz; i++) { String *s = Getitem(typelist,i); /* Replace(s,name,value, DOH_REPLACE_ID); */ /* Printf(stdout,"name = '%s', value = '%s', tbase = '%s', iname='%s' s = '%s' --> ", name, value, tbase, iname, s); */ SwigType_typename_replace(s,name,value); SwigType_typename_replace(s,tbase,iname); /* Printf(stdout,"'%s'\n", s);*/ } if (!tydef) { tydef = value; } tmp = NewStringf("#%s",name); tmpr = NewStringf("\"%s\"", value); sz = Len(cpatchlist); for (i = 0; i < sz; i++) { String *s = Getitem(cpatchlist,i); Replace(s,tmp,tmpr, DOH_REPLACE_ID); /* Replace(s,name,tydef, DOH_REPLACE_ID); */ Replace(s,name,valuestr, DOH_REPLACE_ID); } Delete(tmp); Delete(tmpr); Delete(valuestr); } p = nextSibling(p); tp = nextSibling(tp); if (!p) p = tp; } } else { /* No template parameters at all. This could be a specialization */ int i, sz; sz = Len(typelist); for (i = 0; i < sz; i++) { String *s = Getitem(typelist,i); SwigType_typename_replace(s,tbase,iname); } } } /* Patch bases */ { List *bases = Getattr(n,"baselist"); if (bases) { Iterator b; for (b = First(bases); b.item; b = Next(b)) { String *qn = Swig_symbol_type_qualify(b.item,0); Clear(b.item); Append(b.item,qn); } } } Delete(patchlist); Delete(cpatchlist); Delete(typelist); Delete(tbase); /* set_nodeType(n,"template");*/ return 0; } /* ----------------------------------------------------------------------------- * cparse_template_locate() * * Search for a template that matches name with given parameters. * ----------------------------------------------------------------------------- */ Node * Swig_cparse_template_locate(String *name, Parm *tparms) { Node *n; String *tname, *rname = 0; Node *templ; List *mpartials = 0; Parm *p; Parm *parms; tname = NewString(name); parms = CopyParmList(tparms); p = parms; while (p) { SwigType *ty = Getattr(p,"type"); if (ty) { SwigType *nt = Swig_symbol_typedef_reduce(ty,0); nt = Swig_symbol_type_qualify(nt,0); Setattr(p,"type",nt); } p = nextSibling(p); } SwigType_add_template(tname,parms); if (template_debug) { Printf(stdout,"\n%s:%d: template_debug: Searching for %s\n", cparse_file, cparse_line, tname); } /* Search for an exact specialization. Example: template<> class name { ... } */ { if (template_debug) { Printf(stdout," searching: '%s' (exact specialization)\n", tname); } n = Swig_symbol_clookup_local(tname,0); if (n) { Node *tn; if (Strcmp(nodeType(n),"template") == 0) goto success; tn = Getattr(n,"template"); if (tn) { n = tn; goto success; /* Previously wrapped by a template return that */ } Swig_error(cparse_file, cparse_line, "'%s' is not defined as a template. (%s)\n", name, nodeType(n)); Delete(tname); Delete(parms); return 0; /* Found a match, but it's not a template of any kind. */ } } /* Search for generic template */ templ = Swig_symbol_clookup_local(name,0); /* Search for partial specialization. Example: template class name { ... } */ /* Generate reduced template name (stripped of extraneous pointers, etc.) */ rname = NewStringf("%s<(",name); p = parms; while (p) { String *t; t = Getattr(p,"type"); if (t) { String *tbase = SwigType_base(t); t = SwigType_default(t); Replaceid(t,"SWIGTYPE",tbase); Replaceid(t,"SWIGENUM",tbase); Printf(rname,"%s",t); Delete(t); } else { String *v = Getattr(p,"value"); Printf(rname,"%s",v); } p = nextSibling(p); if (p) { Printf(rname,","); } } Printf(rname,")>"); mpartials = NewList(); if (templ) { /* First, we search using an exact type prototype */ Parm *p; char tmp[32]; int i; List *partials; String *ss; Iterator pi; partials = Getattr(templ,"partials"); if (partials) { for (pi = First(partials); pi.item; pi = Next(pi)) { ss = Copy(pi.item); p = parms; i = 1; while (p) { String *t,*tn; sprintf(tmp,"$%d",i); t = Getattr(p,"type"); if (t) { tn = SwigType_base(t); Replaceid(ss,tmp,tn); Delete(tn); } else { String *v = Getattr(p,"value"); Replaceid(ss,tmp,v); } i++; p = nextSibling(p); } if (template_debug) { Printf(stdout," searching: '%s' (partial specialization - %s)\n", ss, pi.item); } if ((Strcmp(ss,tname) == 0) || (Strcmp(ss,rname) == 0)) { Append(mpartials,pi.item); } Delete(ss); } } } if (template_debug) { Printf(stdout," Matched partials: %s\n", mpartials); } if (Len(mpartials)) { String *s = Getitem(mpartials,0); n = Swig_symbol_clookup_local(s,0); if (Len(mpartials) > 1) { if (n) { Swig_warning(WARN_PARSE_TEMPLATE_AMBIG,cparse_file,cparse_line, "Instantiation of template '%s' is ambiguous,\n", SwigType_namestr(tname)); Swig_warning(WARN_PARSE_TEMPLATE_AMBIG,Getfile(n),Getline(n), " instantiation '%s' is used.\n", SwigType_namestr(Getattr(n,"name"))); } } } if (!n) { n = templ; } if (!n) { Swig_error(cparse_file, cparse_line, "Template '%s' undefined.\n", name); } else if (n && (Strcmp(nodeType(n),"template") != 0)) { Swig_error(cparse_file, cparse_line, "'%s' is not defined as a template. (%s)\n", name, nodeType(n)); n = 0; } success: Delete(tname); Delete(rname); Delete(mpartials); if ((template_debug) && (n)) { Printf(stdout,"Node: %x\n", n); Swig_print_node(n); } Delete(parms); return n; } cableswig-0.1.0+git20150808.orig/SWIG/Source/CParse/util.c0000644000175000000620000001435412561312227021343 0ustar stevestaff/* ----------------------------------------------------------------------------- * util.c * * Parsing utilities * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_util_c[] = "/cvsroot/SWIG/Source/CParse/util.c,v 1.9 2004/01/15 08:16:52 mmatus Exp"; #include "swig.h" #include "cparse.h" /* ----------------------------------------------------------------------------- * Swig_cparse_replace_descriptor() * * Replaces type descriptor string $descriptor() with the SWIG type descriptor * string. * ----------------------------------------------------------------------------- */ void Swig_cparse_replace_descriptor(String *s) { char tmp[512]; String *arg = 0; SwigType *t; while (Strstr(s,"$descriptor(")) { char *d = tmp; int level = 0; char *c = Strstr(s,"$descriptor("); while (*c) { if (*c == '(') level++; if (*c == ')') { level--; if (level == 0) { break; } } *d = *c; d++; c++; } *d = 0; arg = NewString(tmp+12); t = Swig_cparse_type(arg); Delete(arg); arg = 0; if (t) { String *mangle; String *descriptor; mangle = SwigType_manglestr(t); descriptor = NewStringf("SWIGTYPE%s",mangle); SwigType_remember(t); *d = ')'; d++; *d = 0; Replace(s,tmp,descriptor,DOH_REPLACE_ANY); Delete(mangle); Delete(descriptor); } else { Swig_error(Getfile(s),Getline(s),"Bad $descriptor() macro.\n"); break; } } } /* ----------------------------------------------------------------------------- * cparse_normalize_void() * * This function is used to replace arguments of the form (void) with empty * arguments in C++ * ----------------------------------------------------------------------------- */ void cparse_normalize_void(Node *n) { String *decl = Getattr(n,"decl"); Parm *parms = Getattr(n,"parms"); if (SwigType_isfunction(decl)) { if ((ParmList_len(parms) == 1) && (SwigType_type(Getattr(parms,"type")) == T_VOID)) { Replaceall(decl,"f(void).","f()."); Delattr(n,"parms"); } } } /* ----------------------------------------------------------------------------- * int need_protected(Node* n, int dirprot_mode) * * Detects when we need to fully register the protected member. * * ----------------------------------------------------------------------------- */ int need_protected(Node* n, int dirprot_mode) { if (!(Swig_need_protected() || dirprot_mode)) return 0; /* First, 'n' looks like a function */ if ((Strcmp(nodeType(n),"cdecl") == 0) && SwigType_isfunction(Getattr(n,"decl"))) { String *storage = Getattr(n,"storage"); /* and the function is declared like virtual, or it has no storage. This eliminates typedef, static and so on. */ return (!storage || (Strcmp(storage,"virtual") == 0)); } return 0; } /* ----------------------------------------------------------------------------- * int need_name_warning(Node *n) * * Detects if a node needs name warnings * * ----------------------------------------------------------------------------- */ int need_name_warning(Node *n) { int need = 1; /* we don't use name warnings for: - class forwards, no symbol is generated at the target language. - template declarations, only for real instances using %template(name). - typedefs, they have no effect at the target language. */ if (Strcmp(nodeType(n),"classforward") == 0) { need = 0; } else if (Getattr(n,"templatetype")) { need = 0; } else { String *storage = Getattr(n,"storage"); if (storage && (Strcmp(storage,"typedef") == 0)) { need = 0; } } return need; } int are_equivalent_nodes(Node* a, Node* b, int a_inclass) { /* they must have the same type */ SwigType *ta = nodeType(a); SwigType *tb = nodeType(b); if (Cmp(ta, tb) != 0) return 0; /* cdecl case */ if (Cmp(ta, "cdecl") == 0) { /* typedef */ String *a_storage = Getattr(a,"storage"); String *b_storage = Getattr(b,"storage"); if ((Cmp(a_storage,"typedef") == 0) || (Cmp(b_storage,"typedef") == 0)) { if (Cmp(a_storage, b_storage) == 0) { String *a_type = (Getattr(a,"type")); String *b_type = (Getattr(b,"type")); if (Cmp(a_type, b_type) == 0) return 1; } return 0; } /* static functions */ if ((Cmp(a_storage, "static") == 0) || (Cmp(b_storage, "static") == 0)) { if (Cmp(a_storage, b_storage) != 0) return 0; } if (!a_inclass || (Cmp(a_storage,"friend") == 0)) { /* check declaration */ String *a_decl = (Getattr(a,"decl")); String *b_decl = (Getattr(b,"decl")); if (Cmp(a_decl, b_decl) == 0) { /* check return type */ String *a_type = (Getattr(a,"type")); String *b_type = (Getattr(b,"type")); if (Cmp(a_type, b_type) == 0) { /* check parameters */ Parm *ap = (Getattr(a,"parms")); Parm *bp = (Getattr(b,"parms")); int la = Len(ap); int lb = Len(bp); if (la != lb) return 0; while (ap && bp) { SwigType *at = Getattr(ap,"type"); SwigType *bt = Getattr(bp,"type"); if (Cmp(at, bt) != 0) return 0; ap = nextSibling(ap); bp = nextSibling(bp); } return 1; } } } } else { /* %constant case */ String *a_storage = Getattr(a,"storage"); String *b_storage = Getattr(b,"storage"); if ((Cmp(a_storage, "%constant") == 0) || (Cmp(b_storage, "%constant") == 0)) { if (Cmp(a_storage, b_storage) == 0) { String *a_type = (Getattr(a,"type")); String *b_type = (Getattr(b,"type")); if ((Cmp(a_type, b_type) == 0) && (Cmp(Getattr(a,"value"), Getattr(b,"value")) == 0)) return 1; } return 0; } } return 0; } int need_redefined_warn(Node* a, Node* b, int InClass) { String *a_symname = Getattr(a,"sym:name"); String *b_symname = Getattr(b,"sym:name"); /* always send a warning if a 'rename' is involved */ if ((a_symname && Cmp(a_symname,Getattr(a,"name"))) || (b_symname && Cmp(b_symname,Getattr(b,"name")))) return 1; return !are_equivalent_nodes(a, b, InClass); } cableswig-0.1.0+git20150808.orig/SWIG/Source/CParse/parser.y0000644000175000000620000042473112561312227021714 0ustar stevestaff%{ /* ----------------------------------------------------------------------------- * parser.y * * YACC parser for SWIG. The grammar is a somewhat broken subset of C/C++. * This file is a bit of a mess and probably needs to be rewritten at * some point. Beware. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1998-2001. The University of Chicago * Copyright (C) 1995-1998. The University of Utah and The Regents of the * University of California. * * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ #define yylex yylex char cvsroot_parser_y[] = "/cvsroot/SWIG/Source/CParse/parser.y,v 1.45 2004/01/27 23:39:34 mmatus Exp"; #include "swig.h" #include "cparse.h" #include "preprocessor.h" #include /* We do this for portability */ #undef alloca #define alloca malloc /* ----------------------------------------------------------------------------- * Externals * ----------------------------------------------------------------------------- */ int yyparse(); /* NEW Variables */ static Node *top = 0; /* Top of the generated parse tree */ static int unnamed = 0; /* Unnamed datatype counter */ static Hash *extendhash = 0; /* Hash table of added methods */ static Hash *classes = 0; /* Hash table of classes */ static Symtab *prev_symtab = 0; static Node *current_class = 0; String *ModuleName = 0; static Node *module_node = 0; static String *Classprefix = 0; static String *Namespaceprefix = 0; static int inclass = 0; static char *last_cpptype = 0; static int inherit_list = 0; static Parm *template_parameters = 0; static int extendmode = 0; static int dirprot_mode = 0; /* ----------------------------------------------------------------------------- * Assist Functions * ----------------------------------------------------------------------------- */ /* Called by the parser (yyparse) when an error is found.*/ static void yyerror (const char *e) { (void)e; } static Node *new_node(const String_or_char *tag) { Node *n = NewHash(); set_nodeType(n,tag); Setfile(n,cparse_file); Setline(n,cparse_line); return n; } /* Copies a node. Does not copy tree links or symbol table data (except for sym:name) */ static Node *copy_node(Node *n) { Node *nn; String *key; Iterator k; nn = NewHash(); Setfile(nn,Getfile(n)); Setline(nn,Getline(n)); for (k = First(n); k.key; k = Next(k)) { key = k.key; if ((Strcmp(key,"nextSibling") == 0) || (Strcmp(key,"previousSibling") == 0) || (Strcmp(key,"parentNode") == 0) || (Strcmp(key,"lastChild") == 0)) { continue; } if (Strncmp(key,"csym:",5) == 0) continue; /* We do copy sym:name. For templates */ if ((Strcmp(key,"sym:name") == 0) || (Strcmp(key,"sym:weak") == 0) || (Strcmp(key,"sym:typename") == 0)) { Setattr(nn,key, Copy(k.item)); continue; } if (Strcmp(key,"sym:symtab") == 0) { Setattr(nn,"sym:needs_symtab", "1"); } /* We don't copy any other symbol table attributes */ if (Strncmp(key,"sym:",4) == 0) { continue; } /* If children. We copy them recursively using this function */ if (Strcmp(key,"firstChild") == 0) { /* Copy children */ Node *cn = k.item; while (cn) { appendChild(nn,copy_node(cn)); cn = nextSibling(cn); } continue; } /* We don't copy the symbol table. But we drop an attribute requires_symtab so that functions know it needs to be built */ if (Strcmp(key,"symtab") == 0) { /* Node defined a symbol table. */ Setattr(nn,"requires_symtab","1"); continue; } /* Can't copy nodes */ if (Strcmp(key,"node") == 0) { continue; } if ((Strcmp(key,"parms") == 0) || (Strcmp(key,"pattern") == 0) || (Strcmp(key,"throws") == 0)) { Setattr(nn,key,CopyParmList(k.item)); continue; } /* Looks okay. Just copy the data using Copy */ Setattr(nn, key, Copy(k.item)); } return nn; } /* ----------------------------------------------------------------------------- * Variables * ----------------------------------------------------------------------------- */ char *typemap_lang = 0; /* Current language setting */ static int cplus_mode = 0; static String *class_rename = 0; /* C++ modes */ #define CPLUS_PUBLIC 1 #define CPLUS_PRIVATE 2 #define CPLUS_PROTECTED 3 void SWIG_typemap_lang(const char *tm_lang) { typemap_lang = Swig_copy_string(tm_lang); } /* ----------------------------------------------------------------------------- * Assist functions * ----------------------------------------------------------------------------- */ /* Perform type-promotion for binary operators */ static int promote(int t1, int t2) { return t1 > t2 ? t1 : t2; } static String *yyrename = 0; /* Forward renaming operator */ static Hash *rename_hash = 0; static Hash *namewarn_hash = 0; static Hash *features_hash = 0; static String *feature_identifier_fix(String *s) { if (SwigType_istemplate(s)) { String *tp, *ts, *ta, *tq; tp = SwigType_templateprefix(s); ts = SwigType_templatesuffix(s); ta = SwigType_templateargs(s); tq = Swig_symbol_type_qualify(ta,0); Append(tp,tq); Append(tp,ts); Delete(ts); Delete(ta); Delete(tq); return tp; } else { return NewString(s); } } static void rename_add(char *name, SwigType *decl, char *newname) { String *nname; if (!rename_hash) rename_hash = NewHash(); if (Namespaceprefix) { nname = NewStringf("%s::%s",Namespaceprefix, name); } else { nname = NewString(name); } Swig_name_object_set(rename_hash,nname,decl,NewString(newname)); Delete(nname); } static void namewarn_add(char *name, SwigType *decl, char *warning) { String *nname; if (!namewarn_hash) namewarn_hash = NewHash(); if (Namespaceprefix) { nname = NewStringf("%s::%s",Namespaceprefix, name); } else { nname = NewString(name); } Swig_name_object_set(namewarn_hash,nname,decl,NewString(warning)); Delete(nname); } static void rename_inherit(String *base, String *derived) { /* Printf(stdout,"base = '%s', derived = '%s'\n", base, derived); */ Swig_name_object_inherit(rename_hash,base,derived); Swig_name_object_inherit(namewarn_hash,base,derived); Swig_name_object_inherit(features_hash,base,derived); } /* Generate the symbol table name for an object */ /* This is a bit of a mess. Need to clean up */ static String *add_oldname = 0; static String *make_name(String *name,SwigType *decl) { String *rn = 0; String *origname = name; int destructor = 0; if (name && (*(Char(name)) == '~')) { destructor = 1; } if (yyrename) { String *s = yyrename; yyrename = 0; if (destructor) { Insert(s,0,"~"); } return s; } if (!name) return 0; /* Check to see if the name is in the hash */ if (!rename_hash) { if (add_oldname) return Copy(add_oldname); return origname; } rn = Swig_name_object_get(rename_hash, Namespaceprefix, name, decl); if (!rn) { if (add_oldname) return Copy(add_oldname); return name; } if (destructor) { if (Strcmp(rn,"$ignore") != 0) { String *s = NewStringf("~%s", rn); return s; } } return Copy(rn); } /* Generate an unnamed identifier */ static String *make_unnamed() { unnamed++; return NewStringf("$unnamed%d$",unnamed); } /* Return the node name when it requires to emit a name warning */ static String *name_warning(Node *n,String *name,SwigType *decl) { /* Return in the obvious cases */ if (!namewarn_hash || !name || !need_name_warning(n)) return 0; /* Check to see if the name is in the hash */ return Swig_name_object_get(namewarn_hash,Namespaceprefix,name,decl); } /* Return if the node is a friend declaration */ static int is_friend(Node *n) { return Cmp(Getattr(n,"storage"),"friend") == 0; } /* Add declaration list to symbol table */ static int add_only_one = 0; static void add_symbols(Node *n) { String *decl; String *wrn = 0; if (inclass) { cparse_normalize_void(n); } while (n) { String *symname; /* for friends, we need to pop the scope once */ int isfriend = is_friend(n); Symtab *class_scope = isfriend ? Swig_symbol_popscope() : 0; if (!isfriend && inclass && (cplus_mode != CPLUS_PUBLIC)) { int only_csymbol = 1; if (cplus_mode == CPLUS_PROTECTED) { Setattr(n,"access", "protected"); only_csymbol = !need_protected(n, dirprot_mode); } else { Setattr(n,"access", "private"); } if (only_csymbol) { /* Only add to C symbol table and continue */ Swig_symbol_add(0, n); if (add_only_one) break; n = nextSibling(n); continue; } } if (Getattr(n,"sym:name")) { n = nextSibling(n); continue; } decl = Getattr(n,"decl"); if (!SwigType_isfunction(decl)) { symname = make_name(Getattr(n,"name"),0); if (!symname) { symname = Getattr(n,"unnamed"); } if (symname) { wrn = name_warning(n,symname,0); Swig_features_get(features_hash, Namespaceprefix, Getattr(n,"name"), 0, n); } } else { SwigType *fdecl = Copy(decl); SwigType *fun = SwigType_pop_function(fdecl); /* for friends, we need to disable the class prefix */ String* class_prefix = isfriend ? Namespaceprefix : 0; if (isfriend) Namespaceprefix = 0; symname = make_name(Getattr(n,"name"),fun); wrn = name_warning(n,symname,fun); Swig_features_get(features_hash,Namespaceprefix,Getattr(n,"name"),fun,n); Delete(fdecl); Delete(fun); /* restore the class prefix if needed */ if (isfriend) Namespaceprefix = class_prefix; } if (!symname) { n = nextSibling(n); continue; } if (strncmp(Char(symname),"$ignore",7) == 0) { char *c = Char(symname)+7; Setattr(n,"feature:ignore","1"); if (strlen(c)) { Swig_warning(0,Getfile(n), Getline(n), "%s\n",c+1); } Swig_symbol_add(0, n); } else { Node *c; if ((wrn) && (Len(wrn))) { Swig_warning(0,Getfile(n),Getline(n), "%s\n", wrn); } if (Strcmp(nodeType(n),"enum") != 0) { c = Swig_symbol_add(symname,n); if (c != n) { if (Getattr(n,"sym:weak")) { Setattr(n,"sym:name",symname); } else if ((Strcmp(nodeType(n),"template") == 0) && (Strcmp(Getattr(n,"templatetype"),"cdecl") == 0)) { Setattr(n,"sym:name",symname); } else { String *e = NewString(""); String *en = NewString(""); String *ec = NewString(""); int redefined = need_redefined_warn(n,c,inclass); if (redefined) { Printf(en,"Identifier '%s' redefined (ignored)",symname); Printf(ec,"previous definition of '%s'",symname); } else { Printf(en,"Redundant redeclaration of '%s'",symname); Printf(ec,"previous declaration of '%s'",symname); } if (Cmp(symname,Getattr(n,"name"))) { Printf(en," (Renamed from '%s')", SwigType_namestr(Getattr(n,"name"))); } Printf(en,","); if (Cmp(symname,Getattr(c,"name"))) { Printf(ec," (Renamed from '%s')", SwigType_namestr(Getattr(c,"name"))); } Printf(ec,"."); if (redefined) { Swig_warning(WARN_PARSE_REDEFINED,Getfile(n),Getline(n),"%s\n",en); Swig_warning(WARN_PARSE_REDEFINED,Getfile(c),Getline(c),"%s\n",ec); } else if (!is_friend(n) && !is_friend(c)) { Swig_warning(WARN_PARSE_REDUNDANT,Getfile(n),Getline(n),"%s\n",en); Swig_warning(WARN_PARSE_REDUNDANT,Getfile(c),Getline(c),"%s\n",ec); } Printf(e,"%s:%d:%s\n%s:%d:%s\n",Getfile(n),Getline(n),en, Getfile(c),Getline(c),ec); Setattr(n,"error",e); Delete(en); Delete(ec); } } } else { Setattr(n,"sym:name", symname); } } /* restore the class scope if needed */ if (isfriend) Swig_symbol_setscope(class_scope); if (add_only_one) return; n = nextSibling(n); } } /* add symbols a parse tree node copy */ void add_symbols_copy(Node *n) { String *name; int emode = 0; while (n) { if (Strcmp(nodeType(n),"access") == 0) { String *kind = Getattr(n,"kind"); if (Strcmp(kind,"public") == 0) { cplus_mode = CPLUS_PUBLIC; } else if (Strcmp(kind,"private") == 0) { cplus_mode = CPLUS_PRIVATE; } else if (Strcmp(kind,"protected") == 0) { cplus_mode = CPLUS_PROTECTED; } n = nextSibling(n); continue; } add_oldname = Getattr(n,"sym:name"); if ((add_oldname) || (Getattr(n,"sym:needs_symtab"))) { if (add_oldname) { DohIncref(add_oldname); /* If already renamed, we used that name */ if (Strcmp(add_oldname, Getattr(n,"name")) != 0) { yyrename = add_oldname; } } Delattr(n,"sym:needs_symtab"); Delattr(n,"sym:name"); add_only_one = 1; add_symbols(n); if (Getattr(n,"partialargs")) { Swig_symbol_cadd(Getattr(n,"partialargs"),n); } add_only_one = 0; name = Getattr(n,"name"); if (Getattr(n,"requires_symtab")) { Swig_symbol_newscope(); Swig_symbol_setscopename(name); Namespaceprefix = Swig_symbol_qualifiedscopename(0); } if (Strcmp(nodeType(n),"class") == 0) { inclass = 1; if (Strcmp(Getattr(n,"kind"),"class") == 0) { cplus_mode = CPLUS_PRIVATE; } else { cplus_mode = CPLUS_PUBLIC; } } if (Strcmp(nodeType(n),"extend") == 0) { emode = cplus_mode; cplus_mode = CPLUS_PUBLIC; } add_symbols_copy(firstChild(n)); if (Strcmp(nodeType(n),"extend") == 0) { cplus_mode = emode; } if (Getattr(n,"requires_symtab")) { Setattr(n,"symtab", Swig_symbol_popscope()); Delattr(n,"requires_symtab"); Namespaceprefix = Swig_symbol_qualifiedscopename(0); } if (add_oldname) { Delete(add_oldname); } if (Strcmp(nodeType(n),"class") == 0) { inclass = 0; } add_oldname = 0; } else { if (Strcmp(nodeType(n),"extend") == 0) { emode = cplus_mode; cplus_mode = CPLUS_PUBLIC; } add_symbols_copy(firstChild(n)); if (Strcmp(nodeType(n),"extend") == 0) { cplus_mode = emode; } } n = nextSibling(n); } } /* Extension merge. This function is used to handle the %extend directive when it appears before a class definition. To handle this, the %extend actually needs to take precedence. Therefore, we will selectively nuke symbols from the current symbol table, replacing them with the added methods */ static void merge_extensions(Node *cls, Node *am) { Node *n; Node *csym; n = firstChild(am); while (n) { String *symname; if (Strcmp(nodeType(n),"constructor") == 0) { symname = Getattr(n,"sym:name"); if (symname) { if (Strcmp(symname,Getattr(n,"name")) == 0) { /* If the name and the sym:name of a constructor are the same, then it hasn't been renamed. However---the name of the class itself might have been renamed so we need to do a consistency check here */ if (Getattr(cls,"sym:name")) { Setattr(n,"sym:name", Getattr(cls,"sym:name")); } } } } symname = Getattr(n,"sym:name"); DohIncref(symname); if ((symname) && (!Getattr(n,"error"))) { /* Remove node from its symbol table */ Swig_symbol_remove(n); csym = Swig_symbol_add(symname,n); if (csym != n) { /* Conflict with previous definition. Nuke previous definition */ String *e = NewString(""); String *en = NewString(""); String *ec = NewString(""); Printf(ec,"Identifier '%s' redefined by %%extend (ignored),",symname); Printf(en,"%%extend definition of '%s'.",symname); Swig_warning(WARN_PARSE_REDEFINED,Getfile(csym),Getline(csym),"%s\n",ec); Swig_warning(WARN_PARSE_REDEFINED,Getfile(n),Getline(n),"%s\n",en); Printf(e,"%s:%d:%s\n%s:%d:%s\n",Getfile(csym),Getline(csym),ec, Getfile(n),Getline(n),en); Setattr(csym,"error",e); Delete(en); Delete(ec); Swig_symbol_remove(csym); /* Remove class definition */ Swig_symbol_add(symname,n); /* Insert extend definition */ } } n = nextSibling(n); } } /* Check for unused %extend. Special case, don't report unused extensions for templates */ static void check_extensions() { Iterator ki; if (!extendhash) return; for (ki = First(extendhash); ki.key; ki = Next(ki)) { if (!Strstr(ki.key,"<")) { Swig_warning(WARN_PARSE_EXTEND_UNDEF,Getfile(ki.item), Getline(ki.item), "%%extend defined for an undeclared class %s.\n", ki.key); } } } /* Check a set of declarations to see if any are pure-abstract */ static List *pure_abstract(Node *n) { List *abs = 0; while (n) { if (Cmp(nodeType(n),"cdecl") == 0) { String *decl = Getattr(n,"decl"); if (SwigType_isfunction(decl)) { String *init = Getattr(n,"value"); if (Cmp(init,"0") == 0) { if (!abs) { abs = NewList(); } Append(abs,n); Setattr(n,"abstract","1"); } } } else if (Cmp(nodeType(n),"destructor") == 0) { if (Cmp(Getattr(n,"value"),"0") == 0) { if (!abs) { abs = NewList(); } Append(abs,n); Setattr(n,"abstract","1"); } } n = nextSibling(n); } return abs; } /* Make a classname */ static String *make_class_name(String *name) { String *nname = 0; if (Namespaceprefix) { nname= NewStringf("%s::%s", Namespaceprefix, name); } else { nname = NewString(name); } if (SwigType_istemplate(nname)) { String *prefix, *args, *qargs; prefix = SwigType_templateprefix(nname); args = SwigType_templateargs(nname); qargs = Swig_symbol_type_qualify(args,0); Append(prefix,qargs); Delete(nname); nname = prefix; } return nname; } static List *make_inherit_list(String *clsname, List *names) { int i; String *derived; List *bases = NewList(); if (Namespaceprefix) derived = NewStringf("%s::%s", Namespaceprefix,clsname); else derived = NewString(clsname); for (i = 0; i < Len(names); i++) { Node *s; String *base; String *n = Getitem(names,i); /* Try to figure out where this symbol is */ s = Swig_symbol_clookup(n,0); if (s) { while (s && (Strcmp(nodeType(s),"class") != 0)) { /* Not a class. Could be a typedef though. */ String *storage = Getattr(s,"storage"); if (storage && (Strcmp(storage,"typedef") == 0)) { String *nn = Getattr(s,"type"); s = Swig_symbol_clookup(nn,Getattr(s,"sym:symtab")); } else { break; } } if (s && ((Strcmp(nodeType(s),"class") == 0) || (Strcmp(nodeType(s),"template") == 0))) { String *q = Swig_symbol_qualified(s); Append(bases,s); if (q) { base = NewStringf("%s::%s", q, Getattr(s,"name")); } else { base = NewString(Getattr(s,"name")); } } else { base = NewString(n); } } else { base = NewString(n); } if (base) { rename_inherit(base,derived); Delete(base); } } return bases; } /* Structures for handling code fragments built for nested classes */ typedef struct Nested { String *code; /* Associated code fragment */ int line; /* line number where it starts */ char *name; /* Name associated with this nested class */ char *kind; /* Kind of class */ SwigType *type; /* Datatype associated with the name */ struct Nested *next; /* Next code fragment in list */ } Nested; /* Some internal variables for saving nested class information */ static Nested *nested_list = 0; /* Add a function to the nested list */ static void add_nested(Nested *n) { Nested *n1; if (!nested_list) nested_list = n; else { n1 = nested_list; while (n1->next) n1 = n1->next; n1->next = n; } } /* Dump all of the nested class declarations to the inline processor * However. We need to do a few name replacements and other munging * first. This function must be called before closing a class! */ static Node *dump_nested(char *parent) { Nested *n,*n1; Node *ret = 0; n = nested_list; if (!parent) { nested_list = 0; return 0; } while (n) { char temp[256]; Node *retx; /* Token replace the name of the parent class */ Replace(n->code, "$classname", parent, DOH_REPLACE_ANY); /* Fix up the name of the datatype (for building typedefs and other stuff) */ sprintf(temp,"%s_%s", parent,n->name); Append(n->type,parent); Append(n->type,"_"); Append(n->type,n->name); /* Add the appropriate declaration to the C++ processor */ retx = new_node("cdecl"); Setattr(retx,"name",n->name); Setattr(retx,"type",Copy(n->type)); Setattr(retx,"nested",parent); add_symbols(retx); if (ret) { set_nextSibling(retx,ret); } ret = retx; /* Insert a forward class declaration */ /* Disabled: [ 597599 ] union in class: incorrect scope retx = new_node("classforward"); Setattr(retx,"kind",n->kind); Setattr(retx,"name",Copy(n->type)); Setattr(retx,"sym:name", make_name(n->type,0)); set_nextSibling(retx,ret); ret = retx; */ /* Make all SWIG created typedef structs/unions/classes unnamed else redefinition errors occur - nasty hack alert.*/ { const char* types_array[3] = {"struct", "union", "class"}; int i; for (i=0; i<3; i++) { char* code_ptr = Char(n->code); while (code_ptr) { /* Replace struct name (as in 'struct name {' ) with whitespace name will be between struct and { */ code_ptr = strstr(code_ptr, types_array[i]); if (code_ptr) { char *open_bracket_pos; code_ptr += strlen(types_array[i]); open_bracket_pos = strstr(code_ptr, "{"); if (open_bracket_pos) { /* Make sure we don't have something like struct A a; */ char* semi_colon_pos = strstr(code_ptr, ";"); if (!(semi_colon_pos && (semi_colon_pos < open_bracket_pos))) while (code_ptr < open_bracket_pos) *code_ptr++ = ' '; } } } } } { /* Remove SWIG directive %constant which may be left in the SWIG created typedefs */ char* code_ptr = Char(n->code); while (code_ptr) { code_ptr = strstr(code_ptr, "%constant"); if (code_ptr) { char* directive_end_pos = strstr(code_ptr, ";"); if (directive_end_pos) { while (code_ptr <= directive_end_pos) *code_ptr++ = ' '; } } } } { Node *head; head = new_node("insert"); Setattr(head,"code",NewStringf("\n%s\n",n->code)); set_nextSibling(head,ret); ret = head; } /* Dump the code to the scanner */ start_inline(Char(n->code),n->line); n1 = n->next; Delete(n->code); free(n); n = n1; } nested_list = 0; return ret; } Node *Swig_cparse(File *f) { scanner_file(f); top = 0; yyparse(); return top; } %} %union { char *id; List *bases; struct Define { String *val; String *rawval; int type; String *qualifier; String *bitfield; Parm *throws; } dtype; struct { char *type; char *filename; int line; } loc; struct { char *id; SwigType *type; String *defarg; ParmList *parms; short have_parms; ParmList *throws; } decl; Parm *tparms; struct { String *op; Hash *kwargs; } tmap; struct { String *type; String *us; } ptype; SwigType *type; String *str; Parm *p; ParmList *pl; int ivalue; Node *node; }; %token ID %token HBLOCK %token POUND %token STRING %token INCLUDE IMPORT INSERT %token CHARCONST %token NUM_INT NUM_FLOAT NUM_UNSIGNED NUM_LONG NUM_ULONG NUM_LONGLONG NUM_ULONGLONG %token TYPEDEF %token TYPE_INT TYPE_UNSIGNED TYPE_SHORT TYPE_LONG TYPE_FLOAT TYPE_DOUBLE TYPE_CHAR TYPE_VOID TYPE_SIGNED TYPE_BOOL TYPE_TYPEDEF TYPE_RAW %token LPAREN RPAREN COMMA SEMI EXTERN INIT LBRACE RBRACE PERIOD %token CONST VOLATILE STRUCT UNION EQUAL SIZEOF MODULE LBRACKET RBRACKET %token ILLEGAL CONSTANT %token NAME RENAME NAMEWARN EXTEND PRAGMA FEATURE VARARGS %token ENUM %token CLASS TYPENAME PRIVATE PUBLIC PROTECTED COLON STATIC VIRTUAL FRIEND THROW CATCH %token USING %token NAMESPACE %token NATIVE INLINE %token TYPEMAP EXCEPT ECHO APPLY CLEAR SWIGTEMPLATE FRAGMENT %token WARN %token LESSTHAN GREATERTHAN MODULO DELETE %token TYPES PARMS %token NONID DSTAR DCNOT %token TEMPLATE %token OPERATOR %token COPERATOR %token PARSETYPE PARSEPARM %left CAST %left LOR %left LAND %left OR %left XOR %left AND %left LSHIFT RSHIFT %left PLUS MINUS %left STAR SLASH %left UMINUS NOT LNOT %left DCOLON %type program interface declaration swig_directive ; /* SWIG directives */ %type extend_directive apply_directive clear_directive constant_directive ; %type echo_directive except_directive fragment_directive include_directive inline_directive ; %type insert_directive module_directive name_directive native_directive ; %type pragma_directive rename_directive feature_directive varargs_directive typemap_directive ; %type types_directive template_directive warn_directive ; /* C declarations */ %type c_declaration c_decl c_decl_tail c_enum_decl c_constructor_decl ; %type enumlist edecl; /* C++ declarations */ %type cpp_declaration cpp_class_decl cpp_forward_class_decl cpp_template_decl; %type cpp_members cpp_member; %type cpp_constructor_decl cpp_destructor_decl cpp_protection_decl cpp_conversion_operator; %type cpp_swig_directive cpp_temp_possible cpp_nested cpp_opt_declarators ; %type cpp_using_decl cpp_namespace_decl cpp_catch_decl ; %type kwargs options; /* Misc */ %type initializer cpp_const ; %type storage_class; %type parms ptail rawparms varargs_parms ; %type

parm valparm rawvalparms valparms valptail ; %type

typemap_parm tm_list tm_tail ; %type cpptype access_specifier; %type base_specifier %type type rawtype type_right ; %type base_list inherit raw_inherit; %type definetype def_args etype; %type expr exprnum exprcompound ; %type ename ; %type template_decl; %type type_qualifier ; %type type_qualifier_raw; %type idstring idstringopt; %type pragma_lang; %type pragma_arg; %type includetype; %type pointer primitive_type; %type declarator direct_declarator notso_direct_declarator parameter_declarator typemap_parameter_declarator nested_decl; %type abstract_declarator direct_abstract_declarator ctor_end; %type typemap_type; %type idcolon idcolontail idcolonnt idcolontailnt idtemplate stringbrace stringbracesemi; %type string stringnum ; %type template_parms; %type cpp_vend; %type rename_namewarn; %type type_specifier primitive_type_list ; %% /* ====================================================================== * High-level Interface file * * An interface is just a sequence of declarations which may be SWIG directives * or normal C declarations. * ====================================================================== */ program : interface { Setattr($1,"classes",classes); Setattr($1,"name",ModuleName); if ((!module_node) && ModuleName) { module_node = new_node("module"); Setattr(module_node,"name",ModuleName); } Setattr($1,"module",module_node); check_extensions(); top = $1; } | PARSETYPE parm SEMI { top = Getattr($2,"type"); } | PARSETYPE error { top = 0; } | PARSEPARM parm SEMI { top = $2; } | PARSEPARM error { top = 0; } ; interface : interface declaration { appendChild($1,$2); $$ = $1; } | empty { $$ = new_node("top"); } ; declaration : swig_directive { $$ = $1; } | c_declaration { $$ = $1; } | cpp_declaration { $$ = $1; } | SEMI { $$ = 0; } | error { $$ = 0; if (!Swig_error_count()) { static int last_error_line = -1; if (last_error_line != cparse_line) { Swig_error(cparse_file, cparse_line,"Syntax error in input.\n"); last_error_line = cparse_line; skip_decl(); } } } /* Out of class constructor/destructor declarations */ | c_constructor_decl { if ($$) { add_symbols($$); } $$ = $1; } /* Out of class conversion operator. For example: inline A::operator char *() const { ... }. This is nearly impossible to parse normally. We just let the first part generate a syntax error and then resynchronize on the COPERATOR token---discarding the rest of the definition. Ugh. */ | error COPERATOR { $$ = 0; skip_decl(); } ; /* ====================================================================== * SWIG DIRECTIVES * ====================================================================== */ swig_directive : extend_directive { $$ = $1; } | apply_directive { $$ = $1; } | clear_directive { $$ = $1; } | constant_directive { $$ = $1; } | echo_directive { $$ = $1; } | except_directive { $$ = $1; } | fragment_directive { $$ = $1; } | include_directive { $$ = $1; } | inline_directive { $$ = $1; } | insert_directive { $$ = $1; } | module_directive { $$ = $1; } | name_directive { $$ = $1; } | native_directive { $$ = $1; } | pragma_directive { $$ = $1; } | rename_directive { $$ = $1; } | feature_directive { $$ = $1; } | varargs_directive { $$ = $1; } | typemap_directive { $$ = $1; } | types_directive { $$ = $1; } | template_directive { $$ = $1; } | warn_directive { $$ = $1; } ; /* ------------------------------------------------------------ %extend classname { ... } ------------------------------------------------------------ */ extend_directive : EXTEND options idcolon LBRACE { Node *cls; String *clsname; cplus_mode = CPLUS_PUBLIC; if (!classes) classes = NewHash(); if (!extendhash) extendhash = NewHash(); clsname = make_class_name($3); cls = Getattr(classes,clsname); if (!cls) { /* No previous definition. Create a new scope */ Node *am = Getattr(extendhash,clsname); if (!am) { Swig_symbol_newscope(); Swig_symbol_setscopename($3); prev_symtab = 0; } else { prev_symtab = Swig_symbol_setscope(Getattr(am,"symtab")); } current_class = 0; } else { /* Previous class definition. Use its symbol table */ prev_symtab = Swig_symbol_setscope(Getattr(cls,"symtab")); current_class = cls; extendmode = 1; } Classprefix = NewString($3); Namespaceprefix= Swig_symbol_qualifiedscopename(0); Delete(clsname); } cpp_members RBRACE { String *clsname; extendmode = 0; $$ = new_node("extend"); Setattr($$,"symtab",Swig_symbol_popscope()); if (prev_symtab) { Swig_symbol_setscope(prev_symtab); } Namespaceprefix = Swig_symbol_qualifiedscopename(0); clsname = make_class_name($3); Setattr($$,"name",clsname); /* Mark members as extend */ Swig_tag_nodes($6,"feature:extend",(char*) "1"); if (current_class) { /* We add the extension to the previously defined class */ appendChild($$,$6); appendChild(current_class,$$); } else { /* We store the extensions in the extensions hash */ Node *am = Getattr(extendhash,clsname); if (am) { /* Append the members to the previous extend methods */ appendChild(am,$6); } else { appendChild($$,$6); Setattr(extendhash,clsname,$$); } } current_class = 0; Delete(Classprefix); Delete(clsname); Classprefix = 0; prev_symtab = 0; $$ = 0; } ; /* ------------------------------------------------------------ %apply ------------------------------------------------------------ */ apply_directive : APPLY typemap_parm LBRACE tm_list RBRACE { $$ = new_node("apply"); Setattr($$,"pattern",Getattr($2,"pattern")); appendChild($$,$4); }; /* ------------------------------------------------------------ %clear ------------------------------------------------------------ */ clear_directive : CLEAR tm_list SEMI { $$ = new_node("clear"); appendChild($$,$2); } ; /* ------------------------------------------------------------ %constant name = value; %constant type name = value; ------------------------------------------------------------ */ constant_directive : CONSTANT ID EQUAL definetype SEMI { if (($4.type != T_ERROR) && ($4.type != T_SYMBOL)) { $$ = new_node("constant"); Setattr($$,"name",$2); Setattr($$,"type",NewSwigType($4.type)); Setattr($$,"value",$4.val); if ($4.rawval) Setattr($$,"rawval", $4.rawval); Setattr($$,"storage","%constant"); Setattr($$,"feature:immutable","1"); add_symbols($$); } else { if ($4.type == T_ERROR) { Swig_warning(WARN_PARSE_UNSUPPORTED_VALUE,cparse_file,cparse_line,"Unsupported constant value (ignored)\n"); } $$ = 0; } } | CONSTANT type declarator def_args SEMI { if (($4.type != T_ERROR) && ($4.type != T_SYMBOL)) { SwigType_push($2,$3.type); /* Sneaky callback function trick */ if (SwigType_isfunction($2)) { SwigType_add_pointer($2); } $$ = new_node("constant"); Setattr($$,"name",$3.id); Setattr($$,"type",$2); Setattr($$,"value",$4.val); if ($4.rawval) Setattr($$,"rawval", $4.rawval); Setattr($$,"storage","%constant"); Setattr($$,"feature:immutable","1"); add_symbols($$); } else { if ($4.type == T_ERROR) { Swig_warning(WARN_PARSE_UNSUPPORTED_VALUE,cparse_file,cparse_line,"Unsupported constant value\n"); } $$ = 0; } } | CONSTANT error SEMI { Swig_warning(WARN_PARSE_BAD_VALUE,cparse_file,cparse_line,"Bad constant value (ignored).\n"); $$ = 0; } ; /* ------------------------------------------------------------ %echo "text" %echo %{ ... %} ------------------------------------------------------------ */ echo_directive : ECHO HBLOCK { char temp[64]; Replace($2,"$file",cparse_file, DOH_REPLACE_ANY); sprintf(temp,"%d", cparse_line); Replace($2,"$line",temp,DOH_REPLACE_ANY); Printf(stderr,"%s\n", $2); Delete($2); $$ = 0; } | ECHO string { char temp[64]; String *s = NewString($2); Replace(s,"$file",cparse_file, DOH_REPLACE_ANY); sprintf(temp,"%d", cparse_line); Replace(s,"$line",temp,DOH_REPLACE_ANY); Printf(stderr,"%s\n", s); Delete(s); $$ = 0; } ; /* ------------------------------------------------------------ %except(lang) { ... } %except { ... } %except(lang); %except; ------------------------------------------------------------ */ except_directive : EXCEPT LPAREN ID RPAREN LBRACE { skip_balanced('{','}'); $$ = 0; Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n"); } | EXCEPT LBRACE { skip_balanced('{','}'); $$ = 0; Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n"); } | EXCEPT LPAREN ID RPAREN SEMI { $$ = 0; Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n"); } | EXCEPT SEMI { $$ = 0; Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n"); } ; /* ------------------------------------------------------------ %fragment(name,location) { ... } ------------------------------------------------------------ */ fragment_directive: FRAGMENT LPAREN kwargs RPAREN HBLOCK { Hash *p = nextSibling($3); $$ = new_node("fragment"); Setattr($$,"section", Getattr(p,"name")); Setattr($$,"name",Getattr($3,"name")); Setattr($$,"kwargs",nextSibling(p)); Setattr($$,"code",$5); } | FRAGMENT LPAREN kwargs RPAREN LBRACE { Hash *p = nextSibling($3); skip_balanced('{','}'); $$ = new_node("fragment"); Setattr($$,"section", Getattr(p,"name")); Setattr($$,"name",Getattr($3,"name")); Setattr($$,"kwargs",nextSibling(p)); Delitem(scanner_ccode,0); Delitem(scanner_ccode,DOH_END); Setattr($$,"code",Copy(scanner_ccode)); } ; /* ------------------------------------------------------------ %includefile "filename" [ declarations ] %importfile "filename" [ declarations ] ------------------------------------------------------------ */ include_directive: includetype options string LBRACKET { $1.filename = Swig_copy_string(cparse_file); $1.line = cparse_line; cparse_file = Swig_copy_string($3); cparse_line = 0; } interface RBRACKET { $$ = $6; cparse_file = $1.filename; cparse_line = $1.line; if (strcmp($1.type,"include") == 0) set_nodeType($$,"include"); if (strcmp($1.type,"import") == 0) set_nodeType($$,"import"); Setattr($$,"name",$3); /* Search for the module (if any) */ { Node *n = firstChild($$); while (n) { if (Strcmp(nodeType(n),"module") == 0) { Setattr($$,"module",Getattr(n,"name")); break; } n = nextSibling(n); } } Setattr($$,"options",$2); } ; includetype : INCLUDE { $$.type = (char *) "include"; } | IMPORT { $$.type = (char *) "import"; } ; /* ------------------------------------------------------------ %inline %{ ... %} ------------------------------------------------------------ */ inline_directive : INLINE HBLOCK { String *cpps; if (Namespaceprefix) { Swig_error(cparse_file, cparse_start_line, "%%inline directive inside a namespace is disallowed.\n"); $$ = 0; } else { $$ = new_node("insert"); Setattr($$,"code",$2); /* Need to run through the preprocessor */ Setline($2,cparse_start_line); Setfile($2,cparse_file); Seek($2,0,SEEK_SET); cpps = Preprocessor_parse($2); start_inline(Char(cpps), cparse_start_line); Delete($2); Delete(cpps); } } | INLINE LBRACE { String *cpps; skip_balanced('{','}'); if (Namespaceprefix) { Swig_error(cparse_file, cparse_start_line, "%%inline directive inside a namespace is disallowed.\n"); $$ = 0; } else { $$ = new_node("insert"); Delitem(scanner_ccode,0); Delitem(scanner_ccode,DOH_END); Setattr($$,"code", Copy(scanner_ccode)); cpps=Copy(scanner_ccode); start_inline(Char(cpps), cparse_start_line); Delete(cpps); } } ; /* ------------------------------------------------------------ %{ ... %} %insert(section) "filename" %insert("section") "filename" %insert(section) %{ ... %} %insert("section") %{ ... %} ------------------------------------------------------------ */ insert_directive : HBLOCK { $$ = new_node("insert"); Setattr($$,"code",$1); } | INSERT LPAREN idstring RPAREN string { String *code = NewString(""); $$ = new_node("insert"); Setattr($$,"section",$3); Setattr($$,"code",code); if (Swig_insert_file($5,code) < 0) { Swig_error(cparse_file, cparse_line, "Couldn't find '%s'.\n", $5); $$ = 0; } } | INSERT LPAREN idstring RPAREN HBLOCK { $$ = new_node("insert"); Setattr($$,"section",$3); Setattr($$,"code",$5); } | INSERT LPAREN idstring RPAREN LBRACE { skip_balanced('{','}'); $$ = new_node("insert"); Setattr($$,"section",$3); Delitem(scanner_ccode,0); Delitem(scanner_ccode,DOH_END); Setattr($$,"code", Copy(scanner_ccode)); } ; /* ------------------------------------------------------------ %module modname %module "modname" ------------------------------------------------------------ */ module_directive: MODULE options idstring { $$ = new_node("module"); Setattr($$,"name",$3); if ($2) Setattr($$,"options",$2); if ($2 && Getattr($2,"directors") && Getattr($2,"dirprot")) dirprot_mode = 1; if (!ModuleName) ModuleName = NewString($3); if (!module_node) module_node = $$; } ; /* ------------------------------------------------------------ %name(newname) declaration %name("newname") declaration ------------------------------------------------------------ */ name_directive : NAME LPAREN idstring RPAREN { yyrename = NewString($3); $$ = 0; } | NAME LPAREN RPAREN { $$ = 0; Swig_error(cparse_file,cparse_line,"Missing argument to %%name directive.\n"); } ; /* ------------------------------------------------------------ %native(scriptname) name; %native(scriptname) type name (parms); ------------------------------------------------------------ */ native_directive : NATIVE LPAREN ID RPAREN storage_class ID SEMI { $$ = new_node("native"); Setattr($$,"name",$3); Setattr($$,"wrap:name",$6); add_symbols($$); } | NATIVE LPAREN ID RPAREN storage_class type declarator SEMI { if (!SwigType_isfunction($7.type)) { Swig_error(cparse_file,cparse_line,"%%native declaration '%s' is not a function.\n", $7.id); $$ = 0; } else { Delete(SwigType_pop_function($7.type)); /* Need check for function here */ SwigType_push($6,$7.type); $$ = new_node("native"); Setattr($$,"name",$3); Setattr($$,"wrap:name",$7.id); Setattr($$,"type",$6); Setattr($$,"parms",$7.parms); Setattr($$,"decl",$7.type); } add_symbols($$); } ; /* ------------------------------------------------------------ %pragma(lang) name=value %pragma(lang) name %pragma name = value %pragma name ------------------------------------------------------------ */ pragma_directive : PRAGMA pragma_lang ID EQUAL pragma_arg { $$ = new_node("pragma"); Setattr($$,"lang",$2); Setattr($$,"name",$3); Setattr($$,"value",$5); } | PRAGMA pragma_lang ID { $$ = new_node("pragma"); Setattr($$,"lang",$2); Setattr($$,"name",$3); } ; pragma_arg : string { $$ = NewString($1); } | HBLOCK { $$ = $1; } ; pragma_lang : LPAREN ID RPAREN { $$ = $2; } | empty { $$ = (char *) "swig"; } ; /* ------------------------------------------------------------ %rename identifier newname; %rename identifier "newname"; ------------------------------------------------------------ */ rename_directive : rename_namewarn declarator idstring SEMI { SwigType *t = $2.type; if (!Len(t)) t = 0; if ($1) { rename_add($2.id,t,$3); } else { namewarn_add($2.id,t,$3); } $$ = 0; scanner_clear_rename(); } | rename_namewarn LPAREN idstring RPAREN declarator cpp_const SEMI { String *fixname; SwigType *t = $5.type; fixname = feature_identifier_fix($5.id); if (!Len(t)) t = 0; /* Special declarator check */ if (t) { if ($6.qualifier) SwigType_push(t,$6.qualifier); if (SwigType_isfunction(t)) { SwigType *decl = SwigType_pop_function(t); if (SwigType_ispointer(t)) { String *nname = NewStringf("*%s",fixname); if ($1) { rename_add(Char(nname),decl,$3); } else { namewarn_add(Char(nname),decl,$3); } Delete(nname); } else { if ($1) { rename_add(Char(fixname),decl,$3); } else { namewarn_add(Char(fixname),decl,$3); } } } else if (SwigType_ispointer(t)) { String *nname = NewStringf("*%s",fixname); if ($1) { rename_add(Char(nname),0,$3); } else { namewarn_add(Char(nname),0,$3); } Delete(nname); } } else { if ($1) { rename_add(Char(fixname),0,$3); } else { namewarn_add(Char(fixname),0,$3); } } $$ = 0; scanner_clear_rename(); } | rename_namewarn LPAREN idstring RPAREN string SEMI { if ($1) { rename_add($5,0,$3); } else { namewarn_add($5,0,$3); } $$ = 0; scanner_clear_rename(); } ; rename_namewarn : RENAME { $$ = 1; } | NAMEWARN { $$ = 0; }; /* ------------------------------------------------------------ %feature(featurename) name { val } %feature(featurename) name "val"; %feature(featurename) name %{ val % } %feature(featurename,val) name; ------------------------------------------------------------ */ feature_directive : FEATURE LPAREN idstring RPAREN declarator cpp_const stringbracesemi { String *fname; String *val; String *name; String *fixname; SwigType *t; if (!features_hash) features_hash = NewHash(); fname = NewStringf("feature:%s",$3); fixname = feature_identifier_fix($5.id); if (Namespaceprefix) { name = NewStringf("%s::%s",Namespaceprefix, fixname); } else { name = fixname; } val = $7 ? NewString($7) : NewString("1"); if ($5.parms) { Setmeta(val,"parms",$5.parms); } t = $5.type; if ($5.parms) Setmeta(val,"parms",$5.parms); if (!Len(t)) t = 0; if (t) { if ($6.qualifier) SwigType_push(t,$6.qualifier); if (SwigType_isfunction(t)) { SwigType *decl = SwigType_pop_function(t); if (SwigType_ispointer(t)) { String *nname = NewStringf("*%s",name); Swig_feature_set(features_hash, nname, decl, fname, val); Delete(nname); } else { Swig_feature_set(features_hash, name, decl, fname, val); } } else if (SwigType_ispointer(t)) { String *nname = NewStringf("*%s",name); Swig_feature_set(features_hash,nname,0,fname,val); Delete(nname); } } else { Swig_feature_set(features_hash,name,0,fname,val); } Delete(fname); Delete(name); $$ = 0; } /* Special form where value is included in (...) part */ | FEATURE LPAREN idstring COMMA idstring RPAREN declarator cpp_const SEMI { String *fname; String *val; String *name; String *fixname; SwigType *t; if (!features_hash) features_hash = NewHash(); fname = NewStringf("feature:%s",$3); fixname = feature_identifier_fix($7.id); if (Namespaceprefix) { name = NewStringf("%s::%s",Namespaceprefix, fixname); } else { name = fixname; } if (Len($5)) { val = NewString($5); } else { val = 0; } if ($7.parms) { Setmeta(val,"parms",$7.parms); } t = $7.type; if ($7.parms) Setmeta(val,"parms",$7.parms); if (!Len(t)) t = 0; if (t) { if ($8.qualifier) SwigType_push(t,$8.qualifier); if (SwigType_isfunction(t)) { SwigType *decl = SwigType_pop_function(t); if (SwigType_ispointer(t)) { String *nname = NewStringf("*%s",name); Swig_feature_set(features_hash, nname, decl, fname, val); Delete(nname); } else { Swig_feature_set(features_hash, name, decl, fname, val); } } else if (SwigType_ispointer(t)) { String *nname = NewStringf("*%s",name); Swig_feature_set(features_hash,nname,0,fname,val); Delete(nname); } } else { Swig_feature_set(features_hash,name,0,fname,val); } Delete(fname); Delete(name); $$ = 0; } /* Global feature */ | FEATURE LPAREN idstring RPAREN stringbracesemi { String *name; String *fname = NewStringf("feature:%s",$3); if (!features_hash) features_hash = NewHash(); if (Namespaceprefix) name = NewStringf("%s::", Namespaceprefix); else name = NewString(""); Swig_feature_set(features_hash,name,0,fname,($5 ? NewString($5) : NewString("1"))); Delete(name); Delete(fname); $$ = 0; } | FEATURE LPAREN idstring COMMA idstring RPAREN SEMI { String *name; String *fname = NewStringf("feature:%s",$3); if (!features_hash) features_hash = NewHash(); if (Namespaceprefix) name = NewStringf("%s::", Namespaceprefix); else name = NewString(""); Swig_feature_set(features_hash,name,0,fname,(Len($5) ? NewString($5) : 0)); Delete(name); Delete(fname); $$ = 0; } ; stringbracesemi : stringbrace { $$ = $1; } | SEMI { $$ = 0; } | PARMS LPAREN parms RPAREN SEMI { $$ = $3; } ; /* %varargs() directive. */ varargs_directive : VARARGS LPAREN varargs_parms RPAREN declarator cpp_const SEMI { Parm *val; String *name; SwigType *t; if (!features_hash) features_hash = NewHash(); if (Namespaceprefix) name = NewStringf("%s::%s", Namespaceprefix, $5.id); else name = NewString($5.id); val = $3; if ($5.parms) { Setmeta(val,"parms",$5.parms); } t = $5.type; if (!Len(t)) t = 0; if (t) { if ($6.qualifier) SwigType_push(t,$6.qualifier); if (SwigType_isfunction(t)) { SwigType *decl = SwigType_pop_function(t); if (SwigType_ispointer(t)) { String *nname = NewStringf("*%s",name); Swig_feature_set(features_hash, nname, decl, "feature:varargs", val); Delete(nname); } else { Swig_feature_set(features_hash, name, decl, "feature:varargs", val); } } else if (SwigType_ispointer(t)) { String *nname = NewStringf("*%s",name); Swig_feature_set(features_hash,nname,0,"feature:varargs",val); Delete(nname); } } else { Swig_feature_set(features_hash,name,0,"feature:varargs",val); } Delete(name); $$ = 0; }; varargs_parms : parms { $$ = $1; } | NUM_INT COMMA parm { int i; int n; Parm *p; n = atoi(Char($1.val)); if (n <= 0) { Swig_error(cparse_file, cparse_line,"Argument count in %%varargs must be positive.\n"); $$ = 0; } else { $$ = Copy($3); Setattr($$,"name","VARARGS_SENTINEL"); for (i = 0; i < n; i++) { p = Copy($3); set_nextSibling(p,$$); $$ = p; } } } ; /* ------------------------------------------------------------ %typemap(method) type { ... } %typemap(method) type "..." %typemap(method) type; - typemap deletion %typemap(method) type1,type2,... = type; - typemap copy %typemap type1,type2,... = type; - typemap copy ------------------------------------------------------------ */ typemap_directive : TYPEMAP LPAREN typemap_type RPAREN tm_list stringbrace { $$ = 0; if ($3.op) { $$ = new_node("typemap"); Setattr($$,"method",$3.op); Setattr($$,"code",NewString($6)); if ($3.kwargs) { Setattr($$,"kwargs", $3.kwargs); } appendChild($$,$5); } } | TYPEMAP LPAREN typemap_type RPAREN tm_list SEMI { $$ = 0; if ($3.op) { $$ = new_node("typemap"); Setattr($$,"method",$3.op); appendChild($$,$5); } } | TYPEMAP LPAREN typemap_type RPAREN tm_list EQUAL typemap_parm SEMI { $$ = 0; if ($3.op) { $$ = new_node("typemapcopy"); Setattr($$,"method",$3.op); Setattr($$,"pattern", Getattr($7,"pattern")); appendChild($$,$5); } } ; /* typemap method type (lang,method) or (method) */ typemap_type : kwargs { Hash *p; String *name; p = nextSibling($1); if (p && (!Getattr(p,"value"))) { /* two argument typemap form */ name = Getattr($1,"name"); if (!name || (Strcmp(name,typemap_lang))) { $$.op = 0; $$.kwargs = 0; } else { $$.op = Getattr(p,"name"); $$.kwargs = nextSibling(p); } } else { /* one-argument typemap-form */ $$.op = Getattr($1,"name"); $$.kwargs = p; } } ; tm_list : typemap_parm tm_tail { $$ = $1; set_nextSibling($$,$2); } ; tm_tail : COMMA typemap_parm tm_tail { $$ = $2; set_nextSibling($$,$3); } | empty { $$ = 0;} ; typemap_parm : type typemap_parameter_declarator { SwigType_push($1,$2.type); $$ = new_node("typemapitem"); Setattr($$,"pattern",NewParm($1,$2.id)); Setattr($$,"parms", $2.parms); /* $$ = NewParm($1,$2.id); Setattr($$,"parms",$2.parms); */ } | LPAREN parms RPAREN { $$ = new_node("typemapitem"); Setattr($$,"pattern",$2); /* Setattr($$,"multitype",$2); */ } | LPAREN parms RPAREN LPAREN parms RPAREN { $$ = new_node("typemapitem"); Setattr($$,"pattern", $2); /* Setattr($$,"multitype",$2); */ Setattr($$,"parms",$5); } ; /* ------------------------------------------------------------ %types(parmlist); ------------------------------------------------------------ */ types_directive : TYPES LPAREN parms RPAREN SEMI { $$ = new_node("types"); Setattr($$,"parms",$3); } ; /* ------------------------------------------------------------ %template(name) tname; ------------------------------------------------------------ */ template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN valparms GREATERTHAN SEMI { Parm *p, *tp; Node *n; Node *nspace = 0, *nspace_inner = 0; Node *tnode = 0; Symtab *tscope = 0; int specialized = 0; $$ = 0; tscope = Swig_symbol_current(); /* Get the current scope */ /* If the template name is qualified. We need to create or lookup namespace entries */ if (Swig_scopename_check($5)) { String *prefix, *base; Node *ns; prefix = Swig_scopename_prefix($5); base = Swig_scopename_last($5); /* Try to locate the scope */ ns = Swig_symbol_clookup(prefix,0); if (!ns) { Swig_error(cparse_file,cparse_line,"Undefined scope '%s'\n", prefix); } else { if (Strcmp(nodeType(ns),"namespace") != 0) { Swig_error(cparse_file,cparse_line,"'%s' is not defined as namespace.\n", prefix); ns = 0; } else { /* Swig_symbol_setscope(Getattr(ns,"symtab")); Namespaceprefix = Swig_symbol_qualifiedscopename(0); */ } } if (ns && Namespaceprefix) { Swig_error(cparse_file,cparse_line, "Can't instantiate template '%s' inside namespace '%s'.\n" "Suggest moving %%template outside the namespace.\n", $5, Namespaceprefix); } /* Create namespace nodes to enclose the template declaration */ if (ns) { List *scopes; String *sname; Iterator si; String *name = NewString(prefix); scopes = NewList(); while (name) { String *tprefix; String *base = Swig_scopename_last(name); Insert(scopes,0,base); tprefix = Swig_scopename_prefix(name); Delete(name); name = tprefix; } for (si = First(scopes); si.item; si = Next(si)) { Node *ns1,*ns2; sname = si.item; ns1 = Swig_symbol_clookup(sname,0); assert(ns1); if (Strcmp(nodeType(ns1),"namespace") == 0) { if (Getattr(ns1,"alias")) { ns1 = Getattr(ns1,"namespace"); } } else { assert(0); } ns2 = new_node("namespace"); Setattr(ns2,"name",sname); Setattr(ns2,"symtab", Getattr(ns1,"symtab")); add_symbols(ns2); Swig_symbol_setscope(Getattr(ns1,"symtab")); Namespaceprefix = Swig_symbol_qualifiedscopename(0); if (nspace_inner) { appendChild(nspace_inner,ns2); } nspace_inner = ns2; if (!nspace) nspace = ns2; } $5 = base; } } n = Swig_cparse_template_locate($5,$7); /* Patch the argument types to respect namespaces */ p = $7; while (p) { if (!Getattr(p,"value")) { SwigType *ty = Getattr(p,"type"); if (ty) { ty = Swig_symbol_type_qualify(ty,0); /* ty = Swig_symbol_typedef_reduce(ty,0); */ Setattr(p,"type",ty); } } p = nextSibling(p); } /* Look for the template */ if (n && (Strcmp(nodeType(n),"template") == 0)) { Parm *tparms = Getattr(n,"templateparms"); if (!tparms) { specialized = 1; } if (!specialized && ((ParmList_len($7) > ParmList_len(tparms)))) { Swig_error(cparse_file, cparse_line, "Too many template parameters. Maximum of %d.\n", ParmList_len(tparms)); } else if (!specialized && ((ParmList_len($7) < ParmList_numrequired(tparms)))) { Swig_error(cparse_file, cparse_line, "Not enough template parameters specified. %d required.\n", ParmList_numrequired(tparms)); } else { int def_supplied = 0; /* Expand the template */ ParmList *temparms; if (specialized) temparms = CopyParmList($7); else temparms = CopyParmList(tparms); /* Create typedef's and arguments */ p = $7; tp = temparms; while (p) { String *value = Getattr(p,"value"); if (def_supplied) { Setattr(p,"default","1"); } if (value) { Setattr(tp,"value",value); } else { SwigType *ty = Getattr(p,"type"); if (ty) { Setattr(tp,"type",ty); } Delattr(tp,"value"); } p = nextSibling(p); tp = nextSibling(tp); if (!p && tp) { p = tp; def_supplied = 1; } } $$ = copy_node(n); /* We need to set the node name based on name used to instantiate */ Setattr($$,"name",Copy($5)); if (!specialized) { Delattr($$,"sym:typename"); } else { Setattr($$,"sym:typename","1"); } if ($3) { Swig_cparse_template_expand($$,$3,temparms); Setattr($$,"sym:name",$3); } else { static int cnt = 0; String *nname = NewStringf("__dummy_%d__", cnt++); Swig_cparse_template_expand($$,nname,temparms); Setattr($$,"sym:name",nname); Setattr($$,"feature:ignore","1"); } Delattr($$,"templatetype"); Setattr($$,"template",n); tnode = $$; Setfile($$,cparse_file); Setline($$,cparse_line); Delete(temparms); add_symbols_copy($$); if (Strcmp(nodeType($$),"class") == 0) { /* Identify pure abstract methods */ Setattr($$,"abstract", pure_abstract(firstChild($$))); /* Set up inheritance in symbol table */ { Symtab *csyms; List *baselist = Getattr($$,"baselist"); csyms = Swig_symbol_current(); Swig_symbol_setscope(Getattr($$,"symtab")); if (baselist) { List *bases = make_inherit_list(Getattr($$,"name"),baselist); if (bases) { Iterator s; for (s = First(bases); s.item; s = Next(s)) { Symtab *st = Getattr(s.item,"symtab"); if (st) { Swig_symbol_inherit(st); } } } } Swig_symbol_setscope(csyms); } /* Merge in addmethods for this class */ /* !!! This may be broken. We may have to add the addmethods at the beginning of the class */ if (extendhash) { String *clsname; Node *am; if (Namespaceprefix) { clsname = NewStringf("%s::%s", Namespaceprefix, Getattr($$,"name")); } else { clsname = Getattr($$,"name"); } am = Getattr(extendhash,clsname); if (am) { Symtab *st = Swig_symbol_current(); Swig_symbol_setscope(Getattr($$,"symtab")); /* Printf(stdout,"%s: %s %x %x\n", Getattr($$,"name"), clsname, Swig_symbol_current(), Getattr($$,"symtab")); */ merge_extensions($$,am); Swig_symbol_setscope(st); appendChild($$,am); Delattr(extendhash,clsname); } } /* Add to classes hash */ if (!classes) classes = NewHash(); { if (Namespaceprefix) { String *temp = NewStringf("%s::%s", Namespaceprefix, Getattr($$,"name")); Setattr(classes,temp,$$); } else { Setattr(classes,Swig_symbol_qualifiedscopename($$),$$); } } } } if ($$ && nspace) { appendChild(nspace_inner,$$); $$ = nspace; } } Swig_symbol_setscope(tscope); Namespaceprefix = Swig_symbol_qualifiedscopename(0); } ; /* ------------------------------------------------------------ %warn "text" %warn(no) ------------------------------------------------------------ */ warn_directive : WARN string { Swig_warning(0,cparse_file, cparse_line,"%s\n", $2); $$ = 0; } ; /* ====================================================================== * C Parsing * ====================================================================== */ c_declaration : c_decl { $$ = $1; if ($$) { add_symbols($$); } } | c_enum_decl { $$ = $1; } /* A an extern C type declaration. Does nothing, but is ignored */ | EXTERN string LBRACE interface RBRACE { if (Strcmp($2,"C") == 0) { $$ = new_node("extern"); Setattr($$,"name",$2); appendChild($$,firstChild($4)); } else { Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\" (ignored).\n", $2); $$ = 0; } } ; /* ------------------------------------------------------------ A C global declaration of some kind (may be variable, function, typedef, etc.) ------------------------------------------------------------ */ c_decl : storage_class type declarator initializer c_decl_tail { $$ = new_node("cdecl"); if ($4.qualifier) SwigType_push($3.type,$4.qualifier); Setattr($$,"type",$2); Setattr($$,"storage",$1); Setattr($$,"name",$3.id); Setattr($$,"decl",$3.type); Setattr($$,"parms",$3.parms); Setattr($$,"value",$4.val); Setattr($$,"throws",$4.throws); if (!$5) { if (Len(scanner_ccode)) { Setattr($$,"code",Copy(scanner_ccode)); } } else { Node *n = $5; /* Inherit attributes */ while (n) { Setattr(n,"type",Copy($2)); Setattr(n,"storage",$1); n = nextSibling(n); } } if ($4.bitfield) { Setattr($$,"bitfield", $4.bitfield); } /* Look for "::" declarations (ignored) */ if (Strstr($3.id,"::")) { if (Namespaceprefix) { /* This is a special case. If the scope name of the declaration exactly matches that of the declaration, then we will allow it. Otherwise, delete. */ String *p = Swig_scopename_prefix($3.id); if (Strcmp(p,Namespaceprefix) == 0) { Setattr($$,"name",Swig_scopename_last($3.id)); set_nextSibling($$,$5); } else { Delete($$); $$ = $5; } Delete(p); } else { Delete($$); $$ = $5; } } else { set_nextSibling($$,$5); } } ; /* Allow lists of variables and functions to be built up */ c_decl_tail : SEMI { $$ = 0; Clear(scanner_ccode); } | COMMA declarator initializer c_decl_tail { $$ = new_node("cdecl"); if ($3.qualifier) SwigType_push($2.type,$3.qualifier); Setattr($$,"name",$2.id); Setattr($$,"decl",$2.type); Setattr($$,"parms",$2.parms); Setattr($$,"value",$3.val); Setattr($$,"throws",$3.throws); if ($3.bitfield) { Setattr($$,"bitfield", $3.bitfield); } if (!$4) { if (Len(scanner_ccode)) { Setattr($$,"code",Copy(scanner_ccode)); } } else { set_nextSibling($$,$4); } } | LBRACE { skip_balanced('{','}'); $$ = 0; } ; initializer : def_args { $$ = $1; $$.qualifier = 0; $$.throws = 0; } | type_qualifier def_args { $$ = $2; $$.qualifier = $1; $$.throws = 0; } | THROW LPAREN parms RPAREN def_args { $$ = $5; $$.qualifier = 0; $$.throws = $3; } | type_qualifier THROW LPAREN parms RPAREN def_args { $$ = $6; $$.qualifier = $1; $$.throws = $4; } ; /* ------------------------------------------------------------ enum { ... } * ------------------------------------------------------------ */ c_enum_decl : storage_class ENUM ename LBRACE enumlist RBRACE SEMI { $$ = new_node("enum"); Setattr($$,"name",$3); appendChild($$,$5); add_symbols($$); /* Add to tag space */ add_symbols($5); /* Add enum values to id space */ } | storage_class ENUM ename LBRACE enumlist RBRACE declarator c_decl_tail { Node *n; SwigType *ty = 0; String *unnamed = 0; $$ = new_node("enum"); if ($3) { Setattr($$,"name",$3); ty = NewStringf("enum %s", $3); } else if ($7.id){ unnamed = make_unnamed(); ty = NewStringf("enum %s", unnamed); Setattr($$,"unnamed",unnamed); /* WF 20/12/2001: Cannot get sym:name and symtab set without setting name - fix! // I don't think sym:name should be set. */ Setattr($$,"name",$7.id); Setattr($$,"tdname",$7.id); Setattr($$,"storage",$1); } appendChild($$,$5); n = new_node("cdecl"); Setattr(n,"type",ty); Setattr(n,"name",$7.id); Setattr(n,"storage",$1); Setattr(n,"decl",$7.type); Setattr(n,"parms",$7.parms); Setattr(n,"unnamed",unnamed); if ($8) { Node *p = $8; set_nextSibling(n,p); while (p) { Setattr(p,"type",Copy(ty)); Setattr(p,"unnamed",unnamed); Setattr(p,"storage",$1); p = nextSibling(p); } } else { if (Len(scanner_ccode)) { Setattr(n,"code",Copy(scanner_ccode)); } } add_symbols($$); /* Add enum to tag space */ set_nextSibling($$,n); add_symbols($5); /* Add to id space */ add_symbols(n); } ; c_constructor_decl : storage_class type LPAREN parms RPAREN ctor_end { /* This is a sick hack. If the ctor_end has parameters, and the parms paremeter only has 1 parameter, this could be a declaration of the form: type (id)(parms) Otherwise it's an error. */ int err = 0; $$ = 0; if ((ParmList_len($4) == 1) && (!Swig_scopename_check($2))) { SwigType *ty = Getattr($4,"type"); String *name = Getattr($4,"name"); err = 1; if (!name) { $$ = new_node("cdecl"); Setattr($$,"type",$2); Setattr($$,"storage",$1); Setattr($$,"name",ty); if ($6.have_parms) { SwigType *decl = NewString(""); SwigType_add_function(decl,$6.parms); Setattr($$,"decl",decl); Setattr($$,"parms",$6.parms); if (Len(scanner_ccode)) { Setattr($$,"code",Copy(scanner_ccode)); } } if ($6.defarg) { Setattr($$,"value",$6.defarg); } Setattr($$,"throws",$6.throws); err = 0; } } if (err) { Swig_error(cparse_file,cparse_line,"Syntax error in input.\n"); } } ; /* ====================================================================== * C++ Support * ====================================================================== */ cpp_declaration : cpp_class_decl { $$ = $1; } | cpp_forward_class_decl { $$ = $1; } | cpp_template_decl { $$ = $1; } | cpp_using_decl { $$ = $1; } | cpp_namespace_decl { $$ = $1; } | cpp_catch_decl { $$ = 0; } ; cpp_class_decl : /* A simple class/struct/union definition */ storage_class cpptype idcolon inherit LBRACE { List *bases = 0; class_rename = make_name($3,0); Classprefix = NewString($3); /* Deal with inheritance */ if ($4) { bases = make_inherit_list($3,$4); } if (SwigType_istemplate($3)) { String *fbase, *tbase, *prefix; prefix = SwigType_templateprefix($3); if (Namespaceprefix) { fbase = NewStringf("%s::%s", Namespaceprefix,$3); tbase = NewStringf("%s::%s", Namespaceprefix, prefix); } else { fbase = Copy($3); tbase = Copy(prefix); } rename_inherit(tbase,fbase); Delete(fbase); Delete(tbase); Delete(prefix); } if (strcmp($2,"class") == 0) { cplus_mode = CPLUS_PRIVATE; } else { cplus_mode = CPLUS_PUBLIC; } Swig_symbol_newscope(); Swig_symbol_setscopename($3); if (bases) { Iterator s; for (s = First(bases); s.item; s = Next(s)) { Symtab *st = Getattr(s.item,"symtab"); if (st) { Swig_symbol_inherit(st); } } } Namespaceprefix = Swig_symbol_qualifiedscopename(0); cparse_start_line = cparse_line; /* If there are active template parameters, we need to make sure they are placed in the class symbol table so we can catch shadows */ if (template_parameters) { Parm *tp = template_parameters; while(tp) { Node *tn = new_node("templateparm"); Setattr(tn,"name",Getattr(tp,"name")); Swig_symbol_cadd(Copy(Getattr(tp,"name")),tn); tp = nextSibling(tp); } } inclass = 1; } cpp_members RBRACE cpp_opt_declarators { Node *p; SwigType *ty; inclass = 0; $$ = new_node("class"); Setline($$,cparse_start_line); Setattr($$,"name",$3); Setattr($$,"kind",$2); Setattr($$,"baselist",$4); Setattr($$,"allows_typedef","1"); /* Check for pure-abstract class */ Setattr($$,"abstract", pure_abstract($7)); /* This bit of code merges in a previously defined %extend directive (if any) */ if (extendhash) { String *clsname = Swig_symbol_qualifiedscopename(0); Node *am = Getattr(extendhash,clsname); if (am) { merge_extensions($$,am); appendChild($$,am); Delattr(extendhash,clsname); } Delete(clsname); } if (!classes) classes = NewHash(); Setattr(classes,Swig_symbol_qualifiedscopename(0),$$); appendChild($$,$7); p = $9; if (p) { set_nextSibling($$,p); } if (cparse_cplusplus) { ty = NewString($3); } else { ty = NewStringf("%s %s", $2,$3); } while (p) { Setattr(p,"storage",$1); Setattr(p,"type",ty); p = nextSibling(p); } /* Dump nested classes */ { String *name = $3; if ($9) { SwigType *decltype = Getattr($9,"decl"); if (Cmp($1,"typedef") == 0) { if (!decltype || !Len(decltype)) { name = Getattr($9,"name"); Setattr($$,"tdname",Copy(name)); /* Use typedef name as class name */ if (class_rename && (Strcmp(class_rename,$3) == 0)) { class_rename = NewString(name); } if (!Getattr(classes,name)) { Setattr(classes,name,$$); } Setattr($$,"decl",decltype); } } } appendChild($$,dump_nested(Char(name))); } Setattr($$,"symtab",Swig_symbol_popscope()); yyrename = NewString(class_rename); Classprefix = 0; Namespaceprefix = Swig_symbol_qualifiedscopename(0); add_symbols($$); if ($9) add_symbols($9); } /* An unnamed struct, possibly with a typedef */ | storage_class cpptype LBRACE { class_rename = make_name(0,0); if (strcmp($2,"class") == 0) { cplus_mode = CPLUS_PRIVATE; } else { cplus_mode = CPLUS_PUBLIC; } Swig_symbol_newscope(); cparse_start_line = cparse_line; inclass = 1; Classprefix = NewString(""); Namespaceprefix = Swig_symbol_qualifiedscopename(0); } cpp_members RBRACE declarator c_decl_tail { String *unnamed; Node *n, *p, *pp = 0; Classprefix = 0; inclass = 0; unnamed = make_unnamed(); $$ = new_node("class"); Setline($$,cparse_start_line); Setattr($$,"kind",$2); Setattr($$,"storage",$1); Setattr($$,"unnamed",unnamed); Setattr($$,"allows_typedef","1"); /* Check for pure-abstract class */ Setattr($$,"abstract", pure_abstract($5)); n = new_node("cdecl"); Setattr(n,"name",$7.id); Setattr(n,"unnamed",unnamed); Setattr(n,"type",unnamed); Setattr(n,"decl",$7.type); Setattr(n,"parms",$7.parms); Setattr(n,"storage",$1); pp = n; if ($8) { set_nextSibling(n,$8); p = $8; while (p) { pp = p; Setattr(p,"unnamed",unnamed); Setattr(p,"type",Copy(unnamed)); Setattr(p,"storage",$1); p = nextSibling(p); } } set_nextSibling($$,n); { /* If a proper typedef name was given, we'll use it to set the scope name */ String *name = 0; if ($1 && (strcmp($1,"typedef") == 0)) { if (!Len($7.type)) { name = $7.id; Setattr($$,"tdname",name); Setattr($$,"name",name); /* if (!class_rename) class_rename = NewString(name); */ Swig_symbol_setscopename(name); /* If a proper name given, we use that as the typedef, not unnamed */ Clear(unnamed); Append(unnamed, name); n = nextSibling(n); set_nextSibling($$,n); /* Check for previous extensions */ if (extendhash) { String *clsname = Swig_symbol_qualifiedscopename(0); Node *am = Getattr(extendhash,clsname); if (am) { /* Merge the extension into the symbol table */ merge_extensions($$,am); appendChild($$,am); Delattr(extendhash,clsname); } Delete(clsname); } if (!classes) classes = NewHash(); Setattr(classes,Swig_symbol_qualifiedscopename(0),$$); } else { Swig_symbol_setscopename((char*)""); } } appendChild($$,$5); appendChild($$,dump_nested(Char(name))); } /* Pop the scope */ Setattr($$,"symtab",Swig_symbol_popscope()); if (class_rename) { yyrename = NewString(class_rename); } Namespaceprefix = Swig_symbol_qualifiedscopename(0); add_symbols($$); add_symbols(n); } ; cpp_opt_declarators : SEMI { $$ = 0; } | declarator c_decl_tail { $$ = new_node("cdecl"); Setattr($$,"name",$1.id); Setattr($$,"decl",$1.type); Setattr($$,"parms",$1.parms); set_nextSibling($$,$2); } ; /* ------------------------------------------------------------ class Name; ------------------------------------------------------------ */ cpp_forward_class_decl : storage_class cpptype idcolon SEMI { if ($1 && (Strcmp($1,"friend") == 0)) { /* Ignore */ $$ = 0; } else { $$ = new_node("classforward"); Setattr($$,"kind",$2); Setattr($$,"name",$3); Setattr($$,"sym:weak", "1"); add_symbols($$); } } ; /* ------------------------------------------------------------ template<...> decl ------------------------------------------------------------ */ cpp_template_decl : TEMPLATE LESSTHAN template_parms GREATERTHAN { template_parameters = $3; } cpp_temp_possible { String *tname = 0; int error = 0; template_parameters = 0; $$ = $6; if ($$) tname = Getattr($$,"name"); /* Check if the class is a template specialization */ if (($$) && (Strstr(tname,"<")) && (Strncmp(tname,"operator ",9) != 0)) { /* If a specialization. Check if defined. */ Node *tempn = 0; { String *tbase = SwigType_templateprefix(tname); tempn = Swig_symbol_clookup_local(tbase,0); if (!tempn || (Strcmp(nodeType(tempn),"template") != 0)) { Swig_warning(WARN_PARSE_TEMPLATE_SP_UNDEF, Getfile($$),Getline($$),"Specialization of non-template '%s'.\n", tbase); tempn = 0; error = 1; } Delete(tbase); } Setattr($$,"specialization","1"); Setattr($$,"templatetype",nodeType($$)); set_nodeType($$,"template"); /* Template partial specialization */ if (tempn && ($3) && ($6)) { List *tlist; String *targs = SwigType_templateargs(tname); tlist = SwigType_parmlist(targs); /* Printf(stdout,"targs = '%s' %s\n", targs, tlist); */ if (!Getattr($$,"sym:weak")) { Setattr($$,"sym:typename","1"); } if (Len(tlist) != ParmList_len(Getattr(tempn,"templateparms"))) { Swig_error(Getfile($$),Getline($$),"Inconsistent argument count in template partial specialization. %d %d\n", Len(tlist), ParmList_len(Getattr(tempn,"templateparms"))); } else { /* This code builds the argument list for the partial template specialization. This is a little hairy, but the idea is as follows: $3 contains a list of arguments supplied for the template. For example template. tlist is a list of the specialization arguments--which may be different. For example class. tp is a copy of the arguments in the original template definition. The patching algorithm walks through the list of supplied arguments ($3), finds the position in the specialization arguments (tlist), and then patches the name in the argument list of the original template. */ { String *pn; Parm *p, *p1; int i, nargs; Parm *tp = CopyParmList(Getattr(tempn,"templateparms")); nargs = Len(tlist); p = $3; while (p) { for (i = 0; i < nargs; i++){ pn = Getattr(p,"name"); if (Strcmp(pn,SwigType_base(Getitem(tlist,i))) == 0) { int j; Parm *p1 = tp; for (j = 0; j < i; j++) { p1 = nextSibling(p1); } Setattr(p1,"name",pn); Setattr(p1,"partialarg","1"); } } p = nextSibling(p); } p1 = tp; i = 0; while (p1) { if (!Getattr(p1,"partialarg")) { Delattr(p1,"name"); Setattr(p1,"type", Getitem(tlist,i)); } i++; p1 = nextSibling(p1); } Setattr($$,"templateparms",tp); } #if 0 /* Patch the parameter list */ if (tempn) { Parm *p,*p1; ParmList *tp = CopyParmList(Getattr(tempn,"templateparms")); p = $3; p1 = tp; while (p && p1) { String *pn = Getattr(p,"name"); Printf(stdout,"pn = '%s'\n", pn); if (pn) Setattr(p1,"name",pn); else Delattr(p1,"name"); pn = Getattr(p,"type"); if (pn) Setattr(p1,"type",pn); p = nextSibling(p); p1 = nextSibling(p1); } Setattr($$,"templateparms",tp); } else { Setattr($$,"templateparms",$3); } #endif Delattr($$,"specialization"); Setattr($$,"partialspecialization","1"); /* Create a specialized name for matching */ { Parm *p = $3; String *fname = NewString(Getattr($$,"name")); String *ffname = 0; char tmp[32]; int i; while (p) { String *n = Getattr(p,"name"); if (!n) { p = nextSibling(p); continue; } for (i = 0; i < Len(tlist); i++) { if (Strstr(Getitem(tlist,i),n)) { sprintf(tmp,"$%d",i+1); Replaceid(fname,n,tmp); } } p = nextSibling(p); } /* Patch argument names with typedef */ { Iterator tt; List *tparms = SwigType_parmlist(fname); ffname = SwigType_templateprefix(fname); Append(ffname,"<("); for (tt = First(tparms); tt.item; ) { SwigType *ttr = Swig_symbol_typedef_reduce(tt.item,0); ttr = Swig_symbol_type_qualify(ttr,0); Append(ffname,ttr); tt = Next(tt); if (tt.item) Putc(',',ffname); } Append(ffname,")>"); } { String *partials = Getattr(tempn,"partials"); if (!partials) { partials = NewList(); Setattr(tempn,"partials",partials); } /* Printf(stdout,"partial: fname = '%s', '%s'\n", fname, Swig_symbol_typedef_reduce(fname,0)); */ Append(partials,ffname); } Setattr($$,"partialargs",ffname); Swig_symbol_cadd(ffname,$$); } } Delete(tlist); Delete(targs); } else { /* Need to resolve exact specialization name */ /* This needs to be rewritten */ List *tparms; String *fname; Iterator tt; fname = SwigType_templateprefix(tname); tparms = SwigType_parmlist(tname); Append(fname,"<("); for (tt = First(tparms); tt.item; ) { SwigType *ttr = Swig_symbol_typedef_reduce(tt.item,0); ttr = Swig_symbol_type_qualify(ttr,0); Append(fname,ttr); tt = Next(tt); if (tt.item) Putc(',',fname); } Append(fname,")>"); Swig_symbol_cadd(fname,$$); } } else if ($$) { Setattr($$,"templatetype",nodeType($6)); set_nodeType($$,"template"); Setattr($$,"templateparms", $3); if (!Getattr($$,"sym:weak")) { Setattr($$,"sym:typename","1"); } add_symbols($$); /* We also place a fully parameterized version in the symbol table */ { Parm *p; String *fname = NewStringf("%s<(",Getattr($$,"name")); p = $3; while (p) { String *n = Getattr(p,"name"); if (!n) n = Getattr(p,"type"); Printf(fname,"%s", n); p = nextSibling(p); if (p) Putc(',',fname); } Printf(fname,")>"); Swig_symbol_cadd(fname,$$); } } if (error) $$ = 0; } | TEMPLATE cpptype idcolon { Swig_warning(WARN_PARSE_EXPLICIT_TEMPLATE, cparse_file, cparse_line, "Explicit template instantiation ignored.\n"); $$ = 0; } ; cpp_temp_possible: c_decl { $$ = $1; } | cpp_class_decl { $$ = $1; } | cpp_constructor_decl { $$ = $1; } | cpp_template_decl { $$ = 0; } | cpp_forward_class_decl { $$ = $1; } ; template_parms : rawparms { /* Rip out the parameter names */ Parm *p = $1; $$ = $1; while (p) { String *name = Getattr(p,"name"); if (!name) { /* Hmmm. Maybe it's a 'class T' parameter */ char *type = Char(Getattr(p,"type")); /* Template template parameter */ if (strncmp(type,"template ",16) == 0) { type += 16; } if ((strncmp(type,"class ",6) == 0) || (strncmp(type,"typename ", 9) == 0)) { char *t = strchr(type,' '); Setattr(p,"name", t+1); } else { /* Swig_error(cparse_file, cparse_line, "Missing template parameter name\n"); $$.rparms = 0; $$.parms = 0; break; */ } } p = nextSibling(p); } } ; /* Namespace support */ cpp_using_decl : USING idcolon SEMI { $$ = new_node("using"); Setattr($$,"uname",$2); Setattr($$,"name", Swig_scopename_last($2)); add_symbols($$); } | USING NAMESPACE idcolon SEMI { Node *n = Swig_symbol_clookup($3,0); if (!n) { Swig_error(cparse_file, cparse_line, "Nothing known about namespace '%s'\n", $3); $$ = 0; } else { while (Strcmp(nodeType(n),"using") == 0) { n = Getattr(n,"node"); } if (n) { if (Strcmp(nodeType(n),"namespace") == 0) { $$ = new_node("using"); Setattr($$,"node",n); Setattr($$,"namespace", $3); Swig_symbol_inherit(Getattr(n,"symtab")); } else { Swig_error(cparse_file, cparse_line, "'%s' is not a namespace.\n", $3); $$ = 0; } } else { $$ = 0; } } } ; cpp_namespace_decl : NAMESPACE idcolon LBRACE { Hash *h; $1 = Swig_symbol_current(); h = Swig_symbol_clookup($2,0); if (h && (Strcmp(nodeType(h),"namespace") == 0)) { if (Getattr(h,"alias")) { h = Getattr(h,"namespace"); Swig_warning(WARN_PARSE_NAMESPACE_ALIAS, cparse_file, cparse_line, "Namespace alias '%s' not allowed here. Assuming '%s'\n", $2, Getattr(h,"name")); $2 = Getattr(h,"name"); } Swig_symbol_setscope(Getattr(h,"symtab")); } else { Swig_symbol_newscope(); Swig_symbol_setscopename($2); } Namespaceprefix = Swig_symbol_qualifiedscopename(0); } interface RBRACE { Node *n = $5; set_nodeType(n,"namespace"); Setattr(n,"name",$2); Setattr(n,"symtab", Swig_symbol_popscope()); Swig_symbol_setscope($1); $$ = n; Namespaceprefix = Swig_symbol_qualifiedscopename(0); add_symbols($$); } | NAMESPACE LBRACE { Hash *h; $1 = Swig_symbol_current(); h = Swig_symbol_clookup((char *)"",0); if (h && (Strcmp(nodeType(h),"namespace") == 0)) { Swig_symbol_setscope(Getattr(h,"symtab")); } else { Swig_symbol_newscope(); Swig_symbol_setscopename("__unnamed__"); } Namespaceprefix = Swig_symbol_qualifiedscopename(0); } interface RBRACE { $$ = $4; set_nodeType($$,"namespace"); Setattr($$,"unnamed","1"); Setattr($$,"symtab", Swig_symbol_popscope()); Swig_symbol_setscope($1); Namespaceprefix = Swig_symbol_qualifiedscopename(0); add_symbols($$); } | NAMESPACE ID EQUAL idcolon SEMI { /* Namespace alias */ Node *n; $$ = new_node("namespace"); Setattr($$,"name",$2); Setattr($$,"alias",$4); n = Swig_symbol_clookup($4,0); if (!n) { Swig_error(cparse_file, cparse_line, "Unknown namespace '%s'\n", $4); $$ = 0; } else { if (Strcmp(nodeType(n),"namespace") != 0) { Swig_error(cparse_file, cparse_line, "'%s' is not a namespace\n",$4); $$ = 0; } else { while (Getattr(n,"alias")) { n = Getattr(n,"namespace"); } Setattr($$,"namespace",n); add_symbols($$); /* Set up a scope alias */ Swig_symbol_alias($2,Getattr(n,"symtab")); } } } ; cpp_members : cpp_member cpp_members { $$ = $1; if ($$) { Node *p = $$; Node *pp =0; while (p) { pp = p; p = nextSibling(p); } set_nextSibling(pp,$2); } else { $$ = $2; } } | EXTEND LBRACE { if (cplus_mode != CPLUS_PUBLIC) { Swig_error(cparse_file,cparse_line,"%%extend can only be used in a public section\n"); } } cpp_members RBRACE cpp_members { $$ = new_node("extend"); Swig_tag_nodes($4,"feature:extend",(char*) "1"); appendChild($$,$4); set_nextSibling($$,$6); } | empty { $$ = 0;} | error { skip_decl(); { static int last_error_line = -1; if (last_error_line != cparse_line) { Swig_error(cparse_file, cparse_line,"Syntax error in input.\n"); last_error_line = cparse_line; } } } cpp_members { $$ = $3; } ; /* ====================================================================== * C++ Class members * ====================================================================== */ /* A class member. May be data or a function. Static or virtual as well */ cpp_member : c_declaration { $$ = $1; } | cpp_constructor_decl { $$ = $1; if (extendmode) { String *symname; symname= make_name(Getattr($$,"name"), Getattr($$,"decl")); if (Strcmp(symname,Getattr($$,"name")) == 0) { /* No renaming operation. Set name to class name */ yyrename = NewString(Getattr(current_class,"sym:name")); } else { yyrename = symname; } } add_symbols($$); } | cpp_destructor_decl { $$ = $1; } | cpp_protection_decl { $$ = $1; } | cpp_swig_directive { $$ = $1; } | cpp_conversion_operator { $$ = $1; } | cpp_forward_class_decl { $$ = $1; } | cpp_nested { $$ = $1; } | storage_class idcolon SEMI { $$ = 0; } | cpp_using_decl { $$ = $1; } | cpp_template_decl { $$ = $1; } | cpp_catch_decl { $$ = 0; } | template_directive { $$ = $1; } | warn_directive { $$ = $1; } | anonymous_bitfield { $$ = 0; } | SEMI { $$ = 0; } ; /* Possibly a constructor */ /* Note: the use of 'type' is here to resolve a shift-reduce conflict. For example: typedef Foo (); typedef Foo (*ptr)(); */ cpp_constructor_decl : storage_class type LPAREN parms RPAREN ctor_end { if (Classprefix) { SwigType *decl = NewString(""); $$ = new_node("constructor"); Setattr($$,"name",$2); Setattr($$,"parms",$4); SwigType_add_function(decl,$4); Setattr($$,"decl",decl); Setattr($$,"throws",$6.throws); if (Len(scanner_ccode)) { Setattr($$,"code",Copy(scanner_ccode)); } Setattr($$,"feature:new","1"); } else { $$ = 0; } } ; /* A destructor (hopefully) */ cpp_destructor_decl : NOT idtemplate LPAREN parms RPAREN cpp_end { $$ = new_node("destructor"); Setattr($$,"name",NewStringf("~%s",$2)); if (Len(scanner_ccode)) { Setattr($$,"code",Copy(scanner_ccode)); } { String *decl = NewString(""); SwigType_add_function(decl,$4); Setattr($$,"decl",decl); } add_symbols($$); } /* A virtual destructor */ | VIRTUAL NOT idtemplate LPAREN parms RPAREN cpp_vend { $$ = new_node("destructor"); /* Check for template names. If the class is a template and the constructor is missing the template part, we add it */ { char *c = Strstr(Classprefix,"<"); if (c) { if (!Strstr($3,"<")) { $3 = NewStringf("%s%s",$3,c); } } } Setattr($$,"storage","virtual"); Setattr($$,"name",NewStringf("~%s",$3)); if ($7.val) { Setattr($$,"value","0"); } if (Len(scanner_ccode)) { Setattr($$,"code",Copy(scanner_ccode)); } { String *decl = NewString(""); SwigType_add_function(decl,$5); Setattr($$,"decl",decl); } add_symbols($$); } ; /* C++ type conversion operator */ cpp_conversion_operator : storage_class COPERATOR type pointer LPAREN parms RPAREN cpp_vend { $$ = new_node("cdecl"); Setattr($$,"type",$3); Setattr($$,"name",$2); SwigType_add_function($4,$6); if ($8.qualifier) { SwigType_push($4,$8.qualifier); } Setattr($$,"decl",$4); Setattr($$,"parms",$6); Setattr($$,"conversion_operator","1"); add_symbols($$); } | storage_class COPERATOR type AND LPAREN parms RPAREN cpp_vend { SwigType *decl; $$ = new_node("cdecl"); Setattr($$,"type",$3); Setattr($$,"name",$2); decl = NewString(""); SwigType_add_reference(decl); SwigType_add_function(decl,$6); if ($8.qualifier) { SwigType_push(decl,$8.qualifier); } Setattr($$,"decl",decl); Setattr($$,"parms",$6); Setattr($$,"conversion_operator","1"); add_symbols($$); } | storage_class COPERATOR type LPAREN parms RPAREN cpp_vend { String *t = NewString(""); $$ = new_node("cdecl"); Setattr($$,"type",$3); Setattr($$,"name",$2); SwigType_add_function(t,$5); if ($7.qualifier) { SwigType_push(t,$7.qualifier); } Setattr($$,"decl",t); Setattr($$,"parms",$5); Setattr($$,"conversion_operator","1"); add_symbols($$); } ; /* isolated catch clause. */ cpp_catch_decl : CATCH LPAREN parms RPAREN LBRACE { skip_balanced('{','}'); $$ = 0; } ; /* public: */ cpp_protection_decl : PUBLIC COLON { $$ = new_node("access"); Setattr($$,"kind","public"); cplus_mode = CPLUS_PUBLIC; } /* private: */ | PRIVATE COLON { $$ = new_node("access"); Setattr($$,"kind","private"); cplus_mode = CPLUS_PRIVATE; } /* protected: */ | PROTECTED COLON { $$ = new_node("access"); Setattr($$,"kind","protected"); cplus_mode = CPLUS_PROTECTED; } ; /* ---------------------------------------------------------------------- Nested structure. This is a sick "hack". If we encounter a nested structure, we're going to grab the text of its definition and feed it back into the scanner. In the meantime, we need to grab variable declaration information and generate the associated wrapper code later. Yikes! This really only works in a limited sense. Since we use the code attached to the nested class to generate both C/C++ code, it can't have any SWIG directives in it. It also needs to be parsable by SWIG or this whole thing is going to puke. ---------------------------------------------------------------------- */ /* A struct sname { } id; declaration */ cpp_nested : storage_class cpptype ID LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}'); } nested_decl SEMI { $$ = 0; if (cplus_mode == CPLUS_PUBLIC) { if ($6.id) { if (strcmp($2,"class") == 0) { Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested classes not currently supported (ignored).\n"); /* Generate some code for a new class */ } else { Nested *n = (Nested *) malloc(sizeof(Nested)); n->code = NewString(""); Printv(n->code, "typedef ", $2, " ", Char(scanner_ccode), " $classname_", $6.id, ";\n", NIL); n->name = Swig_copy_string($6.id); n->line = cparse_start_line; n->type = NewString(""); n->kind = $2; SwigType_push(n->type, $6.type); n->next = 0; add_nested(n); } } else { Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", $2); } } } /* An unnamed nested structure definition */ | storage_class cpptype LBRACE { cparse_start_line = cparse_line; skip_balanced('{','}'); } nested_decl SEMI { $$ = 0; if (cplus_mode == CPLUS_PUBLIC) { if (strcmp($2,"class") == 0) { Swig_warning(WARN_PARSE_NESTED_CLASS,cparse_file, cparse_line,"Nested class not currently supported (ignored)\n"); /* Generate some code for a new class */ } else if ($5.id) { /* Generate some code for a new class */ Nested *n = (Nested *) malloc(sizeof(Nested)); n->code = NewString(""); Printv(n->code, "typedef ", $2, " " , Char(scanner_ccode), " $classname_", $5.id, ";\n",NIL); n->name = Swig_copy_string($5.id); n->line = cparse_start_line; n->type = NewString(""); n->kind = $2; SwigType_push(n->type,$5.type); n->next = 0; add_nested(n); } else { Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", $2); } } } ; nested_decl : declarator { $$ = $1;} | empty { $$.id = 0; } ; /* These directives can be included inside a class definition */ cpp_swig_directive: pragma_directive { $$ = $1; } /* A constant (includes #defines) inside a class */ | constant_directive { $$ = $1; } /* This is the new style rename */ | name_directive { $$ = $1; } /* rename directive */ | rename_directive { $$ = $1; } | feature_directive { $$ = $1; } | varargs_directive { $$ = $1; } | insert_directive { $$ = $1; } | typemap_directive { $$ = $1; } | apply_directive { $$ = $1; } | clear_directive { $$ = $1; } | echo_directive { $$ = $1; } ; cpp_end : cpp_const SEMI { Clear(scanner_ccode); } | cpp_const LBRACE { skip_balanced('{','}'); } ; cpp_vend : cpp_const SEMI { Clear(scanner_ccode); $$.val = 0; $$.qualifier = $1.qualifier; $$.bitfield = 0; $$.throws = $1.throws; } | cpp_const EQUAL definetype SEMI { Clear(scanner_ccode); $$.val = $3.val; $$.qualifier = $1.qualifier; $$.bitfield = 0; $$.throws = $1.throws; } | cpp_const LBRACE { skip_balanced('{','}'); $$.val = 0; $$.qualifier = $1.qualifier; $$.bitfield = 0; $$.throws = $1.throws; } ; anonymous_bitfield : storage_class type COLON NUM_INT SEMI { }; /* ====================================================================== * PRIMITIVES * ====================================================================== */ storage_class : EXTERN { $$ = "extern"; } | EXTERN string { if (strcmp($2,"C") == 0) { $$ = "externc"; } else { Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\" (ignored).\n", $2); $$ = 0; } } | STATIC { $$ = "static"; } | TYPEDEF { $$ = "typedef"; } | VIRTUAL { $$ = "virtual"; } | FRIEND { $$ = "friend"; } | empty { $$ = 0; } ; /* ------------------------------------------------------------------------------ Function parameter lists ------------------------------------------------------------------------------ */ parms : rawparms { Parm *p; $$ = $1; p = $1; while (p) { Replace(Getattr(p,"type"),"typename ", "", DOH_REPLACE_ANY); p = nextSibling(p); } } ; rawparms : parm ptail { if (1) { set_nextSibling($1,$2); $$ = $1; } else { $$ = $2; } } | empty { $$ = 0; } ; ptail : COMMA parm ptail { set_nextSibling($2,$3); $$ = $2; } | empty { $$ = 0; } ; parm : rawtype parameter_declarator { SwigType_push($1,$2.type); $$ = NewParm($1,$2.id); Setfile($$,cparse_file); Setline($$,cparse_line); if ($2.defarg) { Setattr($$,"value",$2.defarg); } } | TEMPLATE LESSTHAN cpptype GREATERTHAN cpptype idcolon { $$ = NewParm(NewStringf("template %s %s", $5,$6), 0); Setfile($$,cparse_file); Setline($$,cparse_line); } | PERIOD PERIOD PERIOD { SwigType *t = NewString("v(...)"); $$ = NewParm(t, 0); Setfile($$,cparse_file); Setline($$,cparse_line); } ; valparms : rawvalparms { Parm *p; $$ = $1; p = $1; while (p) { if (Getattr(p,"type")) { Replace(Getattr(p,"type"),"typename ", "", DOH_REPLACE_ANY); } p = nextSibling(p); } } ; rawvalparms : valparm valptail { if (1) { set_nextSibling($1,$2); $$ = $1; } else { $$ = $2; } } | empty { $$ = 0; } ; valptail : COMMA valparm valptail { set_nextSibling($2,$3); $$ = $2; } | empty { $$ = 0; } ; valparm : parm { $$ = $1; { /* We need to make a possible adjustment for integer parameters. */ SwigType *type; Node *n = 0; while (!n) { type = Getattr($1,"type"); n = Swig_symbol_clookup(type,0); /* See if we can find a node that matches the typename */ if ((n) && (Strcmp(nodeType(n),"cdecl") == 0)) { SwigType *decl = Getattr(n,"decl"); if (!SwigType_isfunction(decl)) { String *value = Getattr(n,"value"); if (value) { Setattr($1,"type",Copy(value)); n = 0; } } } else { break; } } } } | exprnum { $$ = NewParm(0,0); Setfile($$,cparse_file); Setline($$,cparse_line); Setattr($$,"value",$1.val); } | STRING { $$ = NewParm(0,0); Setfile($$,cparse_file); Setline($$,cparse_line); Setattr($$,"value",NewString($1)); } ; def_args : EQUAL definetype { $$ = $2; if ($2.type == T_ERROR) { Swig_warning(WARN_PARSE_BAD_DEFAULT,cparse_file, cparse_line, "Can't set default argument (ignored)\n"); $$.val = 0; $$.rawval = 0; $$.bitfield = 0; $$.throws = 0; } } | EQUAL AND declarator { Node *n = Swig_symbol_clookup($3.id,0); if (n) { String *q = Swig_symbol_qualified(n); if (Getattr(n,"access")) { if (cplus_mode == CPLUS_PUBLIC) { Swig_warning(WARN_PARSE_PRIVATE, cparse_file, cparse_line,"'%s' is private in this context.\n", $3.id); Swig_warning(WARN_PARSE_BAD_DEFAULT, cparse_file, cparse_line,"Can't set default argument value (ignored)\n"); } $$.val = 0; } else { if (q) { String *temp = NewStringf("%s::%s", q, Getattr(n,"name")); $$.val = NewStringf("&%s", SwigType_str($3.type,temp)); Delete(q); Delete(temp); } else { $$.val = NewStringf("&%s", SwigType_str($3.type,$3.id)); } } } else { $$.val = NewStringf("&%s",SwigType_str($3.type,$3.id)); } $$.rawval = 0; $$.type = T_USER; $$.bitfield = 0; $$.throws = 0; } | EQUAL LBRACE { skip_balanced('{','}'); $$.val = 0; $$.rawval = 0; $$.type = T_INT; $$.bitfield = 0; $$.throws = 0; } | COLON NUM_INT { $$.val = 0; $$.rawval = 0; $$.type = 0; $$.bitfield = $2.val; $$.throws = 0; } | empty { $$.val = 0; $$.rawval = 0; $$.type = T_INT; $$.bitfield = 0; $$.throws = 0; } ; parameter_declarator : declarator def_args { $$ = $1; $$.defarg = $2.rawval ? $2.rawval : $2.val; } | abstract_declarator def_args { $$ = $1; $$.defarg = $2.rawval ? $2.rawval : $2.val; } | def_args { $$.type = 0; $$.id = 0; $$.defarg = $1.rawval ? $1.rawval : $1.val; } ; typemap_parameter_declarator : declarator { $$ = $1; if (SwigType_isfunction($1.type)) { Delete(SwigType_pop_function($1.type)); } else if (SwigType_isarray($1.type)) { SwigType *ta = SwigType_pop_arrays($1.type); if (SwigType_isfunction($1.type)) { Delete(SwigType_pop_function($1.type)); } else { $$.parms = 0; } SwigType_push($1.type,ta); Delete(ta); } else { $$.parms = 0; } } | abstract_declarator { $$ = $1; if (SwigType_isfunction($1.type)) { Delete(SwigType_pop_function($1.type)); } else if (SwigType_isarray($1.type)) { SwigType *ta = SwigType_pop_arrays($1.type); if (SwigType_isfunction($1.type)) { Delete(SwigType_pop_function($1.type)); } else { $$.parms = 0; } SwigType_push($1.type,ta); Delete(ta); } else { $$.parms = 0; } } | empty { $$.type = 0; $$.id = 0; $$.parms = 0; } ; declarator : pointer notso_direct_declarator { $$ = $2; if ($$.type) { SwigType_push($1,$$.type); Delete($$.type); } $$.type = $1; } | pointer AND notso_direct_declarator { $$ = $3; SwigType_add_reference($1); if ($$.type) { SwigType_push($1,$$.type); Delete($$.type); } $$.type = $1; } | direct_declarator { $$ = $1; if (!$$.type) $$.type = NewString(""); } | AND notso_direct_declarator { $$ = $2; $$.type = NewString(""); SwigType_add_reference($$.type); if ($2.type) { SwigType_push($$.type,$2.type); Delete($2.type); } } | idcolon DSTAR notso_direct_declarator { SwigType *t = NewString(""); $$ = $3; SwigType_add_memberpointer(t,$1); if ($$.type) { SwigType_push(t,$$.type); Delete($$.type); } $$.type = t; } | pointer idcolon DSTAR notso_direct_declarator { SwigType *t = NewString(""); $$ = $4; SwigType_add_memberpointer(t,$2); SwigType_push($1,t); if ($$.type) { SwigType_push($1,$$.type); Delete($$.type); } $$.type = $1; Delete(t); } | pointer idcolon DSTAR AND notso_direct_declarator { $$ = $5; SwigType_add_memberpointer($1,$2); SwigType_add_reference($1); if ($$.type) { SwigType_push($1,$$.type); Delete($$.type); } $$.type = $1; } | idcolon DSTAR AND notso_direct_declarator { SwigType *t = NewString(""); $$ = $4; SwigType_add_memberpointer(t,$1); SwigType_add_reference(t); if ($$.type) { SwigType_push(t,$$.type); Delete($$.type); } $$.type = t; } ; notso_direct_declarator : idcolon { /* Note: This is non-standard C. Template declarator is allowed to follow an identifier */ $$.id = Char($1); $$.type = 0; $$.parms = 0; $$.have_parms = 0; } | NOT idcolon { $$.id = Char(NewStringf("~%s",$2)); $$.type = 0; $$.parms = 0; $$.have_parms = 0; } /* This generate a shift-reduce conflict with constructors */ | LPAREN idcolon RPAREN { $$.id = Char($2); $$.type = 0; $$.parms = 0; $$.have_parms = 0; } /* | LPAREN AND idcolon RPAREN { $$.id = Char($3); $$.type = 0; $$.parms = 0; $$.have_parms = 0; } */ /* Technically, this should be LPAREN declarator RPAREN, but we get reduce/reduce conflicts */ | LPAREN pointer notso_direct_declarator RPAREN { $$ = $3; if ($$.type) { SwigType_push($2,$$.type); Delete($$.type); } $$.type = $2; } | LPAREN idcolon DSTAR notso_direct_declarator RPAREN { SwigType *t; $$ = $4; t = NewString(""); SwigType_add_memberpointer(t,$2); if ($$.type) { SwigType_push(t,$$.type); Delete($$.type); } $$.type = t; } | notso_direct_declarator LBRACKET RBRACKET { SwigType *t; $$ = $1; t = NewString(""); SwigType_add_array(t,(char*)""); if ($$.type) { SwigType_push(t,$$.type); Delete($$.type); } $$.type = t; } | notso_direct_declarator LBRACKET expr RBRACKET { SwigType *t; $$ = $1; t = NewString(""); SwigType_add_array(t,$3.val); if ($$.type) { SwigType_push(t,$$.type); Delete($$.type); } $$.type = t; } | notso_direct_declarator LPAREN parms RPAREN { SwigType *t; $$ = $1; t = NewString(""); SwigType_add_function(t,$3); if (!$$.have_parms) { $$.parms = $3; $$.have_parms = 1; } if (!$$.type) { $$.type = t; } else { SwigType_push(t, $$.type); Delete($$.type); $$.type = t; } } ; direct_declarator : idcolon { /* Note: This is non-standard C. Template declarator is allowed to follow an identifier */ $$.id = Char($1); $$.type = 0; $$.parms = 0; $$.have_parms = 0; } | NOT idcolon { $$.id = Char(NewStringf("~%s",$2)); $$.type = 0; $$.parms = 0; $$.have_parms = 0; } /* This generate a shift-reduce conflict with constructors */ /* | LPAREN idcolon RPAREN { $$.id = Char($2); $$.type = 0; $$.parms = 0; $$.have_parms = 0; } */ /* Technically, this should be LPAREN declarator RPAREN, but we get reduce/reduce conflicts */ | LPAREN pointer direct_declarator RPAREN { $$ = $3; if ($$.type) { SwigType_push($2,$$.type); Delete($$.type); } $$.type = $2; } | LPAREN AND direct_declarator RPAREN { $$ = $3; if (!$$.type) { $$.type = NewString(""); } SwigType_add_reference($$.type); } | LPAREN idcolon DSTAR direct_declarator RPAREN { SwigType *t; $$ = $4; t = NewString(""); SwigType_add_memberpointer(t,$2); if ($$.type) { SwigType_push(t,$$.type); Delete($$.type); } $$.type = t; } | direct_declarator LBRACKET RBRACKET { SwigType *t; $$ = $1; t = NewString(""); SwigType_add_array(t,(char*)""); if ($$.type) { SwigType_push(t,$$.type); Delete($$.type); } $$.type = t; } | direct_declarator LBRACKET expr RBRACKET { SwigType *t; $$ = $1; t = NewString(""); SwigType_add_array(t,$3.val); if ($$.type) { SwigType_push(t,$$.type); Delete($$.type); } $$.type = t; } | direct_declarator LPAREN parms RPAREN { SwigType *t; $$ = $1; t = NewString(""); SwigType_add_function(t,$3); if (!$$.have_parms) { $$.parms = $3; $$.have_parms = 1; } if (!$$.type) { $$.type = t; } else { SwigType_push(t, $$.type); Delete($$.type); $$.type = t; } } ; abstract_declarator : pointer { $$.type = $1; $$.id = 0; $$.parms = 0; $$.have_parms = 0; } | pointer direct_abstract_declarator { $$ = $2; SwigType_push($1,$2.type); $$.type = $1; Delete($2.type); } | pointer AND { $$.type = $1; SwigType_add_reference($$.type); $$.id = 0; $$.parms = 0; $$.have_parms = 0; } | pointer AND direct_abstract_declarator { $$ = $3; SwigType_add_reference($1); if ($$.type) { SwigType_push($1,$$.type); Delete($$.type); } $$.type = $1; } | direct_abstract_declarator { $$ = $1; } | AND direct_abstract_declarator { $$ = $2; $$.type = NewString(""); SwigType_add_reference($$.type); if ($2.type) { SwigType_push($$.type,$2.type); Delete($2.type); } } | AND { $$.id = 0; $$.parms = 0; $$.have_parms = 0; $$.type = NewString(""); SwigType_add_reference($$.type); } | idcolon DSTAR { $$.type = NewString(""); SwigType_add_memberpointer($$.type,$1); $$.id = 0; $$.parms = 0; $$.have_parms = 0; } | pointer idcolon DSTAR { SwigType *t = NewString(""); $$.type = $1; $$.id = 0; $$.parms = 0; $$.have_parms = 0; SwigType_add_memberpointer(t,$2); SwigType_push($$.type,t); Delete(t); } | pointer idcolon DSTAR direct_abstract_declarator { $$ = $4; SwigType_add_memberpointer($1,$2); if ($$.type) { SwigType_push($1,$$.type); Delete($$.type); } $$.type = $1; } ; direct_abstract_declarator : direct_abstract_declarator LBRACKET RBRACKET { SwigType *t; $$ = $1; t = NewString(""); SwigType_add_array(t,(char*)""); if ($$.type) { SwigType_push(t,$$.type); Delete($$.type); } $$.type = t; } | direct_abstract_declarator LBRACKET expr RBRACKET { SwigType *t; $$ = $1; t = NewString(""); SwigType_add_array(t,$3.val); if ($$.type) { SwigType_push(t,$$.type); Delete($$.type); } $$.type = t; } | LBRACKET RBRACKET { $$.type = NewString(""); $$.id = 0; $$.parms = 0; $$.have_parms = 0; SwigType_add_array($$.type,(char*)""); } | LBRACKET expr RBRACKET { $$.type = NewString(""); $$.id = 0; $$.parms = 0; $$.have_parms = 0; SwigType_add_array($$.type,$2.val); } | LPAREN abstract_declarator RPAREN { $$ = $2; } | direct_abstract_declarator LPAREN parms RPAREN { SwigType *t; $$ = $1; t = NewString(""); SwigType_add_function(t,$3); if (!$$.type) { $$.type = t; } else { SwigType_push(t,$$.type); Delete($$.type); $$.type = t; } if (!$$.have_parms) { $$.parms = $3; $$.have_parms = 1; } } | LPAREN parms RPAREN { $$.type = NewString(""); SwigType_add_function($$.type,$2); $$.parms = $2; $$.have_parms = 1; $$.id = 0; } ; pointer : STAR type_qualifier pointer { $$ = NewString(""); SwigType_add_pointer($$); SwigType_push($$,$2); SwigType_push($$,$3); Delete($3); } | STAR pointer { $$ = NewString(""); SwigType_add_pointer($$); SwigType_push($$,$2); Delete($2); } | STAR type_qualifier { $$ = NewString(""); SwigType_add_pointer($$); SwigType_push($$,$2); } | STAR { $$ = NewString(""); SwigType_add_pointer($$); } ; type_qualifier : type_qualifier_raw { $$ = NewString(""); SwigType_add_qualifier($$,$1); } | type_qualifier_raw type_qualifier { $$ = $2; SwigType_add_qualifier($$,$1); } ; type_qualifier_raw : CONST { $$ = "const"; } | VOLATILE { $$ = "volatile"; } ; /* Data type must be a built in type or an identifier for user-defined types This type can be preceded by a modifier. */ type : rawtype { $$ = $1; Replace($$,"typename ","", DOH_REPLACE_ANY); } ; rawtype : type_qualifier type_right { $$ = $2; SwigType_push($$,$1); } | type_right { $$ = $1; } ; type_right : primitive_type { $$ = $1; /* Printf(stdout,"primitive = '%s'\n", $$);*/ } | TYPE_BOOL { $$ = $1; } | TYPE_VOID { $$ = $1; } | TYPE_TYPEDEF template_decl { $$ = NewStringf("%s%s",$1,$2); } | ENUM idcolon { $$ = NewStringf("enum %s", $2); } | TYPE_RAW { $$ = $1; } | type_right type_qualifier { $$ = $1; SwigType_push($$,$2); } | idcolon { $$ = $1; } | cpptype idcolon { $$ = NewStringf("%s %s", $1, $2); } ; primitive_type : primitive_type_list { if (!$1.type) $1.type = NewString("int"); if ($1.us) { $$ = NewStringf("%s %s", $1.us, $1.type); Delete($1.us); Delete($1.type); } else { $$ = $1.type; } if (Cmp($$,"signed int") == 0) { Delete($$); $$ = NewString("int"); } else if (Cmp($$,"signed long") == 0) { Delete($$); $$ = NewString("long"); } else if (Cmp($$,"signed short") == 0) { Delete($$); $$ = NewString("short"); } else if (Cmp($$,"signed long long") == 0) { Delete($$); $$ = NewString("long long"); } } ; primitive_type_list : type_specifier { $$ = $1; } | type_specifier primitive_type_list { if ($1.us && $2.us) { Swig_error(cparse_file, cparse_line, "Extra %s specifier.\n", $2.us); } $$ = $2; if ($1.us) $$.us = $1.us; if ($1.type) { if (!$2.type) $$.type = $1.type; else { int err = 0; if ((Cmp($1.type,"long") == 0)) { if ((Cmp($2.type,"long") == 0) || (Cmp($2.type,"double") == 0)) { $$.type = NewStringf("long %s", $2.type); } else if (Cmp($2.type,"int") == 0) { $$.type = $1.type; } else { err = 1; } } else if ((Cmp($1.type,"short")) == 0) { if (Cmp($2.type,"int") == 0) { $$.type = $1.type; } else { err = 1; } } else if (Cmp($1.type,"int") == 0) { $$.type = $2.type; } else if (Cmp($1.type,"double") == 0) { if (Cmp($2.type,"long") == 0) { $$.type = NewString("long double"); } else { err = 1; } } if (err) { Swig_error(cparse_file, cparse_line, "Extra %s specifier.\n", $1.type); } } } } ; type_specifier : TYPE_INT { $$.type = NewString("int"); $$.us = 0; } | TYPE_SHORT { $$.type = NewString("short"); $$.us = 0; } | TYPE_LONG { $$.type = NewString("long"); $$.us = 0; } | TYPE_CHAR { $$.type = NewString("char"); $$.us = 0; } | TYPE_FLOAT { $$.type = NewString("float"); $$.us = 0; } | TYPE_DOUBLE { $$.type = NewString("double"); $$.us = 0; } | TYPE_SIGNED { $$.us = NewString("signed"); $$.type = 0; } | TYPE_UNSIGNED { $$.us = NewString("unsigned"); $$.type = 0; } ; definetype : { /* scanner_check_typedef(); */ } expr { $$ = $2; if ($$.type == T_STRING) { $$.rawval = NewStringf("\"%(escape)s\"",$$.val); } else { $$.rawval = 0; } $$.bitfield = 0; $$.throws = 0; scanner_ignore_typedef(); } /* | string { $$.val = NewString($1); $$.rawval = NewStringf("\"%(escape)s\"",$$.val); $$.type = T_STRING; $$.bitfield = 0; $$.throws = 0; } */ | CHARCONST { $$.val = NewString($1); /* $$.rawval = NewStringf("\'%(escape)s\'",$$.val); */ /* Printf(stdout,"rawval = '%s'\n", $$.rawval); */ if (Len($$.val)) { $$.rawval = NewStringf("\'%(escape)s\'", $$.val); } else { $$.rawval = NewString("\'\\0'"); } $$.type = T_CHAR; $$.bitfield = 0; $$.throws = 0; } ; /* Some stuff for handling enums */ ename : ID { $$ = $1; } | empty { $$ = (char *) 0;} ; /* SWIG enum list */ enumlist : enumlist COMMA edecl { Node *leftSibling = Getattr($1,"_last"); if (!leftSibling) { leftSibling=$1; } set_nextSibling(leftSibling,$3); Setattr($1,"_last",$3); if ($3 && !Getattr($3, "enumvalue")) { /* There is no explicit enum value given, so make one. */ Setattr($3,"enumvalue", NewStringf("%s+1", Getattr(leftSibling,"name"))); } $$ = $1; } | edecl { $$ = $1; if (!Getattr($1, "enumvalue")) { /* first enum item value defaults to 0 */ Setattr($1,"enumvalue", "0"); } } ; edecl : ID { $$ = new_node("enumitem"); Setattr($$,"name",$1); Setattr($$,"type",NewSwigType(T_INT)); Setattr($$,"feature:immutable","1"); } | ID EQUAL etype { $$ = new_node("enumitem"); Setattr($$,"name",$1); Setattr($$,"enumvalue", $3.val); if ($3.type == T_CHAR) { Setattr($$,"value",$3.val); Setattr($$,"type",NewSwigType(T_CHAR)); } else { Setattr($$,"value",$1); Setattr($$,"type",NewSwigType(T_INT)); } Setattr($$,"feature:immutable","1"); } | empty { $$ = 0; } ; etype : expr { $$ = $1; if (($$.type != T_INT) && ($$.type != T_UINT) && ($$.type != T_LONG) && ($$.type != T_ULONG) && ($$.type != T_SHORT) && ($$.type != T_USHORT) && ($$.type != T_SCHAR) && ($$.type != T_UCHAR)) { Swig_error(cparse_file,cparse_line,"Type error. Expecting an int\n"); } } | CHARCONST { $$.val = NewString($1); $$.type = T_INT; } ; /* Arithmetic expressions. Used for constants and other cool stuff. Really, we're not doing anything except string concatenation, but this does allow us to parse many constant declarations. */ expr : exprnum { $$ = $1; } | string { $$.val = NewString($1); $$.type = T_STRING; } | SIZEOF LPAREN type parameter_declarator RPAREN { SwigType_push($3,$4.type); $$.val = NewStringf("sizeof(%s)",SwigType_str($3,0)); $$.type = T_INT; } | exprcompound { $$ = $1; } | type { Node *n; $$.val = $1; $$.type = T_INT; /* Check if value is in scope */ n = Swig_symbol_clookup($1,0); if (n) { if (Getattr(n,"access") && (cplus_mode == CPLUS_PUBLIC)) { Swig_warning(WARN_PARSE_PRIVATE,cparse_file, cparse_line, "'%s' is private in this context.\n", $1); $$.type = T_ERROR; } else { /* A band-aid for enum values used in expressions. */ if (Strcmp(nodeType(n),"enumitem") == 0) { String *q = Swig_symbol_qualified(n); if (q) { $$.val = NewStringf("%s::%s", q, Getattr(n,"name")); Delete(q); } } } } } /* grouping */ | LPAREN expr RPAREN %prec CAST { $$.val = NewStringf("(%s)",$2.val); $$.type = $2.type; } /* A few common casting operations */ | LPAREN expr RPAREN expr %prec CAST { $$ = $4; if ($4.type != T_STRING) { $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $4.val); } } | LPAREN expr pointer RPAREN expr %prec CAST { $$ = $5; if ($5.type != T_STRING) { SwigType_push($2.val,$3); $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $5.val); } } | LPAREN expr AND RPAREN expr %prec CAST { $$ = $5; if ($5.type != T_STRING) { SwigType_add_reference($2.val); $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $5.val); } } | LPAREN expr pointer AND RPAREN expr %prec CAST { $$ = $6; if ($6.type != T_STRING) { SwigType_push($2.val,$3); SwigType_add_reference($2.val); $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $6.val); } } ; exprnum : NUM_INT { $$ = $1; } | NUM_FLOAT { $$ = $1; } | NUM_UNSIGNED { $$ = $1; } | NUM_LONG { $$ = $1; } | NUM_ULONG { $$ = $1; } | NUM_LONGLONG { $$ = $1; } | NUM_ULONGLONG { $$ = $1; } ; exprcompound : expr PLUS expr { $$.val = NewStringf("%s+%s",$1.val,$3.val); $$.type = promote($1.type,$3.type); } | expr MINUS expr { $$.val = NewStringf("%s-%s",$1.val,$3.val); $$.type = promote($1.type,$3.type); } | expr STAR expr { $$.val = NewStringf("%s*%s",$1.val,$3.val); $$.type = promote($1.type,$3.type); } | expr SLASH expr { $$.val = NewStringf("%s/%s",$1.val,$3.val); $$.type = promote($1.type,$3.type); } | expr AND expr { $$.val = NewStringf("%s&%s",$1.val,$3.val); $$.type = promote($1.type,$3.type); } | expr OR expr { $$.val = NewStringf("%s|%s",$1.val,$3.val); $$.type = promote($1.type,$3.type); } | expr XOR expr { $$.val = NewStringf("%s^%s",$1.val,$3.val); $$.type = promote($1.type,$3.type); } | expr LSHIFT expr { $$.val = NewStringf("%s<<%s",$1.val,$3.val); $$.type = promote($1.type,$3.type); } | expr RSHIFT expr { $$.val = NewStringf("%s>>%s",$1.val,$3.val); $$.type = promote($1.type,$3.type); } | expr LAND expr { $$.val = NewStringf("%s&&%s",$1.val,$3.val); $$.type = T_INT; } | expr LOR expr { $$.val = NewStringf("%s||%s",$1.val,$3.val); $$.type = T_INT; } | MINUS expr %prec UMINUS { $$.val = NewStringf("-%s",$2.val); $$.type = $2.type; } | PLUS expr %prec UMINUS { $$.val = NewStringf("+%s",$2.val); $$.type = $2.type; } | NOT expr { $$.val = NewStringf("~%s",$2.val); $$.type = $2.type; } | LNOT expr { $$.val = NewStringf("!%s",$2.val); $$.type = T_INT; } | type LPAREN { skip_balanced('(',')'); if (SwigType_istemplate($1)) { $1 = SwigType_namestr($1); } $$.val = NewStringf("%s%s",$1,scanner_ccode); Clear(scanner_ccode); $$.type = T_INT; } ; inherit : raw_inherit { $$ = $1; } ; raw_inherit : COLON { inherit_list = 1; } base_list { $$ = $3; inherit_list = 0; } | empty { $$ = 0; } ; base_list : base_specifier { $$ = NewList(); if ($1) Append($$,$1); } | base_list COMMA base_specifier { $$ = $1; if ($3) Append($$,$3); } ; base_specifier : opt_virtual idcolon { if (last_cpptype && (Strcmp(last_cpptype,"struct") != 0)) { Swig_warning(WARN_PARSE_NO_ACCESS,cparse_file, cparse_line,"No access specifier given for base class %s (ignored).\n",$2); $$ = (char *) 0; } else { $$ = $2; Setfile($$,cparse_file); Setline($$,cparse_line); } } | opt_virtual access_specifier opt_virtual idcolon { $$ = 0; if (strcmp($2,"public") == 0) { $$ = $4; Setfile($$, cparse_file); Setline($$, cparse_line); } else { Swig_warning(WARN_PARSE_PRIVATE_INHERIT, cparse_file, cparse_line, "%s inheritance ignored.\n", $2); } } ; access_specifier : PUBLIC { $$ = (char*)"public"; } | PRIVATE { $$ = (char*)"private"; } | PROTECTED { $$ = (char*)"protected"; } ; cpptype : CLASS { $$ = (char*)"class"; if (!inherit_list) last_cpptype = $$; } | STRUCT { $$ = (char*)"struct"; if (!inherit_list) last_cpptype = $$; } | UNION { $$ = (char*)"union"; if (!inherit_list) last_cpptype = $$; } | TYPENAME { $$ = (char *)"typename"; if (!inherit_list) last_cpptype = $$; } ; opt_virtual : VIRTUAL | empty ; cpp_const : type_qualifier { $$.qualifier = $1; $$.throws = 0; } | THROW LPAREN parms RPAREN { $$.qualifier = 0; $$.throws = $3; } | type_qualifier THROW LPAREN parms RPAREN { $$.qualifier = $1; $$.throws = $4; } | empty { $$.qualifier = 0; $$.throws = 0; } ; ctor_end : cpp_const ctor_initializer SEMI { Clear(scanner_ccode); $$.have_parms = 0; $$.defarg = 0; $$.throws = $1.throws; } | cpp_const ctor_initializer LBRACE { skip_balanced('{','}'); $$.have_parms = 0; $$.defarg = 0; $$.throws = $1.throws; } | LPAREN parms RPAREN SEMI { Clear(scanner_ccode); $$.parms = $2; $$.have_parms = 1; $$.defarg = 0; $$.throws = 0; } | LPAREN parms RPAREN LBRACE { skip_balanced('{','}'); $$.parms = $2; $$.have_parms = 1; $$.defarg = 0; $$.throws = 0; } | EQUAL definetype SEMI { $$.have_parms = 0; $$.defarg = $2.val; $$.throws = 0; } ; ctor_initializer : COLON mem_initializer_list | empty ; mem_initializer_list : mem_initializer | mem_initializer_list COMMA mem_initializer ; mem_initializer : idcolon LPAREN { skip_balanced('(',')'); Clear(scanner_ccode); } ; template_decl : LESSTHAN valparms GREATERTHAN { String *s = NewString(""); SwigType_add_template(s,$2); $$ = Char(s); scanner_last_id(1); } | empty { $$ = (char*)""; } ; idstring : ID { $$ = $1; } | string { $$ = $1; } ; idstringopt : idstring { $$ = $1; } | empty { $$ = 0; } ; idcolon : idtemplate idcolontail { $$ = 0; if (!$$) $$ = NewStringf("%s%s", $1,$2); Delete($2); } | NONID DCOLON idtemplate idcolontail { $$ = NewStringf("::%s%s",$3,$4); Delete($4); } | idtemplate { $$ = NewString($1); } | NONID DCOLON idtemplate { $$ = NewStringf("::%s",$3); } | OPERATOR { $$ = NewString($1); } | NONID DCOLON OPERATOR { $$ = NewStringf("::%s",$3); } ; idcolontail : DCOLON idtemplate idcolontail { $$ = NewStringf("::%s%s",$2,$3); Delete($3); } | DCOLON idtemplate { $$ = NewStringf("::%s",$2); } | DCOLON OPERATOR { $$ = NewStringf("::%s",$2); } /* | DCOLON COPERATOR { $$ = NewString($2); } */ | DCNOT idtemplate { $$ = NewStringf("::~%s",$2); } ; idtemplate : ID template_decl { $$ = NewStringf("%s%s",$1,$2); /* if (Len($2)) { scanner_last_id(1); } */ } ; /* Identifier, but no templates */ idcolonnt : ID idcolontailnt { $$ = 0; if (!$$) $$ = NewStringf("%s%s", $1,$2); Delete($2); } | NONID DCOLON ID idcolontailnt { $$ = NewStringf("::%s%s",$3,$4); Delete($4); } | ID { $$ = NewString($1); } | NONID DCOLON ID { $$ = NewStringf("::%s",$3); } | OPERATOR { $$ = NewString($1); } | NONID DCOLON OPERATOR { $$ = NewStringf("::%s",$3); } ; idcolontailnt : DCOLON ID idcolontailnt { $$ = NewStringf("::%s%s",$2,$3); Delete($3); } | DCOLON ID { $$ = NewStringf("::%s",$2); } | DCOLON OPERATOR { $$ = NewStringf("::%s",$2); } | DCNOT ID { $$ = NewStringf("::~%s",$2); } ; /* Concatenated strings */ string : string STRING { $$ = (char *) malloc(strlen($1)+strlen($2)+1); strcpy($$,$1); strcat($$,$2); } | STRING { $$ = $1;} ; stringbrace : string { $$ = NewString($1); } | LBRACE { skip_balanced('{','}'); $$ = NewString(scanner_ccode); } | HBLOCK { $$ = $1; } ; options : LPAREN kwargs RPAREN { Hash *n; $$ = NewHash(); n = $2; while(n) { String *name, *value; name = Getattr(n,"name"); value = Getattr(n,"value"); if (!value) value = (String *) "1"; Setattr($$,name, value); n = nextSibling(n); } } | empty { $$ = 0; }; /* Keyword arguments */ kwargs : idstring EQUAL stringnum { $$ = NewHash(); Setattr($$,"name",$1); Setattr($$,"value",$3); } | idstring EQUAL stringnum COMMA kwargs { $$ = NewHash(); Setattr($$,"name",$1); Setattr($$,"value",$3); set_nextSibling($$,$5); } | idstring { $$ = NewHash(); Setattr($$,"name",$1); } | idstring COMMA kwargs { $$ = NewHash(); Setattr($$,"name",$1); set_nextSibling($$,$3); } ; stringnum : string { $$ = $1; } | exprnum { $$ = Char($1.val); } ; empty : ; %% SwigType *Swig_cparse_type(String *s) { String *ns; ns = NewStringf("%s;",s); Seek(ns,0,SEEK_SET); scanner_file(ns); top = 0; scanner_next_token(PARSETYPE); yyparse(); /* Printf(stdout,"typeparse: '%s' ---> '%s'\n", s, top); */ return top; } Parm *Swig_cparse_parm(String *s) { String *ns; ns = NewStringf("%s;",s); Seek(ns,0,SEEK_SET); scanner_file(ns); top = 0; scanner_next_token(PARSEPARM); yyparse(); /* Printf(stdout,"typeparse: '%s' ---> '%s'\n", s, top); */ return top; } cableswig-0.1.0+git20150808.orig/SWIG/Source/CParse/cparse.h0000644000175000000620000000363712561312227021652 0ustar stevestaff/* ----------------------------------------------------------------------------- * cparse.h * * SWIG parser module. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2003. The University of Chicago * See the file LICENSE for information on usage and redistribution. * * /cvsroot/SWIG/Source/CParse/cparse.h,v 1.5 2004/01/15 03:16:40 mmatus Exp * ----------------------------------------------------------------------------- */ #ifndef CPARSE_H_ #define CPARSE_H_ #include "swig.h" #include "swigwarn.h" #ifdef __cplusplus extern "C" { #endif /* cscanner.c */ extern char *cparse_file; extern int cparse_line; extern int cparse_cplusplus; extern int cparse_start_line; extern void Swig_cparse_cplusplus(int); extern void scanner_file(File *); extern void scanner_next_token(int); extern void skip_balanced(int startchar, int endchar); extern void skip_decl(void); extern void scanner_check_typedef(void); extern void scanner_ignore_typedef(void); extern void scanner_last_id(int); extern void scanner_clear_rename(void); extern void start_inline(char *, int); extern String *scanner_ccode; extern int yylex(); /* parser.y */ extern SwigType *Swig_cparse_type(String *); extern Node *Swig_cparse(File *); /* util.c */ extern void Swig_cparse_replace_descriptor(String *s); extern void cparse_normalize_void(Node *); extern int need_protected(Node *n, int dirprot_mode); extern Parm *Swig_cparse_parm(String *s); extern int need_name_warning(Node *n); extern int need_redefined_warn(Node* a, Node* b, int InClass); /* templ.c */ extern int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms); extern Node *Swig_cparse_template_locate(String *name, ParmList *tparms); extern void Swig_cparse_debug_templates(int); #ifdef __cplusplus } #endif #endif cableswig-0.1.0+git20150808.orig/SWIG/Source/CParse/.cvsignore0000644000175000000620000000010612561312227022210 0ustar stevestaff.deps .dirstamp parser.c parser.h cscanner.o parser.o y.tab.c y.tab.h cableswig-0.1.0+git20150808.orig/SWIG/Source/CParse/parser.c.in0000644000175000000620000107023112561312227022264 0ustar stevestaff/* A Bison parser, made by GNU Bison 1.875a. */ /* Skeleton parser for Yacc-like parsing with Bison, Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* As a special exception, when this file is copied by Bison into a Bison output file, you may use that output file without restriction. This special exception was added by the Free Software Foundation in version 1.24 of Bison. */ /* Written by Richard Stallman by simplifying the original so called ``semantic'' parser. */ /* All symbols defined below should begin with yy or YY, to avoid infringing on user name space. This should be done even for local variables, as they might otherwise be expanded by user macros. There are some unavoidable exceptions within include files to define necessary library symbols; they are noted "INFRINGES ON USER NAME SPACE" below. */ /* Identify Bison output. */ #define YYBISON 1 /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" /* Pure parsers. */ #define YYPURE 0 /* Using locations. */ #define YYLSP_NEEDED 0 /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { ID = 258, HBLOCK = 259, POUND = 260, STRING = 261, INCLUDE = 262, IMPORT = 263, INSERT = 264, CHARCONST = 265, NUM_INT = 266, NUM_FLOAT = 267, NUM_UNSIGNED = 268, NUM_LONG = 269, NUM_ULONG = 270, NUM_LONGLONG = 271, NUM_ULONGLONG = 272, TYPEDEF = 273, TYPE_INT = 274, TYPE_UNSIGNED = 275, TYPE_SHORT = 276, TYPE_LONG = 277, TYPE_FLOAT = 278, TYPE_DOUBLE = 279, TYPE_CHAR = 280, TYPE_VOID = 281, TYPE_SIGNED = 282, TYPE_BOOL = 283, TYPE_TYPEDEF = 284, TYPE_RAW = 285, LPAREN = 286, RPAREN = 287, COMMA = 288, SEMI = 289, EXTERN = 290, INIT = 291, LBRACE = 292, RBRACE = 293, PERIOD = 294, CONST = 295, VOLATILE = 296, STRUCT = 297, UNION = 298, EQUAL = 299, SIZEOF = 300, MODULE = 301, LBRACKET = 302, RBRACKET = 303, ILLEGAL = 304, CONSTANT = 305, NAME = 306, RENAME = 307, NAMEWARN = 308, EXTEND = 309, PRAGMA = 310, FEATURE = 311, VARARGS = 312, ENUM = 313, CLASS = 314, TYPENAME = 315, PRIVATE = 316, PUBLIC = 317, PROTECTED = 318, COLON = 319, STATIC = 320, VIRTUAL = 321, FRIEND = 322, THROW = 323, CATCH = 324, USING = 325, NAMESPACE = 326, NATIVE = 327, INLINE = 328, TYPEMAP = 329, EXCEPT = 330, ECHO = 331, APPLY = 332, CLEAR = 333, SWIGTEMPLATE = 334, FRAGMENT = 335, WARN = 336, LESSTHAN = 337, GREATERTHAN = 338, MODULO = 339, DELETE = 340, TYPES = 341, PARMS = 342, NONID = 343, DSTAR = 344, DCNOT = 345, TEMPLATE = 346, OPERATOR = 347, COPERATOR = 348, PARSETYPE = 349, PARSEPARM = 350, CAST = 351, LOR = 352, LAND = 353, OR = 354, XOR = 355, AND = 356, RSHIFT = 357, LSHIFT = 358, MINUS = 359, PLUS = 360, SLASH = 361, STAR = 362, LNOT = 363, NOT = 364, UMINUS = 365, DCOLON = 366 }; #endif #define ID 258 #define HBLOCK 259 #define POUND 260 #define STRING 261 #define INCLUDE 262 #define IMPORT 263 #define INSERT 264 #define CHARCONST 265 #define NUM_INT 266 #define NUM_FLOAT 267 #define NUM_UNSIGNED 268 #define NUM_LONG 269 #define NUM_ULONG 270 #define NUM_LONGLONG 271 #define NUM_ULONGLONG 272 #define TYPEDEF 273 #define TYPE_INT 274 #define TYPE_UNSIGNED 275 #define TYPE_SHORT 276 #define TYPE_LONG 277 #define TYPE_FLOAT 278 #define TYPE_DOUBLE 279 #define TYPE_CHAR 280 #define TYPE_VOID 281 #define TYPE_SIGNED 282 #define TYPE_BOOL 283 #define TYPE_TYPEDEF 284 #define TYPE_RAW 285 #define LPAREN 286 #define RPAREN 287 #define COMMA 288 #define SEMI 289 #define EXTERN 290 #define INIT 291 #define LBRACE 292 #define RBRACE 293 #define PERIOD 294 #define CONST 295 #define VOLATILE 296 #define STRUCT 297 #define UNION 298 #define EQUAL 299 #define SIZEOF 300 #define MODULE 301 #define LBRACKET 302 #define RBRACKET 303 #define ILLEGAL 304 #define CONSTANT 305 #define NAME 306 #define RENAME 307 #define NAMEWARN 308 #define EXTEND 309 #define PRAGMA 310 #define FEATURE 311 #define VARARGS 312 #define ENUM 313 #define CLASS 314 #define TYPENAME 315 #define PRIVATE 316 #define PUBLIC 317 #define PROTECTED 318 #define COLON 319 #define STATIC 320 #define VIRTUAL 321 #define FRIEND 322 #define THROW 323 #define CATCH 324 #define USING 325 #define NAMESPACE 326 #define NATIVE 327 #define INLINE 328 #define TYPEMAP 329 #define EXCEPT 330 #define ECHO 331 #define APPLY 332 #define CLEAR 333 #define SWIGTEMPLATE 334 #define FRAGMENT 335 #define WARN 336 #define LESSTHAN 337 #define GREATERTHAN 338 #define MODULO 339 #define DELETE 340 #define TYPES 341 #define PARMS 342 #define NONID 343 #define DSTAR 344 #define DCNOT 345 #define TEMPLATE 346 #define OPERATOR 347 #define COPERATOR 348 #define PARSETYPE 349 #define PARSEPARM 350 #define CAST 351 #define LOR 352 #define LAND 353 #define OR 354 #define XOR 355 #define AND 356 #define RSHIFT 357 #define LSHIFT 358 #define MINUS 359 #define PLUS 360 #define SLASH 361 #define STAR 362 #define LNOT 363 #define NOT 364 #define UMINUS 365 #define DCOLON 366 /* Copy the first part of user declarations. */ #line 1 "CableSwig/SWIG/Source/CParse/parser.y" /* ----------------------------------------------------------------------------- * parser.y * * YACC parser for SWIG. The grammar is a somewhat broken subset of C/C++. * This file is a bit of a mess and probably needs to be rewritten at * some point. Beware. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1998-2001. The University of Chicago * Copyright (C) 1995-1998. The University of Utah and The Regents of the * University of California. * * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ #define yylex yylex char cvsroot_parser_y[] = "/cvsroot/SWIG/Source/CParse/parser.y,v 1.45 2004/01/27 23:39:34 mmatus Exp"; #include "swig.h" #include "cparse.h" #include "preprocessor.h" #include /* We do this for portability */ #undef alloca #define alloca malloc /* ----------------------------------------------------------------------------- * Externals * ----------------------------------------------------------------------------- */ int yyparse(); /* NEW Variables */ static Node *top = 0; /* Top of the generated parse tree */ static int unnamed = 0; /* Unnamed datatype counter */ static Hash *extendhash = 0; /* Hash table of added methods */ static Hash *classes = 0; /* Hash table of classes */ static Symtab *prev_symtab = 0; static Node *current_class = 0; String *ModuleName = 0; static Node *module_node = 0; static String *Classprefix = 0; static String *Namespaceprefix = 0; static int inclass = 0; static char *last_cpptype = 0; static int inherit_list = 0; static Parm *template_parameters = 0; static int extendmode = 0; static int dirprot_mode = 0; /* ----------------------------------------------------------------------------- * Assist Functions * ----------------------------------------------------------------------------- */ /* Called by the parser (yyparse) when an error is found.*/ static void yyerror (const char *e) { (void)e; } static Node *new_node(const String_or_char *tag) { Node *n = NewHash(); set_nodeType(n,tag); Setfile(n,cparse_file); Setline(n,cparse_line); return n; } /* Copies a node. Does not copy tree links or symbol table data (except for sym:name) */ static Node *copy_node(Node *n) { Node *nn; String *key; Iterator k; nn = NewHash(); Setfile(nn,Getfile(n)); Setline(nn,Getline(n)); for (k = First(n); k.key; k = Next(k)) { key = k.key; if ((Strcmp(key,"nextSibling") == 0) || (Strcmp(key,"previousSibling") == 0) || (Strcmp(key,"parentNode") == 0) || (Strcmp(key,"lastChild") == 0)) { continue; } if (Strncmp(key,"csym:",5) == 0) continue; /* We do copy sym:name. For templates */ if ((Strcmp(key,"sym:name") == 0) || (Strcmp(key,"sym:weak") == 0) || (Strcmp(key,"sym:typename") == 0)) { Setattr(nn,key, Copy(k.item)); continue; } if (Strcmp(key,"sym:symtab") == 0) { Setattr(nn,"sym:needs_symtab", "1"); } /* We don't copy any other symbol table attributes */ if (Strncmp(key,"sym:",4) == 0) { continue; } /* If children. We copy them recursively using this function */ if (Strcmp(key,"firstChild") == 0) { /* Copy children */ Node *cn = k.item; while (cn) { appendChild(nn,copy_node(cn)); cn = nextSibling(cn); } continue; } /* We don't copy the symbol table. But we drop an attribute requires_symtab so that functions know it needs to be built */ if (Strcmp(key,"symtab") == 0) { /* Node defined a symbol table. */ Setattr(nn,"requires_symtab","1"); continue; } /* Can't copy nodes */ if (Strcmp(key,"node") == 0) { continue; } if ((Strcmp(key,"parms") == 0) || (Strcmp(key,"pattern") == 0) || (Strcmp(key,"throws") == 0)) { Setattr(nn,key,CopyParmList(k.item)); continue; } /* Looks okay. Just copy the data using Copy */ Setattr(nn, key, Copy(k.item)); } return nn; } /* ----------------------------------------------------------------------------- * Variables * ----------------------------------------------------------------------------- */ char *typemap_lang = 0; /* Current language setting */ static int cplus_mode = 0; static String *class_rename = 0; /* C++ modes */ #define CPLUS_PUBLIC 1 #define CPLUS_PRIVATE 2 #define CPLUS_PROTECTED 3 void SWIG_typemap_lang(const char *tm_lang) { typemap_lang = Swig_copy_string(tm_lang); } /* ----------------------------------------------------------------------------- * Assist functions * ----------------------------------------------------------------------------- */ /* Perform type-promotion for binary operators */ static int promote(int t1, int t2) { return t1 > t2 ? t1 : t2; } static String *yyrename = 0; /* Forward renaming operator */ static Hash *rename_hash = 0; static Hash *namewarn_hash = 0; static Hash *features_hash = 0; static String *feature_identifier_fix(String *s) { if (SwigType_istemplate(s)) { String *tp, *ts, *ta, *tq; tp = SwigType_templateprefix(s); ts = SwigType_templatesuffix(s); ta = SwigType_templateargs(s); tq = Swig_symbol_type_qualify(ta,0); Append(tp,tq); Append(tp,ts); Delete(ts); Delete(ta); Delete(tq); return tp; } else { return NewString(s); } } static void rename_add(char *name, SwigType *decl, char *newname) { String *nname; if (!rename_hash) rename_hash = NewHash(); if (Namespaceprefix) { nname = NewStringf("%s::%s",Namespaceprefix, name); } else { nname = NewString(name); } Swig_name_object_set(rename_hash,nname,decl,NewString(newname)); Delete(nname); } static void namewarn_add(char *name, SwigType *decl, char *warning) { String *nname; if (!namewarn_hash) namewarn_hash = NewHash(); if (Namespaceprefix) { nname = NewStringf("%s::%s",Namespaceprefix, name); } else { nname = NewString(name); } Swig_name_object_set(namewarn_hash,nname,decl,NewString(warning)); Delete(nname); } static void rename_inherit(String *base, String *derived) { /* Printf(stdout,"base = '%s', derived = '%s'\n", base, derived); */ Swig_name_object_inherit(rename_hash,base,derived); Swig_name_object_inherit(namewarn_hash,base,derived); Swig_name_object_inherit(features_hash,base,derived); } /* Generate the symbol table name for an object */ /* This is a bit of a mess. Need to clean up */ static String *add_oldname = 0; static String *make_name(String *name,SwigType *decl) { String *rn = 0; String *origname = name; int destructor = 0; if (name && (*(Char(name)) == '~')) { destructor = 1; } if (yyrename) { String *s = yyrename; yyrename = 0; if (destructor) { Insert(s,0,"~"); } return s; } if (!name) return 0; /* Check to see if the name is in the hash */ if (!rename_hash) { if (add_oldname) return Copy(add_oldname); return origname; } rn = Swig_name_object_get(rename_hash, Namespaceprefix, name, decl); if (!rn) { if (add_oldname) return Copy(add_oldname); return name; } if (destructor) { if (Strcmp(rn,"$ignore") != 0) { String *s = NewStringf("~%s", rn); return s; } } return Copy(rn); } /* Generate an unnamed identifier */ static String *make_unnamed() { unnamed++; return NewStringf("$unnamed%d$",unnamed); } /* Return the node name when it requires to emit a name warning */ static String *name_warning(Node *n,String *name,SwigType *decl) { /* Return in the obvious cases */ if (!namewarn_hash || !name || !need_name_warning(n)) return 0; /* Check to see if the name is in the hash */ return Swig_name_object_get(namewarn_hash,Namespaceprefix,name,decl); } /* Return if the node is a friend declaration */ static int is_friend(Node *n) { return Cmp(Getattr(n,"storage"),"friend") == 0; } /* Add declaration list to symbol table */ static int add_only_one = 0; static void add_symbols(Node *n) { String *decl; String *wrn = 0; if (inclass) { cparse_normalize_void(n); } while (n) { String *symname; /* for friends, we need to pop the scope once */ int isfriend = is_friend(n); Symtab *class_scope = isfriend ? Swig_symbol_popscope() : 0; if (!isfriend && inclass && (cplus_mode != CPLUS_PUBLIC)) { int only_csymbol = 1; if (cplus_mode == CPLUS_PROTECTED) { Setattr(n,"access", "protected"); only_csymbol = !need_protected(n, dirprot_mode); } else { Setattr(n,"access", "private"); } if (only_csymbol) { /* Only add to C symbol table and continue */ Swig_symbol_add(0, n); if (add_only_one) break; n = nextSibling(n); continue; } } if (Getattr(n,"sym:name")) { n = nextSibling(n); continue; } decl = Getattr(n,"decl"); if (!SwigType_isfunction(decl)) { symname = make_name(Getattr(n,"name"),0); if (!symname) { symname = Getattr(n,"unnamed"); } if (symname) { wrn = name_warning(n,symname,0); Swig_features_get(features_hash, Namespaceprefix, Getattr(n,"name"), 0, n); } } else { SwigType *fdecl = Copy(decl); SwigType *fun = SwigType_pop_function(fdecl); /* for friends, we need to disable the class prefix */ String* class_prefix = isfriend ? Namespaceprefix : 0; if (isfriend) Namespaceprefix = 0; symname = make_name(Getattr(n,"name"),fun); wrn = name_warning(n,symname,fun); Swig_features_get(features_hash,Namespaceprefix,Getattr(n,"name"),fun,n); Delete(fdecl); Delete(fun); /* restore the class prefix if needed */ if (isfriend) Namespaceprefix = class_prefix; } if (!symname) { n = nextSibling(n); continue; } if (strncmp(Char(symname),"$ignore",7) == 0) { char *c = Char(symname)+7; Setattr(n,"feature:ignore","1"); if (strlen(c)) { Swig_warning(0,Getfile(n), Getline(n), "%s\n",c+1); } Swig_symbol_add(0, n); } else { Node *c; if ((wrn) && (Len(wrn))) { Swig_warning(0,Getfile(n),Getline(n), "%s\n", wrn); } if (Strcmp(nodeType(n),"enum") != 0) { c = Swig_symbol_add(symname,n); if (c != n) { if (Getattr(n,"sym:weak")) { Setattr(n,"sym:name",symname); } else if ((Strcmp(nodeType(n),"template") == 0) && (Strcmp(Getattr(n,"templatetype"),"cdecl") == 0)) { Setattr(n,"sym:name",symname); } else { String *e = NewString(""); String *en = NewString(""); String *ec = NewString(""); int redefined = need_redefined_warn(n,c,inclass); if (redefined) { Printf(en,"Identifier '%s' redefined (ignored)",symname); Printf(ec,"previous definition of '%s'",symname); } else { Printf(en,"Redundant redeclaration of '%s'",symname); Printf(ec,"previous declaration of '%s'",symname); } if (Cmp(symname,Getattr(n,"name"))) { Printf(en," (Renamed from '%s')", SwigType_namestr(Getattr(n,"name"))); } Printf(en,","); if (Cmp(symname,Getattr(c,"name"))) { Printf(ec," (Renamed from '%s')", SwigType_namestr(Getattr(c,"name"))); } Printf(ec,"."); if (redefined) { Swig_warning(WARN_PARSE_REDEFINED,Getfile(n),Getline(n),"%s\n",en); Swig_warning(WARN_PARSE_REDEFINED,Getfile(c),Getline(c),"%s\n",ec); } else if (!is_friend(n) && !is_friend(c)) { Swig_warning(WARN_PARSE_REDUNDANT,Getfile(n),Getline(n),"%s\n",en); Swig_warning(WARN_PARSE_REDUNDANT,Getfile(c),Getline(c),"%s\n",ec); } Printf(e,"%s:%d:%s\n%s:%d:%s\n",Getfile(n),Getline(n),en, Getfile(c),Getline(c),ec); Setattr(n,"error",e); Delete(en); Delete(ec); } } } else { Setattr(n,"sym:name", symname); } } /* restore the class scope if needed */ if (isfriend) Swig_symbol_setscope(class_scope); if (add_only_one) return; n = nextSibling(n); } } /* add symbols a parse tree node copy */ void add_symbols_copy(Node *n) { String *name; int emode = 0; while (n) { if (Strcmp(nodeType(n),"access") == 0) { String *kind = Getattr(n,"kind"); if (Strcmp(kind,"public") == 0) { cplus_mode = CPLUS_PUBLIC; } else if (Strcmp(kind,"private") == 0) { cplus_mode = CPLUS_PRIVATE; } else if (Strcmp(kind,"protected") == 0) { cplus_mode = CPLUS_PROTECTED; } n = nextSibling(n); continue; } add_oldname = Getattr(n,"sym:name"); if ((add_oldname) || (Getattr(n,"sym:needs_symtab"))) { if (add_oldname) { DohIncref(add_oldname); /* If already renamed, we used that name */ if (Strcmp(add_oldname, Getattr(n,"name")) != 0) { yyrename = add_oldname; } } Delattr(n,"sym:needs_symtab"); Delattr(n,"sym:name"); add_only_one = 1; add_symbols(n); if (Getattr(n,"partialargs")) { Swig_symbol_cadd(Getattr(n,"partialargs"),n); } add_only_one = 0; name = Getattr(n,"name"); if (Getattr(n,"requires_symtab")) { Swig_symbol_newscope(); Swig_symbol_setscopename(name); Namespaceprefix = Swig_symbol_qualifiedscopename(0); } if (Strcmp(nodeType(n),"class") == 0) { inclass = 1; if (Strcmp(Getattr(n,"kind"),"class") == 0) { cplus_mode = CPLUS_PRIVATE; } else { cplus_mode = CPLUS_PUBLIC; } } if (Strcmp(nodeType(n),"extend") == 0) { emode = cplus_mode; cplus_mode = CPLUS_PUBLIC; } add_symbols_copy(firstChild(n)); if (Strcmp(nodeType(n),"extend") == 0) { cplus_mode = emode; } if (Getattr(n,"requires_symtab")) { Setattr(n,"symtab", Swig_symbol_popscope()); Delattr(n,"requires_symtab"); Namespaceprefix = Swig_symbol_qualifiedscopename(0); } if (add_oldname) { Delete(add_oldname); } if (Strcmp(nodeType(n),"class") == 0) { inclass = 0; } add_oldname = 0; } else { if (Strcmp(nodeType(n),"extend") == 0) { emode = cplus_mode; cplus_mode = CPLUS_PUBLIC; } add_symbols_copy(firstChild(n)); if (Strcmp(nodeType(n),"extend") == 0) { cplus_mode = emode; } } n = nextSibling(n); } } /* Extension merge. This function is used to handle the %extend directive when it appears before a class definition. To handle this, the %extend actually needs to take precedence. Therefore, we will selectively nuke symbols from the current symbol table, replacing them with the added methods */ static void merge_extensions(Node *cls, Node *am) { Node *n; Node *csym; n = firstChild(am); while (n) { String *symname; if (Strcmp(nodeType(n),"constructor") == 0) { symname = Getattr(n,"sym:name"); if (symname) { if (Strcmp(symname,Getattr(n,"name")) == 0) { /* If the name and the sym:name of a constructor are the same, then it hasn't been renamed. However---the name of the class itself might have been renamed so we need to do a consistency check here */ if (Getattr(cls,"sym:name")) { Setattr(n,"sym:name", Getattr(cls,"sym:name")); } } } } symname = Getattr(n,"sym:name"); DohIncref(symname); if ((symname) && (!Getattr(n,"error"))) { /* Remove node from its symbol table */ Swig_symbol_remove(n); csym = Swig_symbol_add(symname,n); if (csym != n) { /* Conflict with previous definition. Nuke previous definition */ String *e = NewString(""); String *en = NewString(""); String *ec = NewString(""); Printf(ec,"Identifier '%s' redefined by %%extend (ignored),",symname); Printf(en,"%%extend definition of '%s'.",symname); Swig_warning(WARN_PARSE_REDEFINED,Getfile(csym),Getline(csym),"%s\n",ec); Swig_warning(WARN_PARSE_REDEFINED,Getfile(n),Getline(n),"%s\n",en); Printf(e,"%s:%d:%s\n%s:%d:%s\n",Getfile(csym),Getline(csym),ec, Getfile(n),Getline(n),en); Setattr(csym,"error",e); Delete(en); Delete(ec); Swig_symbol_remove(csym); /* Remove class definition */ Swig_symbol_add(symname,n); /* Insert extend definition */ } } n = nextSibling(n); } } /* Check for unused %extend. Special case, don't report unused extensions for templates */ static void check_extensions() { Iterator ki; if (!extendhash) return; for (ki = First(extendhash); ki.key; ki = Next(ki)) { if (!Strstr(ki.key,"<")) { Swig_warning(WARN_PARSE_EXTEND_UNDEF,Getfile(ki.item), Getline(ki.item), "%%extend defined for an undeclared class %s.\n", ki.key); } } } /* Check a set of declarations to see if any are pure-abstract */ static List *pure_abstract(Node *n) { List *abs = 0; while (n) { if (Cmp(nodeType(n),"cdecl") == 0) { String *decl = Getattr(n,"decl"); if (SwigType_isfunction(decl)) { String *init = Getattr(n,"value"); if (Cmp(init,"0") == 0) { if (!abs) { abs = NewList(); } Append(abs,n); Setattr(n,"abstract","1"); } } } else if (Cmp(nodeType(n),"destructor") == 0) { if (Cmp(Getattr(n,"value"),"0") == 0) { if (!abs) { abs = NewList(); } Append(abs,n); Setattr(n,"abstract","1"); } } n = nextSibling(n); } return abs; } /* Make a classname */ static String *make_class_name(String *name) { String *nname = 0; if (Namespaceprefix) { nname= NewStringf("%s::%s", Namespaceprefix, name); } else { nname = NewString(name); } if (SwigType_istemplate(nname)) { String *prefix, *args, *qargs; prefix = SwigType_templateprefix(nname); args = SwigType_templateargs(nname); qargs = Swig_symbol_type_qualify(args,0); Append(prefix,qargs); Delete(nname); nname = prefix; } return nname; } static List *make_inherit_list(String *clsname, List *names) { int i; String *derived; List *bases = NewList(); if (Namespaceprefix) derived = NewStringf("%s::%s", Namespaceprefix,clsname); else derived = NewString(clsname); for (i = 0; i < Len(names); i++) { Node *s; String *base; String *n = Getitem(names,i); /* Try to figure out where this symbol is */ s = Swig_symbol_clookup(n,0); if (s) { while (s && (Strcmp(nodeType(s),"class") != 0)) { /* Not a class. Could be a typedef though. */ String *storage = Getattr(s,"storage"); if (storage && (Strcmp(storage,"typedef") == 0)) { String *nn = Getattr(s,"type"); s = Swig_symbol_clookup(nn,Getattr(s,"sym:symtab")); } else { break; } } if (s && ((Strcmp(nodeType(s),"class") == 0) || (Strcmp(nodeType(s),"template") == 0))) { String *q = Swig_symbol_qualified(s); Append(bases,s); if (q) { base = NewStringf("%s::%s", q, Getattr(s,"name")); } else { base = NewString(Getattr(s,"name")); } } else { base = NewString(n); } } else { base = NewString(n); } if (base) { rename_inherit(base,derived); Delete(base); } } return bases; } /* Structures for handling code fragments built for nested classes */ typedef struct Nested { String *code; /* Associated code fragment */ int line; /* line number where it starts */ char *name; /* Name associated with this nested class */ char *kind; /* Kind of class */ SwigType *type; /* Datatype associated with the name */ struct Nested *next; /* Next code fragment in list */ } Nested; /* Some internal variables for saving nested class information */ static Nested *nested_list = 0; /* Add a function to the nested list */ static void add_nested(Nested *n) { Nested *n1; if (!nested_list) nested_list = n; else { n1 = nested_list; while (n1->next) n1 = n1->next; n1->next = n; } } /* Dump all of the nested class declarations to the inline processor * However. We need to do a few name replacements and other munging * first. This function must be called before closing a class! */ static Node *dump_nested(char *parent) { Nested *n,*n1; Node *ret = 0; n = nested_list; if (!parent) { nested_list = 0; return 0; } while (n) { char temp[256]; Node *retx; /* Token replace the name of the parent class */ Replace(n->code, "$classname", parent, DOH_REPLACE_ANY); /* Fix up the name of the datatype (for building typedefs and other stuff) */ sprintf(temp,"%s_%s", parent,n->name); Append(n->type,parent); Append(n->type,"_"); Append(n->type,n->name); /* Add the appropriate declaration to the C++ processor */ retx = new_node("cdecl"); Setattr(retx,"name",n->name); Setattr(retx,"type",Copy(n->type)); Setattr(retx,"nested",parent); add_symbols(retx); if (ret) { set_nextSibling(retx,ret); } ret = retx; /* Insert a forward class declaration */ /* Disabled: [ 597599 ] union in class: incorrect scope retx = new_node("classforward"); Setattr(retx,"kind",n->kind); Setattr(retx,"name",Copy(n->type)); Setattr(retx,"sym:name", make_name(n->type,0)); set_nextSibling(retx,ret); ret = retx; */ /* Make all SWIG created typedef structs/unions/classes unnamed else redefinition errors occur - nasty hack alert.*/ { const char* types_array[3] = {"struct", "union", "class"}; int i; for (i=0; i<3; i++) { char* code_ptr = Char(n->code); while (code_ptr) { /* Replace struct name (as in 'struct name {' ) with whitespace name will be between struct and { */ code_ptr = strstr(code_ptr, types_array[i]); if (code_ptr) { char *open_bracket_pos; code_ptr += strlen(types_array[i]); open_bracket_pos = strstr(code_ptr, "{"); if (open_bracket_pos) { /* Make sure we don't have something like struct A a; */ char* semi_colon_pos = strstr(code_ptr, ";"); if (!(semi_colon_pos && (semi_colon_pos < open_bracket_pos))) while (code_ptr < open_bracket_pos) *code_ptr++ = ' '; } } } } } { /* Remove SWIG directive %constant which may be left in the SWIG created typedefs */ char* code_ptr = Char(n->code); while (code_ptr) { code_ptr = strstr(code_ptr, "%constant"); if (code_ptr) { char* directive_end_pos = strstr(code_ptr, ";"); if (directive_end_pos) { while (code_ptr <= directive_end_pos) *code_ptr++ = ' '; } } } } { Node *head; head = new_node("insert"); Setattr(head,"code",NewStringf("\n%s\n",n->code)); set_nextSibling(head,ret); ret = head; } /* Dump the code to the scanner */ start_inline(Char(n->code),n->line); n1 = n->next; Delete(n->code); free(n); n = n1; } nested_list = 0; return ret; } Node *Swig_cparse(File *f) { scanner_file(f); top = 0; yyparse(); return top; } /* Enabling traces. */ #ifndef YYDEBUG # define YYDEBUG 0 #endif /* Enabling verbose error messages. */ #ifdef YYERROR_VERBOSE # undef YYERROR_VERBOSE # define YYERROR_VERBOSE 1 #else # define YYERROR_VERBOSE 0 #endif #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) #line 823 "CableSwig/SWIG/Source/CParse/parser.y" typedef union YYSTYPE { char *id; List *bases; struct Define { String *val; String *rawval; int type; String *qualifier; String *bitfield; Parm *throws; } dtype; struct { char *type; char *filename; int line; } loc; struct { char *id; SwigType *type; String *defarg; ParmList *parms; short have_parms; ParmList *throws; } decl; Parm *tparms; struct { String *op; Hash *kwargs; } tmap; struct { String *type; String *us; } ptype; SwigType *type; String *str; Parm *p; ParmList *pl; int ivalue; Node *node; } YYSTYPE; /* Line 191 of yacc.c. */ #line 1161 "CableSwig-build/SWIG/Source/CParse/parser.c" # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif /* Copy the second part of user declarations. */ /* Line 214 of yacc.c. */ #line 1173 "CableSwig-build/SWIG/Source/CParse/parser.c" #if ! defined (yyoverflow) || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ # if YYSTACK_USE_ALLOCA # define YYSTACK_ALLOC alloca # else # ifndef YYSTACK_USE_ALLOCA # if defined (alloca) || defined (_ALLOCA_H) # define YYSTACK_ALLOC alloca # else # ifdef __GNUC__ # define YYSTACK_ALLOC __builtin_alloca # endif # endif # endif # endif # ifdef YYSTACK_ALLOC /* Pacify GCC's `empty if-body' warning. */ # define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) # else # if defined (__STDC__) || defined (__cplusplus) # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # endif # define YYSTACK_ALLOC malloc # define YYSTACK_FREE free # endif #endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ #if (! defined (yyoverflow) \ && (! defined (__cplusplus) \ || (YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc { short yyss; YYSTYPE yyvs; }; /* The size of the maximum gap between one aligned stack and the next. */ # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) /* The size of an array large to enough to hold all stacks, each with N elements. */ # define YYSTACK_BYTES(N) \ ((N) * (sizeof (short) + sizeof (YYSTYPE)) \ + YYSTACK_GAP_MAXIMUM) /* Copy COUNT objects from FROM to TO. The source and destination do not overlap. */ # ifndef YYCOPY # if 1 < __GNUC__ # define YYCOPY(To, From, Count) \ __builtin_memcpy (To, From, (Count) * sizeof (*(From))) # else # define YYCOPY(To, From, Count) \ do \ { \ register YYSIZE_T yyi; \ for (yyi = 0; yyi < (Count); yyi++) \ (To)[yyi] = (From)[yyi]; \ } \ while (0) # endif # endif /* Relocate STACK from its old location to the new one. The local variables YYSIZE and YYSTACKSIZE give the old and new number of elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ # define YYSTACK_RELOCATE(Stack) \ do \ { \ YYSIZE_T yynewbytes; \ YYCOPY (&yyptr->Stack, Stack, yysize); \ Stack = &yyptr->Stack; \ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ yyptr += yynewbytes / sizeof (*yyptr); \ } \ while (0) #endif #if defined (__STDC__) || defined (__cplusplus) typedef signed char yysigned_char; #else typedef short yysigned_char; #endif /* YYFINAL -- State number of the termination state. */ #define YYFINAL 44 /* YYLAST -- Last index in YYTABLE. */ #define YYLAST 3362 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 112 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 137 /* YYNRULES -- Number of rules. */ #define YYNRULES 421 /* YYNRULES -- Number of states. */ #define YYNSTATES 813 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 366 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ static const unsigned char yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111 }; #if YYDEBUG /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in YYRHS. */ static const unsigned short yyprhs[] = { 0, 0, 3, 5, 9, 12, 16, 19, 22, 24, 26, 28, 30, 32, 34, 36, 39, 41, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 65, 67, 69, 71, 73, 75, 77, 79, 81, 82, 90, 96, 100, 106, 112, 116, 119, 122, 128, 131, 137, 140, 146, 152, 153, 161, 163, 165, 168, 171, 173, 179, 185, 191, 195, 200, 204, 212, 221, 227, 231, 233, 235, 239, 241, 246, 254, 261, 263, 265, 273, 283, 289, 297, 299, 301, 307, 315, 317, 321, 328, 335, 344, 346, 349, 353, 355, 358, 362, 369, 375, 385, 388, 390, 392, 398, 404, 406, 411, 413, 415, 418, 424, 431, 439, 448, 455, 457, 459, 461, 463, 465, 467, 468, 478, 479, 488, 490, 493, 498, 499, 506, 510, 512, 514, 516, 518, 520, 522, 526, 531, 532, 539, 540, 546, 552, 555, 556, 563, 565, 566, 570, 572, 574, 576, 578, 580, 582, 584, 586, 590, 592, 594, 596, 598, 600, 602, 604, 611, 618, 626, 635, 644, 652, 658, 661, 664, 667, 668, 676, 677, 684, 686, 688, 690, 692, 694, 696, 698, 700, 702, 704, 706, 708, 710, 713, 716, 719, 724, 727, 733, 735, 738, 740, 742, 744, 746, 748, 750, 753, 755, 759, 761, 764, 771, 775, 777, 780, 782, 786, 788, 790, 792, 794, 797, 801, 804, 807, 809, 812, 815, 817, 819, 821, 823, 826, 830, 832, 835, 839, 844, 850, 855, 857, 860, 864, 869, 875, 879, 884, 889, 891, 894, 899, 904, 910, 914, 919, 924, 926, 929, 932, 936, 938, 941, 943, 946, 950, 955, 959, 964, 967, 971, 975, 980, 984, 988, 991, 994, 996, 998, 1001, 1003, 1005, 1007, 1010, 1012, 1014, 1016, 1018, 1021, 1024, 1026, 1029, 1031, 1034, 1036, 1038, 1041, 1043, 1045, 1047, 1049, 1051, 1053, 1055, 1057, 1058, 1061, 1063, 1065, 1067, 1071, 1073, 1075, 1079, 1081, 1083, 1085, 1087, 1089, 1095, 1097, 1099, 1103, 1108, 1114, 1120, 1127, 1129, 1131, 1133, 1135, 1137, 1139, 1141, 1145, 1149, 1153, 1157, 1161, 1165, 1169, 1173, 1177, 1181, 1185, 1188, 1191, 1194, 1197, 1200, 1202, 1203, 1207, 1209, 1211, 1215, 1218, 1223, 1225, 1227, 1229, 1231, 1233, 1235, 1237, 1239, 1241, 1243, 1248, 1254, 1256, 1260, 1264, 1269, 1274, 1278, 1281, 1283, 1285, 1289, 1292, 1296, 1298, 1300, 1302, 1304, 1306, 1309, 1314, 1316, 1320, 1322, 1326, 1330, 1333, 1336, 1339, 1342, 1345, 1350, 1352, 1356, 1358, 1362, 1366, 1369, 1372, 1375, 1378, 1380, 1382, 1384, 1386, 1390, 1392, 1396, 1402, 1404, 1408, 1410, 1412 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const short yyrhs[] = { 113, 0, -1, 114, -1, 94, 191, 34, -1, 94, 1, -1, 95, 191, 34, -1, 95, 1, -1, 114, 115, -1, 248, -1, 116, -1, 150, -1, 156, -1, 34, -1, 1, -1, 155, -1, 1, 93, -1, 117, -1, 119, -1, 120, -1, 121, -1, 122, -1, 123, -1, 124, -1, 125, -1, 128, -1, 129, -1, 130, -1, 131, -1, 132, -1, 133, -1, 136, -1, 138, -1, 140, -1, 142, -1, 147, -1, 148, -1, 149, -1, -1, 54, 245, 238, 37, 118, 170, 38, -1, 77, 146, 37, 144, 38, -1, 78, 144, 34, -1, 50, 3, 44, 213, 34, -1, 50, 207, 199, 196, 34, -1, 50, 1, 34, -1, 76, 4, -1, 76, 243, -1, 75, 31, 3, 32, 37, -1, 75, 37, -1, 75, 31, 3, 32, 34, -1, 75, 34, -1, 80, 31, 246, 32, 4, -1, 80, 31, 246, 32, 37, -1, -1, 127, 245, 243, 47, 126, 114, 48, -1, 7, -1, 8, -1, 73, 4, -1, 73, 37, -1, 4, -1, 9, 31, 236, 32, 243, -1, 9, 31, 236, 32, 4, -1, 9, 31, 236, 32, 37, -1, 46, 245, 236, -1, 51, 31, 236, 32, -1, 51, 31, 32, -1, 72, 31, 3, 32, 187, 3, 34, -1, 72, 31, 3, 32, 187, 207, 199, 34, -1, 55, 135, 3, 44, 134, -1, 55, 135, 3, -1, 243, -1, 4, -1, 31, 3, 32, -1, 248, -1, 137, 199, 236, 34, -1, 137, 31, 236, 32, 199, 230, 34, -1, 137, 31, 236, 32, 243, 34, -1, 52, -1, 53, -1, 56, 31, 236, 32, 199, 230, 139, -1, 56, 31, 236, 33, 236, 32, 199, 230, 34, -1, 56, 31, 236, 32, 139, -1, 56, 31, 236, 33, 236, 32, 34, -1, 244, -1, 34, -1, 87, 31, 188, 32, 34, -1, 57, 31, 141, 32, 199, 230, 34, -1, 188, -1, 11, 33, 191, -1, 74, 31, 143, 32, 144, 244, -1, 74, 31, 143, 32, 144, 34, -1, 74, 31, 143, 32, 144, 44, 146, 34, -1, 246, -1, 146, 145, -1, 33, 146, 145, -1, 248, -1, 207, 198, -1, 31, 188, 32, -1, 31, 188, 32, 31, 188, 32, -1, 86, 31, 188, 32, 34, -1, 79, 31, 237, 32, 241, 82, 192, 83, 34, -1, 81, 243, -1, 151, -1, 154, -1, 35, 243, 37, 114, 38, -1, 187, 207, 199, 153, 152, -1, 34, -1, 33, 199, 153, 152, -1, 37, -1, 196, -1, 205, 196, -1, 68, 31, 188, 32, 196, -1, 205, 68, 31, 188, 32, 196, -1, 187, 58, 215, 37, 216, 38, 34, -1, 187, 58, 215, 37, 216, 38, 199, 152, -1, 187, 207, 31, 188, 32, 231, -1, 157, -1, 161, -1, 162, -1, 166, -1, 167, -1, 177, -1, -1, 187, 228, 238, 222, 37, 158, 170, 38, 160, -1, -1, 187, 228, 37, 159, 170, 38, 199, 152, -1, 34, -1, 199, 152, -1, 187, 228, 238, 34, -1, -1, 91, 82, 165, 83, 163, 164, -1, 91, 228, 238, -1, 151, -1, 157, -1, 174, -1, 162, -1, 161, -1, 189, -1, 70, 238, 34, -1, 70, 71, 238, 34, -1, -1, 71, 238, 37, 168, 114, 38, -1, -1, 71, 37, 169, 114, 38, -1, 71, 3, 44, 238, 34, -1, 173, 170, -1, -1, 54, 37, 171, 170, 38, 170, -1, 248, -1, -1, 1, 172, 170, -1, 150, -1, 174, -1, 175, -1, 178, -1, 183, -1, 176, -1, 161, -1, 179, -1, 187, 238, 34, -1, 166, -1, 162, -1, 177, -1, 148, -1, 149, -1, 186, -1, 34, -1, 187, 207, 31, 188, 32, 231, -1, 109, 240, 31, 188, 32, 184, -1, 66, 109, 240, 31, 188, 32, 185, -1, 187, 93, 207, 204, 31, 188, 32, 185, -1, 187, 93, 207, 101, 31, 188, 32, 185, -1, 187, 93, 207, 31, 188, 32, 185, -1, 69, 31, 188, 32, 37, -1, 62, 64, -1, 61, 64, -1, 63, 64, -1, -1, 187, 228, 3, 37, 180, 182, 34, -1, -1, 187, 228, 37, 181, 182, 34, -1, 199, -1, 248, -1, 133, -1, 121, -1, 131, -1, 136, -1, 138, -1, 140, -1, 129, -1, 142, -1, 119, -1, 120, -1, 122, -1, 230, 34, -1, 230, 37, -1, 230, 34, -1, 230, 44, 213, 34, -1, 230, 37, -1, 187, 207, 64, 11, 34, -1, 35, -1, 35, 243, -1, 65, -1, 18, -1, 66, -1, 67, -1, 248, -1, 189, -1, 191, 190, -1, 248, -1, 33, 191, 190, -1, 248, -1, 208, 197, -1, 91, 82, 228, 83, 228, 238, -1, 39, 39, 39, -1, 193, -1, 195, 194, -1, 248, -1, 33, 195, 194, -1, 248, -1, 191, -1, 220, -1, 6, -1, 44, 213, -1, 44, 101, 199, -1, 44, 37, -1, 64, 11, -1, 248, -1, 199, 196, -1, 202, 196, -1, 196, -1, 199, -1, 202, -1, 248, -1, 204, 200, -1, 204, 101, 200, -1, 201, -1, 101, 200, -1, 238, 89, 200, -1, 204, 238, 89, 200, -1, 204, 238, 89, 101, 200, -1, 238, 89, 101, 200, -1, 238, -1, 109, 238, -1, 31, 238, 32, -1, 31, 204, 200, 32, -1, 31, 238, 89, 200, 32, -1, 200, 47, 48, -1, 200, 47, 219, 48, -1, 200, 31, 188, 32, -1, 238, -1, 109, 238, -1, 31, 204, 201, 32, -1, 31, 101, 201, 32, -1, 31, 238, 89, 201, 32, -1, 201, 47, 48, -1, 201, 47, 219, 48, -1, 201, 31, 188, 32, -1, 204, -1, 204, 203, -1, 204, 101, -1, 204, 101, 203, -1, 203, -1, 101, 203, -1, 101, -1, 238, 89, -1, 204, 238, 89, -1, 204, 238, 89, 203, -1, 203, 47, 48, -1, 203, 47, 219, 48, -1, 47, 48, -1, 47, 219, 48, -1, 31, 202, 32, -1, 203, 31, 188, 32, -1, 31, 188, 32, -1, 107, 205, 204, -1, 107, 204, -1, 107, 205, -1, 107, -1, 206, -1, 206, 205, -1, 40, -1, 41, -1, 208, -1, 205, 209, -1, 209, -1, 210, -1, 28, -1, 26, -1, 29, 235, -1, 58, 238, -1, 30, -1, 209, 205, -1, 238, -1, 228, 238, -1, 211, -1, 212, -1, 212, 211, -1, 19, -1, 21, -1, 22, -1, 25, -1, 23, -1, 24, -1, 27, -1, 20, -1, -1, 214, 219, -1, 10, -1, 3, -1, 248, -1, 216, 33, 217, -1, 217, -1, 3, -1, 3, 44, 218, -1, 248, -1, 219, -1, 10, -1, 220, -1, 243, -1, 45, 31, 207, 197, 32, -1, 221, -1, 207, -1, 31, 219, 32, -1, 31, 219, 32, 219, -1, 31, 219, 204, 32, 219, -1, 31, 219, 101, 32, 219, -1, 31, 219, 204, 101, 32, 219, -1, 11, -1, 12, -1, 13, -1, 14, -1, 15, -1, 16, -1, 17, -1, 219, 105, 219, -1, 219, 104, 219, -1, 219, 107, 219, -1, 219, 106, 219, -1, 219, 101, 219, -1, 219, 99, 219, -1, 219, 100, 219, -1, 219, 103, 219, -1, 219, 102, 219, -1, 219, 98, 219, -1, 219, 97, 219, -1, 104, 219, -1, 105, 219, -1, 109, 219, -1, 108, 219, -1, 207, 31, -1, 223, -1, -1, 64, 224, 225, -1, 248, -1, 226, -1, 225, 33, 226, -1, 229, 238, -1, 229, 227, 229, 238, -1, 62, -1, 61, -1, 63, -1, 59, -1, 42, -1, 43, -1, 60, -1, 66, -1, 248, -1, 205, -1, 68, 31, 188, 32, -1, 205, 68, 31, 188, 32, -1, 248, -1, 230, 232, 34, -1, 230, 232, 37, -1, 31, 188, 32, 34, -1, 31, 188, 32, 37, -1, 44, 213, 34, -1, 64, 233, -1, 248, -1, 234, -1, 233, 33, 234, -1, 238, 31, -1, 82, 192, 83, -1, 248, -1, 3, -1, 243, -1, 236, -1, 248, -1, 240, 239, -1, 88, 111, 240, 239, -1, 240, -1, 88, 111, 240, -1, 92, -1, 88, 111, 92, -1, 111, 240, 239, -1, 111, 240, -1, 111, 92, -1, 90, 240, -1, 3, 235, -1, 3, 242, -1, 88, 111, 3, 242, -1, 3, -1, 88, 111, 3, -1, 92, -1, 88, 111, 92, -1, 111, 3, 242, -1, 111, 3, -1, 111, 92, -1, 90, 3, -1, 243, 6, -1, 6, -1, 243, -1, 37, -1, 4, -1, 31, 246, 32, -1, 248, -1, 236, 44, 247, -1, 236, 44, 247, 33, 246, -1, 236, -1, 236, 33, 246, -1, 243, -1, 220, -1, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const unsigned short yyrline[] = { 0, 965, 965, 977, 980, 983, 986, 991, 995, 1000, 1001, 1002, 1003, 1004, 1016, 1032, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1069, 1069, 1141, 1151, 1162, 1181, 1203, 1214, 1223, 1242, 1248, 1254, 1259, 1269, 1277, 1295, 1295, 1322, 1323, 1330, 1350, 1377, 1381, 1391, 1396, 1411, 1427, 1431, 1443, 1449, 1475, 1481, 1488, 1489, 1492, 1493, 1501, 1512, 1556, 1567, 1570, 1583, 1630, 1682, 1693, 1706, 1707, 1708, 1713, 1749, 1750, 1779, 1791, 1799, 1812, 1834, 1840, 1844, 1847, 1855, 1860, 1872, 1882, 2127, 2137, 2143, 2147, 2163, 2216, 2220, 2239, 2245, 2250, 2255, 2260, 2272, 2280, 2328, 2375, 2376, 2377, 2378, 2379, 2380, 2386, 2386, 2520, 2520, 2618, 2619, 2631, 2649, 2649, 2862, 2868, 2871, 2874, 2877, 2880, 2885, 2917, 2923, 2950, 2950, 2977, 2977, 2997, 3024, 3038, 3038, 3048, 3049, 3049, 3069, 3070, 3084, 3085, 3086, 3087, 3088, 3089, 3090, 3091, 3092, 3093, 3094, 3095, 3096, 3097, 3106, 3127, 3143, 3176, 3190, 3207, 3225, 3232, 3239, 3247, 3270, 3270, 3299, 3299, 3326, 3327, 3333, 3336, 3340, 3343, 3344, 3345, 3346, 3347, 3348, 3349, 3350, 3353, 3356, 3359, 3366, 3373, 3383, 3389, 3390, 3398, 3399, 3400, 3401, 3402, 3409, 3420, 3428, 3431, 3435, 3439, 3449, 3454, 3462, 3475, 3483, 3486, 3490, 3494, 3520, 3526, 3534, 3544, 3572, 3580, 3587, 3596, 3600, 3604, 3611, 3628, 3645, 3653, 3661, 3670, 3674, 3683, 3694, 3706, 3716, 3729, 3736, 3744, 3760, 3768, 3779, 3790, 3801, 3820, 3828, 3845, 3853, 3860, 3871, 3882, 3893, 3912, 3918, 3924, 3931, 3940, 3943, 3952, 3959, 3966, 3976, 3987, 3998, 4009, 4016, 4023, 4026, 4043, 4053, 4060, 4066, 4071, 4077, 4081, 4087, 4088, 4094, 4100, 4104, 4107, 4110, 4111, 4112, 4113, 4114, 4115, 4120, 4123, 4128, 4153, 4156, 4198, 4202, 4206, 4210, 4214, 4218, 4222, 4226, 4232, 4232, 4251, 4268, 4269, 4274, 4287, 4296, 4302, 4315, 4318, 4327, 4338, 4339, 4343, 4348, 4349, 4373, 4380, 4386, 4393, 4400, 4410, 4411, 4412, 4413, 4414, 4415, 4416, 4419, 4423, 4427, 4431, 4435, 4439, 4443, 4447, 4451, 4455, 4459, 4463, 4467, 4471, 4475, 4479, 4490, 4495, 4495, 4496, 4499, 4504, 4510, 4520, 4532, 4533, 4534, 4538, 4542, 4546, 4550, 4556, 4557, 4560, 4564, 4568, 4572, 4578, 4584, 4590, 4597, 4604, 4611, 4612, 4615, 4616, 4619, 4625, 4631, 4634, 4635, 4638, 4639, 4642, 4647, 4651, 4654, 4657, 4660, 4665, 4669, 4672, 4679, 4685, 4694, 4699, 4703, 4706, 4709, 4712, 4717, 4721, 4724, 4727, 4733, 4738, 4741, 4744, 4748, 4753, 4766, 4770, 4775, 4781, 4785, 4792, 4795, 4800 }; #endif #if YYDEBUG || YYERROR_VERBOSE /* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { "$end", "error", "$undefined", "ID", "HBLOCK", "POUND", "STRING", "INCLUDE", "IMPORT", "INSERT", "CHARCONST", "NUM_INT", "NUM_FLOAT", "NUM_UNSIGNED", "NUM_LONG", "NUM_ULONG", "NUM_LONGLONG", "NUM_ULONGLONG", "TYPEDEF", "TYPE_INT", "TYPE_UNSIGNED", "TYPE_SHORT", "TYPE_LONG", "TYPE_FLOAT", "TYPE_DOUBLE", "TYPE_CHAR", "TYPE_VOID", "TYPE_SIGNED", "TYPE_BOOL", "TYPE_TYPEDEF", "TYPE_RAW", "LPAREN", "RPAREN", "COMMA", "SEMI", "EXTERN", "INIT", "LBRACE", "RBRACE", "PERIOD", "CONST", "VOLATILE", "STRUCT", "UNION", "EQUAL", "SIZEOF", "MODULE", "LBRACKET", "RBRACKET", "ILLEGAL", "CONSTANT", "NAME", "RENAME", "NAMEWARN", "EXTEND", "PRAGMA", "FEATURE", "VARARGS", "ENUM", "CLASS", "TYPENAME", "PRIVATE", "PUBLIC", "PROTECTED", "COLON", "STATIC", "VIRTUAL", "FRIEND", "THROW", "CATCH", "USING", "NAMESPACE", "NATIVE", "INLINE", "TYPEMAP", "EXCEPT", "ECHO", "APPLY", "CLEAR", "SWIGTEMPLATE", "FRAGMENT", "WARN", "LESSTHAN", "GREATERTHAN", "MODULO", "DELETE", "TYPES", "PARMS", "NONID", "DSTAR", "DCNOT", "TEMPLATE", "OPERATOR", "COPERATOR", "PARSETYPE", "PARSEPARM", "CAST", "LOR", "LAND", "OR", "XOR", "AND", "RSHIFT", "LSHIFT", "MINUS", "PLUS", "SLASH", "STAR", "LNOT", "NOT", "UMINUS", "DCOLON", "$accept", "program", "interface", "declaration", "swig_directive", "extend_directive", "@1", "apply_directive", "clear_directive", "constant_directive", "echo_directive", "except_directive", "fragment_directive", "include_directive", "@2", "includetype", "inline_directive", "insert_directive", "module_directive", "name_directive", "native_directive", "pragma_directive", "pragma_arg", "pragma_lang", "rename_directive", "rename_namewarn", "feature_directive", "stringbracesemi", "varargs_directive", "varargs_parms", "typemap_directive", "typemap_type", "tm_list", "tm_tail", "typemap_parm", "types_directive", "template_directive", "warn_directive", "c_declaration", "c_decl", "c_decl_tail", "initializer", "c_enum_decl", "c_constructor_decl", "cpp_declaration", "cpp_class_decl", "@3", "@4", "cpp_opt_declarators", "cpp_forward_class_decl", "cpp_template_decl", "@5", "cpp_temp_possible", "template_parms", "cpp_using_decl", "cpp_namespace_decl", "@6", "@7", "cpp_members", "@8", "@9", "cpp_member", "cpp_constructor_decl", "cpp_destructor_decl", "cpp_conversion_operator", "cpp_catch_decl", "cpp_protection_decl", "cpp_nested", "@10", "@11", "nested_decl", "cpp_swig_directive", "cpp_end", "cpp_vend", "anonymous_bitfield", "storage_class", "parms", "rawparms", "ptail", "parm", "valparms", "rawvalparms", "valptail", "valparm", "def_args", "parameter_declarator", "typemap_parameter_declarator", "declarator", "notso_direct_declarator", "direct_declarator", "abstract_declarator", "direct_abstract_declarator", "pointer", "type_qualifier", "type_qualifier_raw", "type", "rawtype", "type_right", "primitive_type", "primitive_type_list", "type_specifier", "definetype", "@12", "ename", "enumlist", "edecl", "etype", "expr", "exprnum", "exprcompound", "inherit", "raw_inherit", "@13", "base_list", "base_specifier", "access_specifier", "cpptype", "opt_virtual", "cpp_const", "ctor_end", "ctor_initializer", "mem_initializer_list", "mem_initializer", "template_decl", "idstring", "idstringopt", "idcolon", "idcolontail", "idtemplate", "idcolonnt", "idcolontailnt", "string", "stringbrace", "options", "kwargs", "stringnum", "empty", 0 }; #endif # ifdef YYPRINT /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to token YYLEX-NUM. */ static const unsigned short yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const unsigned char yyr1[] = { 0, 112, 113, 113, 113, 113, 113, 114, 114, 115, 115, 115, 115, 115, 115, 115, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 116, 118, 117, 119, 120, 121, 121, 121, 122, 122, 123, 123, 123, 123, 124, 124, 126, 125, 127, 127, 128, 128, 129, 129, 129, 129, 130, 131, 131, 132, 132, 133, 133, 134, 134, 135, 135, 136, 136, 136, 137, 137, 138, 138, 138, 138, 139, 139, 139, 140, 141, 141, 142, 142, 142, 143, 144, 145, 145, 146, 146, 146, 147, 148, 149, 150, 150, 150, 151, 152, 152, 152, 153, 153, 153, 153, 154, 154, 155, 156, 156, 156, 156, 156, 156, 158, 157, 159, 157, 160, 160, 161, 163, 162, 162, 164, 164, 164, 164, 164, 165, 166, 166, 168, 167, 169, 167, 167, 170, 171, 170, 170, 172, 170, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 173, 174, 175, 175, 176, 176, 176, 177, 178, 178, 178, 180, 179, 181, 179, 182, 182, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 183, 184, 184, 185, 185, 185, 186, 187, 187, 187, 187, 187, 187, 187, 188, 189, 189, 190, 190, 191, 191, 191, 192, 193, 193, 194, 194, 195, 195, 195, 196, 196, 196, 196, 196, 197, 197, 197, 198, 198, 198, 199, 199, 199, 199, 199, 199, 199, 199, 200, 200, 200, 200, 200, 200, 200, 200, 201, 201, 201, 201, 201, 201, 201, 201, 202, 202, 202, 202, 202, 202, 202, 202, 202, 202, 203, 203, 203, 203, 203, 203, 203, 204, 204, 204, 204, 205, 205, 206, 206, 207, 208, 208, 209, 209, 209, 209, 209, 209, 209, 209, 209, 210, 211, 211, 212, 212, 212, 212, 212, 212, 212, 212, 214, 213, 213, 215, 215, 216, 216, 217, 217, 217, 218, 218, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 220, 220, 220, 220, 220, 220, 220, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 221, 222, 224, 223, 223, 225, 225, 226, 226, 227, 227, 227, 228, 228, 228, 228, 229, 229, 230, 230, 230, 230, 231, 231, 231, 231, 231, 232, 232, 233, 233, 234, 235, 235, 236, 236, 237, 237, 238, 238, 238, 238, 238, 238, 239, 239, 239, 239, 240, 241, 241, 241, 241, 241, 241, 242, 242, 242, 242, 243, 243, 244, 244, 244, 245, 245, 246, 246, 246, 246, 247, 247, 248 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const unsigned char yyr2[] = { 0, 2, 1, 3, 2, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 7, 5, 3, 5, 5, 3, 2, 2, 5, 2, 5, 2, 5, 5, 0, 7, 1, 1, 2, 2, 1, 5, 5, 5, 3, 4, 3, 7, 8, 5, 3, 1, 1, 3, 1, 4, 7, 6, 1, 1, 7, 9, 5, 7, 1, 1, 5, 7, 1, 3, 6, 6, 8, 1, 2, 3, 1, 2, 3, 6, 5, 9, 2, 1, 1, 5, 5, 1, 4, 1, 1, 2, 5, 6, 7, 8, 6, 1, 1, 1, 1, 1, 1, 0, 9, 0, 8, 1, 2, 4, 0, 6, 3, 1, 1, 1, 1, 1, 1, 3, 4, 0, 6, 0, 5, 5, 2, 0, 6, 1, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 6, 6, 7, 8, 8, 7, 5, 2, 2, 2, 0, 7, 0, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 4, 2, 5, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 3, 1, 2, 6, 3, 1, 2, 1, 3, 1, 1, 1, 1, 2, 3, 2, 2, 1, 2, 2, 1, 1, 1, 1, 2, 3, 1, 2, 3, 4, 5, 4, 1, 2, 3, 4, 5, 3, 4, 4, 1, 2, 4, 4, 5, 3, 4, 4, 1, 2, 2, 3, 1, 2, 1, 2, 3, 4, 3, 4, 2, 3, 3, 4, 3, 3, 2, 2, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 2, 2, 1, 2, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 1, 1, 1, 3, 1, 1, 3, 1, 1, 1, 1, 1, 5, 1, 1, 3, 4, 5, 5, 6, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 1, 0, 3, 1, 1, 3, 2, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 5, 1, 3, 3, 4, 4, 3, 2, 1, 1, 3, 2, 3, 1, 1, 1, 1, 1, 2, 4, 1, 3, 1, 3, 3, 2, 2, 2, 2, 2, 4, 1, 3, 1, 3, 3, 2, 2, 2, 2, 1, 1, 1, 1, 3, 1, 3, 5, 1, 3, 1, 1, 0 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state STATE-NUM when YYTABLE doesn't specify something else to do. Zero means the default is an error. */ static const unsigned short yydefact[] = { 421, 0, 0, 0, 0, 8, 4, 421, 297, 304, 298, 299, 301, 302, 300, 287, 303, 286, 421, 290, 0, 280, 281, 362, 363, 0, 361, 364, 0, 0, 391, 0, 0, 278, 421, 284, 285, 294, 295, 0, 292, 389, 6, 0, 1, 13, 58, 54, 55, 0, 202, 12, 199, 421, 0, 0, 76, 77, 421, 421, 0, 0, 201, 203, 204, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 16, 17, 18, 19, 20, 21, 22, 23, 421, 24, 25, 26, 27, 28, 29, 30, 0, 31, 32, 33, 34, 35, 36, 10, 101, 102, 14, 11, 115, 116, 117, 118, 119, 120, 0, 205, 421, 397, 382, 288, 0, 289, 0, 0, 3, 283, 279, 421, 305, 0, 0, 263, 277, 0, 229, 211, 421, 235, 421, 261, 257, 249, 226, 291, 296, 293, 0, 0, 387, 5, 15, 0, 409, 200, 0, 0, 414, 0, 421, 0, 282, 0, 0, 0, 0, 72, 0, 421, 421, 0, 0, 421, 141, 0, 0, 56, 57, 0, 0, 49, 47, 44, 45, 421, 0, 421, 0, 421, 421, 0, 100, 421, 421, 0, 0, 0, 0, 0, 0, 249, 421, 0, 0, 221, 327, 328, 329, 330, 331, 332, 333, 219, 0, 214, 421, 220, 216, 213, 392, 390, 0, 421, 263, 0, 206, 421, 0, 257, 292, 208, 307, 224, 0, 222, 0, 0, 0, 269, 0, 0, 0, 0, 321, 0, 317, 320, 318, 225, 421, 0, 236, 262, 241, 275, 276, 250, 227, 421, 0, 228, 421, 0, 259, 233, 258, 241, 264, 396, 395, 394, 383, 0, 384, 408, 421, 417, 0, 62, 43, 305, 0, 421, 64, 0, 0, 0, 68, 0, 0, 0, 86, 0, 0, 137, 0, 421, 139, 0, 0, 91, 0, 0, 0, 95, 230, 231, 232, 40, 0, 92, 94, 385, 0, 386, 0, 0, 0, 136, 130, 0, 421, 0, 0, 0, 0, 0, 0, 0, 241, 0, 421, 0, 309, 421, 421, 123, 293, 381, 0, 215, 218, 388, 0, 263, 257, 292, 0, 249, 273, 0, 207, 210, 271, 259, 0, 249, 264, 223, 306, 0, 0, 345, 346, 348, 347, 349, 270, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 257, 292, 242, 421, 0, 274, 0, 254, 0, 0, 267, 0, 234, 260, 265, 0, 237, 393, 0, 0, 0, 0, 413, 0, 0, 63, 37, 71, 0, 0, 0, 0, 0, 0, 138, 0, 0, 421, 421, 0, 0, 96, 0, 421, 0, 0, 0, 128, 52, 0, 0, 0, 0, 73, 0, 421, 0, 292, 0, 0, 108, 421, 0, 127, 351, 0, 350, 353, 421, 0, 0, 264, 252, 421, 251, 265, 0, 322, 0, 277, 0, 421, 344, 343, 339, 340, 338, 342, 341, 335, 334, 337, 336, 0, 241, 243, 264, 0, 246, 0, 256, 255, 272, 268, 0, 238, 266, 240, 60, 61, 59, 103, 418, 420, 419, 415, 41, 42, 0, 70, 67, 69, 412, 83, 411, 0, 80, 421, 410, 82, 0, 87, 421, 172, 143, 142, 0, 199, 0, 0, 48, 46, 421, 39, 93, 400, 0, 402, 0, 50, 51, 98, 421, 421, 421, 0, 0, 312, 0, 311, 314, 421, 421, 0, 105, 107, 104, 0, 109, 148, 165, 0, 0, 0, 0, 203, 0, 190, 191, 183, 192, 188, 184, 182, 185, 186, 187, 189, 162, 163, 150, 156, 160, 159, 0, 0, 151, 152, 155, 161, 153, 157, 154, 164, 0, 205, 421, 121, 217, 212, 209, 253, 323, 0, 276, 0, 0, 0, 244, 0, 248, 247, 239, 0, 0, 421, 0, 367, 0, 370, 0, 0, 140, 200, 421, 0, 89, 0, 88, 0, 0, 0, 398, 0, 421, 131, 132, 135, 134, 129, 133, 0, 0, 0, 75, 0, 421, 0, 421, 305, 421, 114, 0, 421, 421, 0, 145, 174, 173, 175, 0, 0, 0, 144, 0, 0, 0, 292, 365, 352, 354, 0, 366, 0, 325, 324, 0, 319, 245, 416, 38, 0, 421, 0, 78, 81, 421, 85, 65, 0, 0, 97, 407, 405, 406, 401, 403, 0, 0, 53, 74, 316, 313, 315, 310, 112, 0, 0, 0, 0, 0, 377, 421, 0, 0, 149, 0, 0, 421, 0, 0, 421, 0, 421, 178, 293, 158, 421, 359, 358, 360, 421, 356, 0, 326, 0, 0, 421, 0, 66, 90, 404, 399, 0, 113, 0, 375, 376, 378, 0, 371, 372, 110, 106, 421, 0, 421, 0, 124, 421, 0, 0, 0, 0, 176, 421, 355, 0, 0, 84, 368, 0, 79, 99, 373, 374, 0, 380, 111, 0, 0, 421, 0, 421, 421, 421, 198, 421, 0, 180, 181, 357, 125, 122, 0, 369, 379, 146, 421, 167, 0, 421, 0, 0, 166, 0, 179, 126, 168, 0, 193, 194, 171, 421, 421, 177, 195, 197, 305, 170, 169, 0, 196 }; /* YYDEFGOTO[NTERM-NUM]. */ static const short yydefgoto[] = { -1, 3, 4, 80, 81, 82, 498, 557, 558, 559, 560, 87, 88, 89, 533, 90, 91, 561, 93, 562, 95, 563, 500, 166, 564, 98, 565, 506, 566, 291, 567, 300, 188, 311, 189, 102, 568, 569, 570, 106, 546, 439, 107, 108, 109, 110, 663, 442, 783, 571, 572, 532, 629, 318, 573, 114, 417, 297, 574, 706, 645, 575, 576, 577, 578, 579, 580, 581, 777, 755, 778, 582, 789, 798, 583, 584, 225, 226, 352, 227, 214, 215, 341, 216, 136, 137, 305, 336, 252, 139, 228, 141, 200, 32, 33, 244, 162, 35, 36, 37, 38, 235, 236, 333, 538, 539, 692, 466, 246, 247, 445, 446, 586, 659, 660, 721, 39, 661, 799, 641, 700, 737, 738, 119, 277, 314, 40, 150, 41, 528, 622, 248, 509, 157, 278, 495, 231 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ #define YYPACT_NINF -615 static const short yypact[] = { 364, 2764, 2807, 42, 2339, -615, -615, -28, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -28, -615, 74, -615, -615, -615, -615, 249, -615, -615, 9, -1, -615, 113, 3270, 483, 762, 483, -615, -615, 812, 249, -615, 88, -615, 117, -615, 115, -615, -615, -615, 211, -615, -615, 185, 217, 2850, 237, -615, -615, 217, 246, 269, 298, -615, -615, -615, 308, 45, 183, 349, 98, 377, 326, 313, 3102, 3102, 401, 408, 185, 440, 467, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, 217, -615, -615, -615, -615, -615, -615, -615, 889, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, 3144, -615, 2976, -615, -615, -615, 444, -615, 23, 500, -615, 483, -615, 2100, 30, 1457, 280, 62, 178, 249, -615, -615, 160, 24, 160, 231, 105, 405, -615, -615, -615, -615, 494, 35, -615, -615, -615, 460, -615, 29, 460, 460, -615, 471, 44, 954, -615, 284, 249, 528, 532, -615, 460, 3018, 3060, 249, 522, 63, -615, 514, 558, -615, -615, 460, 560, -615, -615, -615, 565, 3060, 541, 108, 549, 571, 460, 460, 565, 3060, 3060, 249, 185, 266, 192, 460, 138, 502, 260, 1013, 342, -615, -615, -615, -615, -615, -615, -615, -615, -615, 510, -615, 573, -615, -615, -615, -615, 88, 525, 2190, 65, 580, -615, 590, 596, 517, 544, -615, -615, -615, 954, -615, 2057, 2057, 603, -615, 2057, 2057, 2057, 2057, 604, 1176, -615, -615, 565, -615, 2190, 249, 263, 231, -615, -615, 534, -615, -615, 3060, 1557, -615, 3060, 1657, 62, 263, 231, 562, 651, -615, -615, 88, -615, 615, 565, -615, -615, 202, 623, -615, -615, 655, 252, 160, -615, 624, 632, 638, 628, 507, 640, 648, -615, 654, 657, -615, 249, -615, -615, 656, 660, -615, 663, 664, 3102, -615, -615, -615, -615, -615, 3102, -615, -615, -615, 675, -615, 677, 678, 606, -615, -615, 99, -9, 293, 293, 682, 643, 96, 693, 192, 653, 651, -8, 692, -615, 2244, 513, -615, 130, -615, 2976, -615, -615, -615, 500, 299, 646, 670, 359, -615, -615, 3060, -615, -615, -615, 299, 433, 674, 293, -615, 1421, 1136, 3186, -615, -615, -615, -615, -615, -615, 2057, 2057, 2057, 2057, 2057, 2057, 2057, 2057, 2057, 2057, 2057, 719, -11, -615, 3060, 1757, -615, 708, -615, 1214, 714, -615, 1241, 263, 231, 1099, 192, 263, -615, 383, 2425, 460, 923, -615, 715, 730, -615, -615, -615, 380, 255, 460, 3060, 954, 711, -615, 734, 2511, -615, 555, 3102, 451, 741, 740, 571, 368, 164, 745, -615, -615, 226, 293, 192, 14, -615, 750, 777, 754, 643, 751, 582, -615, 244, 1366, -615, -615, 748, -615, -615, 573, 249, 674, -615, -615, 590, -615, 299, 459, 2057, 1068, 1857, 31, 762, 920, 1201, 899, 1035, 1112, 619, 619, 439, 439, -615, -615, 468, 674, -615, 192, 764, -615, 1527, -615, -615, -615, -615, 192, 263, 231, 263, -615, -615, 565, -615, -615, -615, 565, 765, -615, -615, 1366, -615, -615, 565, -615, -615, -615, 768, -615, 241, 565, -615, 770, -615, 241, -615, -615, -615, 2597, 185, 3228, 366, -615, -615, 3060, -615, -615, 143, 689, -615, 726, -615, -615, -615, 592, -615, 241, 215, 192, 769, 360, -615, -615, 557, 3060, 954, -615, -615, -615, 781, -615, -615, -615, 786, 757, 760, 763, 705, 494, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, -615, 805, 1366, -615, -615, -615, -615, -615, -615, -615, -615, 2893, 810, 783, -615, -615, -615, -615, -615, 1421, 2057, 2295, 2057, 820, 821, -615, 470, -615, -615, 263, 460, 817, 3060, 827, 793, 173, -615, 219, 831, -615, 565, 60, 954, -615, 3102, -615, 834, 864, 36, -615, 66, 2976, -615, -615, -615, -615, -615, -615, 3186, 2683, 839, -615, 1957, 777, 300, 3060, 655, 811, -615, 842, 513, 3060, 1366, -615, -615, -615, -615, 494, 846, 954, -615, 3186, 867, 358, 844, -615, 848, -615, 784, -615, 1366, 1421, 1421, 2057, -615, -615, -615, -615, 850, 3060, 852, -615, -615, 241, -615, -615, 851, 854, -615, -615, 143, -615, 143, -615, 803, 1104, -615, -615, -615, -615, 1421, -615, -615, 582, 857, 856, 249, 542, -615, 160, 582, 861, -615, 1366, 863, 3060, 582, 75, 2244, 886, 4, -615, 869, -615, 783, -615, -615, -615, 783, -615, 866, 1421, 878, 882, 3060, 881, -615, -615, -615, -615, 883, -615, 605, -615, 885, -615, 892, -615, -615, -615, -615, 160, 887, 3060, 894, -615, 3060, 893, 902, 898, 907, -615, 954, -615, 249, 877, -615, -615, 914, -615, -615, -615, -615, 249, -615, -615, 1366, 915, 241, 916, 3060, 3060, 557, -615, 954, 917, -615, -615, -615, -615, -615, 582, -615, -615, -615, 241, -615, 627, 241, 921, 922, -615, 924, -615, -615, -615, 331, -615, -615, -615, 241, 241, -615, -615, -615, 655, -615, -615, 927, -615 }; /* YYPGOTO[NTERM-NUM]. */ static const short yypgoto[] = { -615, -615, -212, -615, -615, -615, -615, 6, 12, 20, 28, -615, -615, -615, -615, -615, -615, 39, -615, 46, -615, 52, -615, -615, 53, -615, 58, 365, 68, -615, 71, -615, -289, 543, -67, -615, 73, 76, 79, 443, -614, 329, -615, -615, -615, 447, -615, -615, -615, -2, 5, -615, -615, -615, 80, -615, -615, -615, -465, -615, -615, -615, 448, -615, -615, 87, -615, -615, -615, -615, 206, -615, -615, -379, -615, -3, 625, 794, 536, 26, 363, -615, 545, 652, -91, 530, -615, 64, 576, -199, -21, -81, -12, -30, -615, -37, 43, -24, -615, 957, -615, -270, -615, -615, -615, 361, -615, 659, -106, -615, -615, -615, -615, -615, 294, -615, -65, 291, -420, 238, -615, -615, 248, 997, -34, -615, 533, -201, -48, -615, -252, 753, 520, 91, -160, -615, 0 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If positive, shift that token. If negative, reduce the rule which number is the opposite. If zero, do what YYDEFACT says. If YYTABLE_NINF, syntax error. */ #define YYTABLE_NINF -422 static const short yytable[] = { 5, 116, 111, 128, 117, 145, 186, 120, 127, 112, 83, 403, 217, 140, 195, 422, 84, 161, 120, 301, 343, 475, 142, -383, 85, 348, 7, 31, 43, -308, 356, 316, 86, 604, 144, 275, 187, 187, 7, 683, 232, 754, 44, 92, 34, 34, 475, 258, 7, 261, 94, 204, 253, 158, 118, 259, 96, 97, 158, 167, 222, 266, 99, 595, 399, 7, 276, 233, 7, 685, 397, 260, 100, 118, 118, 101, 221, 103, 476, 203, 104, 125, 734, 105, 113, 416, 118, 608, 281, 743, 158, 115, 611, 250, 678, 748, 129, 145, 138, 7, 269, 271, 177, 536, 256, 275, 749, 296, 7, 131, 653, 7, 131, 122, 633, 220, 171, 229, 218, 273, 124, 640, 255, 279, 348, 356, 118, 270, 684, 285, 519, 234, 596, 28, 289, 178, 250, 30, 144, 129, 144, 7, 118, 253, 213, 118, 428, 126, 266, 164, 28, 151, 131, 28, 30, 131, 313, 30, 686, 456, 120, 34, 199, 325, 443, 328, 307, -421, 529, 327, 797, 251, 34, 120, 135, 142, 750, 502, 148, 154, 705, 196, 134, 393, 28, 324, 173, 308, 30, 312, 315, 154, 404, 28, 444, 7, 28, 30, 723, 149, 30, 530, 334, 134, 130, 516, 264, 503, 152, 133, 504, 346, 34, 34, 251, 134, 342, 135, 21, 22, 174, 275, 7, 327, 132, 283, 28, 353, 34, 7, 30, 456, 154, 620, 217, 400, 34, 34, 380, 329, 492, 745, 153, 423, 385, 440, 401, 251, 156, 634, 282, 306, 7, 675, 621, 7, 728, 282, 7, 502, 505, 154, 262, 332, 253, 266, 34, 187, 163, 322, 324, 28, 154, 187, 393, 30, 5, 165, 263, 449, 28, 21, 22, 144, 30, 134, 282, 272, 130, 503, 154, 249, 504, 34, 383, 493, 7, 5, 359, 266, 168, 251, 34, 7, 787, 34, 441, 28, 132, 606, 384, 30, 547, 486, 28, 431, 284, 183, 30, 154, 198, 632, 120, 324, 282, 461, 134, 198, 135, 169, 223, 282, 120, 134, 695, 135, 144, 28, 447, 170, 28, 30, 505, 28, 30, 7, 131, 30, 28, 460, 548, 790, 30, 323, 28, 640, 198, 180, 30, 134, 181, 713, 134, 182, 135, 806, 213, 323, 807, 698, 502, 525, 154, 134, 486, 808, 510, 453, 34, 337, 176, 28, 187, 34, 499, 30, 154, 488, 28, 154, 259, 452, 30, 636, 34, 714, 116, 111, 637, 117, 616, 198, 135, 504, 112, 83, 260, 134, 179, 135, 617, 84, 802, 116, 111, 518, 117, 5, 117, 85, 489, 112, 83, 312, 809, 810, 34, 86, 84, 594, 28, 731, 190, 732, 30, 540, 85, 511, 92, 191, 140, 144, 585, 669, 86, 94, 28, 255, 342, 142, 30, 96, 97, 353, 34, 92, 526, 99, 1, 2, 527, 144, 94, 272, 259, 454, 154, 100, 96, 97, 101, 193, 103, 507, 99, 104, 512, 607, 105, 113, 260, 615, 607, 219, 100, 520, 115, 101, 521, 103, 259, 591, 104, 534, 268, 105, 113, 7, 585, 383, 598, 383, 668, 115, 607, 280, 260, 609, 651, 23, 24, 607, 609, 116, 111, 384, 117, 384, 217, 656, 7, 112, 83, 21, 22, 138, 26, 27, 84, 631, 627, 287, 117, 5, 609, 288, 85, 628, 811, 409, 410, 609, 23, 24, 86, 378, 379, 655, 129, 194, 680, 298, 440, 21, 22, 92, 295, 130, 123, 26, 27, 299, 94, 302, 131, 34, 204, 143, 96, 97, 127, 275, 147, 50, 99, 585, 740, 132, 304, 741, 187, 438, 385, 309, 100, 34, 662, 101, 638, 103, 517, 331, 104, 339, 688, 105, 113, 21, 22, 172, 175, 639, 707, 115, 310, 28, 340, 643, 344, 30, 50, 742, 350, 441, 120, 543, 544, 710, 355, 545, 62, 63, 64, 351, 218, 606, 135, 517, 354, 116, 111, 201, 117, 358, 362, 367, 540, 112, 83, 764, 701, 134, 765, 144, 84, 585, 607, 398, 34, 7, 213, 394, 85, 768, 7, 402, 405, 62, 63, 64, 86, 800, 230, 585, 801, 232, 254, 34, 257, 406, 407, 92, 408, 411, 676, 267, 609, 223, 94, 679, 412, 34, 327, 79, 96, 97, 413, 34, 418, 427, 99, 414, 419, 131, 201, 420, 421, 286, 751, 324, 100, 696, 144, 101, 294, 103, 585, 424, 104, 425, 426, 105, 113, 120, 429, 34, 709, 662, 265, 115, 143, 662, 7, 376, 377, 378, 379, 433, 320, 435, 326, 254, 430, 330, 28, 123, 201, 338, 30, 28, 480, 607, 434, 30, 144, 607, 482, 355, 513, 496, 250, 34, 395, 7, 34, 780, 347, 349, 607, 451, 251, 607, 357, 455, 497, 7, 131, 201, 514, 585, 34, 609, 522, 607, 607, 609, 265, 780, 523, 531, 537, 327, 542, 381, 382, 587, 541, 7, 609, 34, 245, 609, 34, 129, 292, 293, 600, 254, 603, 605, 623, 254, 610, 609, 609, 155, 130, 28, 624, 131, 303, 30, 644, 635, 650, 326, 34, 34, 317, 779, 355, 647, 784, 646, 648, 184, 132, 649, 251, 415, 192, 8, 9, 10, 11, 12, 13, 14, 28, 16, 392, 779, 30, 652, 396, 718, 719, 720, -147, 658, 28, 484, 666, 667, 30, 670, 349, 349, 672, 251, 432, 673, 254, 133, 254, 677, 681, 682, 437, 134, 7, 135, 28, 690, 702, 699, 30, 708, 716, 450, 7, 717, 725, 727, 386, 729, 733, 389, 730, 735, 736, 349, 7, 744, 746, 360, 361, 753, 711, 363, 364, 365, 366, 443, 758, 392, 274, 396, 282, 274, 274, 782, 759, 474, 760, 762, 274, 763, 766, 388, 197, 274, 391, 767, 773, 769, 771, 254, 254, 154, 775, 712, 274, 774, 206, 207, 208, 209, 210, 211, 212, 776, 201, 274, 274, 201, 785, 788, 791, 321, 274, 796, 274, 803, 804, 28, 473, 7, 805, 30, 436, 812, 201, 349, 254, 28, 524, 254, 198, 30, 485, 487, 703, 674, 134, 625, 135, 28, 198, 626, 630, 30, 589, 795, 134, 282, 135, 687, 319, 590, 198, 597, 448, 588, 143, 146, 134, 694, 135, 372, 373, 374, 375, 376, 377, 378, 379, 473, 477, 254, 485, 756, 757, 794, 786, 121, 7, 254, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 462, 463, 464, 465, 0, 467, 468, 469, 470, 471, 472, 618, 0, 0, 28, 479, 335, 0, 30, 0, 0, 0, 0, 0, 599, 0, 0, 198, 0, 0, 0, 0, 602, 134, 0, 135, 0, 0, 0, 0, 0, 254, 0, 7, 0, 0, 154, 0, 201, 0, 0, 206, 207, 208, 209, 210, 211, 212, 0, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 237, 593, 28, 7, 0, 0, 30, 0, 7, 21, 22, 23, 24, 599, 238, 198, 0, 592, 657, 472, 0, 134, 0, 135, 0, 0, 0, 25, 26, 27, 0, 250, 0, 0, 0, 0, 711, 373, 374, 375, 376, 377, 378, 379, 201, 0, 0, 131, 619, 201, 0, 0, 490, 0, 274, 494, 0, 28, 0, 0, 0, 30, 501, 508, 274, 0, 0, 0, 642, 457, 0, 201, 0, 240, 241, 0, 0, 242, 243, 0, 0, 0, 0, 535, 0, 0, 201, 0, 28, 201, 715, 0, 30, 28, 0, 722, 0, 30, 0, 0, 0, 484, 0, 0, 0, 0, 198, 0, 0, 251, 0, 0, 134, 0, 135, 374, 375, 376, 377, 378, 379, 0, 201, 0, 0, 368, 0, 0, 0, 0, 0, 671, 0, 739, 369, 370, 371, 372, 458, 374, 375, 376, 377, 378, 459, 437, 0, 0, 0, 0, 0, 0, 0, 664, 0, 665, 0, 0, 0, 0, 0, 0, 0, 481, 697, 0, 0, 0, 0, 0, 704, 613, 0, 508, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 0, 0, 0, 0, 201, 483, 781, 201, 0, 0, 693, 0, 0, 726, 0, 739, 371, 372, 373, 374, 375, 376, 377, 378, 379, 0, 201, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 0, 0, 0, 724, 0, 0, 0, 0, 0, 0, 0, 747, 0, 0, 752, 0, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 0, 0, 0, 761, 0, 0, 0, 274, 0, 0, 0, 0, 508, 0, 0, 0, 0, 0, 549, 0, -421, 46, 770, 0, 0, 772, 49, 0, 0, 0, 0, 0, 0, 0, 0, 50, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, 0, 792, 793, 550, 52, 0, 0, -421, 0, -421, -421, -421, -421, 0, 0, 0, 0, 0, 0, 54, 55, 56, 57, 551, 59, 60, 61, -421, -421, -421, 552, 553, 554, 0, 62, 555, 64, 0, 65, 66, 0, 0, 0, 70, 0, 72, 73, 74, 75, 0, 77, 0, 0, 0, 0, 0, 0, -421, 0, 0, 79, -421, -421, 7, 0, 0, 154, 0, 0, 0, 0, 206, 207, 208, 209, 210, 211, 212, 556, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 237, 0, 0, 0, 0, 0, 0, 0, 0, 21, 22, 23, 24, 0, 238, 0, 0, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 26, 27, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 240, 241, 154, 0, 242, 243, 0, 206, 207, 208, 209, 210, 211, 212, 601, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 237, 0, 0, 0, 0, 0, 0, 0, 0, 21, 22, 23, 24, 0, 238, 0, 0, 387, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 26, 27, 0, 0, 0, 0, 0, 0, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 240, 241, 154, 0, 242, 243, 0, 206, 207, 208, 209, 210, 211, 212, 0, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 237, 0, 0, 0, 0, 0, 0, 0, 0, 21, 22, 23, 24, 0, 238, 0, 0, 390, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 240, 241, 154, 0, 242, 243, 0, 206, 207, 208, 209, 210, 211, 212, 0, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 237, 0, 0, 0, 0, 0, 0, 0, 0, 21, 22, 23, 24, 0, 238, 0, 0, 478, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 240, 241, 154, 0, 242, 243, 0, 206, 207, 208, 209, 210, 211, 212, 0, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 237, 0, 0, 0, 0, 0, 0, 0, 0, 21, 22, 23, 24, 0, 238, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 240, 241, 154, 134, 242, 243, 691, 206, 207, 208, 209, 210, 211, 212, 0, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 237, 0, 0, 0, 0, 0, 0, 0, 0, 21, 22, 23, 24, 0, 238, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 240, 241, 154, 0, 242, 243, 0, 206, 207, 208, 209, 210, 211, 212, 0, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 237, 0, 0, 0, 0, 0, 0, 0, 0, 21, 22, 23, 24, 0, 238, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 26, 27, 0, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 223, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 0, 28, 0, 131, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 25, 26, 27, 240, 241, 0, 0, 242, 243, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 29, 30, 7, 0, 0, 0, 0, 0, 0, 0, 224, 0, 0, 0, 0, 0, 134, 0, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 223, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 0, 0, 0, 131, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 25, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, 0, 28, 0, 0, 29, 30, 20, 21, 22, 23, 24, 0, 0, 0, 345, 0, 0, 0, 0, 0, 134, 7, 0, 0, 0, 25, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, 28, 0, 0, 29, 30, 23, 24, -2, 45, 0, -421, 46, 0, 323, 47, 48, 49, 0, 0, 134, 0, 25, 26, 27, 0, 50, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, 0, 0, 0, 51, 52, 0, 0, 0, 0, -421, -421, -421, -421, 28, 0, 53, 0, 30, 0, 54, 55, 56, 57, 58, 59, 60, 61, -421, -421, -421, 0, 0, 134, 0, 62, 63, 64, 0, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 0, 0, 0, 0, 78, 45, -421, -421, 46, 79, -421, 47, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 50, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, 0, 0, 0, 51, 52, 0, 0, 491, 0, -421, -421, -421, -421, 0, 0, 53, 0, 0, 0, 54, 55, 56, 57, 58, 59, 60, 61, -421, -421, -421, 0, 0, 0, 0, 62, 63, 64, 0, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 0, 0, 0, 0, 78, 45, -421, -421, 46, 79, -421, 47, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 50, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, 0, 0, 0, 51, 52, 0, 0, 515, 0, -421, -421, -421, -421, 0, 0, 53, 0, 0, 0, 54, 55, 56, 57, 58, 59, 60, 61, -421, -421, -421, 0, 0, 0, 0, 62, 63, 64, 0, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 0, 0, 0, 0, 78, 45, -421, -421, 46, 79, -421, 47, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 50, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, 0, 0, 0, 51, 52, 0, 0, 612, 0, -421, -421, -421, -421, 0, 0, 53, 0, 0, 0, 54, 55, 56, 57, 58, 59, 60, 61, -421, -421, -421, 0, 0, 0, 0, 62, 63, 64, 0, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 0, 0, 0, 0, 78, 45, -421, -421, 46, 79, -421, 47, 48, 49, 0, 0, 0, 0, 0, 0, 0, 0, 50, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, -421, 0, 0, 0, 51, 52, 0, 0, 0, 0, -421, -421, -421, -421, 0, 0, 53, 0, 689, 0, 54, 55, 56, 57, 58, 59, 60, 61, -421, -421, -421, 0, 0, 0, 0, 62, 63, 64, 0, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 6, 0, 7, 0, 78, 0, -421, 0, 0, 79, -421, 0, 0, 0, 0, 0, 0, 0, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 42, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 25, 26, 27, 0, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 159, 28, 160, 0, 29, 30, 0, 0, 0, 0, 0, 0, 0, 0, 25, 26, 27, 0, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 22, 23, 24, 0, 28, 7, 0, 29, 30, 0, 0, 0, 0, 0, 0, 0, 0, 25, 26, 27, 0, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 22, 23, 24, 0, 28, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 202, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 28, 205, 0, 0, 30, 654, 206, 207, 208, 209, 210, 211, 212, 0, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 0, 7, 0, 0, 0, 0, 0, 0, 0, 290, 0, 0, 0, 0, 25, 26, 27, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 0, 7, 28, 0, 0, 29, 30, 0, 0, 0, 0, 0, 0, 0, 25, 26, 27, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 0, 7, 28, 0, 0, 29, 30, 0, 0, 0, 0, 0, 0, 0, 25, 26, 27, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 185, 0, 0, 0, 0, 0, 0, 0, 0, 21, 22, 23, 24, 0, 7, 28, 0, 0, 29, 30, 0, 0, 0, 0, 0, 0, 0, 25, 26, 27, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 22, 23, 24, 0, 7, 28, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 202, 26, 27, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 22, 23, 24, 0, 614, 28, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 25, 26, 27, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 22, 23, 24, 0, 7, 28, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 25, 26, 27, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 0, 0, 28, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 25, 26, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 30 }; static const short yycheck[] = { 0, 4, 4, 33, 4, 35, 73, 7, 32, 4, 4, 281, 118, 34, 79, 304, 4, 54, 18, 179, 221, 32, 34, 32, 4, 224, 3, 1, 2, 37, 229, 191, 4, 498, 34, 6, 73, 74, 3, 3, 10, 37, 0, 4, 1, 2, 32, 138, 3, 140, 4, 116, 133, 53, 82, 31, 4, 4, 58, 59, 125, 142, 4, 32, 276, 3, 37, 37, 3, 3, 271, 47, 4, 82, 82, 4, 124, 4, 89, 116, 4, 82, 696, 4, 4, 297, 82, 507, 44, 703, 90, 4, 512, 31, 34, 709, 31, 127, 34, 3, 148, 149, 4, 89, 134, 6, 31, 44, 3, 47, 575, 3, 47, 39, 534, 92, 71, 129, 118, 153, 111, 541, 134, 157, 323, 324, 82, 92, 92, 163, 419, 101, 101, 88, 168, 37, 31, 92, 138, 31, 140, 3, 82, 224, 118, 82, 47, 34, 229, 58, 88, 34, 47, 88, 92, 47, 190, 92, 92, 358, 160, 118, 98, 197, 34, 199, 187, 37, 4, 31, 784, 109, 129, 173, 109, 187, 101, 4, 90, 6, 645, 90, 107, 264, 88, 197, 3, 187, 92, 189, 190, 6, 283, 88, 64, 3, 88, 92, 663, 111, 92, 37, 202, 107, 44, 417, 101, 34, 93, 101, 37, 223, 169, 170, 109, 107, 216, 109, 40, 41, 37, 6, 3, 31, 64, 161, 88, 227, 185, 3, 92, 430, 6, 90, 340, 33, 193, 194, 250, 101, 400, 706, 31, 310, 256, 336, 44, 109, 31, 34, 31, 187, 3, 34, 111, 3, 676, 31, 3, 4, 87, 6, 31, 3, 345, 346, 223, 304, 31, 3, 282, 88, 6, 310, 355, 92, 276, 31, 47, 344, 88, 40, 41, 283, 92, 107, 31, 3, 44, 34, 6, 11, 37, 250, 31, 401, 3, 297, 234, 380, 31, 109, 259, 3, 769, 262, 336, 88, 64, 68, 47, 92, 68, 394, 88, 327, 32, 4, 92, 6, 101, 533, 322, 335, 31, 362, 107, 101, 109, 31, 31, 31, 332, 107, 34, 109, 336, 88, 338, 31, 88, 92, 87, 88, 92, 3, 47, 92, 88, 361, 441, 771, 92, 101, 88, 775, 101, 31, 92, 107, 34, 3, 107, 37, 109, 34, 340, 101, 37, 639, 4, 3, 6, 107, 455, 44, 410, 351, 335, 37, 31, 88, 419, 340, 4, 92, 6, 4, 88, 6, 31, 32, 92, 33, 351, 37, 399, 399, 38, 399, 34, 101, 109, 37, 399, 399, 47, 107, 31, 109, 44, 399, 791, 416, 416, 418, 416, 417, 418, 399, 37, 416, 416, 423, 803, 804, 383, 399, 416, 459, 88, 683, 31, 685, 92, 435, 416, 411, 399, 31, 461, 441, 442, 603, 416, 399, 88, 459, 448, 461, 92, 399, 399, 453, 411, 416, 88, 399, 94, 95, 92, 461, 416, 3, 31, 32, 6, 399, 416, 416, 399, 31, 399, 409, 416, 399, 412, 507, 399, 399, 47, 518, 512, 39, 416, 34, 399, 416, 37, 416, 31, 32, 416, 429, 89, 416, 416, 3, 498, 31, 32, 31, 32, 416, 534, 34, 47, 507, 556, 42, 43, 541, 512, 516, 516, 47, 516, 47, 624, 584, 3, 516, 516, 40, 41, 461, 59, 60, 516, 532, 532, 3, 532, 533, 534, 3, 516, 532, 808, 32, 33, 541, 42, 43, 516, 106, 107, 584, 31, 82, 617, 37, 643, 40, 41, 516, 34, 44, 25, 59, 60, 3, 516, 3, 47, 522, 631, 34, 516, 516, 594, 6, 39, 18, 516, 575, 34, 64, 37, 37, 617, 68, 594, 34, 516, 542, 586, 516, 31, 516, 35, 89, 516, 83, 631, 516, 516, 40, 41, 66, 67, 44, 650, 516, 33, 88, 33, 543, 83, 92, 18, 702, 32, 643, 614, 33, 34, 654, 101, 37, 65, 66, 67, 33, 624, 68, 109, 35, 32, 632, 632, 98, 632, 89, 31, 31, 636, 632, 632, 34, 640, 107, 37, 643, 632, 645, 676, 32, 605, 3, 624, 89, 632, 744, 3, 32, 32, 65, 66, 67, 632, 34, 129, 663, 37, 10, 133, 624, 135, 37, 32, 632, 44, 33, 610, 142, 676, 31, 632, 615, 32, 638, 31, 91, 632, 632, 32, 644, 32, 83, 632, 34, 32, 47, 161, 32, 32, 164, 710, 711, 632, 637, 702, 632, 171, 632, 706, 32, 632, 32, 32, 632, 632, 713, 32, 672, 652, 717, 142, 632, 187, 721, 3, 104, 105, 106, 107, 34, 195, 37, 197, 198, 89, 200, 88, 202, 203, 204, 92, 88, 32, 771, 89, 92, 744, 775, 32, 101, 37, 34, 31, 708, 101, 3, 711, 755, 223, 224, 788, 89, 109, 791, 229, 89, 34, 3, 47, 234, 34, 769, 727, 771, 31, 803, 804, 775, 200, 777, 38, 34, 3, 31, 31, 250, 251, 37, 32, 3, 788, 746, 131, 791, 749, 31, 169, 170, 32, 264, 33, 31, 111, 268, 32, 803, 804, 52, 44, 88, 82, 47, 185, 92, 31, 44, 109, 282, 773, 774, 193, 755, 101, 64, 758, 37, 64, 72, 64, 64, 109, 296, 77, 19, 20, 21, 22, 23, 24, 25, 88, 27, 264, 777, 92, 38, 268, 61, 62, 63, 38, 66, 88, 101, 32, 32, 92, 38, 323, 324, 31, 109, 327, 68, 329, 101, 331, 34, 32, 3, 335, 107, 3, 109, 88, 34, 32, 64, 92, 31, 34, 346, 3, 33, 32, 31, 259, 34, 83, 262, 34, 32, 34, 358, 3, 32, 31, 236, 237, 11, 31, 240, 241, 242, 243, 34, 38, 329, 153, 331, 31, 156, 157, 34, 34, 380, 32, 34, 163, 34, 33, 260, 31, 168, 263, 31, 31, 38, 32, 394, 395, 6, 32, 64, 179, 31, 11, 12, 13, 14, 15, 16, 17, 34, 409, 190, 191, 412, 32, 32, 32, 196, 197, 34, 199, 32, 32, 88, 380, 3, 34, 92, 335, 34, 429, 430, 431, 88, 423, 434, 101, 92, 394, 395, 643, 608, 107, 532, 109, 88, 101, 532, 532, 92, 449, 777, 107, 31, 109, 624, 194, 453, 101, 461, 340, 448, 461, 38, 107, 636, 109, 100, 101, 102, 103, 104, 105, 106, 107, 431, 383, 476, 434, 717, 721, 775, 766, 18, 3, 484, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 369, 370, 371, 372, -1, 374, 375, 376, 377, 378, 379, 519, -1, -1, 88, 384, 31, -1, 92, -1, -1, -1, -1, -1, 476, -1, -1, 101, -1, -1, -1, -1, 484, 107, -1, 109, -1, -1, -1, -1, -1, 536, -1, 3, -1, -1, 6, -1, 543, -1, -1, 11, 12, 13, 14, 15, 16, 17, -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 88, 3, -1, -1, 92, -1, 3, 40, 41, 42, 43, 536, 45, 101, -1, 457, 584, 459, -1, 107, -1, 109, -1, -1, -1, 58, 59, 60, -1, 31, -1, -1, -1, -1, 31, 101, 102, 103, 104, 105, 106, 107, 610, -1, -1, 47, 522, 615, -1, -1, 398, -1, 400, 401, -1, 88, -1, -1, -1, 92, 408, 409, 410, -1, -1, -1, 542, 32, -1, 637, -1, 104, 105, -1, -1, 108, 109, -1, -1, -1, -1, 429, -1, -1, 652, -1, 88, 655, 656, -1, 92, 88, -1, 661, -1, 92, -1, -1, -1, 101, -1, -1, -1, -1, 101, -1, -1, 109, -1, -1, 107, -1, 109, 102, 103, 104, 105, 106, 107, -1, 688, -1, -1, 48, -1, -1, -1, -1, -1, 605, -1, 699, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 711, -1, -1, -1, -1, -1, -1, -1, 593, -1, 595, -1, -1, -1, -1, -1, -1, -1, 48, 638, -1, -1, -1, -1, -1, 644, 517, -1, 519, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, -1, -1, -1, -1, 755, 48, 757, 758, -1, -1, 635, -1, -1, 672, -1, 766, 99, 100, 101, 102, 103, 104, 105, 106, 107, -1, 777, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, -1, -1, -1, 666, -1, -1, -1, -1, -1, -1, -1, 708, -1, -1, 711, -1, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, -1, -1, -1, 727, -1, -1, -1, 603, -1, -1, -1, -1, 608, -1, -1, -1, -1, -1, 1, -1, 3, 4, 746, -1, -1, 749, 9, -1, -1, -1, -1, -1, -1, -1, -1, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, -1, 773, 774, 34, 35, -1, -1, 38, -1, 40, 41, 42, 43, -1, -1, -1, -1, -1, -1, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, -1, 65, 66, 67, -1, 69, 70, -1, -1, -1, 74, -1, 76, 77, 78, 79, -1, 81, -1, -1, -1, -1, -1, -1, 88, -1, -1, 91, 92, 93, 3, -1, -1, 6, -1, -1, -1, -1, 11, 12, 13, 14, 15, 16, 17, 109, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, -1, -1, -1, -1, 40, 41, 42, 43, -1, 45, -1, -1, 48, -1, -1, -1, -1, -1, -1, -1, -1, -1, 58, 59, 60, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 88, -1, -1, -1, 92, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 104, 105, 6, -1, 108, 109, -1, 11, 12, 13, 14, 15, 16, 17, 48, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, -1, -1, -1, -1, 40, 41, 42, 43, -1, 45, -1, -1, 48, -1, -1, -1, -1, -1, -1, -1, -1, -1, 58, 59, 60, -1, -1, -1, -1, -1, -1, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 88, -1, -1, -1, 92, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 104, 105, 6, -1, 108, 109, -1, 11, 12, 13, 14, 15, 16, 17, -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, -1, -1, -1, -1, 40, 41, 42, 43, -1, 45, -1, -1, 48, -1, -1, -1, -1, -1, -1, -1, -1, -1, 58, 59, 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 88, -1, -1, -1, 92, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 104, 105, 6, -1, 108, 109, -1, 11, 12, 13, 14, 15, 16, 17, -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, -1, -1, -1, -1, 40, 41, 42, 43, -1, 45, -1, -1, 48, -1, -1, -1, -1, -1, -1, -1, -1, -1, 58, 59, 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 88, -1, -1, -1, 92, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 104, 105, 6, -1, 108, 109, -1, 11, 12, 13, 14, 15, 16, 17, -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, -1, -1, -1, -1, 40, 41, 42, 43, -1, 45, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 58, 59, 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 88, -1, -1, -1, 92, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 104, 105, 6, 107, 108, 109, 10, 11, 12, 13, 14, 15, 16, 17, -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, -1, -1, -1, -1, 40, 41, 42, 43, -1, 45, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 58, 59, 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 88, -1, -1, -1, 92, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 104, 105, 6, -1, 108, 109, -1, 11, 12, 13, 14, 15, 16, 17, -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, -1, -1, -1, -1, 40, 41, 42, 43, -1, 45, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 58, 59, 60, -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, -1, -1, -1, 39, 40, 41, 42, 43, -1, 88, -1, 47, -1, 92, -1, -1, -1, -1, -1, -1, -1, -1, 58, 59, 60, 104, 105, -1, -1, 108, 109, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 88, -1, -1, 91, 92, 3, -1, -1, -1, -1, -1, -1, -1, 101, -1, -1, -1, -1, -1, 107, -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, -1, -1, -1, 39, 40, 41, 42, 43, -1, -1, -1, 47, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, 58, 59, 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, -1, -1, -1, 88, -1, -1, 91, 92, 39, 40, 41, 42, 43, -1, -1, -1, 101, -1, -1, -1, -1, -1, 107, 3, -1, -1, -1, 58, 59, 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, -1, -1, -1, -1, -1, -1, 88, -1, -1, 91, 92, 42, 43, 0, 1, -1, 3, 4, -1, 101, 7, 8, 9, -1, -1, 107, -1, 58, 59, 60, -1, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, -1, -1, -1, 34, 35, -1, -1, -1, -1, 40, 41, 42, 43, 88, -1, 46, -1, 92, -1, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, -1, -1, 107, -1, 65, 66, 67, -1, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, -1, -1, -1, -1, 86, 1, 88, 3, 4, 91, 92, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, -1, -1, -1, 34, 35, -1, -1, 38, -1, 40, 41, 42, 43, -1, -1, 46, -1, -1, -1, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, -1, -1, -1, -1, 65, 66, 67, -1, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, -1, -1, -1, -1, 86, 1, 88, 3, 4, 91, 92, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, -1, -1, -1, 34, 35, -1, -1, 38, -1, 40, 41, 42, 43, -1, -1, 46, -1, -1, -1, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, -1, -1, -1, -1, 65, 66, 67, -1, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, -1, -1, -1, -1, 86, 1, 88, 3, 4, 91, 92, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, -1, -1, -1, 34, 35, -1, -1, 38, -1, 40, 41, 42, 43, -1, -1, 46, -1, -1, -1, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, -1, -1, -1, -1, 65, 66, 67, -1, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, -1, -1, -1, -1, 86, 1, 88, 3, 4, 91, 92, 7, 8, 9, -1, -1, -1, -1, -1, -1, -1, -1, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, -1, -1, -1, 34, 35, -1, -1, -1, -1, 40, 41, 42, 43, -1, -1, 46, -1, 48, -1, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, -1, -1, -1, -1, 65, 66, 67, -1, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 1, -1, 3, -1, 86, -1, 88, -1, -1, 91, 92, -1, -1, -1, -1, -1, -1, -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, -1, 39, 40, 41, 42, 43, 1, -1, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 58, 59, 60, -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, -1, 39, 40, 41, 42, 43, 1, 88, 3, -1, 91, 92, -1, -1, -1, -1, -1, -1, -1, -1, 58, 59, 60, -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, 40, 41, 42, 43, -1, 88, 3, -1, 91, 92, -1, -1, -1, -1, -1, -1, -1, -1, 58, 59, 60, -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, 40, 41, 42, 43, -1, 88, -1, -1, -1, 92, -1, -1, -1, -1, -1, -1, -1, -1, 58, 59, 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 3, -1, 88, 6, -1, -1, 92, 93, 11, 12, 13, 14, 15, 16, 17, -1, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, -1, 39, 40, 41, 42, 43, -1, 3, -1, -1, -1, -1, -1, -1, -1, 11, -1, -1, -1, -1, 58, 59, 60, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, -1, 39, 40, 41, 42, 43, -1, 3, 88, -1, -1, 91, 92, -1, -1, -1, -1, -1, -1, -1, 58, 59, 60, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, -1, 39, 40, 41, 42, 43, -1, 3, 88, -1, -1, 91, 92, -1, -1, -1, -1, -1, -1, -1, 58, 59, 60, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1, -1, -1, -1, -1, 40, 41, 42, 43, -1, 3, 88, -1, -1, 91, 92, -1, -1, -1, -1, -1, -1, -1, 58, 59, 60, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, 40, 41, 42, 43, -1, 3, 88, -1, -1, -1, 92, -1, -1, -1, -1, -1, -1, -1, 58, 59, 60, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, 40, 41, 42, 43, -1, 3, 88, -1, -1, -1, 92, -1, -1, -1, -1, -1, -1, -1, 58, 59, 60, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, 40, 41, 42, 43, -1, 3, 88, -1, -1, -1, 92, -1, -1, -1, -1, -1, -1, -1, 58, 59, 60, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 42, 43, -1, -1, 88, -1, -1, -1, 92, -1, -1, -1, -1, -1, -1, -1, 58, 59, 60, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 88, -1, -1, -1, 92 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const unsigned char yystos[] = { 0, 94, 95, 113, 114, 248, 1, 3, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 39, 40, 41, 42, 43, 58, 59, 60, 88, 91, 92, 191, 205, 206, 208, 209, 210, 211, 212, 228, 238, 240, 1, 191, 0, 1, 4, 7, 8, 9, 18, 34, 35, 46, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 86, 91, 115, 116, 117, 119, 120, 121, 122, 123, 124, 125, 127, 128, 129, 130, 131, 132, 133, 136, 137, 138, 140, 142, 147, 148, 149, 150, 151, 154, 155, 156, 157, 161, 162, 166, 167, 177, 187, 248, 82, 235, 248, 235, 39, 238, 111, 82, 34, 209, 205, 31, 44, 47, 64, 101, 107, 109, 196, 197, 199, 201, 202, 203, 204, 238, 248, 205, 211, 238, 90, 111, 239, 34, 93, 31, 6, 243, 31, 245, 248, 1, 3, 207, 208, 31, 245, 31, 135, 248, 31, 31, 31, 71, 238, 3, 37, 238, 31, 4, 37, 31, 31, 34, 37, 4, 243, 31, 146, 207, 144, 146, 31, 31, 243, 31, 82, 228, 245, 31, 101, 199, 204, 238, 58, 207, 228, 6, 11, 12, 13, 14, 15, 16, 17, 191, 192, 193, 195, 220, 248, 39, 92, 240, 228, 31, 101, 188, 189, 191, 202, 204, 238, 248, 10, 37, 101, 213, 214, 31, 45, 48, 104, 105, 108, 109, 207, 219, 220, 221, 243, 11, 31, 109, 200, 203, 238, 204, 205, 238, 196, 31, 47, 196, 31, 47, 101, 200, 203, 238, 89, 240, 92, 240, 3, 236, 243, 6, 37, 236, 246, 236, 34, 44, 31, 199, 32, 236, 238, 3, 3, 236, 11, 141, 188, 188, 238, 34, 44, 169, 37, 3, 143, 246, 3, 188, 37, 198, 199, 202, 248, 34, 33, 145, 248, 236, 237, 248, 246, 188, 165, 189, 238, 243, 3, 101, 204, 236, 238, 31, 236, 101, 238, 89, 3, 215, 248, 31, 199, 37, 238, 83, 33, 194, 248, 239, 83, 101, 204, 238, 201, 238, 32, 33, 190, 248, 32, 101, 201, 238, 89, 199, 219, 219, 31, 219, 219, 219, 219, 31, 48, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 204, 238, 238, 31, 47, 204, 188, 48, 219, 188, 48, 219, 200, 203, 89, 101, 200, 239, 32, 114, 33, 44, 32, 213, 196, 32, 37, 32, 44, 32, 33, 33, 32, 32, 34, 238, 114, 168, 32, 32, 32, 32, 144, 146, 32, 32, 32, 83, 47, 32, 89, 204, 238, 34, 89, 37, 188, 238, 68, 153, 196, 205, 159, 34, 64, 222, 223, 248, 195, 228, 238, 89, 32, 191, 32, 89, 201, 32, 101, 107, 204, 207, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 219, 200, 238, 32, 89, 188, 48, 219, 32, 48, 32, 48, 101, 200, 203, 200, 4, 37, 243, 38, 246, 220, 243, 247, 34, 34, 118, 4, 134, 243, 4, 34, 37, 87, 139, 199, 243, 244, 236, 191, 199, 37, 34, 38, 114, 35, 187, 144, 34, 37, 31, 38, 145, 3, 88, 92, 241, 4, 37, 34, 163, 126, 199, 243, 89, 3, 216, 217, 248, 32, 31, 33, 34, 37, 152, 68, 196, 1, 34, 54, 61, 62, 63, 66, 109, 119, 120, 121, 122, 129, 131, 133, 136, 138, 140, 142, 148, 149, 150, 161, 162, 166, 170, 173, 174, 175, 176, 177, 178, 179, 183, 186, 187, 248, 224, 37, 194, 238, 190, 32, 219, 32, 205, 32, 101, 197, 32, 200, 32, 48, 200, 33, 170, 31, 68, 205, 230, 248, 32, 230, 38, 243, 3, 207, 34, 44, 244, 188, 90, 111, 242, 111, 82, 151, 157, 161, 162, 164, 174, 187, 114, 230, 34, 44, 33, 38, 31, 44, 230, 231, 188, 199, 31, 172, 37, 64, 64, 64, 109, 240, 38, 170, 93, 207, 228, 238, 66, 225, 226, 229, 248, 158, 219, 219, 32, 32, 32, 246, 38, 188, 31, 68, 139, 34, 199, 34, 34, 199, 146, 32, 3, 3, 92, 3, 92, 192, 207, 48, 34, 10, 218, 219, 217, 34, 199, 188, 213, 64, 232, 248, 32, 153, 188, 170, 171, 240, 31, 199, 207, 31, 64, 3, 37, 238, 34, 33, 61, 62, 63, 227, 238, 170, 219, 32, 188, 31, 230, 34, 34, 242, 242, 83, 152, 32, 34, 233, 234, 238, 34, 37, 196, 152, 32, 170, 31, 188, 152, 31, 101, 204, 188, 11, 37, 181, 226, 229, 38, 34, 32, 188, 34, 34, 34, 37, 33, 31, 196, 38, 188, 32, 188, 31, 31, 32, 34, 180, 182, 199, 248, 238, 34, 160, 199, 32, 234, 170, 32, 184, 230, 32, 188, 188, 231, 182, 34, 152, 185, 230, 34, 37, 185, 32, 32, 34, 34, 37, 44, 185, 185, 213, 34 }; #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) # define YYSIZE_T __SIZE_TYPE__ #endif #if ! defined (YYSIZE_T) && defined (size_t) # define YYSIZE_T size_t #endif #if ! defined (YYSIZE_T) # if defined (__STDC__) || defined (__cplusplus) # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # endif #endif #if ! defined (YYSIZE_T) # define YYSIZE_T unsigned int #endif #define yyerrok (yyerrstatus = 0) #define yyclearin (yychar = YYEMPTY) #define YYEMPTY (-2) #define YYEOF 0 #define YYACCEPT goto yyacceptlab #define YYABORT goto yyabortlab #define YYERROR goto yyerrlab1 /* Like YYERROR except do call yyerror. This remains here temporarily to ease the transition to the new meaning of YYERROR, for GCC. Once GCC version 2 has supplanted version 1, this can go. */ #define YYFAIL goto yyerrlab #define YYRECOVERING() (!!yyerrstatus) #define YYBACKUP(Token, Value) \ do \ if (yychar == YYEMPTY && yylen == 1) \ { \ yychar = (Token); \ yylval = (Value); \ yytoken = YYTRANSLATE (yychar); \ YYPOPSTACK; \ goto yybackup; \ } \ else \ { \ yyerror ("syntax error: cannot back up");\ YYERROR; \ } \ while (0) #define YYTERROR 1 #define YYERRCODE 256 /* YYLLOC_DEFAULT -- Compute the default location (before the actions are run). */ #ifndef YYLLOC_DEFAULT # define YYLLOC_DEFAULT(Current, Rhs, N) \ Current.first_line = Rhs[1].first_line; \ Current.first_column = Rhs[1].first_column; \ Current.last_line = Rhs[N].last_line; \ Current.last_column = Rhs[N].last_column; #endif /* YYLEX -- calling `yylex' with the right arguments. */ #ifdef YYLEX_PARAM # define YYLEX yylex (YYLEX_PARAM) #else # define YYLEX yylex () #endif /* Enable debugging if requested. */ #if YYDEBUG # ifndef YYFPRINTF # include /* INFRINGES ON USER NAME SPACE */ # define YYFPRINTF fprintf # endif # define YYDPRINTF(Args) \ do { \ if (yydebug) \ YYFPRINTF Args; \ } while (0) # define YYDSYMPRINT(Args) \ do { \ if (yydebug) \ yysymprint Args; \ } while (0) # define YYDSYMPRINTF(Title, Token, Value, Location) \ do { \ if (yydebug) \ { \ YYFPRINTF (stderr, "%s ", Title); \ yysymprint (stderr, \ Token, Value); \ YYFPRINTF (stderr, "\n"); \ } \ } while (0) /*------------------------------------------------------------------. | yy_stack_print -- Print the state stack from its BOTTOM up to its | | TOP (cinluded). | `------------------------------------------------------------------*/ #if defined (__STDC__) || defined (__cplusplus) static void yy_stack_print (short *bottom, short *top) #else static void yy_stack_print (bottom, top) short *bottom; short *top; #endif { YYFPRINTF (stderr, "Stack now"); for (/* Nothing. */; bottom <= top; ++bottom) YYFPRINTF (stderr, " %d", *bottom); YYFPRINTF (stderr, "\n"); } # define YY_STACK_PRINT(Bottom, Top) \ do { \ if (yydebug) \ yy_stack_print ((Bottom), (Top)); \ } while (0) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ #if defined (__STDC__) || defined (__cplusplus) static void yy_reduce_print (int yyrule) #else static void yy_reduce_print (yyrule) int yyrule; #endif { int yyi; unsigned int yylineno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", yyrule - 1, yylineno); /* Print the symbols being reduced, and their result. */ for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); } # define YY_REDUCE_PRINT(Rule) \ do { \ if (yydebug) \ yy_reduce_print (Rule); \ } while (0) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ int yydebug; #else /* !YYDEBUG */ # define YYDPRINTF(Args) # define YYDSYMPRINT(Args) # define YYDSYMPRINTF(Title, Token, Value, Location) # define YY_STACK_PRINT(Bottom, Top) # define YY_REDUCE_PRINT(Rule) #endif /* !YYDEBUG */ /* YYINITDEPTH -- initial size of the parser's stacks. */ #ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only if the built-in stack extension method is used). Do not make this value too large; the results are undefined if SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) evaluated with infinite-precision integer arithmetic. */ #if YYMAXDEPTH == 0 # undef YYMAXDEPTH #endif #ifndef YYMAXDEPTH # define YYMAXDEPTH 10000 #endif #if YYERROR_VERBOSE # ifndef yystrlen # if defined (__GLIBC__) && defined (_STRING_H) # define yystrlen strlen # else /* Return the length of YYSTR. */ static YYSIZE_T # if defined (__STDC__) || defined (__cplusplus) yystrlen (const char *yystr) # else yystrlen (yystr) const char *yystr; # endif { register const char *yys = yystr; while (*yys++ != '\0') continue; return yys - yystr - 1; } # endif # endif # ifndef yystpcpy # if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) # define yystpcpy stpcpy # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ static char * # if defined (__STDC__) || defined (__cplusplus) yystpcpy (char *yydest, const char *yysrc) # else yystpcpy (yydest, yysrc) char *yydest; const char *yysrc; # endif { register char *yyd = yydest; register const char *yys = yysrc; while ((*yyd++ = *yys++) != '\0') continue; return yyd - 1; } # endif # endif #endif /* !YYERROR_VERBOSE */ #if YYDEBUG /*--------------------------------. | Print this symbol on YYOUTPUT. | `--------------------------------*/ #if defined (__STDC__) || defined (__cplusplus) static void yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) #else static void yysymprint (yyoutput, yytype, yyvaluep) FILE *yyoutput; int yytype; YYSTYPE *yyvaluep; #endif { /* Pacify ``unused variable'' warnings. */ (void) yyvaluep; if (yytype < YYNTOKENS) { YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); # ifdef YYPRINT YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); # endif } else YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); switch (yytype) { default: break; } YYFPRINTF (yyoutput, ")"); } #endif /* ! YYDEBUG */ /*-----------------------------------------------. | Release the memory associated to this symbol. | `-----------------------------------------------*/ #if defined (__STDC__) || defined (__cplusplus) static void yydestruct (int yytype, YYSTYPE *yyvaluep) #else static void yydestruct (yytype, yyvaluep) int yytype; YYSTYPE *yyvaluep; #endif { /* Pacify ``unused variable'' warnings. */ (void) yyvaluep; switch (yytype) { default: break; } } /* Prevent warnings from -Wmissing-prototypes. */ #ifdef YYPARSE_PARAM # if defined (__STDC__) || defined (__cplusplus) int yyparse (void *YYPARSE_PARAM); # else int yyparse (); # endif #else /* ! YYPARSE_PARAM */ #if defined (__STDC__) || defined (__cplusplus) int yyparse (void); #else int yyparse (); #endif #endif /* ! YYPARSE_PARAM */ /* The lookahead symbol. */ int yychar; /* The semantic value of the lookahead symbol. */ YYSTYPE yylval; /* Number of syntax errors so far. */ int yynerrs; /*----------. | yyparse. | `----------*/ #ifdef YYPARSE_PARAM # if defined (__STDC__) || defined (__cplusplus) int yyparse (void *YYPARSE_PARAM) # else int yyparse (YYPARSE_PARAM) void *YYPARSE_PARAM; # endif #else /* ! YYPARSE_PARAM */ #if defined (__STDC__) || defined (__cplusplus) int yyparse (void) #else int yyparse () #endif #endif { register int yystate; register int yyn; int yyresult; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* Lookahead token as an internal (translated) token number. */ int yytoken = 0; /* Three stacks and their tools: `yyss': related to states, `yyvs': related to semantic values, `yyls': related to locations. Refer to the stacks thru separate pointers, to allow yyoverflow to reallocate them elsewhere. */ /* The state stack. */ short yyssa[YYINITDEPTH]; short *yyss = yyssa; register short *yyssp; /* The semantic value stack. */ YYSTYPE yyvsa[YYINITDEPTH]; YYSTYPE *yyvs = yyvsa; register YYSTYPE *yyvsp; #define YYPOPSTACK (yyvsp--, yyssp--) YYSIZE_T yystacksize = YYINITDEPTH; /* The variables used to return semantic value and location from the action routines. */ YYSTYPE yyval; /* When reducing, the number of symbols on the RHS of the reduced rule. */ int yylen; YYDPRINTF ((stderr, "Starting parse\n")); yystate = 0; yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ /* Initialize stack pointers. Waste one element of value and location stack so that they stay on the same level as the state stack. The wasted elements are never initialized. */ yyssp = yyss; yyvsp = yyvs; goto yysetstate; /*------------------------------------------------------------. | yynewstate -- Push a new state, which is found in yystate. | `------------------------------------------------------------*/ yynewstate: /* In all cases, when you get here, the value and location stacks have just been pushed. so pushing a state here evens the stacks. */ yyssp++; yysetstate: *yyssp = yystate; if (yyss + yystacksize - 1 <= yyssp) { /* Get the current used size of the three stacks, in elements. */ YYSIZE_T yysize = yyssp - yyss + 1; #ifdef yyoverflow { /* Give user a chance to reallocate the stack. Use copies of these so that the &'s don't force the real ones into memory. */ YYSTYPE *yyvs1 = yyvs; short *yyss1 = yyss; /* Each stack pointer address is followed by the size of the data in use in that stack, in bytes. This used to be a conditional around just the two extra args, but that might be undefined if yyoverflow is a macro. */ yyoverflow ("parser stack overflow", &yyss1, yysize * sizeof (*yyssp), &yyvs1, yysize * sizeof (*yyvsp), &yystacksize); yyss = yyss1; yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE goto yyoverflowlab; # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) goto yyoverflowlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) yystacksize = YYMAXDEPTH; { short *yyss1 = yyss; union yyalloc *yyptr = (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); if (! yyptr) goto yyoverflowlab; YYSTACK_RELOCATE (yyss); YYSTACK_RELOCATE (yyvs); # undef YYSTACK_RELOCATE if (yyss1 != yyssa) YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ yyssp = yyss + yysize - 1; yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); goto yybackup; /*-----------. | yybackup. | `-----------*/ yybackup: /* Do appropriate processing given the current state. */ /* Read a lookahead token if we need one and don't already have one. */ /* yyresume: */ /* First try to decide what to do without reference to lookahead token. */ yyn = yypact[yystate]; if (yyn == YYPACT_NINF) goto yydefault; /* Not known => get a lookahead token if don't already have one. */ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); yychar = YYLEX; } if (yychar <= YYEOF) { yychar = yytoken = YYEOF; YYDPRINTF ((stderr, "Now at end of input.\n")); } else { yytoken = YYTRANSLATE (yychar); YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); } /* If the proper action on seeing token YYTOKEN is to reduce or to detect an error, take that action. */ yyn += yytoken; if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) goto yydefault; yyn = yytable[yyn]; if (yyn <= 0) { if (yyn == 0 || yyn == YYTABLE_NINF) goto yyerrlab; yyn = -yyn; goto yyreduce; } if (yyn == YYFINAL) YYACCEPT; /* Shift the lookahead token. */ YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); /* Discard the token being shifted unless it is eof. */ if (yychar != YYEOF) yychar = YYEMPTY; *++yyvsp = yylval; /* Count tokens shifted since error; after three, turn off error status. */ if (yyerrstatus) yyerrstatus--; yystate = yyn; goto yynewstate; /*-----------------------------------------------------------. | yydefault -- do the default action for the current state. | `-----------------------------------------------------------*/ yydefault: yyn = yydefact[yystate]; if (yyn == 0) goto yyerrlab; goto yyreduce; /*-----------------------------. | yyreduce -- Do a reduction. | `-----------------------------*/ yyreduce: /* yyn is the number of a rule to reduce with. */ yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: `$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison users should not rely upon it. Assigning to YYVAL unconditionally makes the parser a bit smaller, and it avoids a GCC warning that YYVAL may be used uninitialized. */ yyval = yyvsp[1-yylen]; YY_REDUCE_PRINT (yyn); switch (yyn) { case 2: #line 965 "CableSwig/SWIG/Source/CParse/parser.y" { Setattr(yyvsp[0].node,"classes",classes); Setattr(yyvsp[0].node,"name",ModuleName); if ((!module_node) && ModuleName) { module_node = new_node("module"); Setattr(module_node,"name",ModuleName); } Setattr(yyvsp[0].node,"module",module_node); check_extensions(); top = yyvsp[0].node; } break; case 3: #line 977 "CableSwig/SWIG/Source/CParse/parser.y" { top = Getattr(yyvsp[-1].p,"type"); } break; case 4: #line 980 "CableSwig/SWIG/Source/CParse/parser.y" { top = 0; } break; case 5: #line 983 "CableSwig/SWIG/Source/CParse/parser.y" { top = yyvsp[-1].p; } break; case 6: #line 986 "CableSwig/SWIG/Source/CParse/parser.y" { top = 0; } break; case 7: #line 991 "CableSwig/SWIG/Source/CParse/parser.y" { appendChild(yyvsp[-1].node,yyvsp[0].node); yyval.node = yyvsp[-1].node; } break; case 8: #line 995 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = new_node("top"); } break; case 9: #line 1000 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 10: #line 1001 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 11: #line 1002 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 12: #line 1003 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = 0; } break; case 13: #line 1004 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = 0; if (!Swig_error_count()) { static int last_error_line = -1; if (last_error_line != cparse_line) { Swig_error(cparse_file, cparse_line,"Syntax error in input.\n"); last_error_line = cparse_line; skip_decl(); } } } break; case 14: #line 1016 "CableSwig/SWIG/Source/CParse/parser.y" { if (yyval.node) { add_symbols(yyval.node); } yyval.node = yyvsp[0].node; } break; case 15: #line 1032 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = 0; skip_decl(); } break; case 16: #line 1042 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 17: #line 1043 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 18: #line 1044 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 19: #line 1045 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 20: #line 1046 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 21: #line 1047 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 22: #line 1048 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 23: #line 1049 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 24: #line 1050 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 25: #line 1051 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 26: #line 1052 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 27: #line 1053 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 28: #line 1054 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 29: #line 1055 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 30: #line 1056 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 31: #line 1057 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 32: #line 1058 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 33: #line 1059 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 34: #line 1060 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 35: #line 1061 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 36: #line 1062 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 37: #line 1069 "CableSwig/SWIG/Source/CParse/parser.y" { Node *cls; String *clsname; cplus_mode = CPLUS_PUBLIC; if (!classes) classes = NewHash(); if (!extendhash) extendhash = NewHash(); clsname = make_class_name(yyvsp[-1].str); cls = Getattr(classes,clsname); if (!cls) { /* No previous definition. Create a new scope */ Node *am = Getattr(extendhash,clsname); if (!am) { Swig_symbol_newscope(); Swig_symbol_setscopename(yyvsp[-1].str); prev_symtab = 0; } else { prev_symtab = Swig_symbol_setscope(Getattr(am,"symtab")); } current_class = 0; } else { /* Previous class definition. Use its symbol table */ prev_symtab = Swig_symbol_setscope(Getattr(cls,"symtab")); current_class = cls; extendmode = 1; } Classprefix = NewString(yyvsp[-1].str); Namespaceprefix= Swig_symbol_qualifiedscopename(0); Delete(clsname); } break; case 38: #line 1097 "CableSwig/SWIG/Source/CParse/parser.y" { String *clsname; extendmode = 0; yyval.node = new_node("extend"); Setattr(yyval.node,"symtab",Swig_symbol_popscope()); if (prev_symtab) { Swig_symbol_setscope(prev_symtab); } Namespaceprefix = Swig_symbol_qualifiedscopename(0); clsname = make_class_name(yyvsp[-4].str); Setattr(yyval.node,"name",clsname); /* Mark members as extend */ Swig_tag_nodes(yyvsp[-1].node,"feature:extend",(char*) "1"); if (current_class) { /* We add the extension to the previously defined class */ appendChild(yyval.node,yyvsp[-1].node); appendChild(current_class,yyval.node); } else { /* We store the extensions in the extensions hash */ Node *am = Getattr(extendhash,clsname); if (am) { /* Append the members to the previous extend methods */ appendChild(am,yyvsp[-1].node); } else { appendChild(yyval.node,yyvsp[-1].node); Setattr(extendhash,clsname,yyval.node); } } current_class = 0; Delete(Classprefix); Delete(clsname); Classprefix = 0; prev_symtab = 0; yyval.node = 0; } break; case 39: #line 1141 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = new_node("apply"); Setattr(yyval.node,"pattern",Getattr(yyvsp[-3].p,"pattern")); appendChild(yyval.node,yyvsp[-1].p); } break; case 40: #line 1151 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = new_node("clear"); appendChild(yyval.node,yyvsp[-1].p); } break; case 41: #line 1162 "CableSwig/SWIG/Source/CParse/parser.y" { if ((yyvsp[-1].dtype.type != T_ERROR) && (yyvsp[-1].dtype.type != T_SYMBOL)) { yyval.node = new_node("constant"); Setattr(yyval.node,"name",yyvsp[-3].id); Setattr(yyval.node,"type",NewSwigType(yyvsp[-1].dtype.type)); Setattr(yyval.node,"value",yyvsp[-1].dtype.val); if (yyvsp[-1].dtype.rawval) Setattr(yyval.node,"rawval", yyvsp[-1].dtype.rawval); Setattr(yyval.node,"storage","%constant"); Setattr(yyval.node,"feature:immutable","1"); add_symbols(yyval.node); } else { if (yyvsp[-1].dtype.type == T_ERROR) { Swig_warning(WARN_PARSE_UNSUPPORTED_VALUE,cparse_file,cparse_line,"Unsupported constant value (ignored)\n"); } yyval.node = 0; } } break; case 42: #line 1181 "CableSwig/SWIG/Source/CParse/parser.y" { if ((yyvsp[-1].dtype.type != T_ERROR) && (yyvsp[-1].dtype.type != T_SYMBOL)) { SwigType_push(yyvsp[-3].type,yyvsp[-2].decl.type); /* Sneaky callback function trick */ if (SwigType_isfunction(yyvsp[-3].type)) { SwigType_add_pointer(yyvsp[-3].type); } yyval.node = new_node("constant"); Setattr(yyval.node,"name",yyvsp[-2].decl.id); Setattr(yyval.node,"type",yyvsp[-3].type); Setattr(yyval.node,"value",yyvsp[-1].dtype.val); if (yyvsp[-1].dtype.rawval) Setattr(yyval.node,"rawval", yyvsp[-1].dtype.rawval); Setattr(yyval.node,"storage","%constant"); Setattr(yyval.node,"feature:immutable","1"); add_symbols(yyval.node); } else { if (yyvsp[-1].dtype.type == T_ERROR) { Swig_warning(WARN_PARSE_UNSUPPORTED_VALUE,cparse_file,cparse_line,"Unsupported constant value\n"); } yyval.node = 0; } } break; case 43: #line 1203 "CableSwig/SWIG/Source/CParse/parser.y" { Swig_warning(WARN_PARSE_BAD_VALUE,cparse_file,cparse_line,"Bad constant value (ignored).\n"); yyval.node = 0; } break; case 44: #line 1214 "CableSwig/SWIG/Source/CParse/parser.y" { char temp[64]; Replace(yyvsp[0].str,"$file",cparse_file, DOH_REPLACE_ANY); sprintf(temp,"%d", cparse_line); Replace(yyvsp[0].str,"$line",temp,DOH_REPLACE_ANY); Printf(stderr,"%s\n", yyvsp[0].str); Delete(yyvsp[0].str); yyval.node = 0; } break; case 45: #line 1223 "CableSwig/SWIG/Source/CParse/parser.y" { char temp[64]; String *s = NewString(yyvsp[0].id); Replace(s,"$file",cparse_file, DOH_REPLACE_ANY); sprintf(temp,"%d", cparse_line); Replace(s,"$line",temp,DOH_REPLACE_ANY); Printf(stderr,"%s\n", s); Delete(s); yyval.node = 0; } break; case 46: #line 1242 "CableSwig/SWIG/Source/CParse/parser.y" { skip_balanced('{','}'); yyval.node = 0; Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n"); } break; case 47: #line 1248 "CableSwig/SWIG/Source/CParse/parser.y" { skip_balanced('{','}'); yyval.node = 0; Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n"); } break; case 48: #line 1254 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = 0; Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n"); } break; case 49: #line 1259 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = 0; Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated. Use %%exception instead.\n"); } break; case 50: #line 1269 "CableSwig/SWIG/Source/CParse/parser.y" { Hash *p = nextSibling(yyvsp[-2].node); yyval.node = new_node("fragment"); Setattr(yyval.node,"section", Getattr(p,"name")); Setattr(yyval.node,"name",Getattr(yyvsp[-2].node,"name")); Setattr(yyval.node,"kwargs",nextSibling(p)); Setattr(yyval.node,"code",yyvsp[0].str); } break; case 51: #line 1277 "CableSwig/SWIG/Source/CParse/parser.y" { Hash *p = nextSibling(yyvsp[-2].node); skip_balanced('{','}'); yyval.node = new_node("fragment"); Setattr(yyval.node,"section", Getattr(p,"name")); Setattr(yyval.node,"name",Getattr(yyvsp[-2].node,"name")); Setattr(yyval.node,"kwargs",nextSibling(p)); Delitem(scanner_ccode,0); Delitem(scanner_ccode,DOH_END); Setattr(yyval.node,"code",Copy(scanner_ccode)); } break; case 52: #line 1295 "CableSwig/SWIG/Source/CParse/parser.y" { yyvsp[-3].loc.filename = Swig_copy_string(cparse_file); yyvsp[-3].loc.line = cparse_line; cparse_file = Swig_copy_string(yyvsp[-1].id); cparse_line = 0; } break; case 53: #line 1300 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[-1].node; cparse_file = yyvsp[-6].loc.filename; cparse_line = yyvsp[-6].loc.line; if (strcmp(yyvsp[-6].loc.type,"include") == 0) set_nodeType(yyval.node,"include"); if (strcmp(yyvsp[-6].loc.type,"import") == 0) set_nodeType(yyval.node,"import"); Setattr(yyval.node,"name",yyvsp[-4].id); /* Search for the module (if any) */ { Node *n = firstChild(yyval.node); while (n) { if (Strcmp(nodeType(n),"module") == 0) { Setattr(yyval.node,"module",Getattr(n,"name")); break; } n = nextSibling(n); } } Setattr(yyval.node,"options",yyvsp[-5].node); } break; case 54: #line 1322 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.loc.type = (char *) "include"; } break; case 55: #line 1323 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.loc.type = (char *) "import"; } break; case 56: #line 1330 "CableSwig/SWIG/Source/CParse/parser.y" { String *cpps; if (Namespaceprefix) { Swig_error(cparse_file, cparse_start_line, "%%inline directive inside a namespace is disallowed.\n"); yyval.node = 0; } else { yyval.node = new_node("insert"); Setattr(yyval.node,"code",yyvsp[0].str); /* Need to run through the preprocessor */ Setline(yyvsp[0].str,cparse_start_line); Setfile(yyvsp[0].str,cparse_file); Seek(yyvsp[0].str,0,SEEK_SET); cpps = Preprocessor_parse(yyvsp[0].str); start_inline(Char(cpps), cparse_start_line); Delete(yyvsp[0].str); Delete(cpps); } } break; case 57: #line 1350 "CableSwig/SWIG/Source/CParse/parser.y" { String *cpps; skip_balanced('{','}'); if (Namespaceprefix) { Swig_error(cparse_file, cparse_start_line, "%%inline directive inside a namespace is disallowed.\n"); yyval.node = 0; } else { yyval.node = new_node("insert"); Delitem(scanner_ccode,0); Delitem(scanner_ccode,DOH_END); Setattr(yyval.node,"code", Copy(scanner_ccode)); cpps=Copy(scanner_ccode); start_inline(Char(cpps), cparse_start_line); Delete(cpps); } } break; case 58: #line 1377 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = new_node("insert"); Setattr(yyval.node,"code",yyvsp[0].str); } break; case 59: #line 1381 "CableSwig/SWIG/Source/CParse/parser.y" { String *code = NewString(""); yyval.node = new_node("insert"); Setattr(yyval.node,"section",yyvsp[-2].id); Setattr(yyval.node,"code",code); if (Swig_insert_file(yyvsp[0].id,code) < 0) { Swig_error(cparse_file, cparse_line, "Couldn't find '%s'.\n", yyvsp[0].id); yyval.node = 0; } } break; case 60: #line 1391 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = new_node("insert"); Setattr(yyval.node,"section",yyvsp[-2].id); Setattr(yyval.node,"code",yyvsp[0].str); } break; case 61: #line 1396 "CableSwig/SWIG/Source/CParse/parser.y" { skip_balanced('{','}'); yyval.node = new_node("insert"); Setattr(yyval.node,"section",yyvsp[-2].id); Delitem(scanner_ccode,0); Delitem(scanner_ccode,DOH_END); Setattr(yyval.node,"code", Copy(scanner_ccode)); } break; case 62: #line 1411 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = new_node("module"); Setattr(yyval.node,"name",yyvsp[0].id); if (yyvsp[-1].node) Setattr(yyval.node,"options",yyvsp[-1].node); if (yyvsp[-1].node && Getattr(yyvsp[-1].node,"directors") && Getattr(yyvsp[-1].node,"dirprot")) dirprot_mode = 1; if (!ModuleName) ModuleName = NewString(yyvsp[0].id); if (!module_node) module_node = yyval.node; } break; case 63: #line 1427 "CableSwig/SWIG/Source/CParse/parser.y" { yyrename = NewString(yyvsp[-1].id); yyval.node = 0; } break; case 64: #line 1431 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = 0; Swig_error(cparse_file,cparse_line,"Missing argument to %%name directive.\n"); } break; case 65: #line 1443 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = new_node("native"); Setattr(yyval.node,"name",yyvsp[-4].id); Setattr(yyval.node,"wrap:name",yyvsp[-1].id); add_symbols(yyval.node); } break; case 66: #line 1449 "CableSwig/SWIG/Source/CParse/parser.y" { if (!SwigType_isfunction(yyvsp[-1].decl.type)) { Swig_error(cparse_file,cparse_line,"%%native declaration '%s' is not a function.\n", yyvsp[-1].decl.id); yyval.node = 0; } else { Delete(SwigType_pop_function(yyvsp[-1].decl.type)); /* Need check for function here */ SwigType_push(yyvsp[-2].type,yyvsp[-1].decl.type); yyval.node = new_node("native"); Setattr(yyval.node,"name",yyvsp[-5].id); Setattr(yyval.node,"wrap:name",yyvsp[-1].decl.id); Setattr(yyval.node,"type",yyvsp[-2].type); Setattr(yyval.node,"parms",yyvsp[-1].decl.parms); Setattr(yyval.node,"decl",yyvsp[-1].decl.type); } add_symbols(yyval.node); } break; case 67: #line 1475 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = new_node("pragma"); Setattr(yyval.node,"lang",yyvsp[-3].id); Setattr(yyval.node,"name",yyvsp[-2].id); Setattr(yyval.node,"value",yyvsp[0].str); } break; case 68: #line 1481 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = new_node("pragma"); Setattr(yyval.node,"lang",yyvsp[-1].id); Setattr(yyval.node,"name",yyvsp[0].id); } break; case 69: #line 1488 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.str = NewString(yyvsp[0].id); } break; case 70: #line 1489 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.str = yyvsp[0].str; } break; case 71: #line 1492 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.id = yyvsp[-1].id; } break; case 72: #line 1493 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.id = (char *) "swig"; } break; case 73: #line 1501 "CableSwig/SWIG/Source/CParse/parser.y" { SwigType *t = yyvsp[-2].decl.type; if (!Len(t)) t = 0; if (yyvsp[-3].ivalue) { rename_add(yyvsp[-2].decl.id,t,yyvsp[-1].id); } else { namewarn_add(yyvsp[-2].decl.id,t,yyvsp[-1].id); } yyval.node = 0; scanner_clear_rename(); } break; case 74: #line 1512 "CableSwig/SWIG/Source/CParse/parser.y" { String *fixname; SwigType *t = yyvsp[-2].decl.type; fixname = feature_identifier_fix(yyvsp[-2].decl.id); if (!Len(t)) t = 0; /* Special declarator check */ if (t) { if (yyvsp[-1].dtype.qualifier) SwigType_push(t,yyvsp[-1].dtype.qualifier); if (SwigType_isfunction(t)) { SwigType *decl = SwigType_pop_function(t); if (SwigType_ispointer(t)) { String *nname = NewStringf("*%s",fixname); if (yyvsp[-6].ivalue) { rename_add(Char(nname),decl,yyvsp[-4].id); } else { namewarn_add(Char(nname),decl,yyvsp[-4].id); } Delete(nname); } else { if (yyvsp[-6].ivalue) { rename_add(Char(fixname),decl,yyvsp[-4].id); } else { namewarn_add(Char(fixname),decl,yyvsp[-4].id); } } } else if (SwigType_ispointer(t)) { String *nname = NewStringf("*%s",fixname); if (yyvsp[-6].ivalue) { rename_add(Char(nname),0,yyvsp[-4].id); } else { namewarn_add(Char(nname),0,yyvsp[-4].id); } Delete(nname); } } else { if (yyvsp[-6].ivalue) { rename_add(Char(fixname),0,yyvsp[-4].id); } else { namewarn_add(Char(fixname),0,yyvsp[-4].id); } } yyval.node = 0; scanner_clear_rename(); } break; case 75: #line 1556 "CableSwig/SWIG/Source/CParse/parser.y" { if (yyvsp[-5].ivalue) { rename_add(yyvsp[-1].id,0,yyvsp[-3].id); } else { namewarn_add(yyvsp[-1].id,0,yyvsp[-3].id); } yyval.node = 0; scanner_clear_rename(); } break; case 76: #line 1567 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.ivalue = 1; } break; case 77: #line 1570 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.ivalue = 0; } break; case 78: #line 1583 "CableSwig/SWIG/Source/CParse/parser.y" { String *fname; String *val; String *name; String *fixname; SwigType *t; if (!features_hash) features_hash = NewHash(); fname = NewStringf("feature:%s",yyvsp[-4].id); fixname = feature_identifier_fix(yyvsp[-2].decl.id); if (Namespaceprefix) { name = NewStringf("%s::%s",Namespaceprefix, fixname); } else { name = fixname; } val = yyvsp[0].str ? NewString(yyvsp[0].str) : NewString("1"); if (yyvsp[-2].decl.parms) { Setmeta(val,"parms",yyvsp[-2].decl.parms); } t = yyvsp[-2].decl.type; if (yyvsp[-2].decl.parms) Setmeta(val,"parms",yyvsp[-2].decl.parms); if (!Len(t)) t = 0; if (t) { if (yyvsp[-1].dtype.qualifier) SwigType_push(t,yyvsp[-1].dtype.qualifier); if (SwigType_isfunction(t)) { SwigType *decl = SwigType_pop_function(t); if (SwigType_ispointer(t)) { String *nname = NewStringf("*%s",name); Swig_feature_set(features_hash, nname, decl, fname, val); Delete(nname); } else { Swig_feature_set(features_hash, name, decl, fname, val); } } else if (SwigType_ispointer(t)) { String *nname = NewStringf("*%s",name); Swig_feature_set(features_hash,nname,0,fname,val); Delete(nname); } } else { Swig_feature_set(features_hash,name,0,fname,val); } Delete(fname); Delete(name); yyval.node = 0; } break; case 79: #line 1630 "CableSwig/SWIG/Source/CParse/parser.y" { String *fname; String *val; String *name; String *fixname; SwigType *t; if (!features_hash) features_hash = NewHash(); fname = NewStringf("feature:%s",yyvsp[-6].id); fixname = feature_identifier_fix(yyvsp[-2].decl.id); if (Namespaceprefix) { name = NewStringf("%s::%s",Namespaceprefix, fixname); } else { name = fixname; } if (Len(yyvsp[-4].id)) { val = NewString(yyvsp[-4].id); } else { val = 0; } if (yyvsp[-2].decl.parms) { Setmeta(val,"parms",yyvsp[-2].decl.parms); } t = yyvsp[-2].decl.type; if (yyvsp[-2].decl.parms) Setmeta(val,"parms",yyvsp[-2].decl.parms); if (!Len(t)) t = 0; if (t) { if (yyvsp[-1].dtype.qualifier) SwigType_push(t,yyvsp[-1].dtype.qualifier); if (SwigType_isfunction(t)) { SwigType *decl = SwigType_pop_function(t); if (SwigType_ispointer(t)) { String *nname = NewStringf("*%s",name); Swig_feature_set(features_hash, nname, decl, fname, val); Delete(nname); } else { Swig_feature_set(features_hash, name, decl, fname, val); } } else if (SwigType_ispointer(t)) { String *nname = NewStringf("*%s",name); Swig_feature_set(features_hash,nname,0,fname,val); Delete(nname); } } else { Swig_feature_set(features_hash,name,0,fname,val); } Delete(fname); Delete(name); yyval.node = 0; } break; case 80: #line 1682 "CableSwig/SWIG/Source/CParse/parser.y" { String *name; String *fname = NewStringf("feature:%s",yyvsp[-2].id); if (!features_hash) features_hash = NewHash(); if (Namespaceprefix) name = NewStringf("%s::", Namespaceprefix); else name = NewString(""); Swig_feature_set(features_hash,name,0,fname,(yyvsp[0].str ? NewString(yyvsp[0].str) : NewString("1"))); Delete(name); Delete(fname); yyval.node = 0; } break; case 81: #line 1693 "CableSwig/SWIG/Source/CParse/parser.y" { String *name; String *fname = NewStringf("feature:%s",yyvsp[-4].id); if (!features_hash) features_hash = NewHash(); if (Namespaceprefix) name = NewStringf("%s::", Namespaceprefix); else name = NewString(""); Swig_feature_set(features_hash,name,0,fname,(Len(yyvsp[-2].id) ? NewString(yyvsp[-2].id) : 0)); Delete(name); Delete(fname); yyval.node = 0; } break; case 82: #line 1706 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.str = yyvsp[0].str; } break; case 83: #line 1707 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.str = 0; } break; case 84: #line 1708 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.str = yyvsp[-2].pl; } break; case 85: #line 1713 "CableSwig/SWIG/Source/CParse/parser.y" { Parm *val; String *name; SwigType *t; if (!features_hash) features_hash = NewHash(); if (Namespaceprefix) name = NewStringf("%s::%s", Namespaceprefix, yyvsp[-2].decl.id); else name = NewString(yyvsp[-2].decl.id); val = yyvsp[-4].pl; if (yyvsp[-2].decl.parms) { Setmeta(val,"parms",yyvsp[-2].decl.parms); } t = yyvsp[-2].decl.type; if (!Len(t)) t = 0; if (t) { if (yyvsp[-1].dtype.qualifier) SwigType_push(t,yyvsp[-1].dtype.qualifier); if (SwigType_isfunction(t)) { SwigType *decl = SwigType_pop_function(t); if (SwigType_ispointer(t)) { String *nname = NewStringf("*%s",name); Swig_feature_set(features_hash, nname, decl, "feature:varargs", val); Delete(nname); } else { Swig_feature_set(features_hash, name, decl, "feature:varargs", val); } } else if (SwigType_ispointer(t)) { String *nname = NewStringf("*%s",name); Swig_feature_set(features_hash,nname,0,"feature:varargs",val); Delete(nname); } } else { Swig_feature_set(features_hash,name,0,"feature:varargs",val); } Delete(name); yyval.node = 0; } break; case 86: #line 1749 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.pl = yyvsp[0].pl; } break; case 87: #line 1750 "CableSwig/SWIG/Source/CParse/parser.y" { int i; int n; Parm *p; n = atoi(Char(yyvsp[-2].dtype.val)); if (n <= 0) { Swig_error(cparse_file, cparse_line,"Argument count in %%varargs must be positive.\n"); yyval.pl = 0; } else { yyval.pl = Copy(yyvsp[0].p); Setattr(yyval.pl,"name","VARARGS_SENTINEL"); for (i = 0; i < n; i++) { p = Copy(yyvsp[0].p); set_nextSibling(p,yyval.pl); yyval.pl = p; } } } break; case 88: #line 1779 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = 0; if (yyvsp[-3].tmap.op) { yyval.node = new_node("typemap"); Setattr(yyval.node,"method",yyvsp[-3].tmap.op); Setattr(yyval.node,"code",NewString(yyvsp[0].str)); if (yyvsp[-3].tmap.kwargs) { Setattr(yyval.node,"kwargs", yyvsp[-3].tmap.kwargs); } appendChild(yyval.node,yyvsp[-1].p); } } break; case 89: #line 1791 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = 0; if (yyvsp[-3].tmap.op) { yyval.node = new_node("typemap"); Setattr(yyval.node,"method",yyvsp[-3].tmap.op); appendChild(yyval.node,yyvsp[-1].p); } } break; case 90: #line 1799 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = 0; if (yyvsp[-5].tmap.op) { yyval.node = new_node("typemapcopy"); Setattr(yyval.node,"method",yyvsp[-5].tmap.op); Setattr(yyval.node,"pattern", Getattr(yyvsp[-1].p,"pattern")); appendChild(yyval.node,yyvsp[-3].p); } } break; case 91: #line 1812 "CableSwig/SWIG/Source/CParse/parser.y" { Hash *p; String *name; p = nextSibling(yyvsp[0].node); if (p && (!Getattr(p,"value"))) { /* two argument typemap form */ name = Getattr(yyvsp[0].node,"name"); if (!name || (Strcmp(name,typemap_lang))) { yyval.tmap.op = 0; yyval.tmap.kwargs = 0; } else { yyval.tmap.op = Getattr(p,"name"); yyval.tmap.kwargs = nextSibling(p); } } else { /* one-argument typemap-form */ yyval.tmap.op = Getattr(yyvsp[0].node,"name"); yyval.tmap.kwargs = p; } } break; case 92: #line 1834 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.p = yyvsp[-1].p; set_nextSibling(yyval.p,yyvsp[0].p); } break; case 93: #line 1840 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.p = yyvsp[-1].p; set_nextSibling(yyval.p,yyvsp[0].p); } break; case 94: #line 1844 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.p = 0;} break; case 95: #line 1847 "CableSwig/SWIG/Source/CParse/parser.y" { SwigType_push(yyvsp[-1].type,yyvsp[0].decl.type); yyval.p = new_node("typemapitem"); Setattr(yyval.p,"pattern",NewParm(yyvsp[-1].type,yyvsp[0].decl.id)); Setattr(yyval.p,"parms", yyvsp[0].decl.parms); /* $$ = NewParm($1,$2.id); Setattr($$,"parms",$2.parms); */ } break; case 96: #line 1855 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.p = new_node("typemapitem"); Setattr(yyval.p,"pattern",yyvsp[-1].pl); /* Setattr($$,"multitype",$2); */ } break; case 97: #line 1860 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.p = new_node("typemapitem"); Setattr(yyval.p,"pattern", yyvsp[-4].pl); /* Setattr($$,"multitype",$2); */ Setattr(yyval.p,"parms",yyvsp[-1].pl); } break; case 98: #line 1872 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = new_node("types"); Setattr(yyval.node,"parms",yyvsp[-2].pl); } break; case 99: #line 1882 "CableSwig/SWIG/Source/CParse/parser.y" { Parm *p, *tp; Node *n; Node *nspace = 0, *nspace_inner = 0; Node *tnode = 0; Symtab *tscope = 0; int specialized = 0; yyval.node = 0; tscope = Swig_symbol_current(); /* Get the current scope */ /* If the template name is qualified. We need to create or lookup namespace entries */ if (Swig_scopename_check(yyvsp[-4].str)) { String *prefix, *base; Node *ns; prefix = Swig_scopename_prefix(yyvsp[-4].str); base = Swig_scopename_last(yyvsp[-4].str); /* Try to locate the scope */ ns = Swig_symbol_clookup(prefix,0); if (!ns) { Swig_error(cparse_file,cparse_line,"Undefined scope '%s'\n", prefix); } else { if (Strcmp(nodeType(ns),"namespace") != 0) { Swig_error(cparse_file,cparse_line,"'%s' is not defined as namespace.\n", prefix); ns = 0; } else { /* Swig_symbol_setscope(Getattr(ns,"symtab")); Namespaceprefix = Swig_symbol_qualifiedscopename(0); */ } } if (ns && Namespaceprefix) { Swig_error(cparse_file,cparse_line, "Can't instantiate template '%s' inside namespace '%s'.\n" "Suggest moving %%template outside the namespace.\n", yyvsp[-4].str, Namespaceprefix); } /* Create namespace nodes to enclose the template declaration */ if (ns) { List *scopes; String *sname; Iterator si; String *name = NewString(prefix); scopes = NewList(); while (name) { String *tprefix; String *base = Swig_scopename_last(name); Insert(scopes,0,base); tprefix = Swig_scopename_prefix(name); Delete(name); name = tprefix; } for (si = First(scopes); si.item; si = Next(si)) { Node *ns1,*ns2; sname = si.item; ns1 = Swig_symbol_clookup(sname,0); assert(ns1); if (Strcmp(nodeType(ns1),"namespace") == 0) { if (Getattr(ns1,"alias")) { ns1 = Getattr(ns1,"namespace"); } } else { assert(0); } ns2 = new_node("namespace"); Setattr(ns2,"name",sname); Setattr(ns2,"symtab", Getattr(ns1,"symtab")); add_symbols(ns2); Swig_symbol_setscope(Getattr(ns1,"symtab")); Namespaceprefix = Swig_symbol_qualifiedscopename(0); if (nspace_inner) { appendChild(nspace_inner,ns2); } nspace_inner = ns2; if (!nspace) nspace = ns2; } yyvsp[-4].str = base; } } n = Swig_cparse_template_locate(yyvsp[-4].str,yyvsp[-2].p); /* Patch the argument types to respect namespaces */ p = yyvsp[-2].p; while (p) { if (!Getattr(p,"value")) { SwigType *ty = Getattr(p,"type"); if (ty) { ty = Swig_symbol_type_qualify(ty,0); /* ty = Swig_symbol_typedef_reduce(ty,0); */ Setattr(p,"type",ty); } } p = nextSibling(p); } /* Look for the template */ if (n && (Strcmp(nodeType(n),"template") == 0)) { Parm *tparms = Getattr(n,"templateparms"); if (!tparms) { specialized = 1; } if (!specialized && ((ParmList_len(yyvsp[-2].p) > ParmList_len(tparms)))) { Swig_error(cparse_file, cparse_line, "Too many template parameters. Maximum of %d.\n", ParmList_len(tparms)); } else if (!specialized && ((ParmList_len(yyvsp[-2].p) < ParmList_numrequired(tparms)))) { Swig_error(cparse_file, cparse_line, "Not enough template parameters specified. %d required.\n", ParmList_numrequired(tparms)); } else { int def_supplied = 0; /* Expand the template */ ParmList *temparms; if (specialized) temparms = CopyParmList(yyvsp[-2].p); else temparms = CopyParmList(tparms); /* Create typedef's and arguments */ p = yyvsp[-2].p; tp = temparms; while (p) { String *value = Getattr(p,"value"); if (def_supplied) { Setattr(p,"default","1"); } if (value) { Setattr(tp,"value",value); } else { SwigType *ty = Getattr(p,"type"); if (ty) { Setattr(tp,"type",ty); } Delattr(tp,"value"); } p = nextSibling(p); tp = nextSibling(tp); if (!p && tp) { p = tp; def_supplied = 1; } } yyval.node = copy_node(n); /* We need to set the node name based on name used to instantiate */ Setattr(yyval.node,"name",Copy(yyvsp[-4].str)); if (!specialized) { Delattr(yyval.node,"sym:typename"); } else { Setattr(yyval.node,"sym:typename","1"); } if (yyvsp[-6].id) { Swig_cparse_template_expand(yyval.node,yyvsp[-6].id,temparms); Setattr(yyval.node,"sym:name",yyvsp[-6].id); } else { static int cnt = 0; String *nname = NewStringf("__dummy_%d__", cnt++); Swig_cparse_template_expand(yyval.node,nname,temparms); Setattr(yyval.node,"sym:name",nname); Setattr(yyval.node,"feature:ignore","1"); } Delattr(yyval.node,"templatetype"); Setattr(yyval.node,"template",n); tnode = yyval.node; Setfile(yyval.node,cparse_file); Setline(yyval.node,cparse_line); Delete(temparms); add_symbols_copy(yyval.node); if (Strcmp(nodeType(yyval.node),"class") == 0) { /* Identify pure abstract methods */ Setattr(yyval.node,"abstract", pure_abstract(firstChild(yyval.node))); /* Set up inheritance in symbol table */ { Symtab *csyms; List *baselist = Getattr(yyval.node,"baselist"); csyms = Swig_symbol_current(); Swig_symbol_setscope(Getattr(yyval.node,"symtab")); if (baselist) { List *bases = make_inherit_list(Getattr(yyval.node,"name"),baselist); if (bases) { Iterator s; for (s = First(bases); s.item; s = Next(s)) { Symtab *st = Getattr(s.item,"symtab"); if (st) { Swig_symbol_inherit(st); } } } } Swig_symbol_setscope(csyms); } /* Merge in addmethods for this class */ /* !!! This may be broken. We may have to add the addmethods at the beginning of the class */ if (extendhash) { String *clsname; Node *am; if (Namespaceprefix) { clsname = NewStringf("%s::%s", Namespaceprefix, Getattr(yyval.node,"name")); } else { clsname = Getattr(yyval.node,"name"); } am = Getattr(extendhash,clsname); if (am) { Symtab *st = Swig_symbol_current(); Swig_symbol_setscope(Getattr(yyval.node,"symtab")); /* Printf(stdout,"%s: %s %x %x\n", Getattr($$,"name"), clsname, Swig_symbol_current(), Getattr($$,"symtab")); */ merge_extensions(yyval.node,am); Swig_symbol_setscope(st); appendChild(yyval.node,am); Delattr(extendhash,clsname); } } /* Add to classes hash */ if (!classes) classes = NewHash(); { if (Namespaceprefix) { String *temp = NewStringf("%s::%s", Namespaceprefix, Getattr(yyval.node,"name")); Setattr(classes,temp,yyval.node); } else { Setattr(classes,Swig_symbol_qualifiedscopename(yyval.node),yyval.node); } } } } if (yyval.node && nspace) { appendChild(nspace_inner,yyval.node); yyval.node = nspace; } } Swig_symbol_setscope(tscope); Namespaceprefix = Swig_symbol_qualifiedscopename(0); } break; case 100: #line 2127 "CableSwig/SWIG/Source/CParse/parser.y" { Swig_warning(0,cparse_file, cparse_line,"%s\n", yyvsp[0].id); yyval.node = 0; } break; case 101: #line 2137 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; if (yyval.node) { add_symbols(yyval.node); } } break; case 102: #line 2143 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 103: #line 2147 "CableSwig/SWIG/Source/CParse/parser.y" { if (Strcmp(yyvsp[-3].id,"C") == 0) { yyval.node = new_node("extern"); Setattr(yyval.node,"name",yyvsp[-3].id); appendChild(yyval.node,firstChild(yyvsp[-1].node)); } else { Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\" (ignored).\n", yyvsp[-3].id); yyval.node = 0; } } break; case 104: #line 2163 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = new_node("cdecl"); if (yyvsp[-1].dtype.qualifier) SwigType_push(yyvsp[-2].decl.type,yyvsp[-1].dtype.qualifier); Setattr(yyval.node,"type",yyvsp[-3].type); Setattr(yyval.node,"storage",yyvsp[-4].id); Setattr(yyval.node,"name",yyvsp[-2].decl.id); Setattr(yyval.node,"decl",yyvsp[-2].decl.type); Setattr(yyval.node,"parms",yyvsp[-2].decl.parms); Setattr(yyval.node,"value",yyvsp[-1].dtype.val); Setattr(yyval.node,"throws",yyvsp[-1].dtype.throws); if (!yyvsp[0].node) { if (Len(scanner_ccode)) { Setattr(yyval.node,"code",Copy(scanner_ccode)); } } else { Node *n = yyvsp[0].node; /* Inherit attributes */ while (n) { Setattr(n,"type",Copy(yyvsp[-3].type)); Setattr(n,"storage",yyvsp[-4].id); n = nextSibling(n); } } if (yyvsp[-1].dtype.bitfield) { Setattr(yyval.node,"bitfield", yyvsp[-1].dtype.bitfield); } /* Look for "::" declarations (ignored) */ if (Strstr(yyvsp[-2].decl.id,"::")) { if (Namespaceprefix) { /* This is a special case. If the scope name of the declaration exactly matches that of the declaration, then we will allow it. Otherwise, delete. */ String *p = Swig_scopename_prefix(yyvsp[-2].decl.id); if (Strcmp(p,Namespaceprefix) == 0) { Setattr(yyval.node,"name",Swig_scopename_last(yyvsp[-2].decl.id)); set_nextSibling(yyval.node,yyvsp[0].node); } else { Delete(yyval.node); yyval.node = yyvsp[0].node; } Delete(p); } else { Delete(yyval.node); yyval.node = yyvsp[0].node; } } else { set_nextSibling(yyval.node,yyvsp[0].node); } } break; case 105: #line 2216 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = 0; Clear(scanner_ccode); } break; case 106: #line 2220 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = new_node("cdecl"); if (yyvsp[-1].dtype.qualifier) SwigType_push(yyvsp[-2].decl.type,yyvsp[-1].dtype.qualifier); Setattr(yyval.node,"name",yyvsp[-2].decl.id); Setattr(yyval.node,"decl",yyvsp[-2].decl.type); Setattr(yyval.node,"parms",yyvsp[-2].decl.parms); Setattr(yyval.node,"value",yyvsp[-1].dtype.val); Setattr(yyval.node,"throws",yyvsp[-1].dtype.throws); if (yyvsp[-1].dtype.bitfield) { Setattr(yyval.node,"bitfield", yyvsp[-1].dtype.bitfield); } if (!yyvsp[0].node) { if (Len(scanner_ccode)) { Setattr(yyval.node,"code",Copy(scanner_ccode)); } } else { set_nextSibling(yyval.node,yyvsp[0].node); } } break; case 107: #line 2239 "CableSwig/SWIG/Source/CParse/parser.y" { skip_balanced('{','}'); yyval.node = 0; } break; case 108: #line 2245 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype = yyvsp[0].dtype; yyval.dtype.qualifier = 0; yyval.dtype.throws = 0; } break; case 109: #line 2250 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype = yyvsp[0].dtype; yyval.dtype.qualifier = yyvsp[-1].str; yyval.dtype.throws = 0; } break; case 110: #line 2255 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype = yyvsp[0].dtype; yyval.dtype.qualifier = 0; yyval.dtype.throws = yyvsp[-2].pl; } break; case 111: #line 2260 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype = yyvsp[0].dtype; yyval.dtype.qualifier = yyvsp[-5].str; yyval.dtype.throws = yyvsp[-2].pl; } break; case 112: #line 2272 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = new_node("enum"); Setattr(yyval.node,"name",yyvsp[-4].id); appendChild(yyval.node,yyvsp[-2].node); add_symbols(yyval.node); /* Add to tag space */ add_symbols(yyvsp[-2].node); /* Add enum values to id space */ } break; case 113: #line 2280 "CableSwig/SWIG/Source/CParse/parser.y" { Node *n; SwigType *ty = 0; String *unnamed = 0; yyval.node = new_node("enum"); if (yyvsp[-5].id) { Setattr(yyval.node,"name",yyvsp[-5].id); ty = NewStringf("enum %s", yyvsp[-5].id); } else if (yyvsp[-1].decl.id){ unnamed = make_unnamed(); ty = NewStringf("enum %s", unnamed); Setattr(yyval.node,"unnamed",unnamed); /* WF 20/12/2001: Cannot get sym:name and symtab set without setting name - fix! // I don't think sym:name should be set. */ Setattr(yyval.node,"name",yyvsp[-1].decl.id); Setattr(yyval.node,"tdname",yyvsp[-1].decl.id); Setattr(yyval.node,"storage",yyvsp[-7].id); } appendChild(yyval.node,yyvsp[-3].node); n = new_node("cdecl"); Setattr(n,"type",ty); Setattr(n,"name",yyvsp[-1].decl.id); Setattr(n,"storage",yyvsp[-7].id); Setattr(n,"decl",yyvsp[-1].decl.type); Setattr(n,"parms",yyvsp[-1].decl.parms); Setattr(n,"unnamed",unnamed); if (yyvsp[0].node) { Node *p = yyvsp[0].node; set_nextSibling(n,p); while (p) { Setattr(p,"type",Copy(ty)); Setattr(p,"unnamed",unnamed); Setattr(p,"storage",yyvsp[-7].id); p = nextSibling(p); } } else { if (Len(scanner_ccode)) { Setattr(n,"code",Copy(scanner_ccode)); } } add_symbols(yyval.node); /* Add enum to tag space */ set_nextSibling(yyval.node,n); add_symbols(yyvsp[-3].node); /* Add to id space */ add_symbols(n); } break; case 114: #line 2328 "CableSwig/SWIG/Source/CParse/parser.y" { /* This is a sick hack. If the ctor_end has parameters, and the parms paremeter only has 1 parameter, this could be a declaration of the form: type (id)(parms) Otherwise it's an error. */ int err = 0; yyval.node = 0; if ((ParmList_len(yyvsp[-2].pl) == 1) && (!Swig_scopename_check(yyvsp[-4].type))) { SwigType *ty = Getattr(yyvsp[-2].pl,"type"); String *name = Getattr(yyvsp[-2].pl,"name"); err = 1; if (!name) { yyval.node = new_node("cdecl"); Setattr(yyval.node,"type",yyvsp[-4].type); Setattr(yyval.node,"storage",yyvsp[-5].id); Setattr(yyval.node,"name",ty); if (yyvsp[0].decl.have_parms) { SwigType *decl = NewString(""); SwigType_add_function(decl,yyvsp[0].decl.parms); Setattr(yyval.node,"decl",decl); Setattr(yyval.node,"parms",yyvsp[0].decl.parms); if (Len(scanner_ccode)) { Setattr(yyval.node,"code",Copy(scanner_ccode)); } } if (yyvsp[0].decl.defarg) { Setattr(yyval.node,"value",yyvsp[0].decl.defarg); } Setattr(yyval.node,"throws",yyvsp[0].decl.throws); err = 0; } } if (err) { Swig_error(cparse_file,cparse_line,"Syntax error in input.\n"); } } break; case 115: #line 2375 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 116: #line 2376 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 117: #line 2377 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 118: #line 2378 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 119: #line 2379 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 120: #line 2380 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = 0; } break; case 121: #line 2386 "CableSwig/SWIG/Source/CParse/parser.y" { List *bases = 0; class_rename = make_name(yyvsp[-2].str,0); Classprefix = NewString(yyvsp[-2].str); /* Deal with inheritance */ if (yyvsp[-1].bases) { bases = make_inherit_list(yyvsp[-2].str,yyvsp[-1].bases); } if (SwigType_istemplate(yyvsp[-2].str)) { String *fbase, *tbase, *prefix; prefix = SwigType_templateprefix(yyvsp[-2].str); if (Namespaceprefix) { fbase = NewStringf("%s::%s", Namespaceprefix,yyvsp[-2].str); tbase = NewStringf("%s::%s", Namespaceprefix, prefix); } else { fbase = Copy(yyvsp[-2].str); tbase = Copy(prefix); } rename_inherit(tbase,fbase); Delete(fbase); Delete(tbase); Delete(prefix); } if (strcmp(yyvsp[-3].id,"class") == 0) { cplus_mode = CPLUS_PRIVATE; } else { cplus_mode = CPLUS_PUBLIC; } Swig_symbol_newscope(); Swig_symbol_setscopename(yyvsp[-2].str); if (bases) { Iterator s; for (s = First(bases); s.item; s = Next(s)) { Symtab *st = Getattr(s.item,"symtab"); if (st) { Swig_symbol_inherit(st); } } } Namespaceprefix = Swig_symbol_qualifiedscopename(0); cparse_start_line = cparse_line; /* If there are active template parameters, we need to make sure they are placed in the class symbol table so we can catch shadows */ if (template_parameters) { Parm *tp = template_parameters; while(tp) { Node *tn = new_node("templateparm"); Setattr(tn,"name",Getattr(tp,"name")); Swig_symbol_cadd(Copy(Getattr(tp,"name")),tn); tp = nextSibling(tp); } } inclass = 1; } break; case 122: #line 2441 "CableSwig/SWIG/Source/CParse/parser.y" { Node *p; SwigType *ty; inclass = 0; yyval.node = new_node("class"); Setline(yyval.node,cparse_start_line); Setattr(yyval.node,"name",yyvsp[-6].str); Setattr(yyval.node,"kind",yyvsp[-7].id); Setattr(yyval.node,"baselist",yyvsp[-5].bases); Setattr(yyval.node,"allows_typedef","1"); /* Check for pure-abstract class */ Setattr(yyval.node,"abstract", pure_abstract(yyvsp[-2].node)); /* This bit of code merges in a previously defined %extend directive (if any) */ if (extendhash) { String *clsname = Swig_symbol_qualifiedscopename(0); Node *am = Getattr(extendhash,clsname); if (am) { merge_extensions(yyval.node,am); appendChild(yyval.node,am); Delattr(extendhash,clsname); } Delete(clsname); } if (!classes) classes = NewHash(); Setattr(classes,Swig_symbol_qualifiedscopename(0),yyval.node); appendChild(yyval.node,yyvsp[-2].node); p = yyvsp[0].node; if (p) { set_nextSibling(yyval.node,p); } if (cparse_cplusplus) { ty = NewString(yyvsp[-6].str); } else { ty = NewStringf("%s %s", yyvsp[-7].id,yyvsp[-6].str); } while (p) { Setattr(p,"storage",yyvsp[-8].id); Setattr(p,"type",ty); p = nextSibling(p); } /* Dump nested classes */ { String *name = yyvsp[-6].str; if (yyvsp[0].node) { SwigType *decltype = Getattr(yyvsp[0].node,"decl"); if (Cmp(yyvsp[-8].id,"typedef") == 0) { if (!decltype || !Len(decltype)) { name = Getattr(yyvsp[0].node,"name"); Setattr(yyval.node,"tdname",Copy(name)); /* Use typedef name as class name */ if (class_rename && (Strcmp(class_rename,yyvsp[-6].str) == 0)) { class_rename = NewString(name); } if (!Getattr(classes,name)) { Setattr(classes,name,yyval.node); } Setattr(yyval.node,"decl",decltype); } } } appendChild(yyval.node,dump_nested(Char(name))); } Setattr(yyval.node,"symtab",Swig_symbol_popscope()); yyrename = NewString(class_rename); Classprefix = 0; Namespaceprefix = Swig_symbol_qualifiedscopename(0); add_symbols(yyval.node); if (yyvsp[0].node) add_symbols(yyvsp[0].node); } break; case 123: #line 2520 "CableSwig/SWIG/Source/CParse/parser.y" { class_rename = make_name(0,0); if (strcmp(yyvsp[-1].id,"class") == 0) { cplus_mode = CPLUS_PRIVATE; } else { cplus_mode = CPLUS_PUBLIC; } Swig_symbol_newscope(); cparse_start_line = cparse_line; inclass = 1; Classprefix = NewString(""); Namespaceprefix = Swig_symbol_qualifiedscopename(0); } break; case 124: #line 2532 "CableSwig/SWIG/Source/CParse/parser.y" { String *unnamed; Node *n, *p, *pp = 0; Classprefix = 0; inclass = 0; unnamed = make_unnamed(); yyval.node = new_node("class"); Setline(yyval.node,cparse_start_line); Setattr(yyval.node,"kind",yyvsp[-6].id); Setattr(yyval.node,"storage",yyvsp[-7].id); Setattr(yyval.node,"unnamed",unnamed); Setattr(yyval.node,"allows_typedef","1"); /* Check for pure-abstract class */ Setattr(yyval.node,"abstract", pure_abstract(yyvsp[-3].node)); n = new_node("cdecl"); Setattr(n,"name",yyvsp[-1].decl.id); Setattr(n,"unnamed",unnamed); Setattr(n,"type",unnamed); Setattr(n,"decl",yyvsp[-1].decl.type); Setattr(n,"parms",yyvsp[-1].decl.parms); Setattr(n,"storage",yyvsp[-7].id); pp = n; if (yyvsp[0].node) { set_nextSibling(n,yyvsp[0].node); p = yyvsp[0].node; while (p) { pp = p; Setattr(p,"unnamed",unnamed); Setattr(p,"type",Copy(unnamed)); Setattr(p,"storage",yyvsp[-7].id); p = nextSibling(p); } } set_nextSibling(yyval.node,n); { /* If a proper typedef name was given, we'll use it to set the scope name */ String *name = 0; if (yyvsp[-7].id && (strcmp(yyvsp[-7].id,"typedef") == 0)) { if (!Len(yyvsp[-1].decl.type)) { name = yyvsp[-1].decl.id; Setattr(yyval.node,"tdname",name); Setattr(yyval.node,"name",name); /* if (!class_rename) class_rename = NewString(name); */ Swig_symbol_setscopename(name); /* If a proper name given, we use that as the typedef, not unnamed */ Clear(unnamed); Append(unnamed, name); n = nextSibling(n); set_nextSibling(yyval.node,n); /* Check for previous extensions */ if (extendhash) { String *clsname = Swig_symbol_qualifiedscopename(0); Node *am = Getattr(extendhash,clsname); if (am) { /* Merge the extension into the symbol table */ merge_extensions(yyval.node,am); appendChild(yyval.node,am); Delattr(extendhash,clsname); } Delete(clsname); } if (!classes) classes = NewHash(); Setattr(classes,Swig_symbol_qualifiedscopename(0),yyval.node); } else { Swig_symbol_setscopename((char*)""); } } appendChild(yyval.node,yyvsp[-3].node); appendChild(yyval.node,dump_nested(Char(name))); } /* Pop the scope */ Setattr(yyval.node,"symtab",Swig_symbol_popscope()); if (class_rename) { yyrename = NewString(class_rename); } Namespaceprefix = Swig_symbol_qualifiedscopename(0); add_symbols(yyval.node); add_symbols(n); } break; case 125: #line 2618 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = 0; } break; case 126: #line 2619 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = new_node("cdecl"); Setattr(yyval.node,"name",yyvsp[-1].decl.id); Setattr(yyval.node,"decl",yyvsp[-1].decl.type); Setattr(yyval.node,"parms",yyvsp[-1].decl.parms); set_nextSibling(yyval.node,yyvsp[0].node); } break; case 127: #line 2631 "CableSwig/SWIG/Source/CParse/parser.y" { if (yyvsp[-3].id && (Strcmp(yyvsp[-3].id,"friend") == 0)) { /* Ignore */ yyval.node = 0; } else { yyval.node = new_node("classforward"); Setattr(yyval.node,"kind",yyvsp[-2].id); Setattr(yyval.node,"name",yyvsp[-1].str); Setattr(yyval.node,"sym:weak", "1"); add_symbols(yyval.node); } } break; case 128: #line 2649 "CableSwig/SWIG/Source/CParse/parser.y" { template_parameters = yyvsp[-1].tparms; } break; case 129: #line 2649 "CableSwig/SWIG/Source/CParse/parser.y" { String *tname = 0; int error = 0; template_parameters = 0; yyval.node = yyvsp[0].node; if (yyval.node) tname = Getattr(yyval.node,"name"); /* Check if the class is a template specialization */ if ((yyval.node) && (Strstr(tname,"<")) && (Strncmp(tname,"operator ",9) != 0)) { /* If a specialization. Check if defined. */ Node *tempn = 0; { String *tbase = SwigType_templateprefix(tname); tempn = Swig_symbol_clookup_local(tbase,0); if (!tempn || (Strcmp(nodeType(tempn),"template") != 0)) { Swig_warning(WARN_PARSE_TEMPLATE_SP_UNDEF, Getfile(yyval.node),Getline(yyval.node),"Specialization of non-template '%s'.\n", tbase); tempn = 0; error = 1; } Delete(tbase); } Setattr(yyval.node,"specialization","1"); Setattr(yyval.node,"templatetype",nodeType(yyval.node)); set_nodeType(yyval.node,"template"); /* Template partial specialization */ if (tempn && (yyvsp[-3].tparms) && (yyvsp[0].node)) { List *tlist; String *targs = SwigType_templateargs(tname); tlist = SwigType_parmlist(targs); /* Printf(stdout,"targs = '%s' %s\n", targs, tlist); */ if (!Getattr(yyval.node,"sym:weak")) { Setattr(yyval.node,"sym:typename","1"); } if (Len(tlist) != ParmList_len(Getattr(tempn,"templateparms"))) { Swig_error(Getfile(yyval.node),Getline(yyval.node),"Inconsistent argument count in template partial specialization. %d %d\n", Len(tlist), ParmList_len(Getattr(tempn,"templateparms"))); } else { /* This code builds the argument list for the partial template specialization. This is a little hairy, but the idea is as follows: $3 contains a list of arguments supplied for the template. For example template. tlist is a list of the specialization arguments--which may be different. For example class. tp is a copy of the arguments in the original template definition. The patching algorithm walks through the list of supplied arguments ($3), finds the position in the specialization arguments (tlist), and then patches the name in the argument list of the original template. */ { String *pn; Parm *p, *p1; int i, nargs; Parm *tp = CopyParmList(Getattr(tempn,"templateparms")); nargs = Len(tlist); p = yyvsp[-3].tparms; while (p) { for (i = 0; i < nargs; i++){ pn = Getattr(p,"name"); if (Strcmp(pn,SwigType_base(Getitem(tlist,i))) == 0) { int j; Parm *p1 = tp; for (j = 0; j < i; j++) { p1 = nextSibling(p1); } Setattr(p1,"name",pn); Setattr(p1,"partialarg","1"); } } p = nextSibling(p); } p1 = tp; i = 0; while (p1) { if (!Getattr(p1,"partialarg")) { Delattr(p1,"name"); Setattr(p1,"type", Getitem(tlist,i)); } i++; p1 = nextSibling(p1); } Setattr(yyval.node,"templateparms",tp); } #if 0 /* Patch the parameter list */ if (tempn) { Parm *p,*p1; ParmList *tp = CopyParmList(Getattr(tempn,"templateparms")); p = yyvsp[-3].tparms; p1 = tp; while (p && p1) { String *pn = Getattr(p,"name"); Printf(stdout,"pn = '%s'\n", pn); if (pn) Setattr(p1,"name",pn); else Delattr(p1,"name"); pn = Getattr(p,"type"); if (pn) Setattr(p1,"type",pn); p = nextSibling(p); p1 = nextSibling(p1); } Setattr(yyval.node,"templateparms",tp); } else { Setattr(yyval.node,"templateparms",yyvsp[-3].tparms); } #endif Delattr(yyval.node,"specialization"); Setattr(yyval.node,"partialspecialization","1"); /* Create a specialized name for matching */ { Parm *p = yyvsp[-3].tparms; String *fname = NewString(Getattr(yyval.node,"name")); String *ffname = 0; char tmp[32]; int i; while (p) { String *n = Getattr(p,"name"); if (!n) { p = nextSibling(p); continue; } for (i = 0; i < Len(tlist); i++) { if (Strstr(Getitem(tlist,i),n)) { sprintf(tmp,"$%d",i+1); Replaceid(fname,n,tmp); } } p = nextSibling(p); } /* Patch argument names with typedef */ { Iterator tt; List *tparms = SwigType_parmlist(fname); ffname = SwigType_templateprefix(fname); Append(ffname,"<("); for (tt = First(tparms); tt.item; ) { SwigType *ttr = Swig_symbol_typedef_reduce(tt.item,0); ttr = Swig_symbol_type_qualify(ttr,0); Append(ffname,ttr); tt = Next(tt); if (tt.item) Putc(',',ffname); } Append(ffname,")>"); } { String *partials = Getattr(tempn,"partials"); if (!partials) { partials = NewList(); Setattr(tempn,"partials",partials); } /* Printf(stdout,"partial: fname = '%s', '%s'\n", fname, Swig_symbol_typedef_reduce(fname,0)); */ Append(partials,ffname); } Setattr(yyval.node,"partialargs",ffname); Swig_symbol_cadd(ffname,yyval.node); } } Delete(tlist); Delete(targs); } else { /* Need to resolve exact specialization name */ /* This needs to be rewritten */ List *tparms; String *fname; Iterator tt; fname = SwigType_templateprefix(tname); tparms = SwigType_parmlist(tname); Append(fname,"<("); for (tt = First(tparms); tt.item; ) { SwigType *ttr = Swig_symbol_typedef_reduce(tt.item,0); ttr = Swig_symbol_type_qualify(ttr,0); Append(fname,ttr); tt = Next(tt); if (tt.item) Putc(',',fname); } Append(fname,")>"); Swig_symbol_cadd(fname,yyval.node); } } else if (yyval.node) { Setattr(yyval.node,"templatetype",nodeType(yyvsp[0].node)); set_nodeType(yyval.node,"template"); Setattr(yyval.node,"templateparms", yyvsp[-3].tparms); if (!Getattr(yyval.node,"sym:weak")) { Setattr(yyval.node,"sym:typename","1"); } add_symbols(yyval.node); /* We also place a fully parameterized version in the symbol table */ { Parm *p; String *fname = NewStringf("%s<(",Getattr(yyval.node,"name")); p = yyvsp[-3].tparms; while (p) { String *n = Getattr(p,"name"); if (!n) n = Getattr(p,"type"); Printf(fname,"%s", n); p = nextSibling(p); if (p) Putc(',',fname); } Printf(fname,")>"); Swig_symbol_cadd(fname,yyval.node); } } if (error) yyval.node = 0; } break; case 130: #line 2862 "CableSwig/SWIG/Source/CParse/parser.y" { Swig_warning(WARN_PARSE_EXPLICIT_TEMPLATE, cparse_file, cparse_line, "Explicit template instantiation ignored.\n"); yyval.node = 0; } break; case 131: #line 2868 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 132: #line 2871 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 133: #line 2874 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 134: #line 2877 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = 0; } break; case 135: #line 2880 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 136: #line 2885 "CableSwig/SWIG/Source/CParse/parser.y" { /* Rip out the parameter names */ Parm *p = yyvsp[0].pl; yyval.tparms = yyvsp[0].pl; while (p) { String *name = Getattr(p,"name"); if (!name) { /* Hmmm. Maybe it's a 'class T' parameter */ char *type = Char(Getattr(p,"type")); /* Template template parameter */ if (strncmp(type,"template ",16) == 0) { type += 16; } if ((strncmp(type,"class ",6) == 0) || (strncmp(type,"typename ", 9) == 0)) { char *t = strchr(type,' '); Setattr(p,"name", t+1); } else { /* Swig_error(cparse_file, cparse_line, "Missing template parameter name\n"); $$.rparms = 0; $$.parms = 0; break; */ } } p = nextSibling(p); } } break; case 137: #line 2917 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = new_node("using"); Setattr(yyval.node,"uname",yyvsp[-1].str); Setattr(yyval.node,"name", Swig_scopename_last(yyvsp[-1].str)); add_symbols(yyval.node); } break; case 138: #line 2923 "CableSwig/SWIG/Source/CParse/parser.y" { Node *n = Swig_symbol_clookup(yyvsp[-1].str,0); if (!n) { Swig_error(cparse_file, cparse_line, "Nothing known about namespace '%s'\n", yyvsp[-1].str); yyval.node = 0; } else { while (Strcmp(nodeType(n),"using") == 0) { n = Getattr(n,"node"); } if (n) { if (Strcmp(nodeType(n),"namespace") == 0) { yyval.node = new_node("using"); Setattr(yyval.node,"node",n); Setattr(yyval.node,"namespace", yyvsp[-1].str); Swig_symbol_inherit(Getattr(n,"symtab")); } else { Swig_error(cparse_file, cparse_line, "'%s' is not a namespace.\n", yyvsp[-1].str); yyval.node = 0; } } else { yyval.node = 0; } } } break; case 139: #line 2950 "CableSwig/SWIG/Source/CParse/parser.y" { Hash *h; yyvsp[-2].node = Swig_symbol_current(); h = Swig_symbol_clookup(yyvsp[-1].str,0); if (h && (Strcmp(nodeType(h),"namespace") == 0)) { if (Getattr(h,"alias")) { h = Getattr(h,"namespace"); Swig_warning(WARN_PARSE_NAMESPACE_ALIAS, cparse_file, cparse_line, "Namespace alias '%s' not allowed here. Assuming '%s'\n", yyvsp[-1].str, Getattr(h,"name")); yyvsp[-1].str = Getattr(h,"name"); } Swig_symbol_setscope(Getattr(h,"symtab")); } else { Swig_symbol_newscope(); Swig_symbol_setscopename(yyvsp[-1].str); } Namespaceprefix = Swig_symbol_qualifiedscopename(0); } break; case 140: #line 2967 "CableSwig/SWIG/Source/CParse/parser.y" { Node *n = yyvsp[-1].node; set_nodeType(n,"namespace"); Setattr(n,"name",yyvsp[-4].str); Setattr(n,"symtab", Swig_symbol_popscope()); Swig_symbol_setscope(yyvsp[-5].node); yyval.node = n; Namespaceprefix = Swig_symbol_qualifiedscopename(0); add_symbols(yyval.node); } break; case 141: #line 2977 "CableSwig/SWIG/Source/CParse/parser.y" { Hash *h; yyvsp[-1].node = Swig_symbol_current(); h = Swig_symbol_clookup((char *)"",0); if (h && (Strcmp(nodeType(h),"namespace") == 0)) { Swig_symbol_setscope(Getattr(h,"symtab")); } else { Swig_symbol_newscope(); Swig_symbol_setscopename("__unnamed__"); } Namespaceprefix = Swig_symbol_qualifiedscopename(0); } break; case 142: #line 2988 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[-1].node; set_nodeType(yyval.node,"namespace"); Setattr(yyval.node,"unnamed","1"); Setattr(yyval.node,"symtab", Swig_symbol_popscope()); Swig_symbol_setscope(yyvsp[-4].node); Namespaceprefix = Swig_symbol_qualifiedscopename(0); add_symbols(yyval.node); } break; case 143: #line 2997 "CableSwig/SWIG/Source/CParse/parser.y" { /* Namespace alias */ Node *n; yyval.node = new_node("namespace"); Setattr(yyval.node,"name",yyvsp[-3].id); Setattr(yyval.node,"alias",yyvsp[-1].str); n = Swig_symbol_clookup(yyvsp[-1].str,0); if (!n) { Swig_error(cparse_file, cparse_line, "Unknown namespace '%s'\n", yyvsp[-1].str); yyval.node = 0; } else { if (Strcmp(nodeType(n),"namespace") != 0) { Swig_error(cparse_file, cparse_line, "'%s' is not a namespace\n",yyvsp[-1].str); yyval.node = 0; } else { while (Getattr(n,"alias")) { n = Getattr(n,"namespace"); } Setattr(yyval.node,"namespace",n); add_symbols(yyval.node); /* Set up a scope alias */ Swig_symbol_alias(yyvsp[-3].id,Getattr(n,"symtab")); } } } break; case 144: #line 3024 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[-1].node; if (yyval.node) { Node *p = yyval.node; Node *pp =0; while (p) { pp = p; p = nextSibling(p); } set_nextSibling(pp,yyvsp[0].node); } else { yyval.node = yyvsp[0].node; } } break; case 145: #line 3038 "CableSwig/SWIG/Source/CParse/parser.y" { if (cplus_mode != CPLUS_PUBLIC) { Swig_error(cparse_file,cparse_line,"%%extend can only be used in a public section\n"); } } break; case 146: #line 3042 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = new_node("extend"); Swig_tag_nodes(yyvsp[-2].node,"feature:extend",(char*) "1"); appendChild(yyval.node,yyvsp[-2].node); set_nextSibling(yyval.node,yyvsp[0].node); } break; case 147: #line 3048 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = 0;} break; case 148: #line 3049 "CableSwig/SWIG/Source/CParse/parser.y" { skip_decl(); { static int last_error_line = -1; if (last_error_line != cparse_line) { Swig_error(cparse_file, cparse_line,"Syntax error in input.\n"); last_error_line = cparse_line; } } } break; case 149: #line 3058 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 150: #line 3069 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 151: #line 3070 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; if (extendmode) { String *symname; symname= make_name(Getattr(yyval.node,"name"), Getattr(yyval.node,"decl")); if (Strcmp(symname,Getattr(yyval.node,"name")) == 0) { /* No renaming operation. Set name to class name */ yyrename = NewString(Getattr(current_class,"sym:name")); } else { yyrename = symname; } } add_symbols(yyval.node); } break; case 152: #line 3084 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 153: #line 3085 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 154: #line 3086 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 155: #line 3087 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 156: #line 3088 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 157: #line 3089 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 158: #line 3090 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = 0; } break; case 159: #line 3091 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 160: #line 3092 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 161: #line 3093 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = 0; } break; case 162: #line 3094 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 163: #line 3095 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 164: #line 3096 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = 0; } break; case 165: #line 3097 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = 0; } break; case 166: #line 3106 "CableSwig/SWIG/Source/CParse/parser.y" { if (Classprefix) { SwigType *decl = NewString(""); yyval.node = new_node("constructor"); Setattr(yyval.node,"name",yyvsp[-4].type); Setattr(yyval.node,"parms",yyvsp[-2].pl); SwigType_add_function(decl,yyvsp[-2].pl); Setattr(yyval.node,"decl",decl); Setattr(yyval.node,"throws",yyvsp[0].decl.throws); if (Len(scanner_ccode)) { Setattr(yyval.node,"code",Copy(scanner_ccode)); } Setattr(yyval.node,"feature:new","1"); } else { yyval.node = 0; } } break; case 167: #line 3127 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = new_node("destructor"); Setattr(yyval.node,"name",NewStringf("~%s",yyvsp[-4].str)); if (Len(scanner_ccode)) { Setattr(yyval.node,"code",Copy(scanner_ccode)); } { String *decl = NewString(""); SwigType_add_function(decl,yyvsp[-2].pl); Setattr(yyval.node,"decl",decl); } add_symbols(yyval.node); } break; case 168: #line 3143 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = new_node("destructor"); /* Check for template names. If the class is a template and the constructor is missing the template part, we add it */ { char *c = Strstr(Classprefix,"<"); if (c) { if (!Strstr(yyvsp[-4].str,"<")) { yyvsp[-4].str = NewStringf("%s%s",yyvsp[-4].str,c); } } } Setattr(yyval.node,"storage","virtual"); Setattr(yyval.node,"name",NewStringf("~%s",yyvsp[-4].str)); if (yyvsp[0].dtype.val) { Setattr(yyval.node,"value","0"); } if (Len(scanner_ccode)) { Setattr(yyval.node,"code",Copy(scanner_ccode)); } { String *decl = NewString(""); SwigType_add_function(decl,yyvsp[-2].pl); Setattr(yyval.node,"decl",decl); } add_symbols(yyval.node); } break; case 169: #line 3176 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = new_node("cdecl"); Setattr(yyval.node,"type",yyvsp[-5].type); Setattr(yyval.node,"name",yyvsp[-6].str); SwigType_add_function(yyvsp[-4].type,yyvsp[-2].pl); if (yyvsp[0].dtype.qualifier) { SwigType_push(yyvsp[-4].type,yyvsp[0].dtype.qualifier); } Setattr(yyval.node,"decl",yyvsp[-4].type); Setattr(yyval.node,"parms",yyvsp[-2].pl); Setattr(yyval.node,"conversion_operator","1"); add_symbols(yyval.node); } break; case 170: #line 3190 "CableSwig/SWIG/Source/CParse/parser.y" { SwigType *decl; yyval.node = new_node("cdecl"); Setattr(yyval.node,"type",yyvsp[-5].type); Setattr(yyval.node,"name",yyvsp[-6].str); decl = NewString(""); SwigType_add_reference(decl); SwigType_add_function(decl,yyvsp[-2].pl); if (yyvsp[0].dtype.qualifier) { SwigType_push(decl,yyvsp[0].dtype.qualifier); } Setattr(yyval.node,"decl",decl); Setattr(yyval.node,"parms",yyvsp[-2].pl); Setattr(yyval.node,"conversion_operator","1"); add_symbols(yyval.node); } break; case 171: #line 3207 "CableSwig/SWIG/Source/CParse/parser.y" { String *t = NewString(""); yyval.node = new_node("cdecl"); Setattr(yyval.node,"type",yyvsp[-4].type); Setattr(yyval.node,"name",yyvsp[-5].str); SwigType_add_function(t,yyvsp[-2].pl); if (yyvsp[0].dtype.qualifier) { SwigType_push(t,yyvsp[0].dtype.qualifier); } Setattr(yyval.node,"decl",t); Setattr(yyval.node,"parms",yyvsp[-2].pl); Setattr(yyval.node,"conversion_operator","1"); add_symbols(yyval.node); } break; case 172: #line 3225 "CableSwig/SWIG/Source/CParse/parser.y" { skip_balanced('{','}'); yyval.node = 0; } break; case 173: #line 3232 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = new_node("access"); Setattr(yyval.node,"kind","public"); cplus_mode = CPLUS_PUBLIC; } break; case 174: #line 3239 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = new_node("access"); Setattr(yyval.node,"kind","private"); cplus_mode = CPLUS_PRIVATE; } break; case 175: #line 3247 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = new_node("access"); Setattr(yyval.node,"kind","protected"); cplus_mode = CPLUS_PROTECTED; } break; case 176: #line 3270 "CableSwig/SWIG/Source/CParse/parser.y" { cparse_start_line = cparse_line; skip_balanced('{','}'); } break; case 177: #line 3271 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = 0; if (cplus_mode == CPLUS_PUBLIC) { if (yyvsp[-1].decl.id) { if (strcmp(yyvsp[-5].id,"class") == 0) { Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested classes not currently supported (ignored).\n"); /* Generate some code for a new class */ } else { Nested *n = (Nested *) malloc(sizeof(Nested)); n->code = NewString(""); Printv(n->code, "typedef ", yyvsp[-5].id, " ", Char(scanner_ccode), " $classname_", yyvsp[-1].decl.id, ";\n", NIL); n->name = Swig_copy_string(yyvsp[-1].decl.id); n->line = cparse_start_line; n->type = NewString(""); n->kind = yyvsp[-5].id; SwigType_push(n->type, yyvsp[-1].decl.type); n->next = 0; add_nested(n); } } else { Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", yyvsp[-5].id); } } } break; case 178: #line 3299 "CableSwig/SWIG/Source/CParse/parser.y" { cparse_start_line = cparse_line; skip_balanced('{','}'); } break; case 179: #line 3300 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = 0; if (cplus_mode == CPLUS_PUBLIC) { if (strcmp(yyvsp[-4].id,"class") == 0) { Swig_warning(WARN_PARSE_NESTED_CLASS,cparse_file, cparse_line,"Nested class not currently supported (ignored)\n"); /* Generate some code for a new class */ } else if (yyvsp[-1].decl.id) { /* Generate some code for a new class */ Nested *n = (Nested *) malloc(sizeof(Nested)); n->code = NewString(""); Printv(n->code, "typedef ", yyvsp[-4].id, " " , Char(scanner_ccode), " $classname_", yyvsp[-1].decl.id, ";\n",NIL); n->name = Swig_copy_string(yyvsp[-1].decl.id); n->line = cparse_start_line; n->type = NewString(""); n->kind = yyvsp[-4].id; SwigType_push(n->type,yyvsp[-1].decl.type); n->next = 0; add_nested(n); } else { Swig_warning(WARN_PARSE_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (ignored).\n", yyvsp[-4].id); } } } break; case 180: #line 3326 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl = yyvsp[0].decl;} break; case 181: #line 3327 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl.id = 0; } break; case 182: #line 3333 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 183: #line 3336 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 184: #line 3340 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 185: #line 3343 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 186: #line 3344 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 187: #line 3345 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 188: #line 3346 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 189: #line 3347 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 190: #line 3348 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 191: #line 3349 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 192: #line 3350 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; } break; case 193: #line 3353 "CableSwig/SWIG/Source/CParse/parser.y" { Clear(scanner_ccode); } break; case 194: #line 3356 "CableSwig/SWIG/Source/CParse/parser.y" { skip_balanced('{','}'); } break; case 195: #line 3359 "CableSwig/SWIG/Source/CParse/parser.y" { Clear(scanner_ccode); yyval.dtype.val = 0; yyval.dtype.qualifier = yyvsp[-1].dtype.qualifier; yyval.dtype.bitfield = 0; yyval.dtype.throws = yyvsp[-1].dtype.throws; } break; case 196: #line 3366 "CableSwig/SWIG/Source/CParse/parser.y" { Clear(scanner_ccode); yyval.dtype.val = yyvsp[-1].dtype.val; yyval.dtype.qualifier = yyvsp[-3].dtype.qualifier; yyval.dtype.bitfield = 0; yyval.dtype.throws = yyvsp[-3].dtype.throws; } break; case 197: #line 3373 "CableSwig/SWIG/Source/CParse/parser.y" { skip_balanced('{','}'); yyval.dtype.val = 0; yyval.dtype.qualifier = yyvsp[-1].dtype.qualifier; yyval.dtype.bitfield = 0; yyval.dtype.throws = yyvsp[-1].dtype.throws; } break; case 198: #line 3383 "CableSwig/SWIG/Source/CParse/parser.y" { } break; case 199: #line 3389 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.id = "extern"; } break; case 200: #line 3390 "CableSwig/SWIG/Source/CParse/parser.y" { if (strcmp(yyvsp[0].id,"C") == 0) { yyval.id = "externc"; } else { Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\" (ignored).\n", yyvsp[0].id); yyval.id = 0; } } break; case 201: #line 3398 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.id = "static"; } break; case 202: #line 3399 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.id = "typedef"; } break; case 203: #line 3400 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.id = "virtual"; } break; case 204: #line 3401 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.id = "friend"; } break; case 205: #line 3402 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.id = 0; } break; case 206: #line 3409 "CableSwig/SWIG/Source/CParse/parser.y" { Parm *p; yyval.pl = yyvsp[0].pl; p = yyvsp[0].pl; while (p) { Replace(Getattr(p,"type"),"typename ", "", DOH_REPLACE_ANY); p = nextSibling(p); } } break; case 207: #line 3420 "CableSwig/SWIG/Source/CParse/parser.y" { if (1) { set_nextSibling(yyvsp[-1].p,yyvsp[0].pl); yyval.pl = yyvsp[-1].p; } else { yyval.pl = yyvsp[0].pl; } } break; case 208: #line 3428 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.pl = 0; } break; case 209: #line 3431 "CableSwig/SWIG/Source/CParse/parser.y" { set_nextSibling(yyvsp[-1].p,yyvsp[0].pl); yyval.pl = yyvsp[-1].p; } break; case 210: #line 3435 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.pl = 0; } break; case 211: #line 3439 "CableSwig/SWIG/Source/CParse/parser.y" { SwigType_push(yyvsp[-1].type,yyvsp[0].decl.type); yyval.p = NewParm(yyvsp[-1].type,yyvsp[0].decl.id); Setfile(yyval.p,cparse_file); Setline(yyval.p,cparse_line); if (yyvsp[0].decl.defarg) { Setattr(yyval.p,"value",yyvsp[0].decl.defarg); } } break; case 212: #line 3449 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.p = NewParm(NewStringf("template %s %s", yyvsp[-1].id,yyvsp[0].str), 0); Setfile(yyval.p,cparse_file); Setline(yyval.p,cparse_line); } break; case 213: #line 3454 "CableSwig/SWIG/Source/CParse/parser.y" { SwigType *t = NewString("v(...)"); yyval.p = NewParm(t, 0); Setfile(yyval.p,cparse_file); Setline(yyval.p,cparse_line); } break; case 214: #line 3462 "CableSwig/SWIG/Source/CParse/parser.y" { Parm *p; yyval.p = yyvsp[0].p; p = yyvsp[0].p; while (p) { if (Getattr(p,"type")) { Replace(Getattr(p,"type"),"typename ", "", DOH_REPLACE_ANY); } p = nextSibling(p); } } break; case 215: #line 3475 "CableSwig/SWIG/Source/CParse/parser.y" { if (1) { set_nextSibling(yyvsp[-1].p,yyvsp[0].p); yyval.p = yyvsp[-1].p; } else { yyval.p = yyvsp[0].p; } } break; case 216: #line 3483 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.p = 0; } break; case 217: #line 3486 "CableSwig/SWIG/Source/CParse/parser.y" { set_nextSibling(yyvsp[-1].p,yyvsp[0].p); yyval.p = yyvsp[-1].p; } break; case 218: #line 3490 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.p = 0; } break; case 219: #line 3494 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.p = yyvsp[0].p; { /* We need to make a possible adjustment for integer parameters. */ SwigType *type; Node *n = 0; while (!n) { type = Getattr(yyvsp[0].p,"type"); n = Swig_symbol_clookup(type,0); /* See if we can find a node that matches the typename */ if ((n) && (Strcmp(nodeType(n),"cdecl") == 0)) { SwigType *decl = Getattr(n,"decl"); if (!SwigType_isfunction(decl)) { String *value = Getattr(n,"value"); if (value) { Setattr(yyvsp[0].p,"type",Copy(value)); n = 0; } } } else { break; } } } } break; case 220: #line 3520 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.p = NewParm(0,0); Setfile(yyval.p,cparse_file); Setline(yyval.p,cparse_line); Setattr(yyval.p,"value",yyvsp[0].dtype.val); } break; case 221: #line 3526 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.p = NewParm(0,0); Setfile(yyval.p,cparse_file); Setline(yyval.p,cparse_line); Setattr(yyval.p,"value",NewString(yyvsp[0].id)); } break; case 222: #line 3534 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype = yyvsp[0].dtype; if (yyvsp[0].dtype.type == T_ERROR) { Swig_warning(WARN_PARSE_BAD_DEFAULT,cparse_file, cparse_line, "Can't set default argument (ignored)\n"); yyval.dtype.val = 0; yyval.dtype.rawval = 0; yyval.dtype.bitfield = 0; yyval.dtype.throws = 0; } } break; case 223: #line 3544 "CableSwig/SWIG/Source/CParse/parser.y" { Node *n = Swig_symbol_clookup(yyvsp[0].decl.id,0); if (n) { String *q = Swig_symbol_qualified(n); if (Getattr(n,"access")) { if (cplus_mode == CPLUS_PUBLIC) { Swig_warning(WARN_PARSE_PRIVATE, cparse_file, cparse_line,"'%s' is private in this context.\n", yyvsp[0].decl.id); Swig_warning(WARN_PARSE_BAD_DEFAULT, cparse_file, cparse_line,"Can't set default argument value (ignored)\n"); } yyval.dtype.val = 0; } else { if (q) { String *temp = NewStringf("%s::%s", q, Getattr(n,"name")); yyval.dtype.val = NewStringf("&%s", SwigType_str(yyvsp[0].decl.type,temp)); Delete(q); Delete(temp); } else { yyval.dtype.val = NewStringf("&%s", SwigType_str(yyvsp[0].decl.type,yyvsp[0].decl.id)); } } } else { yyval.dtype.val = NewStringf("&%s",SwigType_str(yyvsp[0].decl.type,yyvsp[0].decl.id)); } yyval.dtype.rawval = 0; yyval.dtype.type = T_USER; yyval.dtype.bitfield = 0; yyval.dtype.throws = 0; } break; case 224: #line 3572 "CableSwig/SWIG/Source/CParse/parser.y" { skip_balanced('{','}'); yyval.dtype.val = 0; yyval.dtype.rawval = 0; yyval.dtype.type = T_INT; yyval.dtype.bitfield = 0; yyval.dtype.throws = 0; } break; case 225: #line 3580 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype.val = 0; yyval.dtype.rawval = 0; yyval.dtype.type = 0; yyval.dtype.bitfield = yyvsp[0].dtype.val; yyval.dtype.throws = 0; } break; case 226: #line 3587 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype.val = 0; yyval.dtype.rawval = 0; yyval.dtype.type = T_INT; yyval.dtype.bitfield = 0; yyval.dtype.throws = 0; } break; case 227: #line 3596 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl = yyvsp[-1].decl; yyval.decl.defarg = yyvsp[0].dtype.rawval ? yyvsp[0].dtype.rawval : yyvsp[0].dtype.val; } break; case 228: #line 3600 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl = yyvsp[-1].decl; yyval.decl.defarg = yyvsp[0].dtype.rawval ? yyvsp[0].dtype.rawval : yyvsp[0].dtype.val; } break; case 229: #line 3604 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl.type = 0; yyval.decl.id = 0; yyval.decl.defarg = yyvsp[0].dtype.rawval ? yyvsp[0].dtype.rawval : yyvsp[0].dtype.val; } break; case 230: #line 3611 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl = yyvsp[0].decl; if (SwigType_isfunction(yyvsp[0].decl.type)) { Delete(SwigType_pop_function(yyvsp[0].decl.type)); } else if (SwigType_isarray(yyvsp[0].decl.type)) { SwigType *ta = SwigType_pop_arrays(yyvsp[0].decl.type); if (SwigType_isfunction(yyvsp[0].decl.type)) { Delete(SwigType_pop_function(yyvsp[0].decl.type)); } else { yyval.decl.parms = 0; } SwigType_push(yyvsp[0].decl.type,ta); Delete(ta); } else { yyval.decl.parms = 0; } } break; case 231: #line 3628 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl = yyvsp[0].decl; if (SwigType_isfunction(yyvsp[0].decl.type)) { Delete(SwigType_pop_function(yyvsp[0].decl.type)); } else if (SwigType_isarray(yyvsp[0].decl.type)) { SwigType *ta = SwigType_pop_arrays(yyvsp[0].decl.type); if (SwigType_isfunction(yyvsp[0].decl.type)) { Delete(SwigType_pop_function(yyvsp[0].decl.type)); } else { yyval.decl.parms = 0; } SwigType_push(yyvsp[0].decl.type,ta); Delete(ta); } else { yyval.decl.parms = 0; } } break; case 232: #line 3645 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl.type = 0; yyval.decl.id = 0; yyval.decl.parms = 0; } break; case 233: #line 3653 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl = yyvsp[0].decl; if (yyval.decl.type) { SwigType_push(yyvsp[-1].type,yyval.decl.type); Delete(yyval.decl.type); } yyval.decl.type = yyvsp[-1].type; } break; case 234: #line 3661 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl = yyvsp[0].decl; SwigType_add_reference(yyvsp[-2].type); if (yyval.decl.type) { SwigType_push(yyvsp[-2].type,yyval.decl.type); Delete(yyval.decl.type); } yyval.decl.type = yyvsp[-2].type; } break; case 235: #line 3670 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl = yyvsp[0].decl; if (!yyval.decl.type) yyval.decl.type = NewString(""); } break; case 236: #line 3674 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl = yyvsp[0].decl; yyval.decl.type = NewString(""); SwigType_add_reference(yyval.decl.type); if (yyvsp[0].decl.type) { SwigType_push(yyval.decl.type,yyvsp[0].decl.type); Delete(yyvsp[0].decl.type); } } break; case 237: #line 3683 "CableSwig/SWIG/Source/CParse/parser.y" { SwigType *t = NewString(""); yyval.decl = yyvsp[0].decl; SwigType_add_memberpointer(t,yyvsp[-2].str); if (yyval.decl.type) { SwigType_push(t,yyval.decl.type); Delete(yyval.decl.type); } yyval.decl.type = t; } break; case 238: #line 3694 "CableSwig/SWIG/Source/CParse/parser.y" { SwigType *t = NewString(""); yyval.decl = yyvsp[0].decl; SwigType_add_memberpointer(t,yyvsp[-2].str); SwigType_push(yyvsp[-3].type,t); if (yyval.decl.type) { SwigType_push(yyvsp[-3].type,yyval.decl.type); Delete(yyval.decl.type); } yyval.decl.type = yyvsp[-3].type; Delete(t); } break; case 239: #line 3706 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl = yyvsp[0].decl; SwigType_add_memberpointer(yyvsp[-4].type,yyvsp[-3].str); SwigType_add_reference(yyvsp[-4].type); if (yyval.decl.type) { SwigType_push(yyvsp[-4].type,yyval.decl.type); Delete(yyval.decl.type); } yyval.decl.type = yyvsp[-4].type; } break; case 240: #line 3716 "CableSwig/SWIG/Source/CParse/parser.y" { SwigType *t = NewString(""); yyval.decl = yyvsp[0].decl; SwigType_add_memberpointer(t,yyvsp[-3].str); SwigType_add_reference(t); if (yyval.decl.type) { SwigType_push(t,yyval.decl.type); Delete(yyval.decl.type); } yyval.decl.type = t; } break; case 241: #line 3729 "CableSwig/SWIG/Source/CParse/parser.y" { /* Note: This is non-standard C. Template declarator is allowed to follow an identifier */ yyval.decl.id = Char(yyvsp[0].str); yyval.decl.type = 0; yyval.decl.parms = 0; yyval.decl.have_parms = 0; } break; case 242: #line 3736 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl.id = Char(NewStringf("~%s",yyvsp[0].str)); yyval.decl.type = 0; yyval.decl.parms = 0; yyval.decl.have_parms = 0; } break; case 243: #line 3744 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl.id = Char(yyvsp[-1].str); yyval.decl.type = 0; yyval.decl.parms = 0; yyval.decl.have_parms = 0; } break; case 244: #line 3760 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl = yyvsp[-1].decl; if (yyval.decl.type) { SwigType_push(yyvsp[-2].type,yyval.decl.type); Delete(yyval.decl.type); } yyval.decl.type = yyvsp[-2].type; } break; case 245: #line 3768 "CableSwig/SWIG/Source/CParse/parser.y" { SwigType *t; yyval.decl = yyvsp[-1].decl; t = NewString(""); SwigType_add_memberpointer(t,yyvsp[-3].str); if (yyval.decl.type) { SwigType_push(t,yyval.decl.type); Delete(yyval.decl.type); } yyval.decl.type = t; } break; case 246: #line 3779 "CableSwig/SWIG/Source/CParse/parser.y" { SwigType *t; yyval.decl = yyvsp[-2].decl; t = NewString(""); SwigType_add_array(t,(char*)""); if (yyval.decl.type) { SwigType_push(t,yyval.decl.type); Delete(yyval.decl.type); } yyval.decl.type = t; } break; case 247: #line 3790 "CableSwig/SWIG/Source/CParse/parser.y" { SwigType *t; yyval.decl = yyvsp[-3].decl; t = NewString(""); SwigType_add_array(t,yyvsp[-1].dtype.val); if (yyval.decl.type) { SwigType_push(t,yyval.decl.type); Delete(yyval.decl.type); } yyval.decl.type = t; } break; case 248: #line 3801 "CableSwig/SWIG/Source/CParse/parser.y" { SwigType *t; yyval.decl = yyvsp[-3].decl; t = NewString(""); SwigType_add_function(t,yyvsp[-1].pl); if (!yyval.decl.have_parms) { yyval.decl.parms = yyvsp[-1].pl; yyval.decl.have_parms = 1; } if (!yyval.decl.type) { yyval.decl.type = t; } else { SwigType_push(t, yyval.decl.type); Delete(yyval.decl.type); yyval.decl.type = t; } } break; case 249: #line 3820 "CableSwig/SWIG/Source/CParse/parser.y" { /* Note: This is non-standard C. Template declarator is allowed to follow an identifier */ yyval.decl.id = Char(yyvsp[0].str); yyval.decl.type = 0; yyval.decl.parms = 0; yyval.decl.have_parms = 0; } break; case 250: #line 3828 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl.id = Char(NewStringf("~%s",yyvsp[0].str)); yyval.decl.type = 0; yyval.decl.parms = 0; yyval.decl.have_parms = 0; } break; case 251: #line 3845 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl = yyvsp[-1].decl; if (yyval.decl.type) { SwigType_push(yyvsp[-2].type,yyval.decl.type); Delete(yyval.decl.type); } yyval.decl.type = yyvsp[-2].type; } break; case 252: #line 3853 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl = yyvsp[-1].decl; if (!yyval.decl.type) { yyval.decl.type = NewString(""); } SwigType_add_reference(yyval.decl.type); } break; case 253: #line 3860 "CableSwig/SWIG/Source/CParse/parser.y" { SwigType *t; yyval.decl = yyvsp[-1].decl; t = NewString(""); SwigType_add_memberpointer(t,yyvsp[-3].str); if (yyval.decl.type) { SwigType_push(t,yyval.decl.type); Delete(yyval.decl.type); } yyval.decl.type = t; } break; case 254: #line 3871 "CableSwig/SWIG/Source/CParse/parser.y" { SwigType *t; yyval.decl = yyvsp[-2].decl; t = NewString(""); SwigType_add_array(t,(char*)""); if (yyval.decl.type) { SwigType_push(t,yyval.decl.type); Delete(yyval.decl.type); } yyval.decl.type = t; } break; case 255: #line 3882 "CableSwig/SWIG/Source/CParse/parser.y" { SwigType *t; yyval.decl = yyvsp[-3].decl; t = NewString(""); SwigType_add_array(t,yyvsp[-1].dtype.val); if (yyval.decl.type) { SwigType_push(t,yyval.decl.type); Delete(yyval.decl.type); } yyval.decl.type = t; } break; case 256: #line 3893 "CableSwig/SWIG/Source/CParse/parser.y" { SwigType *t; yyval.decl = yyvsp[-3].decl; t = NewString(""); SwigType_add_function(t,yyvsp[-1].pl); if (!yyval.decl.have_parms) { yyval.decl.parms = yyvsp[-1].pl; yyval.decl.have_parms = 1; } if (!yyval.decl.type) { yyval.decl.type = t; } else { SwigType_push(t, yyval.decl.type); Delete(yyval.decl.type); yyval.decl.type = t; } } break; case 257: #line 3912 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl.type = yyvsp[0].type; yyval.decl.id = 0; yyval.decl.parms = 0; yyval.decl.have_parms = 0; } break; case 258: #line 3918 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl = yyvsp[0].decl; SwigType_push(yyvsp[-1].type,yyvsp[0].decl.type); yyval.decl.type = yyvsp[-1].type; Delete(yyvsp[0].decl.type); } break; case 259: #line 3924 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl.type = yyvsp[-1].type; SwigType_add_reference(yyval.decl.type); yyval.decl.id = 0; yyval.decl.parms = 0; yyval.decl.have_parms = 0; } break; case 260: #line 3931 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl = yyvsp[0].decl; SwigType_add_reference(yyvsp[-2].type); if (yyval.decl.type) { SwigType_push(yyvsp[-2].type,yyval.decl.type); Delete(yyval.decl.type); } yyval.decl.type = yyvsp[-2].type; } break; case 261: #line 3940 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl = yyvsp[0].decl; } break; case 262: #line 3943 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl = yyvsp[0].decl; yyval.decl.type = NewString(""); SwigType_add_reference(yyval.decl.type); if (yyvsp[0].decl.type) { SwigType_push(yyval.decl.type,yyvsp[0].decl.type); Delete(yyvsp[0].decl.type); } } break; case 263: #line 3952 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl.id = 0; yyval.decl.parms = 0; yyval.decl.have_parms = 0; yyval.decl.type = NewString(""); SwigType_add_reference(yyval.decl.type); } break; case 264: #line 3959 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl.type = NewString(""); SwigType_add_memberpointer(yyval.decl.type,yyvsp[-1].str); yyval.decl.id = 0; yyval.decl.parms = 0; yyval.decl.have_parms = 0; } break; case 265: #line 3966 "CableSwig/SWIG/Source/CParse/parser.y" { SwigType *t = NewString(""); yyval.decl.type = yyvsp[-2].type; yyval.decl.id = 0; yyval.decl.parms = 0; yyval.decl.have_parms = 0; SwigType_add_memberpointer(t,yyvsp[-1].str); SwigType_push(yyval.decl.type,t); Delete(t); } break; case 266: #line 3976 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl = yyvsp[0].decl; SwigType_add_memberpointer(yyvsp[-3].type,yyvsp[-2].str); if (yyval.decl.type) { SwigType_push(yyvsp[-3].type,yyval.decl.type); Delete(yyval.decl.type); } yyval.decl.type = yyvsp[-3].type; } break; case 267: #line 3987 "CableSwig/SWIG/Source/CParse/parser.y" { SwigType *t; yyval.decl = yyvsp[-2].decl; t = NewString(""); SwigType_add_array(t,(char*)""); if (yyval.decl.type) { SwigType_push(t,yyval.decl.type); Delete(yyval.decl.type); } yyval.decl.type = t; } break; case 268: #line 3998 "CableSwig/SWIG/Source/CParse/parser.y" { SwigType *t; yyval.decl = yyvsp[-3].decl; t = NewString(""); SwigType_add_array(t,yyvsp[-1].dtype.val); if (yyval.decl.type) { SwigType_push(t,yyval.decl.type); Delete(yyval.decl.type); } yyval.decl.type = t; } break; case 269: #line 4009 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl.type = NewString(""); yyval.decl.id = 0; yyval.decl.parms = 0; yyval.decl.have_parms = 0; SwigType_add_array(yyval.decl.type,(char*)""); } break; case 270: #line 4016 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl.type = NewString(""); yyval.decl.id = 0; yyval.decl.parms = 0; yyval.decl.have_parms = 0; SwigType_add_array(yyval.decl.type,yyvsp[-1].dtype.val); } break; case 271: #line 4023 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl = yyvsp[-1].decl; } break; case 272: #line 4026 "CableSwig/SWIG/Source/CParse/parser.y" { SwigType *t; yyval.decl = yyvsp[-3].decl; t = NewString(""); SwigType_add_function(t,yyvsp[-1].pl); if (!yyval.decl.type) { yyval.decl.type = t; } else { SwigType_push(t,yyval.decl.type); Delete(yyval.decl.type); yyval.decl.type = t; } if (!yyval.decl.have_parms) { yyval.decl.parms = yyvsp[-1].pl; yyval.decl.have_parms = 1; } } break; case 273: #line 4043 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl.type = NewString(""); SwigType_add_function(yyval.decl.type,yyvsp[-1].pl); yyval.decl.parms = yyvsp[-1].pl; yyval.decl.have_parms = 1; yyval.decl.id = 0; } break; case 274: #line 4053 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.type = NewString(""); SwigType_add_pointer(yyval.type); SwigType_push(yyval.type,yyvsp[-1].str); SwigType_push(yyval.type,yyvsp[0].type); Delete(yyvsp[0].type); } break; case 275: #line 4060 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.type = NewString(""); SwigType_add_pointer(yyval.type); SwigType_push(yyval.type,yyvsp[0].type); Delete(yyvsp[0].type); } break; case 276: #line 4066 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.type = NewString(""); SwigType_add_pointer(yyval.type); SwigType_push(yyval.type,yyvsp[0].str); } break; case 277: #line 4071 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.type = NewString(""); SwigType_add_pointer(yyval.type); } break; case 278: #line 4077 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.str = NewString(""); SwigType_add_qualifier(yyval.str,yyvsp[0].id); } break; case 279: #line 4081 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.str = yyvsp[0].str; SwigType_add_qualifier(yyval.str,yyvsp[-1].id); } break; case 280: #line 4087 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.id = "const"; } break; case 281: #line 4088 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.id = "volatile"; } break; case 282: #line 4094 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.type = yyvsp[0].type; Replace(yyval.type,"typename ","", DOH_REPLACE_ANY); } break; case 283: #line 4100 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.type = yyvsp[0].type; SwigType_push(yyval.type,yyvsp[-1].str); } break; case 284: #line 4104 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.type = yyvsp[0].type; } break; case 285: #line 4107 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.type = yyvsp[0].type; /* Printf(stdout,"primitive = '%s'\n", $$);*/ } break; case 286: #line 4110 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.type = yyvsp[0].type; } break; case 287: #line 4111 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.type = yyvsp[0].type; } break; case 288: #line 4112 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.type = NewStringf("%s%s",yyvsp[-1].type,yyvsp[0].id); } break; case 289: #line 4113 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.type = NewStringf("enum %s", yyvsp[0].str); } break; case 290: #line 4114 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.type = yyvsp[0].type; } break; case 291: #line 4115 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.type = yyvsp[-1].type; SwigType_push(yyval.type,yyvsp[0].str); } break; case 292: #line 4120 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.type = yyvsp[0].str; } break; case 293: #line 4123 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.type = NewStringf("%s %s", yyvsp[-1].id, yyvsp[0].str); } break; case 294: #line 4128 "CableSwig/SWIG/Source/CParse/parser.y" { if (!yyvsp[0].ptype.type) yyvsp[0].ptype.type = NewString("int"); if (yyvsp[0].ptype.us) { yyval.type = NewStringf("%s %s", yyvsp[0].ptype.us, yyvsp[0].ptype.type); Delete(yyvsp[0].ptype.us); Delete(yyvsp[0].ptype.type); } else { yyval.type = yyvsp[0].ptype.type; } if (Cmp(yyval.type,"signed int") == 0) { Delete(yyval.type); yyval.type = NewString("int"); } else if (Cmp(yyval.type,"signed long") == 0) { Delete(yyval.type); yyval.type = NewString("long"); } else if (Cmp(yyval.type,"signed short") == 0) { Delete(yyval.type); yyval.type = NewString("short"); } else if (Cmp(yyval.type,"signed long long") == 0) { Delete(yyval.type); yyval.type = NewString("long long"); } } break; case 295: #line 4153 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.ptype = yyvsp[0].ptype; } break; case 296: #line 4156 "CableSwig/SWIG/Source/CParse/parser.y" { if (yyvsp[-1].ptype.us && yyvsp[0].ptype.us) { Swig_error(cparse_file, cparse_line, "Extra %s specifier.\n", yyvsp[0].ptype.us); } yyval.ptype = yyvsp[0].ptype; if (yyvsp[-1].ptype.us) yyval.ptype.us = yyvsp[-1].ptype.us; if (yyvsp[-1].ptype.type) { if (!yyvsp[0].ptype.type) yyval.ptype.type = yyvsp[-1].ptype.type; else { int err = 0; if ((Cmp(yyvsp[-1].ptype.type,"long") == 0)) { if ((Cmp(yyvsp[0].ptype.type,"long") == 0) || (Cmp(yyvsp[0].ptype.type,"double") == 0)) { yyval.ptype.type = NewStringf("long %s", yyvsp[0].ptype.type); } else if (Cmp(yyvsp[0].ptype.type,"int") == 0) { yyval.ptype.type = yyvsp[-1].ptype.type; } else { err = 1; } } else if ((Cmp(yyvsp[-1].ptype.type,"short")) == 0) { if (Cmp(yyvsp[0].ptype.type,"int") == 0) { yyval.ptype.type = yyvsp[-1].ptype.type; } else { err = 1; } } else if (Cmp(yyvsp[-1].ptype.type,"int") == 0) { yyval.ptype.type = yyvsp[0].ptype.type; } else if (Cmp(yyvsp[-1].ptype.type,"double") == 0) { if (Cmp(yyvsp[0].ptype.type,"long") == 0) { yyval.ptype.type = NewString("long double"); } else { err = 1; } } if (err) { Swig_error(cparse_file, cparse_line, "Extra %s specifier.\n", yyvsp[-1].ptype.type); } } } } break; case 297: #line 4198 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.ptype.type = NewString("int"); yyval.ptype.us = 0; } break; case 298: #line 4202 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.ptype.type = NewString("short"); yyval.ptype.us = 0; } break; case 299: #line 4206 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.ptype.type = NewString("long"); yyval.ptype.us = 0; } break; case 300: #line 4210 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.ptype.type = NewString("char"); yyval.ptype.us = 0; } break; case 301: #line 4214 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.ptype.type = NewString("float"); yyval.ptype.us = 0; } break; case 302: #line 4218 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.ptype.type = NewString("double"); yyval.ptype.us = 0; } break; case 303: #line 4222 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.ptype.us = NewString("signed"); yyval.ptype.type = 0; } break; case 304: #line 4226 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.ptype.us = NewString("unsigned"); yyval.ptype.type = 0; } break; case 305: #line 4232 "CableSwig/SWIG/Source/CParse/parser.y" { /* scanner_check_typedef(); */ } break; case 306: #line 4232 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype = yyvsp[0].dtype; if (yyval.dtype.type == T_STRING) { yyval.dtype.rawval = NewStringf("\"%(escape)s\"",yyval.dtype.val); } else { yyval.dtype.rawval = 0; } yyval.dtype.bitfield = 0; yyval.dtype.throws = 0; scanner_ignore_typedef(); } break; case 307: #line 4251 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype.val = NewString(yyvsp[0].str); /* $$.rawval = NewStringf("\'%(escape)s\'",$$.val); */ /* Printf(stdout,"rawval = '%s'\n", $$.rawval); */ if (Len(yyval.dtype.val)) { yyval.dtype.rawval = NewStringf("\'%(escape)s\'", yyval.dtype.val); } else { yyval.dtype.rawval = NewString("\'\\0'"); } yyval.dtype.type = T_CHAR; yyval.dtype.bitfield = 0; yyval.dtype.throws = 0; } break; case 308: #line 4268 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.id = yyvsp[0].id; } break; case 309: #line 4269 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.id = (char *) 0;} break; case 310: #line 4274 "CableSwig/SWIG/Source/CParse/parser.y" { Node *leftSibling = Getattr(yyvsp[-2].node,"_last"); if (!leftSibling) { leftSibling=yyvsp[-2].node; } set_nextSibling(leftSibling,yyvsp[0].node); Setattr(yyvsp[-2].node,"_last",yyvsp[0].node); if (yyvsp[0].node && !Getattr(yyvsp[0].node, "enumvalue")) { /* There is no explicit enum value given, so make one. */ Setattr(yyvsp[0].node,"enumvalue", NewStringf("%s+1", Getattr(leftSibling,"name"))); } yyval.node = yyvsp[-2].node; } break; case 311: #line 4287 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = yyvsp[0].node; if (!Getattr(yyvsp[0].node, "enumvalue")) { /* first enum item value defaults to 0 */ Setattr(yyvsp[0].node,"enumvalue", "0"); } } break; case 312: #line 4296 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = new_node("enumitem"); Setattr(yyval.node,"name",yyvsp[0].id); Setattr(yyval.node,"type",NewSwigType(T_INT)); Setattr(yyval.node,"feature:immutable","1"); } break; case 313: #line 4302 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = new_node("enumitem"); Setattr(yyval.node,"name",yyvsp[-2].id); Setattr(yyval.node,"enumvalue", yyvsp[0].dtype.val); if (yyvsp[0].dtype.type == T_CHAR) { Setattr(yyval.node,"value",yyvsp[0].dtype.val); Setattr(yyval.node,"type",NewSwigType(T_CHAR)); } else { Setattr(yyval.node,"value",yyvsp[-2].id); Setattr(yyval.node,"type",NewSwigType(T_INT)); } Setattr(yyval.node,"feature:immutable","1"); } break; case 314: #line 4315 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = 0; } break; case 315: #line 4318 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype = yyvsp[0].dtype; if ((yyval.dtype.type != T_INT) && (yyval.dtype.type != T_UINT) && (yyval.dtype.type != T_LONG) && (yyval.dtype.type != T_ULONG) && (yyval.dtype.type != T_SHORT) && (yyval.dtype.type != T_USHORT) && (yyval.dtype.type != T_SCHAR) && (yyval.dtype.type != T_UCHAR)) { Swig_error(cparse_file,cparse_line,"Type error. Expecting an int\n"); } } break; case 316: #line 4327 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype.val = NewString(yyvsp[0].str); yyval.dtype.type = T_INT; } break; case 317: #line 4338 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype = yyvsp[0].dtype; } break; case 318: #line 4339 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype.val = NewString(yyvsp[0].id); yyval.dtype.type = T_STRING; } break; case 319: #line 4343 "CableSwig/SWIG/Source/CParse/parser.y" { SwigType_push(yyvsp[-2].type,yyvsp[-1].decl.type); yyval.dtype.val = NewStringf("sizeof(%s)",SwigType_str(yyvsp[-2].type,0)); yyval.dtype.type = T_INT; } break; case 320: #line 4348 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype = yyvsp[0].dtype; } break; case 321: #line 4349 "CableSwig/SWIG/Source/CParse/parser.y" { Node *n; yyval.dtype.val = yyvsp[0].type; yyval.dtype.type = T_INT; /* Check if value is in scope */ n = Swig_symbol_clookup(yyvsp[0].type,0); if (n) { if (Getattr(n,"access") && (cplus_mode == CPLUS_PUBLIC)) { Swig_warning(WARN_PARSE_PRIVATE,cparse_file, cparse_line, "'%s' is private in this context.\n", yyvsp[0].type); yyval.dtype.type = T_ERROR; } else { /* A band-aid for enum values used in expressions. */ if (Strcmp(nodeType(n),"enumitem") == 0) { String *q = Swig_symbol_qualified(n); if (q) { yyval.dtype.val = NewStringf("%s::%s", q, Getattr(n,"name")); Delete(q); } } } } } break; case 322: #line 4373 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype.val = NewStringf("(%s)",yyvsp[-1].dtype.val); yyval.dtype.type = yyvsp[-1].dtype.type; } break; case 323: #line 4380 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype = yyvsp[0].dtype; if (yyvsp[0].dtype.type != T_STRING) { yyval.dtype.val = NewStringf("(%s) %s", SwigType_str(yyvsp[-2].dtype.val,0), yyvsp[0].dtype.val); } } break; case 324: #line 4386 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype = yyvsp[0].dtype; if (yyvsp[0].dtype.type != T_STRING) { SwigType_push(yyvsp[-3].dtype.val,yyvsp[-2].type); yyval.dtype.val = NewStringf("(%s) %s", SwigType_str(yyvsp[-3].dtype.val,0), yyvsp[0].dtype.val); } } break; case 325: #line 4393 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype = yyvsp[0].dtype; if (yyvsp[0].dtype.type != T_STRING) { SwigType_add_reference(yyvsp[-3].dtype.val); yyval.dtype.val = NewStringf("(%s) %s", SwigType_str(yyvsp[-3].dtype.val,0), yyvsp[0].dtype.val); } } break; case 326: #line 4400 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype = yyvsp[0].dtype; if (yyvsp[0].dtype.type != T_STRING) { SwigType_push(yyvsp[-4].dtype.val,yyvsp[-3].type); SwigType_add_reference(yyvsp[-4].dtype.val); yyval.dtype.val = NewStringf("(%s) %s", SwigType_str(yyvsp[-4].dtype.val,0), yyvsp[0].dtype.val); } } break; case 327: #line 4410 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype = yyvsp[0].dtype; } break; case 328: #line 4411 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype = yyvsp[0].dtype; } break; case 329: #line 4412 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype = yyvsp[0].dtype; } break; case 330: #line 4413 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype = yyvsp[0].dtype; } break; case 331: #line 4414 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype = yyvsp[0].dtype; } break; case 332: #line 4415 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype = yyvsp[0].dtype; } break; case 333: #line 4416 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype = yyvsp[0].dtype; } break; case 334: #line 4419 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype.val = NewStringf("%s+%s",yyvsp[-2].dtype.val,yyvsp[0].dtype.val); yyval.dtype.type = promote(yyvsp[-2].dtype.type,yyvsp[0].dtype.type); } break; case 335: #line 4423 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype.val = NewStringf("%s-%s",yyvsp[-2].dtype.val,yyvsp[0].dtype.val); yyval.dtype.type = promote(yyvsp[-2].dtype.type,yyvsp[0].dtype.type); } break; case 336: #line 4427 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype.val = NewStringf("%s*%s",yyvsp[-2].dtype.val,yyvsp[0].dtype.val); yyval.dtype.type = promote(yyvsp[-2].dtype.type,yyvsp[0].dtype.type); } break; case 337: #line 4431 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype.val = NewStringf("%s/%s",yyvsp[-2].dtype.val,yyvsp[0].dtype.val); yyval.dtype.type = promote(yyvsp[-2].dtype.type,yyvsp[0].dtype.type); } break; case 338: #line 4435 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype.val = NewStringf("%s&%s",yyvsp[-2].dtype.val,yyvsp[0].dtype.val); yyval.dtype.type = promote(yyvsp[-2].dtype.type,yyvsp[0].dtype.type); } break; case 339: #line 4439 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype.val = NewStringf("%s|%s",yyvsp[-2].dtype.val,yyvsp[0].dtype.val); yyval.dtype.type = promote(yyvsp[-2].dtype.type,yyvsp[0].dtype.type); } break; case 340: #line 4443 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype.val = NewStringf("%s^%s",yyvsp[-2].dtype.val,yyvsp[0].dtype.val); yyval.dtype.type = promote(yyvsp[-2].dtype.type,yyvsp[0].dtype.type); } break; case 341: #line 4447 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype.val = NewStringf("%s<<%s",yyvsp[-2].dtype.val,yyvsp[0].dtype.val); yyval.dtype.type = promote(yyvsp[-2].dtype.type,yyvsp[0].dtype.type); } break; case 342: #line 4451 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype.val = NewStringf("%s>>%s",yyvsp[-2].dtype.val,yyvsp[0].dtype.val); yyval.dtype.type = promote(yyvsp[-2].dtype.type,yyvsp[0].dtype.type); } break; case 343: #line 4455 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype.val = NewStringf("%s&&%s",yyvsp[-2].dtype.val,yyvsp[0].dtype.val); yyval.dtype.type = T_INT; } break; case 344: #line 4459 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype.val = NewStringf("%s||%s",yyvsp[-2].dtype.val,yyvsp[0].dtype.val); yyval.dtype.type = T_INT; } break; case 345: #line 4463 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype.val = NewStringf("-%s",yyvsp[0].dtype.val); yyval.dtype.type = yyvsp[0].dtype.type; } break; case 346: #line 4467 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype.val = NewStringf("+%s",yyvsp[0].dtype.val); yyval.dtype.type = yyvsp[0].dtype.type; } break; case 347: #line 4471 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype.val = NewStringf("~%s",yyvsp[0].dtype.val); yyval.dtype.type = yyvsp[0].dtype.type; } break; case 348: #line 4475 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype.val = NewStringf("!%s",yyvsp[0].dtype.val); yyval.dtype.type = T_INT; } break; case 349: #line 4479 "CableSwig/SWIG/Source/CParse/parser.y" { skip_balanced('(',')'); if (SwigType_istemplate(yyvsp[-1].type)) { yyvsp[-1].type = SwigType_namestr(yyvsp[-1].type); } yyval.dtype.val = NewStringf("%s%s",yyvsp[-1].type,scanner_ccode); Clear(scanner_ccode); yyval.dtype.type = T_INT; } break; case 350: #line 4490 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.bases = yyvsp[0].bases; } break; case 351: #line 4495 "CableSwig/SWIG/Source/CParse/parser.y" { inherit_list = 1; } break; case 352: #line 4495 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.bases = yyvsp[0].bases; inherit_list = 0; } break; case 353: #line 4496 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.bases = 0; } break; case 354: #line 4499 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.bases = NewList(); if (yyvsp[0].node) Append(yyval.bases,yyvsp[0].node); } break; case 355: #line 4504 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.bases = yyvsp[-2].bases; if (yyvsp[0].node) Append(yyval.bases,yyvsp[0].node); } break; case 356: #line 4510 "CableSwig/SWIG/Source/CParse/parser.y" { if (last_cpptype && (Strcmp(last_cpptype,"struct") != 0)) { Swig_warning(WARN_PARSE_NO_ACCESS,cparse_file, cparse_line,"No access specifier given for base class %s (ignored).\n",yyvsp[0].str); yyval.node = (char *) 0; } else { yyval.node = yyvsp[0].str; Setfile(yyval.node,cparse_file); Setline(yyval.node,cparse_line); } } break; case 357: #line 4520 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = 0; if (strcmp(yyvsp[-2].id,"public") == 0) { yyval.node = yyvsp[0].str; Setfile(yyval.node, cparse_file); Setline(yyval.node, cparse_line); } else { Swig_warning(WARN_PARSE_PRIVATE_INHERIT, cparse_file, cparse_line, "%s inheritance ignored.\n", yyvsp[-2].id); } } break; case 358: #line 4532 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.id = (char*)"public"; } break; case 359: #line 4533 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.id = (char*)"private"; } break; case 360: #line 4534 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.id = (char*)"protected"; } break; case 361: #line 4538 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.id = (char*)"class"; if (!inherit_list) last_cpptype = yyval.id; } break; case 362: #line 4542 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.id = (char*)"struct"; if (!inherit_list) last_cpptype = yyval.id; } break; case 363: #line 4546 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.id = (char*)"union"; if (!inherit_list) last_cpptype = yyval.id; } break; case 364: #line 4550 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.id = (char *)"typename"; if (!inherit_list) last_cpptype = yyval.id; } break; case 367: #line 4560 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype.qualifier = yyvsp[0].str; yyval.dtype.throws = 0; } break; case 368: #line 4564 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype.qualifier = 0; yyval.dtype.throws = yyvsp[-1].pl; } break; case 369: #line 4568 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype.qualifier = yyvsp[-4].str; yyval.dtype.throws = yyvsp[-1].pl; } break; case 370: #line 4572 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.dtype.qualifier = 0; yyval.dtype.throws = 0; } break; case 371: #line 4578 "CableSwig/SWIG/Source/CParse/parser.y" { Clear(scanner_ccode); yyval.decl.have_parms = 0; yyval.decl.defarg = 0; yyval.decl.throws = yyvsp[-2].dtype.throws; } break; case 372: #line 4584 "CableSwig/SWIG/Source/CParse/parser.y" { skip_balanced('{','}'); yyval.decl.have_parms = 0; yyval.decl.defarg = 0; yyval.decl.throws = yyvsp[-2].dtype.throws; } break; case 373: #line 4590 "CableSwig/SWIG/Source/CParse/parser.y" { Clear(scanner_ccode); yyval.decl.parms = yyvsp[-2].pl; yyval.decl.have_parms = 1; yyval.decl.defarg = 0; yyval.decl.throws = 0; } break; case 374: #line 4597 "CableSwig/SWIG/Source/CParse/parser.y" { skip_balanced('{','}'); yyval.decl.parms = yyvsp[-2].pl; yyval.decl.have_parms = 1; yyval.decl.defarg = 0; yyval.decl.throws = 0; } break; case 375: #line 4604 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.decl.have_parms = 0; yyval.decl.defarg = yyvsp[-1].dtype.val; yyval.decl.throws = 0; } break; case 380: #line 4619 "CableSwig/SWIG/Source/CParse/parser.y" { skip_balanced('(',')'); Clear(scanner_ccode); } break; case 381: #line 4625 "CableSwig/SWIG/Source/CParse/parser.y" { String *s = NewString(""); SwigType_add_template(s,yyvsp[-1].p); yyval.id = Char(s); scanner_last_id(1); } break; case 382: #line 4631 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.id = (char*)""; } break; case 383: #line 4634 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.id = yyvsp[0].id; } break; case 384: #line 4635 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.id = yyvsp[0].id; } break; case 385: #line 4638 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.id = yyvsp[0].id; } break; case 386: #line 4639 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.id = 0; } break; case 387: #line 4642 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.str = 0; if (!yyval.str) yyval.str = NewStringf("%s%s", yyvsp[-1].str,yyvsp[0].str); Delete(yyvsp[0].str); } break; case 388: #line 4647 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.str = NewStringf("::%s%s",yyvsp[-1].str,yyvsp[0].str); Delete(yyvsp[0].str); } break; case 389: #line 4651 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.str = NewString(yyvsp[0].str); } break; case 390: #line 4654 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.str = NewStringf("::%s",yyvsp[0].str); } break; case 391: #line 4657 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.str = NewString(yyvsp[0].str); } break; case 392: #line 4660 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.str = NewStringf("::%s",yyvsp[0].str); } break; case 393: #line 4665 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.str = NewStringf("::%s%s",yyvsp[-1].str,yyvsp[0].str); Delete(yyvsp[0].str); } break; case 394: #line 4669 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.str = NewStringf("::%s",yyvsp[0].str); } break; case 395: #line 4672 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.str = NewStringf("::%s",yyvsp[0].str); } break; case 396: #line 4679 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.str = NewStringf("::~%s",yyvsp[0].str); } break; case 397: #line 4685 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.str = NewStringf("%s%s",yyvsp[-1].id,yyvsp[0].id); /* if (Len($2)) { scanner_last_id(1); } */ } break; case 398: #line 4694 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.str = 0; if (!yyval.str) yyval.str = NewStringf("%s%s", yyvsp[-1].id,yyvsp[0].str); Delete(yyvsp[0].str); } break; case 399: #line 4699 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.str = NewStringf("::%s%s",yyvsp[-1].id,yyvsp[0].str); Delete(yyvsp[0].str); } break; case 400: #line 4703 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.str = NewString(yyvsp[0].id); } break; case 401: #line 4706 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.str = NewStringf("::%s",yyvsp[0].id); } break; case 402: #line 4709 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.str = NewString(yyvsp[0].str); } break; case 403: #line 4712 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.str = NewStringf("::%s",yyvsp[0].str); } break; case 404: #line 4717 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.str = NewStringf("::%s%s",yyvsp[-1].id,yyvsp[0].str); Delete(yyvsp[0].str); } break; case 405: #line 4721 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.str = NewStringf("::%s",yyvsp[0].id); } break; case 406: #line 4724 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.str = NewStringf("::%s",yyvsp[0].str); } break; case 407: #line 4727 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.str = NewStringf("::~%s",yyvsp[0].id); } break; case 408: #line 4733 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.id = (char *) malloc(strlen(yyvsp[-1].id)+strlen(yyvsp[0].id)+1); strcpy(yyval.id,yyvsp[-1].id); strcat(yyval.id,yyvsp[0].id); } break; case 409: #line 4738 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.id = yyvsp[0].id;} break; case 410: #line 4741 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.str = NewString(yyvsp[0].id); } break; case 411: #line 4744 "CableSwig/SWIG/Source/CParse/parser.y" { skip_balanced('{','}'); yyval.str = NewString(scanner_ccode); } break; case 412: #line 4748 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.str = yyvsp[0].str; } break; case 413: #line 4753 "CableSwig/SWIG/Source/CParse/parser.y" { Hash *n; yyval.node = NewHash(); n = yyvsp[-1].node; while(n) { String *name, *value; name = Getattr(n,"name"); value = Getattr(n,"value"); if (!value) value = (String *) "1"; Setattr(yyval.node,name, value); n = nextSibling(n); } } break; case 414: #line 4766 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = 0; } break; case 415: #line 4770 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = NewHash(); Setattr(yyval.node,"name",yyvsp[-2].id); Setattr(yyval.node,"value",yyvsp[0].id); } break; case 416: #line 4775 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = NewHash(); Setattr(yyval.node,"name",yyvsp[-4].id); Setattr(yyval.node,"value",yyvsp[-2].id); set_nextSibling(yyval.node,yyvsp[0].node); } break; case 417: #line 4781 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = NewHash(); Setattr(yyval.node,"name",yyvsp[0].id); } break; case 418: #line 4785 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.node = NewHash(); Setattr(yyval.node,"name",yyvsp[-2].id); set_nextSibling(yyval.node,yyvsp[0].node); } break; case 419: #line 4792 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.id = yyvsp[0].id; } break; case 420: #line 4795 "CableSwig/SWIG/Source/CParse/parser.y" { yyval.id = Char(yyvsp[0].dtype.val); } break; } /* Line 999 of yacc.c. */ #line 8303 "CableSwig-build/SWIG/Source/CParse/parser.c" yyvsp -= yylen; yyssp -= yylen; YY_STACK_PRINT (yyss, yyssp); *++yyvsp = yyval; /* Now `shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ yyn = yyr1[yyn]; yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) yystate = yytable[yystate]; else yystate = yydefgoto[yyn - YYNTOKENS]; goto yynewstate; /*------------------------------------. | yyerrlab -- here on detecting error | `------------------------------------*/ yyerrlab: /* If not already recovering from an error, report this error. */ if (!yyerrstatus) { ++yynerrs; #if YYERROR_VERBOSE yyn = yypact[yystate]; if (YYPACT_NINF < yyn && yyn < YYLAST) { YYSIZE_T yysize = 0; int yytype = YYTRANSLATE (yychar); char *yymsg; int yyx, yycount; yycount = 0; /* Start YYX at -YYN if negative to avoid negative indexes in YYCHECK. */ for (yyx = yyn < 0 ? -yyn : 0; yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) yysize += yystrlen (yytname[yyx]) + 15, yycount++; yysize += yystrlen ("syntax error, unexpected ") + 1; yysize += yystrlen (yytname[yytype]); yymsg = (char *) YYSTACK_ALLOC (yysize); if (yymsg != 0) { char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); yyp = yystpcpy (yyp, yytname[yytype]); if (yycount < 5) { yycount = 0; for (yyx = yyn < 0 ? -yyn : 0; yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++) if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) { const char *yyq = ! yycount ? ", expecting " : " or "; yyp = yystpcpy (yyp, yyq); yyp = yystpcpy (yyp, yytname[yyx]); yycount++; } } yyerror (yymsg); YYSTACK_FREE (yymsg); } else yyerror ("syntax error; also virtual memory exhausted"); } else #endif /* YYERROR_VERBOSE */ yyerror ("syntax error"); } if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an error, discard it. */ /* Return failure if at end of input. */ if (yychar == YYEOF) { /* Pop the error token. */ YYPOPSTACK; /* Pop the rest of the stack. */ while (yyss < yyssp) { YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); yydestruct (yystos[*yyssp], yyvsp); YYPOPSTACK; } YYABORT; } YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); yydestruct (yytoken, &yylval); yychar = YYEMPTY; } /* Else will try to reuse lookahead token after shifting the error token. */ goto yyerrlab1; /*----------------------------------------------------. | yyerrlab1 -- error raised explicitly by an action. | `----------------------------------------------------*/ yyerrlab1: yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (yyn != YYPACT_NINF) { yyn += YYTERROR; if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) { yyn = yytable[yyn]; if (0 < yyn) break; } } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) YYABORT; YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); yydestruct (yystos[yystate], yyvsp); yyvsp--; yystate = *--yyssp; YY_STACK_PRINT (yyss, yyssp); } if (yyn == YYFINAL) YYACCEPT; YYDPRINTF ((stderr, "Shifting error token, ")); *++yyvsp = yylval; yystate = yyn; goto yynewstate; /*-------------------------------------. | yyacceptlab -- YYACCEPT comes here. | `-------------------------------------*/ yyacceptlab: yyresult = 0; goto yyreturn; /*-----------------------------------. | yyabortlab -- YYABORT comes here. | `-----------------------------------*/ yyabortlab: yyresult = 1; goto yyreturn; #ifndef yyoverflow /*----------------------------------------------. | yyoverflowlab -- parser overflow comes here. | `----------------------------------------------*/ yyoverflowlab: yyerror ("parser stack overflow"); yyresult = 2; /* Fall through. */ #endif yyreturn: #ifndef yyoverflow if (yyss != yyssa) YYSTACK_FREE (yyss); #endif return yyresult; } #line 4802 "CableSwig/SWIG/Source/CParse/parser.y" SwigType *Swig_cparse_type(String *s) { String *ns; ns = NewStringf("%s;",s); Seek(ns,0,SEEK_SET); scanner_file(ns); top = 0; scanner_next_token(PARSETYPE); yyparse(); /* Printf(stdout,"typeparse: '%s' ---> '%s'\n", s, top); */ return top; } Parm *Swig_cparse_parm(String *s) { String *ns; ns = NewStringf("%s;",s); Seek(ns,0,SEEK_SET); scanner_file(ns); top = 0; scanner_next_token(PARSEPARM); yyparse(); /* Printf(stdout,"typeparse: '%s' ---> '%s'\n", s, top); */ return top; } cableswig-0.1.0+git20150808.orig/SWIG/Source/CParse/cscanner.c0000644000175000000620000007615412561312227022170 0ustar stevestaff/* ----------------------------------------------------------------------------- * scanner.cxx * * SWIG1.1 tokenizer. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1998-2000. The University of Chicago * Copyright (C) 1995-1998. The University of Utah and The Regents of the * University of California. * * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ char cvsroot_cscanner_c[] = "/cvsroot/SWIG/Source/CParse/cscanner.c,v 1.7 2004/01/15 22:46:04 cheetah Exp"; #include "cparse.h" #include <../CParse/parser.h> /* Hack include to find correct parser.h */ #include #include #define YYBSIZE 8192 typedef struct InFile { DOHFile *f; int line_number; char *in_file; struct InFile *prev; } InFile; InFile *in_head; DOHFile *LEX_in = 0; static DOHString *header = 0; static DOHString *comment = 0; DOHString *scanner_ccode = 0; /* String containing C code */ static char *yybuffer = 0; static char yytext[YYBSIZE]; static int yylen = 0; int cparse_line = 1; char *cparse_file; int cparse_start_line = 0; static int comment_start; static int scan_init = 0; static int num_brace = 0; static int last_brace = 0; static int last_id = 0; static int rename_active = 0; int cparse_cplusplus; /* ----------------------------------------------------------------------------- * Swig_cparse_cplusplus() * ----------------------------------------------------------------------------- */ void Swig_cparse_cplusplus(int v) { cparse_cplusplus = v; } /* ---------------------------------------------------------------------- * locator() * * Support for locator strings. These are strings of the form * @filename,line,id@ emitted by the SWIG preprocessor. They * are primarily used for macro line number reporting * ---------------------------------------------------------------------- */ typedef struct Locator { char *filename; int line_number; struct Locator *next; } Locator; static Locator *locs = 0; static void scanner_locator(String *loc) { int c; Locator *l; Seek(loc,1,SEEK_SET); c = Getc(loc); if (c == '@') { /* Empty locator. We pop the last location off */ if (locs) { cparse_file = locs->filename; cparse_line = locs->line_number; l = locs->next; free(locs); locs = l; } /* Printf(stderr,"location: %s:%d\n",cparse_file,cparse_line);*/ return; } /* We're going to push a new location */ l = (Locator *) malloc(sizeof(Locator)); l->filename = cparse_file; l->line_number = cparse_line; l->next = locs; locs = l; /* Now, parse the new location out of the locator string */ { String *fn = NewString(""); Putc(c,fn); while ((c = Getc(loc)) != EOF) { if ((c == '@') || (c == ',')) break; Putc(c,fn); } cparse_file = Swig_copy_string(Char(fn)); Clear(fn); cparse_line = 1; /* Get the line number */ while ((c = Getc(loc)) != EOF) { if ((c == '@') || (c == ',')) break; Putc(c,fn); } cparse_line = atoi(Char(fn)); Clear(fn); /* Get the rest of it */ while (( c= Getc(loc)) != EOF) { if (c == '@') break; Putc(c,fn); } /* Printf(stderr,"location: %s:%d\n",cparse_file,cparse_line); */ Delete(fn); } } /************************************************************** * scanner_init() * * Initialize buffers **************************************************************/ void scanner_init() { yybuffer = (char *) malloc(YYBSIZE); scan_init = 1; header = NewString(""); comment = NewString(""); scanner_ccode = NewString(""); } /************************************************************** * scanner_file(FILE *f) * * Start reading from new file **************************************************************/ void scanner_file(DOHFile *f) { InFile *in; in = (InFile *) malloc(sizeof(InFile)); in->f = f; in->in_file = cparse_file; in->line_number = 1; if (!in_head) in->prev = 0; else in->prev = in_head; in_head = in; LEX_in = f; cparse_line = 1; } /************************************************************** * scanner_close() * * Close current input file and go to next **************************************************************/ void scanner_close() { InFile *p; if (!in_head) return; Delete(LEX_in); p = in_head->prev; if (p != 0) { LEX_in = p->f; cparse_line = p->line_number; cparse_file = p->in_file; } else { LEX_in = 0; } free(in_head); in_head = p; } /************************************************************** * char nextchar() * * gets next character from input. * If we're in inlining mode, we actually retrieve a character * from inline_yybuffer instead. **************************************************************/ char nextchar() { int c = 0; while (LEX_in) { c = Getc(LEX_in); if (c == EOF) { scanner_close(); } else { break; } } if (!LEX_in) return 0; if (yylen >= YYBSIZE) { Printf(stderr,"** FATAL ERROR. Buffer overflow in scanner.cxx.\nReport this to swig-dev@cs.uchicago.edu.\n"); exit (EXIT_FAILURE); } yytext[yylen] = c; yylen++; if (c == '\n') { cparse_line++; } return(c); } void retract(int n) { int i; for (i = 0; i < n; i++) { yylen--; if (yylen >= 0) { Ungetc(yytext[yylen],LEX_in); if (yytext[yylen] == '\n') { cparse_line--; } } } if (yylen < 0) yylen = 0; } /************************************************************** * start_inline(char *text, int line) * * This grabs a chunk of text and tries to inline it into * the current file. (This is kind of wild, but cool when * it works). * * If we're already in inlining mode, we will save the code * as a new fragment. **************************************************************/ void start_inline(char *text, int line) { InFile *in; /* Save current state */ in_head->line_number = cparse_line; in_head->in_file = cparse_file; in = (InFile *) malloc(sizeof(InFile)); in->f = NewString(text); Seek(in->f,0,SEEK_SET); in->in_file = Swig_copy_string(cparse_file); in->line_number = line; in->prev = in_head; in_head = in; LEX_in = in->f; cparse_line = line; } /************************************************************** * yycomment(char *, int line) * * Inserts a comment into a documentation entry. **************************************************************/ /* void yycomment(char *a, int b, int c) { } */ /* ----------------------------------------------------------------------------- * skip_balanced() * * Skips a piece of code enclosed in begin/end symbols such as '{...}' or * (...). Ignores symbols inside comments or strings. * ----------------------------------------------------------------------------- */ void skip_balanced(int startchar, int endchar) { char c; int num_levels = 1; int state = 0; char temp[2] = {0,0}; int start_line = cparse_line; Clear(scanner_ccode); Putc(startchar,scanner_ccode); temp[0] = (char) startchar; while (num_levels > 0) { c = nextchar(); if (c == 0) { Swig_error(cparse_file, start_line, "Missing '%c'. Reached end of input.\n", endchar); return; } Putc(c,scanner_ccode); switch(state) { case 0: if (c == startchar) num_levels++; else if (c == endchar) num_levels--; else if (c == '/') state = 10; else if (c == '\"') state = 20; else if (c == '\'') state = 30; break; case 10: if (c == '/') state = 11; else if (c == '*') state = 12; else state = 0; break; case 11: if (c == '\n') state = 0; else state = 11; break; case 12: if (c == '*') state = 13; break; case 13: if (c == '*') state = 13; else if (c == '/') state = 0; else state = 12; break; case 20: if (c == '\"') state = 0; else if (c == '\\') state = 21; break; case 21: state = 20; break; case 30: if (c == '\'') state = 0; else if (c == '\\') state = 31; break; case 31: state = 30; break; default: break; } yylen = 0; } if (endchar == '}') num_brace--; return; } /************************************************************** * void skip_decl(void) * * This tries to skip over an entire declaration. For example * * friend ostream& operator<<(ostream&, const char *s); * * or * friend ostream& operator<<(ostream&, const char *s) { }; * **************************************************************/ void skip_decl(void) { char c; int done = 0; while (!done) { if ((c = nextchar()) == 0) { Swig_error(cparse_file,cparse_line,"Missing semicolon. Reached end of input.\n"); return; } if (c == '{') { last_brace = num_brace; num_brace++; break; } yylen = 0; if (c == ';') done = 1; } if (!done) { while (num_brace > last_brace) { if ((c = nextchar()) == 0) { Swig_error(cparse_file,cparse_line,"Missing '}'. Reached end of input.\n"); return; } if (c == '{') num_brace++; if (c == '}') num_brace--; yylen = 0; } } } /* This function is called when a backslash is found in a string */ static void get_escape() { int result = 0; int state = 0; int c; while(1) { c = nextchar(); if (c == 0) break; switch(state) { case 0: if (c == 'n') { yytext[yylen-1] = '\n'; return; } if (c == 'r') { yytext[yylen-1] = '\r'; return; } if (c == 't') { yytext[yylen-1] = '\t'; return; } if (c == 'a') { yytext[yylen-1] = '\a'; return; } if (c == 'b') { yytext[yylen-1] = '\b'; return; } if (c == 'f') { yytext[yylen-1] = '\f'; return; } if (c == '\\') { yytext[yylen-1] = '\\'; return; } if (c == 'v') { yytext[yylen-1] = '\v'; return; } if (c == 'e') { yytext[yylen-1] = '\033'; return; } if (c == '\'') { yytext[yylen-1] = '\''; return; } if (c == '\"') { yytext[yylen-1] = '\"'; return; } if (c == '\n') { yylen--; return; } if (isdigit(c)) { state = 10; result = (c-'0'); } else if (c == 'x') { state = 20; } else { yytext[yylen-1] = '\\'; yytext[yylen] = c; yylen++; return; } break; case 10: if (!isdigit(c)) { retract(1); yytext[yylen-1] = (char) result; return; } result = (result << 3) + (c - '0'); yylen--; break; case 20: if (!isxdigit(c)) { retract(1); yytext[yylen-1] = (char) result; return; } if (isdigit(c)) result = (result << 4) + (c - '0'); else result = (result << 4) + (10 + tolower(c) - 'a'); yylen--; break; } } return; } /************************************************************** * int yylook() * * Lexical scanner. * See Aho,Sethi, and Ullman, pg. 106 **************************************************************/ int yylook(void) { int state; int c = 0; state = 0; yylen = 0; while(1) { /* printf("State = %d\n", state); */ switch(state) { case 0 : if((c = nextchar()) == 0) return (0); /* Process delimeters */ if (c == '\n') { state = 0; yylen = 0; /* last_id = 0;*/ } else if (isspace(c) || (c=='\\')) { state = 0; yylen = 0; /* last_id = 0; */ } else if ((isalpha(c)) || (c == '_')) state = 7; else if (c == '$') state = 75; /* Look for single character symbols */ else if (c == '(') return (LPAREN); else if (c == ')') return (RPAREN); else if (c == ';') return (SEMI); else if (c == ',') return (COMMA); else if (c == '*') return (STAR); else if (c == '}') { num_brace--; if (num_brace < 0) { Swig_error(cparse_file, cparse_line, "Syntax error. Extraneous '}'\n"); state = 0; num_brace = 0; } else { return (RBRACE); } } else if (c == '{') { last_brace = num_brace; num_brace++; return (LBRACE); } else if (c == '=') return (EQUAL); else if (c == '+') return (PLUS); else if (c == '-') return (MINUS); else if (c == '&') { state = 300; } else if (c == '|') { state = 301; } else if (c == '^') return (XOR); else if (c == '<') state = 60; else if (c == '>') state = 61; else if (c == '~') { return (NOT); } else if (c == '!') return (LNOT); else if (c == '\\') { state = 99; } else if (c == '[') return (LBRACKET); else if (c == ']') return (RBRACKET); /* Look for multi-character sequences */ else if (c == '/') state = 1; /* Comment (maybe) */ else if (c == '\"') state = 2; /* Possibly a string */ else if (c == '#') state = 3; /* CPP */ else if (c == '%') state = 4; /* Directive */ else if (c == '@') state = 4; /* Objective C keyword */ else if (c == ':') state = 5; /* maybe double colon */ else if (c == '0') state = 83; /* An octal or hex value */ else if (c == '\'') state = 9; /* A character constant */ else if (c == '.') state = 100; /* Maybe a number, maybe just a period */ else if (c == '`') { state = 200; /* Back-tick type */ yylen = 0; } else if (isdigit(c)) state = 8; /* A numerical value */ else state = 99; break; case 1: /* Comment block */ if ((c = nextchar()) == 0) return(0); if (c == '/') { comment_start = cparse_line; Clear(comment); state = 10; /* C++ style comment */ } else if (c == '*') { comment_start = cparse_line; Clear(comment); state = 12; /* C style comment */ } else { retract(1); return(SLASH); } break; case 300: /* & or && */ if ((c = nextchar()) == 0) return(AND); if (c == '&') return(LAND); else { retract(1); return(AND); } case 301: /* | or || */ if ((c = nextchar()) == 0) return(OR); if (c == '|') return(LOR); else { retract(1); return(OR); } case 10: /* C++ style comment */ if ((c = nextchar()) == 0) { Swig_error(cparse_file,-1, "Unterminated comment detected.\n"); return 0; } if (c == '\n') { Putc(c,comment); /* Add the comment to documentation */ /* yycomment(Char(comment),comment_start, column_start);*/ yylen = 0; state = 0; } else { state = 10; Putc(c,comment); yylen = 0; } break; case 12: /* C style comment block */ if ((c = nextchar()) == 0) { Swig_error(cparse_file,-1,"Unterminated comment detected.\n"); return 0; } if (c == '*') { state = 13; } else { Putc(c,comment); yylen = 0; state = 12; } break; case 13: /* Still in C style comment */ if ((c = nextchar()) == 0) { Swig_error(cparse_file,-1,"Unterminated comment detected.\n"); return 0; } if (c == '*') { Putc(c,comment); state = 13; } else if (c == '/') { /* Look for locator markers */ { char *loc = Char(comment); if (Len(comment)) { if ((*loc == '@') && (*(loc+Len(comment)-1) == '@')) { /* Locator */ scanner_locator(comment); } } } /* yycomment(Char(comment),comment_start,column_start); */ yylen = 0; state = 0; } else { Putc('*',comment); Putc(c,comment); yylen = 0; state = 12; } break; case 2: /* Processing a string */ if ((c = nextchar()) == 0) { Swig_error(cparse_file,-1, "Unterminated string detected.\n"); return 0; } if (c == '\"') { yytext[yylen-1] = 0; yylval.id = Swig_copy_string(yytext+1); return(STRING); } else if (c == '\\') { yylen--; get_escape(); break; } else state = 2; break; case 3: /* a CPP directive */ if (( c= nextchar()) == 0) return 0; if (c == '\n') { retract(1); yytext[yylen] = 0; yylval.id = yytext; return(POUND); } break; case 4: /* A wrapper generator directive (maybe) */ if (( c= nextchar()) == 0) return 0; if (c == '{') { state = 40; /* Include block */ Clear(header); cparse_start_line = cparse_line; } else if ((isalpha(c)) || (c == '_')) state = 7; else if (c == '}') { Swig_error(cparse_file,cparse_line, "Misplaced %%}.\n"); return 0; } else { retract(1); return(MODULO); } break; case 40: /* Process an include block */ if ((c = nextchar()) == 0) { Swig_error(cparse_file,-1, "Unterminated include block detected.\n"); return 0; } yylen = 0; if (c == '%') state = 41; else { Putc(c,header); yylen = 0; state = 40; } break; case 41: /* Still processing include block */ if ((c = nextchar()) == 0) { Swig_error(cparse_file,-1, "Unterminated include block detected.\n"); return 0; } if (c == '}') { yylval.str = NewString(header); return(HBLOCK); } else { Putc('%',header); Putc(c,header); yylen = 0; state = 40; } break; case 5: /* Maybe a double colon */ if (( c= nextchar()) == 0) return 0; if ( c == ':') { state = 51; } else { retract(1); return COLON; } break; case 51: /* Maybe a ::*, ::~, or :: */ if (( c = nextchar()) == 0) return 0; if (c == '*') { return DSTAR; } else if (c == '~') { return DCNOT; } else if (isspace(c)) { /* Keep scanning ahead. Might be :: * or :: ~ */ } else { retract(1); if (!last_id) { retract(2); return NONID; } else { return DCOLON; } } break; case 60: /* shift operators */ if ((c = nextchar()) == 0) return (0); if (c == '<') return LSHIFT; else { retract(1); return LESSTHAN; } break; case 61: if ((c = nextchar()) == 0) return (0); if (c == '>') return RSHIFT; else { retract(1); return GREATERTHAN; } break; case 7: /* Identifier */ if ((c = nextchar()) == 0) return(0); if (isalnum(c) || (c == '_') || (c == '.') || (c == '$')) { state = 7; } else { retract(1); return(ID); } break; case 75: /* Special identifier $*/ if ((c = nextchar()) == 0) return(0); if (isalnum(c) || (c == '_') || (c == '*') || (c == '&')) { state = 7; } else { retract(1); return(ID); } break; case 8: /* A numerical digit */ if ((c = nextchar()) == 0) return(0); if (c == '.') {state = 81;} else if ((c == 'e') || (c == 'E')) {state = 86;} else if ((c == 'f') || (c == 'F')) { return(NUM_FLOAT); } else if (isdigit(c)) { state = 8;} else if ((c == 'l') || (c == 'L')) { state = 87; } else if ((c == 'u') || (c == 'U')) { state = 88; } else { retract(1); return(NUM_INT); } break; case 81: /* A floating pointer number of some sort */ if ((c = nextchar()) == 0) return(0); if (isdigit(c)) state = 81; else if ((c == 'e') || (c == 'E')) state = 82; else if ((c == 'f') || (c == 'F') || (c == 'l') || (c == 'L')) { return(NUM_FLOAT); } else { retract(1); return(NUM_FLOAT); } break; case 82: if ((c = nextchar()) == 0) return(0); if ((isdigit(c)) || (c == '-') || (c == '+')) state = 86; else { retract(2); yytext[yylen-1] = 0; return(NUM_INT); } break; case 83: /* Might be a hexidecimal or octal number */ if ((c = nextchar()) == 0) return(0); if (isdigit(c)) state = 84; else if ((c == 'x') || (c == 'X')) state = 85; else if (c == '.') state = 81; else if ((c == 'l') || (c == 'L')) { state = 87; } else if ((c == 'u') || (c == 'U')) { state = 88; } else { retract(1); return(NUM_INT); } break; case 84: /* This is an octal number */ if ((c = nextchar()) == 0) return (0); if (isdigit(c)) state = 84; else if ((c == 'l') || (c == 'L')) { state = 87; } else if ((c == 'u') || (c == 'U')) { state = 88; } else { retract(1); return(NUM_INT); } break; case 85: /* This is an hex number */ if ((c = nextchar()) == 0) return (0); if ((isdigit(c)) || (c=='a') || (c=='b') || (c=='c') || (c=='d') || (c=='e') || (c=='f') || (c=='A') || (c=='B') || (c=='C') || (c=='D') || (c=='E') || (c=='F')) state = 85; else if ((c == 'l') || (c == 'L')) { state = 87; } else if ((c == 'u') || (c == 'U')) { state = 88; } else { retract(1); return(NUM_INT); } break; case 86: /* Rest of floating point number */ if ((c = nextchar()) == 0) return (0); if (isdigit(c)) state = 86; else if ((c == 'f') || (c == 'F') || (c == 'l') || (c == 'L')) { return(NUM_FLOAT); } else { retract(1); return(NUM_FLOAT); } /* Parse a character constant. ie. 'a' */ break; case 87 : /* A long integer of some sort */ if ((c = nextchar()) == 0) return (NUM_LONG); if ((c == 'u') || (c == 'U')) { return(NUM_ULONG); } else if ((c == 'l') || (c == 'L')) { state = 870; } else { retract(1); return(NUM_LONG); } break; case 870: if ((c = nextchar()) == 0) return (NUM_LONGLONG); if ((c == 'u') || (c == 'U')) { return (NUM_ULONGLONG); } else { retract(1); return(NUM_LONGLONG); } case 88: /* An unsigned integer of some sort */ if ((c = nextchar()) == 0) return (NUM_UNSIGNED); if ((c == 'l') || (c == 'L')) { state = 880; } else { retract(1); return(NUM_UNSIGNED); } break; case 880: if ((c = nextchar()) == 0) return (NUM_ULONG); if ((c == 'l') || (c == 'L')) return (NUM_ULONGLONG); else { retract(1); return(NUM_ULONG); } case 9: if ((c = nextchar()) == 0) return (0); if (c == '\\') { yylen--; get_escape(); } else if (c == '\'') { yytext[yylen-1] = 0; yylval.str = NewString(yytext+1); if (yylen == 2) { Swig_error(cparse_file, cparse_line, "Empty character constant\n"); } return(CHARCONST); } break; case 100: if ((c = nextchar()) == 0) return (0); if (isdigit(c)) state = 81; else { retract(1); return(PERIOD); } break; case 200: if ((c = nextchar()) == 0) return (0); if (c == '`') { yytext[yylen-1] = 0; yylval.type = NewString(yytext); return(TYPE_RAW); } break; default: Swig_error(cparse_file, cparse_line, "Illegal character '%c'=%d.\n",c,c); state = 0; return(ILLEGAL); } } } static int check_typedef = 0; void scanner_check_typedef() { check_typedef = 1; } void scanner_ignore_typedef() { check_typedef = 0; } void scanner_last_id(int x) { /* printf("Setting last_id = %d\n", x); */ last_id = x; } void scanner_clear_rename() { rename_active = 0; } static int next_token = 0; void scanner_next_token(int tok) { next_token = tok; } /************************************************************** * int yylex() * * Gets the lexene and returns tokens. *************************************************************/ int yylex(void) { int l; if (!scan_init) { scanner_init(); } if (next_token) { l = next_token; next_token = 0; return l; } /* Printf(stdout,"%d\n", last_id);*/ l = yylook(); if (l == NONID) { last_id = 1; } else { last_id = 0; } /* yytext[yylen]= 0; Printf(stdout,"%d '%s' %d\n", l, yytext, last_id); */ /* We got some sort of non-white space object. We set the start_line variable unless it has already been set */ if (!cparse_start_line) { cparse_start_line = cparse_line; } /* Copy the lexene */ yytext[yylen] = 0; switch(l) { case NUM_INT: case NUM_FLOAT: case NUM_ULONG: case NUM_LONG: case NUM_UNSIGNED: case NUM_LONGLONG: case NUM_ULONGLONG: if (l == NUM_INT) yylval.dtype.type = T_INT; if (l == NUM_FLOAT) yylval.dtype.type = T_DOUBLE; if (l == NUM_ULONG) yylval.dtype.type = T_ULONG; if (l == NUM_LONG) yylval.dtype.type = T_LONG; if (l == NUM_UNSIGNED) yylval.dtype.type = T_UINT; if (l == NUM_LONGLONG) yylval.dtype.type = T_LONGLONG; if (l == NUM_ULONGLONG) yylval.dtype.type = T_ULONGLONG; yylval.dtype.val = NewString(yytext); yylval.dtype.bitfield = 0; yylval.dtype.throws = 0; return(l); break; case ID: if (yytext[0] != '%') { /* Look for keywords now */ if (strcmp(yytext,"int") == 0) { yylval.type = NewSwigType(T_INT); return(TYPE_INT); } if (strcmp(yytext,"double") == 0) { yylval.type = NewSwigType(T_DOUBLE); return(TYPE_DOUBLE); } if (strcmp(yytext,"void") == 0) { yylval.type = NewSwigType(T_VOID); return(TYPE_VOID); } if (strcmp(yytext,"char") == 0) { yylval.type = NewSwigType(T_CHAR); return(TYPE_CHAR); } if (strcmp(yytext,"short") == 0) { yylval.type = NewSwigType(T_SHORT); return(TYPE_SHORT); } if (strcmp(yytext,"long") == 0) { yylval.type = NewSwigType(T_LONG); return(TYPE_LONG); } if (strcmp(yytext,"float") == 0) { yylval.type = NewSwigType(T_FLOAT); return(TYPE_FLOAT); } if (strcmp(yytext,"signed") == 0) { yylval.type = NewSwigType(T_INT); return(TYPE_SIGNED); } if (strcmp(yytext,"unsigned") == 0) { yylval.type = NewSwigType(T_UINT); return(TYPE_UNSIGNED); } if (strcmp(yytext,"bool") == 0) { yylval.type = NewSwigType(T_BOOL); return(TYPE_BOOL); } /* C++ keywords */ if (cparse_cplusplus) { if (strcmp(yytext,"class") == 0) return(CLASS); if (strcmp(yytext,"private") == 0) return(PRIVATE); if (strcmp(yytext,"public") == 0) return(PUBLIC); if (strcmp(yytext,"protected") == 0) return(PROTECTED); if (strcmp(yytext,"friend") == 0) return(FRIEND); if (strcmp(yytext,"virtual") == 0) return(VIRTUAL); if (strcmp(yytext,"operator") == 0) { String *s = NewString("operator"); int c; int state = 0; int sticky = 0; int isconversion = 0; int count = 0; while ((c = nextchar())) { if (((c == '(') || (c == ';')) && state) { retract(1); break; } count++; if (!isspace(c)) { if ((!state) && (isalpha(c))) isconversion = 1; if (!state && !sticky) Putc(' ',s); Putc(c,s); sticky = 0; state = 1; } else { if (!sticky) Putc(' ',s); sticky = 1; } } Chop(s); yylval.str = s; while(Replaceall(s,"[ ", "[")); if (isconversion) { String *ns = Swig_symbol_string_qualify(s,0); yylval.str = ns; } if (isconversion && !rename_active) { char *t = Char(s) + 9; if (!((strcmp(t,"new") == 0) || (strcmp(t,"delete") == 0) || (strcmp(t,"new[]") == 0) || (strcmp(t,"delete[]") == 0))) { /* retract(strlen(t));*/ retract(count); return COPERATOR; } } return(OPERATOR); } if (strcmp(yytext,"throw") == 0) return(THROW); if (strcmp(yytext,"try") == 0) return (yylex()); if (strcmp(yytext,"catch") == 0) return (CATCH); if (strcmp(yytext,"inline") == 0) return(yylex()); if (strcmp(yytext,"mutable") == 0) return(yylex()); if (strcmp(yytext,"explicit") == 0) return(yylex()); if (strcmp(yytext,"export") == 0) return(yylex()); if (strcmp(yytext,"typename") == 0) return (TYPENAME); if (strcmp(yytext,"template") == 0) { yylval.ivalue = cparse_line; return(TEMPLATE); } if (strcmp(yytext,"delete") == 0) { return(DELETE); } if (strcmp(yytext,"using") == 0) { return(USING); } if (strcmp(yytext,"namespace") == 0) { return(NAMESPACE); } } else { if (strcmp(yytext,"class") == 0) { Swig_warning(WARN_PARSE_CLASS_KEYWORD,cparse_file,cparse_line, "class keyword used, but not in C++ mode.\n"); } } /* Objective-C keywords */ #ifdef OBJECTIVEC if ((ObjC) && (yytext[0] == '@')) { if (strcmp(yytext,"@interface") == 0) return (OC_INTERFACE); if (strcmp(yytext,"@end") == 0) return (OC_END); if (strcmp(yytext,"@public") == 0) return (OC_PUBLIC); if (strcmp(yytext,"@private") == 0) return (OC_PRIVATE); if (strcmp(yytext,"@protected") == 0) return (OC_PROTECTED); if (strcmp(yytext,"@class") == 0) return(OC_CLASS); if (strcmp(yytext,"@implementation") == 0) return(OC_IMPLEMENT); if (strcmp(yytext,"@protocol") == 0) return(OC_PROTOCOL); } #endif /* Misc keywords */ if (strcmp(yytext,"extern") == 0) return(EXTERN); if (strcmp(yytext,"const") == 0) return(CONST); if (strcmp(yytext,"static") == 0) return(STATIC); if (strcmp(yytext,"struct") == 0) return(STRUCT); if (strcmp(yytext,"union") == 0) return(UNION); if (strcmp(yytext,"enum") == 0) return(ENUM); if (strcmp(yytext,"sizeof") == 0) return(SIZEOF); if (strcmp(yytext,"typedef") == 0) { yylval.ivalue = 0; return(TYPEDEF); } /* Ignored keywords */ if (strcmp(yytext,"volatile") == 0) return(VOLATILE); /* SWIG directives */ } else { if (strcmp(yytext,"%module") == 0) return(MODULE); if (strcmp(yytext,"%insert") == 0) return(INSERT); if (strcmp(yytext,"%name") == 0) return(NAME); if (strcmp(yytext,"%rename") == 0) { rename_active = 1; return(RENAME); } if (strcmp(yytext,"%namewarn") == 0) { rename_active = 1; return (NAMEWARN); } if (strcmp(yytext,"%includefile") == 0) return(INCLUDE); if (strcmp(yytext,"%val") == 0) { Swig_warning(WARN_DEPRECATED_VAL, cparse_file, cparse_line, "%%val directive deprecated (ignored).\n"); return (yylex()); } if (strcmp(yytext,"%out") == 0) { Swig_warning(WARN_DEPRECATED_OUT, cparse_file, cparse_line, "%%out directive deprecated (ignored).\n"); return(yylex()); } if (strcmp(yytext,"%constant") == 0) return(CONSTANT); if (strcmp(yytext,"%typedef") == 0) { yylval.ivalue = 1; return(TYPEDEF); } if (strcmp(yytext,"%native") == 0) return(NATIVE); if (strcmp(yytext,"%pragma") == 0) return(PRAGMA); if (strcmp(yytext,"%extend") == 0) return(EXTEND); if (strcmp(yytext,"%fragment") == 0) return(FRAGMENT); if (strcmp(yytext,"%inline") == 0) return(INLINE); if (strcmp(yytext,"%typemap") == 0) return(TYPEMAP); if (strcmp(yytext,"%feature") == 0) return(FEATURE); if (strcmp(yytext,"%except") == 0) return(EXCEPT); if (strcmp(yytext,"%importfile") == 0) return(IMPORT); if (strcmp(yytext,"%echo") == 0) return(ECHO); if (strcmp(yytext,"%apply") == 0) return(APPLY); if (strcmp(yytext,"%clear") == 0) return(CLEAR); if (strcmp(yytext,"%types") == 0) return(TYPES); if (strcmp(yytext,"%parms") == 0) return(PARMS); if (strcmp(yytext,"%varargs") == 0) return(VARARGS); if (strcmp(yytext,"%template") == 0) return (SWIGTEMPLATE); if (strcmp(yytext,"%warn") == 0) return(WARN); } /* Have an unknown identifier, as a last step, we'll do a typedef lookup on it. */ /* Need to fix this */ if (check_typedef) { if (SwigType_istypedef(yytext)) { yylval.type = NewString(yytext); return(TYPE_TYPEDEF); } } yylval.id = Swig_copy_string(yytext); last_id = 1; return(ID); case POUND: return yylex(); default: return(l); } } cableswig-0.1.0+git20150808.orig/SWIG/Source/CParse/parser.h.in0000644000175000000620000001504312561312227022270 0ustar stevestaff/* A Bison parser, made by GNU Bison 1.875a. */ /* Skeleton parser for Yacc-like parsing with Bison, Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* As a special exception, when this file is copied by Bison into a Bison output file, you may use that output file without restriction. This special exception was added by the Free Software Foundation in version 1.24 of Bison. */ /* Tokens. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { ID = 258, HBLOCK = 259, POUND = 260, STRING = 261, INCLUDE = 262, IMPORT = 263, INSERT = 264, CHARCONST = 265, NUM_INT = 266, NUM_FLOAT = 267, NUM_UNSIGNED = 268, NUM_LONG = 269, NUM_ULONG = 270, NUM_LONGLONG = 271, NUM_ULONGLONG = 272, TYPEDEF = 273, TYPE_INT = 274, TYPE_UNSIGNED = 275, TYPE_SHORT = 276, TYPE_LONG = 277, TYPE_FLOAT = 278, TYPE_DOUBLE = 279, TYPE_CHAR = 280, TYPE_VOID = 281, TYPE_SIGNED = 282, TYPE_BOOL = 283, TYPE_TYPEDEF = 284, TYPE_RAW = 285, LPAREN = 286, RPAREN = 287, COMMA = 288, SEMI = 289, EXTERN = 290, INIT = 291, LBRACE = 292, RBRACE = 293, PERIOD = 294, CONST = 295, VOLATILE = 296, STRUCT = 297, UNION = 298, EQUAL = 299, SIZEOF = 300, MODULE = 301, LBRACKET = 302, RBRACKET = 303, ILLEGAL = 304, CONSTANT = 305, NAME = 306, RENAME = 307, NAMEWARN = 308, EXTEND = 309, PRAGMA = 310, FEATURE = 311, VARARGS = 312, ENUM = 313, CLASS = 314, TYPENAME = 315, PRIVATE = 316, PUBLIC = 317, PROTECTED = 318, COLON = 319, STATIC = 320, VIRTUAL = 321, FRIEND = 322, THROW = 323, CATCH = 324, USING = 325, NAMESPACE = 326, NATIVE = 327, INLINE = 328, TYPEMAP = 329, EXCEPT = 330, ECHO = 331, APPLY = 332, CLEAR = 333, SWIGTEMPLATE = 334, FRAGMENT = 335, WARN = 336, LESSTHAN = 337, GREATERTHAN = 338, MODULO = 339, DELETE = 340, TYPES = 341, PARMS = 342, NONID = 343, DSTAR = 344, DCNOT = 345, TEMPLATE = 346, OPERATOR = 347, COPERATOR = 348, PARSETYPE = 349, PARSEPARM = 350, CAST = 351, LOR = 352, LAND = 353, OR = 354, XOR = 355, AND = 356, RSHIFT = 357, LSHIFT = 358, MINUS = 359, PLUS = 360, SLASH = 361, STAR = 362, LNOT = 363, NOT = 364, UMINUS = 365, DCOLON = 366 }; #endif #define ID 258 #define HBLOCK 259 #define POUND 260 #define STRING 261 #define INCLUDE 262 #define IMPORT 263 #define INSERT 264 #define CHARCONST 265 #define NUM_INT 266 #define NUM_FLOAT 267 #define NUM_UNSIGNED 268 #define NUM_LONG 269 #define NUM_ULONG 270 #define NUM_LONGLONG 271 #define NUM_ULONGLONG 272 #define TYPEDEF 273 #define TYPE_INT 274 #define TYPE_UNSIGNED 275 #define TYPE_SHORT 276 #define TYPE_LONG 277 #define TYPE_FLOAT 278 #define TYPE_DOUBLE 279 #define TYPE_CHAR 280 #define TYPE_VOID 281 #define TYPE_SIGNED 282 #define TYPE_BOOL 283 #define TYPE_TYPEDEF 284 #define TYPE_RAW 285 #define LPAREN 286 #define RPAREN 287 #define COMMA 288 #define SEMI 289 #define EXTERN 290 #define INIT 291 #define LBRACE 292 #define RBRACE 293 #define PERIOD 294 #define CONST 295 #define VOLATILE 296 #define STRUCT 297 #define UNION 298 #define EQUAL 299 #define SIZEOF 300 #define MODULE 301 #define LBRACKET 302 #define RBRACKET 303 #define ILLEGAL 304 #define CONSTANT 305 #define NAME 306 #define RENAME 307 #define NAMEWARN 308 #define EXTEND 309 #define PRAGMA 310 #define FEATURE 311 #define VARARGS 312 #define ENUM 313 #define CLASS 314 #define TYPENAME 315 #define PRIVATE 316 #define PUBLIC 317 #define PROTECTED 318 #define COLON 319 #define STATIC 320 #define VIRTUAL 321 #define FRIEND 322 #define THROW 323 #define CATCH 324 #define USING 325 #define NAMESPACE 326 #define NATIVE 327 #define INLINE 328 #define TYPEMAP 329 #define EXCEPT 330 #define ECHO 331 #define APPLY 332 #define CLEAR 333 #define SWIGTEMPLATE 334 #define FRAGMENT 335 #define WARN 336 #define LESSTHAN 337 #define GREATERTHAN 338 #define MODULO 339 #define DELETE 340 #define TYPES 341 #define PARMS 342 #define NONID 343 #define DSTAR 344 #define DCNOT 345 #define TEMPLATE 346 #define OPERATOR 347 #define COPERATOR 348 #define PARSETYPE 349 #define PARSEPARM 350 #define CAST 351 #define LOR 352 #define LAND 353 #define OR 354 #define XOR 355 #define AND 356 #define RSHIFT 357 #define LSHIFT 358 #define MINUS 359 #define PLUS 360 #define SLASH 361 #define STAR 362 #define LNOT 363 #define NOT 364 #define UMINUS 365 #define DCOLON 366 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) #line 823 "CableSwig/SWIG/Source/CParse/parser.y" typedef union YYSTYPE { char *id; List *bases; struct Define { String *val; String *rawval; int type; String *qualifier; String *bitfield; Parm *throws; } dtype; struct { char *type; char *filename; int line; } loc; struct { char *id; SwigType *type; String *defarg; ParmList *parms; short have_parms; ParmList *throws; } decl; Parm *tparms; struct { String *op; Hash *kwargs; } tmap; struct { String *type; String *us; } ptype; SwigType *type; String *str; Parm *p; ParmList *pl; int ivalue; Node *node; } YYSTYPE; /* Line 1240 of yacc.c. */ #line 300 "CableSwig-build/SWIG/Source/CParse/parser.h" # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 # define YYSTYPE_IS_TRIVIAL 1 #endif extern YYSTYPE yylval; cableswig-0.1.0+git20150808.orig/SWIG/debian/0002755000175000000620000000000012561312227017022 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/debian/dirs0000644000175000000620000000010412561312227017677 0ustar stevestaffusr/bin usr/lib #usr/share/swig1.3-pnet #usr/share/doc/swig1.3-pnet cableswig-0.1.0+git20150808.orig/SWIG/debian/postinst0000755000175000000620000000233412561312227020633 0ustar stevestaff#! /bin/sh # postinst script for swig1.3 # # see: dh_installdeb(1) set -e # summary of how this script can be called: # * `configure' # * `abort-upgrade' # * `abort-remove' `in-favour' # # * `abort-deconfigure' `in-favour' # `removing' # # for details, see /usr/share/doc/packaging-manual/ # # quoting from the policy: # Any necessary prompting should almost always be confined to the # post-installation script, and should be protected with a conditional # so that unnecessary prompting doesn't happen if a package's # installation fails and the `postinst' is called with `abort-upgrade', # `abort-remove' or `abort-deconfigure'. case "$1" in configure) ;; abort-upgrade|abort-remove|abort-deconfigure) ;; *) echo "postinst called with unknown argument \`$1'" >&2 exit 0 ;; esac # dh_installdeb will replace this with shell code automatically # generated by other debhelper scripts. #DEBHELPER# exit 0 cableswig-0.1.0+git20150808.orig/SWIG/debian/substvars0000644000175000000620000000007212561312227020776 0ustar stevestaffshlibs:Depends=libc6 (>= 2.2.3-1), libstdc++2.10-glibc2.2 cableswig-0.1.0+git20150808.orig/SWIG/debian/copyright0000644000175000000620000000706712561312227020765 0ustar stevestaffThis is SWIG, written and maintained by: Dave Beazley (beazley@cs.uchicago.edu) (SWIG core) Loic Dachary (loic@ceic.com) (Perl5) Harco de Hilster (Harco.de.Hilster@ATComputing.nl) (Java) Thien-Thi Nguyen (ttn@glug.org) (Testing/Misc) Masaki Fukushima (fukusima@goto.info.waseda.ac.jp) (Ruby) Matthias Koeppe (mkoeppe@mail.math.uni-magdeburg.de) (Guile/MzScheme) Past contributors: Dustin Mitchell, Ian Cooke, Catalin Dumitrescu, Baran Kovuk, Gary Holt, David Fletcher, Oleg Tolmatcev. SWIG can be obtained by anonymous CVS: cvs -d :pserver:cvs@swig.cs.uchicago.edu:/cvsroot co SWIG SWIG is distributed under the following terms: I. Copyright (C) 1998-2000 The University of Chicago Permission is hereby granted, without written agreement and without license or royalty fees, to use, copy, modify, and distribute this software and its documentation for any purpose, provided that (1) The above copyright notice and the following two paragraphs appear in all copies of the source code and (2) redistributions including binaries reproduces these notices in the supporting documentation. Substantial modifications to this software may be copyrighted by their authors and need not follow the licensing terms described here, provided that the new terms are clearly indicated in all files where they apply. IN NO EVENT SHALL THE AUTHOR, THE UNIVERSITY OF CHICAGO, OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHOR AND THE UNIVERSITY OF CHICAGO SPECIFICALLY DISCLAIM ANY WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. II. Copyright (c) 1995-1998 The University of Utah and the Regents of the University of California All Rights Reserved Permission is hereby granted, without written agreement and without license or royalty fees, to use, copy, modify, and distribute this software and its documentation for any purpose, provided that (1) The above copyright notice and the following two paragraphs appear in all copies of the source code and (2) redistributions including binaries reproduces these notices in the supporting documentation. Substantial modifications to this software may be copyrighted by their authors and need not follow the licensing terms described here, provided that the new terms are clearly indicated in all files where they apply. IN NO EVENT SHALL THE AUTHOR, THE UNIVERSITY OF CALIFORNIA, THE UNIVERSITY OF UTAH OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHOR, THE UNIVERSITY OF CALIFORNIA, AND THE UNIVERSITY OF UTAH SPECIFICALLY DISCLAIM ANY WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. cableswig-0.1.0+git20150808.orig/SWIG/debian/.cvsignore0000644000175000000620000000001412561312227021013 0ustar stevestaff*.debhelper cableswig-0.1.0+git20150808.orig/SWIG/debian/docs0000644000175000000620000000177012561312227017700 0ustar stevestaffREADME TODO ANNOUNCE CHANGES NEW Doc/Devel/engineering.html Doc/Devel/index.html Doc/Devel/internals.html Doc/Devel/migrate.txt Doc/README Doc/Manual/About.html Doc/Manual/Advanced.html Doc/Manual/Arguments.html Doc/Manual/Chicken.html Doc/Manual/Contents.html Doc/Manual/Copyright.html Doc/Manual/Customization.html Doc/Manual/Documentation.html Doc/Manual/Extending.html Doc/Manual/Guile.html Doc/Manual/Introduction.html Doc/Manual/Java.html Doc/Manual/Library.html Doc/Manual/Ocaml.html Doc/Manual/Perl5.html Doc/Manual/Php.html Doc/Manual/Preface.html Doc/Manual/Preprocessor.html Doc/Manual/Python.html Doc/Manual/README Doc/Manual/Ruby.html Doc/Manual/SWIG.html Doc/Manual/SWIGPlus.html Doc/Manual/Scripting.html Doc/Manual/Tcl.html Doc/Manual/Typemaps.html Doc/Manual/Varargs.html Doc/Manual/Warnings.html Doc/Manual/Windows.html Doc/Manual/ch11.1.png Doc/Manual/ch11.2.png Doc/Manual/ch11.3.png Doc/Manual/ch12.1.png Doc/Manual/ch2.1.png Doc/Manual/ch9.table.2.png Doc/Manual/chapters Doc/Manual/index.html cableswig-0.1.0+git20150808.orig/SWIG/debian/control0000644000175000000620000000131112561312227020417 0ustar stevestaffSource: swig1.3 Section: interpreters Priority: optional Maintainer: Matthias Koeppe Build-Depends: debhelper (>> 3.0.0), libguile-dev, python-dev, perl, ruby-dev, ruby, tcl8.0-dev Standards-Version: 3.5.2 Package: swig1.3 Architecture: any Depends: ${shlibs:Depends} Description: Generate scripting interfaces to C/C++ code SWIG (Simplified Wrapper and Interface Generator) is a system for automatically generating wrapper/glue code for several languages (Tcl, Python, Perl, Ruby, MzScheme, Guile, Java) from annotated C or C++ header files. This package represents some point in the SWIG 1.3 development series. It is not fully compatible with the SWIG 1.1 release. cableswig-0.1.0+git20150808.orig/SWIG/debian/changelog0000644000175000000620000000363212561312227020676 0ustar stevestaffswig1.3 (1.3.pnet) unstable; urgency=low * Support for dotgnu pnet under debian -- James Michael DuPont Wed, 12 Mar 2003 20:55:53 +0200 swig1.3 (1.3.a5+patches-9) unstable; urgency=low * New upstream version -- Matthias Koeppe Wed, 6 Jun 2001 16:11:41 +0200 swig1.3 (1.3.a5+patches-8) unstable; urgency=low * New upstream version -- Matthias Koeppe Wed, 6 Jun 2001 14:06:51 +0200 swig1.3 (1.3.a5+patches-7) unstable; urgency=low * New upstream version -- Matthias Koeppe Wed, 6 Jun 2001 13:34:44 +0200 swig1.3 (1.3.a5+patches-6) unstable; urgency=low * New upstream version -- Matthias Koeppe Tue, 5 Jun 2001 14:11:52 +0200 swig1.3 (1.3.a5+patches-5) unstable; urgency=low * New upstream version. -- Matthias Koeppe Fri, 1 Jun 2001 18:48:59 +0200 swig1.3 (1.3.a5+patches-4) unstable; urgency=low * Fix hard-coded location of swig library. Added build-dependency on tcl-dev. -- Matthias Koeppe Fri, 1 Jun 2001 13:32:34 +0200 swig1.3 (1.3.a5+patches-3) unstable; urgency=low * New upstream version -- Matthias Koeppe Thu, 31 May 2001 13:15:20 +0200 swig1.3 (1.3.a5+patches-2) unstable; urgency=low * Binary and manpage now include version number, to improve cooperation with the "swig" package. -- Matthias Koeppe Tue, 29 May 2001 15:15:07 +0200 swig1.3 (1.3.a5+patches-1) unstable; urgency=low * First release. -- Matthias Koeppe Sat, 20 Nov 1999 01:09:11 +0100 Local variables: mode: debian-changelog add-log-mailing-address: "mkoeppe@mail.math.uni-magdeburg.de" End:cableswig-0.1.0+git20150808.orig/SWIG/debian/rules0000755000175000000620000000273612561312227020110 0ustar stevestaff#!/usr/bin/make -f # Sample debian/rules that uses debhelper. # GNU copyright 1997 to 1999 by Joey Hess. # Uncomment this to turn on verbose mode. export DH_VERBOSE=1 # This is the debhelper compatability version to use. export DH_COMPAT=3 configure: configure-stamp configure-stamp: dh_testdir ./autogen-debian.sh ./configure --prefix=/usr --mandir=/usr/share/man --with-swiglibdir=/usr/share/swig1.3 --with-release-suffix=-1.3 touch configure-stamp build: configure-stamp build-stamp build-stamp: dh_testdir $(MAKE) $(MAKE) runtime touch build-stamp clean: dh_testdir dh_testroot rm -f build-stamp configure-stamp -$(MAKE) clean dh_clean install: build dh_testdir dh_testroot dh_clean -k dh_installdirs $(MAKE) install DESTDIR=$(CURDIR)/debian/swig1.3 # Build architecture-independent files here. binary-indep: build install # We have nothing to do by default. # Build architecture-dependent files here. binary-arch: build install dh_testdir dh_testroot # dh_installdebconf dh_installdocs dh_installexamples dh_installmenu # dh_installlogrotate # dh_installemacsen # dh_installpam # dh_installmime # dh_installinit # dh_installcron dh_installman dh_installinfo dh_undocumented swig-1.3.1 # dh_installchangelogs CHANGES dh_link dh_strip dh_compress dh_fixperms dh_makeshlibs dh_installdeb # dh_perl dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install configure cableswig-0.1.0+git20150808.orig/SWIG/debian/README0000644000175000000620000000150312561312227017677 0ustar stevestaffThe Debian Package swig1.3 -------------------------- This is SWIG 1.3 (Simplified Wrapper and Interface Generator) packaged for Debian GNU/Linux. SWIG 1.3 is not fully compatible with SWIG 1.1. It is a re-development effort of SWIG 1.1 (which was written in C++) in ANSI C. The 1.3 series is in "alpha" state. Release 1.3a5 was rather stable, and it should be used for new projects rather than the ancient release 1.1p5. See the file `NEW' for information on the new features of the 1.3 series. This Debian package derives from the release 1.3a5 and corresponds to the "mkoeppe-1-3-a5-patches" branch of the SWIG CVS repository. It fixes several bugs and enhances several language backends. See the top of the file `CHANGES' for details. Matthias Koeppe , Mon, 28 May 2001 15:08:55 +0200 cableswig-0.1.0+git20150808.orig/SWIG/Makefile.in0000644000175000000620000003001112561312227017636 0ustar stevestaff####################################################################### # /cvsroot/SWIG/Makefile.in,v 1.77 2003/12/09 22:06:58 cheetah Exp ####################################################################### prefix = @prefix@ exec_prefix = @exec_prefix@ srcdir = @srcdir@ ############################################################################## # Compiler and system configuration ############################################################################## SHELL = /bin/sh SWIG_LIB = @swig_lib@ BIN_DIR = @bindir@ TARGET = swig@release_suffix@@EXEEXT@ SOURCE = Source RUNTIME = Runtime swig: source swig.spec source: @cd $(SOURCE); $(MAKE) runtime: @cd $(RUNTIME); $(MAKE) swig.spec: $(srcdir)/swig.spec.in config.status @CONFIG_HEADERS= CONFIG_LINKS= CONFIG_FILES=swig.spec $(SHELL) ./config.status .PHONY: source runtime ##################################################################### # All the languages SWIG speaks (when it wants to) ##################################################################### skip-tcl = test -n "@SKIP_TCL@" skip-perl5 = test -n "@SKIP_PERL5@" skip-python = test -n "@SKIP_PYTHON@" skip-java = test -n "@SKIP_JAVA@" skip-guilescm = test -n "@SKIP_GUILESCM@" skip-guile = test -n "@SKIP_GUILE@" skip-mzscheme = test -n "@SKIP_MZSCHEME@" skip-ruby = test -n "@SKIP_RUBY@" skip-php4 = test -n "@SKIP_PHP4@" skip-ocaml = test -n "@SKIP_OCAML@" skip-pike = test -n "@SKIP_PIKE@" skip-chicken = test -n "@SKIP_CHICKEN@" skip-csharp = test -n "@SKIP_CSHARP@" ##################################################################### # CHECK ##################################################################### ACTION = check chk-set-swiglib = SWIG_LIB=@ROOT_DIR@/Lib chk-set-runtimelib = RUNTIMEDIR=@ROOT_DIR@/$(RUNTIME)/.libs chk-set-swig = SWIG=@ROOT_DIR@/$(TARGET) chk-set-env = $(chk-set-swiglib) $(chk-set-swig) $(chk-set-runtimelib) chk = $(MAKE) -k -s $(chk-set-env) $(ACTION) check-aliveness: test -x ./$(TARGET) ./$(TARGET) -version ./$(TARGET) -help @$(skip-tcl) || ./$(TARGET) -tcl -help @$(skip-perl5) || ./$(TARGET) -perl -help @$(skip-python) || ./$(TARGET) -python -help @$(skip-java) || ./$(TARGET) -java -help @$(skip-guile) || ./$(TARGET) -guile -help @$(skip-mzscheme) || ./$(TARGET) -mzscheme -help @$(skip-ruby) || ./$(TARGET) -ruby -help @$(skip-ocaml) || ./$(TARGET) -ocaml -help @$(skip-php4) || ./$(TARGET) -php4 -help @$(skip-pike) || ./$(TARGET) -pike -help @$(skip-chicken) || ./$(TARGET) -chicken -help @$(skip-csharp) || ./$(TARGET) -csharp -help check-examples: \ check-tcl-examples \ check-perl5-examples \ check-python-examples \ check-java-examples \ check-guile-examples \ check-mzscheme-examples \ check-ruby-examples \ check-ocaml-examples \ check-php4-examples \ check-pike-examples \ check-chicken-examples \ check-csharp-examples check-%-examples: @passed=true; \ dir="Examples/$*"; \ if $(skip-$*); then \ echo skipping $* $(ACTION); \ elif [ ! -f $$dir/check.list ]; then \ echo skipping $* $(ACTION) "(no $$dir/check.list)"; \ else \ all=`sed '/^#/d' $$dir/check.list`; \ for a in $$all; do \ echo $(ACTION)ing $$dir/$$a; \ (cd $$dir/$$a && $(chk)) \ || passed=false; \ done; \ fi; \ test $$passed = true # Checks testcases in the test-suite excluding those which are known to be broken check-test-suite: \ check-tcl-test-suite \ check-perl5-test-suite \ check-python-test-suite \ check-java-test-suite \ check-guilescm-test-suite \ check-guile-test-suite \ check-mzscheme-test-suite \ check-ruby-test-suite \ check-ocaml-test-suite \ check-php4-test-suite \ check-pike-test-suite \ check-csharp-test-suite \ # check-chicken-test-suite check-%-test-suite: @passed=true; \ dir="Examples/test-suite/$*"; \ if $(skip-$*); then \ echo skipping $* test-suite $(ACTION); \ elif [ ! -d $$dir ]; then \ echo warning: cannot $(ACTION) $* test-suite "(no dir $$dir)";\ else \ (cd $$dir && $(MAKE) -k -s $(ACTION)) \ || passed=false; \ fi; \ test $$passed = true gifplot-library: @echo $(ACTION)ing Examples/GIFPlot/Lib @cd Examples/GIFPlot/Lib ; $(MAKE) -k -s $(ACTION) check-gifplot: \ check-tcl-gifplot \ check-perl5-gifplot \ check-python-gifplot \ check-java-gifplot \ check-guile-gifplot \ check-mzscheme-gifplot \ check-ruby-gifplot \ check-ocaml-gifplot \ check-php4-gifplot \ check-pike-gifplot \ check-chicken-gifplot \ # check-csharp-gifplot check-%-gifplot: gifplot-library @passed=true; \ up=`$(srcdir)/Tools/capitalize $*`; \ dir="Examples/GIFPlot/$$up"; \ if $(skip-$*); then \ echo skipping $$up $(ACTION); \ elif [ ! -f $$dir/check.list ]; then \ echo skipping $$up $(ACTION) "(no $$dir/check.list)"; \ else \ all=`sed '/^#/d' $$dir/check.list`; \ for a in $$all; do \ echo $(ACTION)ing $$dir/$$a; \ (cd $$dir/$$a && $(chk)) \ || passed=false; \ done; \ fi; \ test $$passed = true check: check-aliveness check-examples check-gifplot check-test-suite ##################################################################### # ALL TEST SUITE: Known broken and broken testcases in the test-suite ##################################################################### all-test-suite: \ all-tcl-test-suite \ all-perl5-test-suite \ all-python-test-suite \ all-java-test-suite \ all-guilescm-test-suite \ all-guile-test-suite \ all-mzscheme-test-suite \ all-ruby-test-suite \ all-ocaml-test-suite \ all-php4-test-suite \ all-pike-test-suite \ all-csharp-test-suite \ # all-chicken-test-suite all-%-test-suite: @$(MAKE) -k -s check-$*-test-suite ACTION=all ##################################################################### # BROKEN: Known broken tests in the test-suite ##################################################################### broken-test-suite: \ broken-tcl-test-suite \ broken-perl5-test-suite \ broken-python-test-suite \ broken-java-test-suite \ broken-guilescm-test-suite \ broken-guile-test-suite \ broken-mzscheme-test-suite \ broken-ruby-test-suite \ broken-ocaml-test-suite \ broken-php4-test-suite \ broken-pike-test-suite \ broken-csharp-test-suite \ # broken-chicken-test-suite broken-%-test-suite: @$(MAKE) -k -s check-$*-test-suite ACTION=broken ##################################################################### # CLEAN ##################################################################### clean: clean-objects clean-examples clean-gifplot clean-test-suite clean-objects: clean-source clean-runtime clean-source: @echo cleaning Source @cd $(SOURCE); $(MAKE) -s clean @rm -f $(TARGET) clean-runtime: @echo cleaning Runtime @cd $(RUNTIME); $(MAKE) -s clean clean-examples: @$(MAKE) -k -s check-examples ACTION=clean clean-gifplot: @$(MAKE) -k -s check-gifplot ACTION=clean clean-test-suite: @echo cleaning Examples/test-suite @$(MAKE) -k -s check-test-suite ACTION=clean clean-%-examples: @$(MAKE) -k -s check-$*-examples ACTION=clean clean-%-test-suite: @$(MAKE) -k -s check-$*-test-suite ACTION=clean clean-%-gifplot: @$(MAKE) -k -s check-$*-gifplot ACTION=clean ##################################################################### # DISTCLEAN ##################################################################### DISTCLEAN-DEAD = config.status config.log config.cache swig.spec Makefile mkmf.log libtool distclean: distclean-objects clean-examples clean-gifplot distclean-test-suite distclean-dead distclean-objects: distclean-source distclean-runtime distclean-source: @echo dist cleaning Source @cd $(SOURCE); $(MAKE) -s distclean @rm -f $(TARGET) distclean-runtime: @echo dist cleaning Runtime @cd $(RUNTIME); $(MAKE) -s distclean distclean-test-suite: @echo dist cleaning Examples/test-suite @$(MAKE) -k -s noskip-test-suite ACTION=distclean noskip-test-suite: \ noskip-tcl-test-suite \ noskip-perl5-test-suite \ noskip-python-test-suite \ noskip-java-test-suite \ noskip-guilescm-test-suite \ noskip-guile-test-suite \ noskip-mzscheme-test-suite \ noskip-ruby-test-suite \ noskip-ocaml-test-suite \ noskip-php4-test-suite \ noskip-pike-test-suite \ noskip-csharp-test-suite \ noskip-chicken-test-suite noskip-%-test-suite: dir="Examples/test-suite/$*"; \ if [ ! -d $$dir ]; then \ echo warning: cannot $(ACTION) $* test-suite "(no dir $$dir)";\ else \ (cd $$dir && $(MAKE) -k -s $(ACTION)) \ fi; distclean-dead: rm -f $(DISTCLEAN-DEAD) ##################################################################### # TARGETS: install & friends ##################################################################### INSTALL = @abs_srcdir@/Tools/config/install-sh -c INSTALL_DATA = ${INSTALL} -m 644 INSTALL_PROGRAM = ${INSTALL} -m 755 MKINSTDIRS = @abs_srcdir@/Tools/config/install-sh -m 0755 -d M4_SOURCE_DIR = @abs_srcdir@/Tools/config M4_INSTALL_DIR = @datadir@/aclocal install: install-main install-lib install-m4 @echo "Installation complete" install-main: @echo "Installing SWIG executable" @$(MKINSTDIRS) $(DESTDIR)$(BIN_DIR) @echo "Installing $(BIN_DIR)/$(TARGET)" @$(INSTALL_PROGRAM) $(TARGET) $(DESTDIR)$(BIN_DIR)/$(TARGET) lib-languages = tcl perl5 python guile java mzscheme ruby php4 ocaml \ pike chicken csharp install-lib: @echo "Installing the SWIG library" @$(MKINSTDIRS) $(DESTDIR)$(SWIG_LIB) @cd $(srcdir)/Lib; for i in *.i *.swg; \ do \ echo "Installing $(DESTDIR)$(SWIG_LIB)/$$i"; \ $(INSTALL_DATA) $$i $(DESTDIR)$(SWIG_LIB)/$$i; \ done; @for lang in $(lib-languages); \ do \ dst=$(DESTDIR)$(SWIG_LIB)/$$lang; \ $(MKINSTDIRS) $$dst; \ ( cd $(srcdir)/Lib/$$lang; \ doti="`ls *.i 2>/dev/null`"; \ dotswg="`ls *.swg 2>/dev/null`"; \ if [ -f extra-install.list ]; then \ extra="`sed '/^#/d' extra-install.list`"; \ fi; \ files="`echo $$doti $$dotswg $$extra`"; \ if [ x"$$files" = x ]; then \ echo "Installing nothing from Lib/$$lang"; \ else for file in $$doti $$dotswg $$extra; \ do \ echo "Installing $$dst/$$file"; \ $(INSTALL_DATA) $$file $$dst/$$file; \ done; \ fi ); \ done install-runtime: @cd $(RUNTIME); $(MAKE) install install-m4: @echo "Installing M4 macros" @$(MKINSTDIRS) $(M4_INSTALL_DIR) @echo "Installing $(M4_INSTALL_DIR)/swig.m4" @$(INSTALL_DATA) $(M4_SOURCE_DIR)/swig.m4 $(M4_INSTALL_DIR)/swig.m4 ##################################################################### # TARGETS: uninstall & friends ##################################################################### uninstall: uninstall-main uninstall-lib uninstall-m4 @echo "Uninstall complete" uninstall-main: @echo "Uninstalling $(BIN_DIR)/$(TARGET)" rm -f $(DESTDIR)$(BIN_DIR)/$(TARGET); uninstall-lib: @echo "Uninstalling the SWIG library" rm -rf $(DESTDIR)$(SWIG_LIB)/; uninstall-runtime: @cd $(RUNTIME); $(MAKE) uninstall uninstall-m4: @echo "Uninstalling $(M4_INSTALL_DIR)/swig.m4" rm -f $(M4_INSTALL_DIR)/swig.m4; ############################################################################ # DIST and other maintenance ############################################################################ # distribution directory dd = @PACKAGE_NAME@-@PACKAGE_VERSION@ srpm = @PACKAGE_NAME@-@PACKAGE_VERSION@ dist: @echo 'Dave, what do you want to do w/ "make dist"?' @echo 'See Makefile.in target "dist-suggested" for an idea.' @echo ' --thi' false dist-suggested: rm -rf $(dd) $(dd).tar.gz cvs export -d $(dd) -r HEAD SWIG tar cf - $(dd) | gzip --best > $(dd).tar.gz rm -rf $(dd) srcrpm: swig.spec rm -fr $(srpm) $(srpm).src.rpm cvs export -d $(srpm) -r HEAD SWIG cp swig.spec $(srpm) tar -cf - $(srpm) | gzip --best > $(srpm).tar.gz rm -fr $(srpm) rpmbuild -ts $(srpm).tar.gz # Makefile ends here cableswig-0.1.0+git20150808.orig/SWIG/INSTALL0000644000175000000620000002200512561312227016626 0ustar stevestaffBasic Installation ================== These are generic installation instructions. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves the results of its tests to speed up reconfiguring. (Caching is disabled by default to prevent problems with accidental use of stale cache files.) If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If you are using the cache, and at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create `configure' by a program called `autoconf'. You only need `configure.ac' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes awhile. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. Run `./configure --help' for details on some of the pertinent environment variables. You can give `configure' initial values for variables by setting them in the environment. You can do that on the command line like this: ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix *Note Environment Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. If you have to use a `make' that does not support the `VPATH' variable, you have to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. Installation Names ================== By default, `make install' will install the package's files in `/usr/local/bin', `/usr/local/man', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PATH'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec-prefix=PATH', the package will use PATH as the prefix for installing programs and libraries. Documentation and other data files will still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=PATH' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Specifying the System Type ========================== There may be some features `configure' cannot figure out automatically, but needs to determine by the type of host the package will run on. Usually `configure' can figure that out, but if it prints a message saying it cannot guess the host type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the host type. If you are _building_ compiler tools for cross-compiling, you should use the `--target=TYPE' option to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the host platform (i.e., that on which the generated programs will eventually be run) with `--host=TYPE'. In this case, you should also specify the build platform with `--build=TYPE', because, in this case, it may not be possible to guess the build platform (it sometimes involves compiling and running simple test programs, and this can't be done if the compiler is a cross compiler). Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Environment Variables ===================== Variables not defined in a site shell script can be set in the environment passed to configure. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc will cause the specified gcc to be used as the C compiler (unless it is overridden in the site shell script). `configure' Invocation ====================== `configure' recognizes the following options to control how it operates. `--help' `-h' Print a summary of the options to `configure', and exit. `--version' `-V' Print the version of Autoconf used to generate the `configure' script, and exit. `--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally `config.cache'. FILE defaults to `/dev/null' to disable caching. `--config-cache' `-C' Alias for `--cache-file=config.cache'. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. cableswig-0.1.0+git20150808.orig/SWIG/.cvsignore0000644000175000000620000000017612561312226017601 0ustar stevestaffaclocal.m4 config.* libtool Makefile swig swig.exe swig.spec *.tar.gz configure autom4te.cache .gdbinit mkmf.log preinst-swig cableswig-0.1.0+git20150808.orig/SWIG/swig.spec.in0000644000175000000620000000532712561312227020037 0ustar stevestaff# You can make the package from CVS by something like: # tar -cvzf swig-1.3.11cvs.tar.gz SWIG-1.3.11cvs && rpm -tb swig-1.3.11cvs.tar.gz # @configure_input@ %define ver @PACKAGE_VERSION@ %define rel 1 %define prefix /usr %define home_page http://swig.sourceforge.net/ %define docprefix %{prefix}/share ###################################################################### # Usually, nothing needs to be changed below here between releases ###################################################################### Summary: Simplified Wrapper and Interface Generator Name: swig Version: %{ver} Release: %{rel} URL: %{home_page} Source0: %{name}-%{version}.tar.gz License: BSD Group: Development/Tools BuildRoot: %{_tmppath}/%{name}-root %description SWIG is a software development tool that connects programs written in C and C++ with a variety of high-level programming languages. SWIG is primarily used with common scripting languages such as Perl, Python, Tcl/Tk, and Ruby, however the list of supported languages also includes non-scripting languages such as Java, OCAML and C#. Also several interpreted and compiled Scheme implementations (Guile, MzScheme, Chicken) are supported. SWIG is most commonly used to create high-level interpreted or compiled programming environments, user interfaces, and as a tool for testing and prototyping C/C++ software. SWIG can also export its parse tree in the form of XML and Lisp s-expressions. %package runtime Summary: Runtime libraries required for dynamically loading swig-generated modules Group: Development/Libraries %description runtime The swig-runtime package contains shared libraries used to share type information between swig-generated modules loaded into the same application. Dynamically loading swig-generated modules should use the swig-runtime libs. %prep %setup -q -n SWIG-%{version} %build # so we can build package from cvs source too [ ! -r configure ] && ./autogen.sh %configure make make runtime %install rm -rf ${RPM_BUILD_ROOT} # Why is exec_prefix not used in BIN_DIR in Makefile? %makeinstall prefix=${RPM_BUILD_ROOT}%prefix BIN_DIR=${RPM_BUILD_ROOT}%{_exec_prefix}/bin DIR=${RPM_BUILD_ROOT} find $DIR -type f | sed -e "s#^${RPM_BUILD_ROOT}##g" > %{name}.files %clean rm -rf ${RPM_BUILD_ROOT} %files # -f %{name}.files /usr/bin/* /usr/lib/swig* #%doc /usr/share/doc/swig* #/usr/share/doc/swig* %defattr(-,root,root) %files runtime /usr/lib/lib* %changelog * Wed Jul 24 2002 Sam Liddicott - Added runtime package of runtime libs * Mon Sep 10 2001 Tony Seward - Merge Red Hat's and Dustin Mitchell's .spec files. - Install all of the examples in the documantation directory. - Auto create the list of installed files. cableswig-0.1.0+git20150808.orig/SWIG/FUTURE0000644000175000000620000004313012561312227016534 0ustar stevestaffSWIG-1.3.12, SWIG 2.0, and Beyond ================================= With the release of SWIG-1.3.12, I thought I'd take a few moments of everyone's time to talk about the past, the present, and the future of SWIG development. I'm really quite excited about the current release because I think it represents a huge turning point in SWIG's development. Furthermore, it is only the beginning of bigger and better things to come. However, we definitely need your help. To put a little perspective on the discussion, I'd start with a few development statistics. In the last 12 months, there have been over 300 entries added to the CHANGES log and over 4000 CVS commits. Although that may not sound like a lot compared to a huge software project, it is significant in the context of SWIG. As a point of comparison, there has been more SWIG development this year than in any other year of the project and more than in the previous three years combined. This even includes the first few years of development in which there was also a lot of activity. Furthermore, many of the recent changes have been extremely non-trivial (e.g., templates, namespaces, type system, operators, etc.). As a result, SWIG is more capable than I ever imagined possible. Regrettably, I must admit that I've been a little negligent in discussing the roadmap for where I thought this flurry of SWIG development was actually headed. In part, this is because I've been buried in work. However, the real reason is that I didn't really know where we were going---except that in a time far far far away in the future, we might arrive at some kind of "stable" release with a version number other than "1.3.x". Needless to say, that's not a very compelling story. That said, I've spent a lot of time thinking about SWIG and trying to wrap my brain around it. Specifically, just what is (or should be) the primary focus of this project and what are we really trying to do? That's what the rest of this message is about. SWIG Prehistory --------------- The first version of SWIG was written in 1995. The original system was developed to help with some software wrapping problems I encountered while writing molecular dynamics software at Los Alamos. Later that year, I became interested in extending the wrapper generator to support other scripting languages so it was rewritten in C++ and modified with multiple backends (Tcl, Perl, and Guile). This led to a first public release in February, 1996. Feedback from this release led to a series of enhancements and the release of SWIG 1.0 in September 1996. Throughout this process, my intent was to create a tool that I would want to use---I never viewed the project as an CS experiment in programming languages or software engineering. SWIG 1.1 -------- SWIG-1.1 (June, 1997) represented a series of enhancements that were added in response to feedback at conferences and from users. Shadow classes, exception handling, typemaps, and a number of more useful features were added. However, the overall structure of the system was relatively unchanged from the initial version. Following the release of 1.1, a series of minor patch releases were made. This resulted in the release of SWIG-1.1p5 in February, 1998. Unfortunately, this release would remain the last "stable" release for quite a long time---in fact, it is still listed as the last "stable" release on the SWIG web page! SWIG Hell --------- Even during the development of SWIG-1.1, it was clear that the whole design of the system was deeply flawed. The implementation was a mess and the C/C++ support was full of holes and nasty corner cases. Furthermore, there was no unifying principle that tied all of the different SWIG directives together. Not only that, fixing these problems appeared to be nothing short of impossible---requiring a total ground-up rewrite at best. The only redeeming quality was that the system basically worked "well enough," it was extensively documented, and its flaws mostly known. People could use it and there were work-arounds for most common problems. To deal with the design problem, there were at least four attempts to completely rewrite SWIG, some of which were attempted in parallel with the work on SWIG-1.1. Unfortunately, none of these were ever completed. The primary problem was a strong "second system" effect and a desire to make SWIG do everything that one might conceivably want to do with a wrapper generator (somehow). Clearly, this was a recipe for disaster. In fact, all such attempts to rewrite SWIG were eventually abandoned several years ago. In hindsight, I think the real problem was that these rewrite efforts focused far too much attention on implementation technique rather than principles. In short, the failure of these efforts was due to a lack of clarity in understanding how SWIG ought to work (regardless of how it was actually implemented). SWIG Restart (1.3a1-1.3a5) -------------------------- Having languished for several years, the SWIG1.1p5 release had a growing pile of maintenance issues. It didn't work for newer versions of certain language modules and a lot of minor bug reports and feature requests had been building up. With a lot of help from Loic Dachary and Thien-Thi Nguyen, we put together the 1.3a1 release (February, 2000). This was mostly a bug fix release to 1.1p5 except that the preprocessor module from SWIG1.2 was added and a lot of minor enhancements were added. For the next six months, a massive effort was made to rewrite all of SWIG's internal data structures (strings, lists, hashes, etc.). This work was all going on underneath the covers while we tried to keep SWIG in an operational state. The primary focus of this work was really one of cleanup. Having given up on a total rewrite, perhaps we could settle with making the implementation incrementally better than before. In addition this, Matthias Koppe jumped on board to reimplement the Guile module and to make other improvements to the system. An important aspect of these releases was that many parts of the system not directly related to wrapper code generation were removed. This included the documentation system and Objective-C support. These were not removed because they weren't useful. Instead, the documentation system was removed because it accounted for nearly half of the special SWIG directives, yet had no direct bearing on what SWIG actually did. Obective-C support was removed because it was tangled with C++ support in a way that was very difficult to understand and maintain. The removal of these features was seen as a way to vastly simplify cleanup--and to buy some time where we could rethink their role in a future release. SWIG Redux (1.3.6-1.3.11) ------------------------- This work, started in February 2001, is the beginning of the current SWIG implementation. With the help of William Fulton, Matthias Koppe, Lyle Johnson, Luigi Ballabio, Jason Stewart, Richard Palmer, Sam Liddicot, and others, this work can best be described as the wholesale destruction of everything remaining from SWIG-1.1. The language module API, type system, the parser, numerous SWIG directives, and SWIG library files---all destroyed or rewritten. Not only that, we started introducing significant incompatibilities with SWIG-1.1---mostly in an effort to correct past wrongs and get ourselves out of the tangled mess of earlier versions. A huge number of long-standing bugs and difficult feature requests have also been resolved. The general goal of this development could best be described as an attempt to reduce SWIG to an easily described set of general "ideas" about how it should operate. Special SWIG directives have been eliminated or combined with others. Different parts of the system have been better integrated. Features not directly related to wrapper code generation have been removed and the system has become more focused. Changes in internal data structures and APIs have allowed SWIG to capture more information from interface files and to resolve hard corner cases. More often than not, these are things that you never notice unless you are an old user and you suddenly realize that a problem you had several years back has disappeared. Along with the destruction of old code, this work has quietly introduced a new core--the most significant features of which are a new C++ type system and multi-pass compilation. More importantly, this work has really tried to provide a more principled foundation for future SWIG development. However, just what is this "more principled foundation?" Convergence (1.3.12) -------------------- With the upcoming 1.3.12 release, SWIG is about to take a big leap forward. Almost all of this is due to one realization---that almost every hard problem in past SWIG releases has been directly related to errors and limitations in its type system. Types are the key to understanding the structure of C and C++ code. They are at the heart of understanding advanced language features like namespaces, nested classes, and templates. They are directly related to the data marshalling that occurs in wrappers. Not only that, they interact with nearly every SWIG directive. A proper type system *is* the necessary foundation for moving SWIG forward. To be honest, I don't think that the emphasis on types is entirely obvious. In fact, a great deal of work in past SWIG rewrites has focused on the problem of C++ parsing. For instance, modifying the parser to handle more advanced C++ code or representing parse trees as XML. Furthermore, if one looks at the SWIG mailing list, you can find a *lot* of messages related to issues of C++ parsing whereas almost no one ever talks about types (well, other than typemaps). Even other wrapper generation tools seems to spend a lot of time dealing with the parsing issue. Although parsing is clearly important, I don't think it has ever been the real problem in SWIG. This is because even though a parser can tell you what's in a header file, it doesn't tell you anything about how the different pieces of the system behave or how they might interact. To do that, you need to do a lot more than just parsing--and that's really the whole point. Although earlier 1.3 releases have made big improvements to the type system, SWIG-1.3.12 is the first release that really tries to tackle the type-system issue in a major way. We have patched nearly all remaining holes in the type system and we have added full support for C++ namespaces. Not only that, we have completely reimplemented C++ template support in a way that supports templates, member templates, and template specialization. Luigi and I are currently using this to work on proper SWIG library support for parts of the C++ standard library and the Standard Template Library (STL). Although some crusty C programmers (present company excepted), might balk at such apparent insanity, this work has impacted all parts of SWIG at all levels. Even a variety of subtle errors in C support have been fixed by this work. In addition to the type system work, SWIG-1.3.12 contains continued reduction in the implementation. Directives have been removed, refined, renamed, or consolidated. We're still narrowing the focus of the system and working towards some kind of convergence. "Convergence to what?!?", you ask. So, what is SWIG? ----------------- In a nutshell, SWIG is a C/C++ declaration compiler that generates wrapper code (okay, so you knew that much). However, to really understand what SWIG is doing and where SWIG-1.3.x is headed, it is useful to know that the whole system is essentially being built around three extensions to the C++ type system: - Typemaps. Typemaps are rules that define the process by which data is converted between languages. They are fully integrated with the C++ type system and they are applied using a type-based pattern matching mechanism. All data conversion SWIG is defined by typemaps and is fully reconfigurable. - Declaration annotation. There are special directives that modify the wrapping behavior of individual declarations. Declarations can be selectively identified and decorated with arbitrary attributes that affect wrapper generation. Like typemaps, declaration matching is fully integrated with the C++ type system. Almost all SWIG customization directives are a form of declaration annotation. - Class extension. The ability to extend classes and structures with new methods/attributes when building wrappers. Classes are part of the type system so class extension is naturally integrated with the C++ type system as well (big surprise). And that's it--this is the end-game of SWIG-1.3.x development. When stabilized and documented it will become SWIG-2.0. The Bigger Picture ------------------ I really want to emphasize that all of this work is part of a much bigger picture. SWIG is used by a surprising number of people in industry, government, and academia. It's used to build systems used by millions of people every day. It has even shown up in video games and other unlikely settings. Although SWIG doesn't have the same visibility as many large software projects, over 12000 people have downloaded SWIG-1.3.11 in the last 4 months. Clearly someone is using it for something! Because of this, I think it is important for us to work on moving SWIG towards a more solid foundation. Doing so will give the system more credibility and long term viability---and it will be a lot more fun to use! It's also worth noting that there are some rather interesting CS connections at work here. Extensions to the type system and typemaps have some interesting relations to work in programming languages. The SWIG declaration annotation system and class extension feature seem oddly similar to work in the emerging area of Aspect Oriented Programming (AOP). There are undoubtedly connections to other areas of software engineering and architecture. The key point is that SWIG isn't going to connect to anything if no-one can quite describe what it is or how it works. SWIG-2.0 and the Future ----------------------- SWIG-1.3.12 still represents work in progress. There are bugs, the documentation is still incomplete, and there are parts of the implementation that are rather ugly. We are also still working out a few very hard problems like nested classes, callback functions, and overloading. A few old features are still missing (Objective-C, documentation). However, I believe the end of the 1.3.x series is near and achievable. Over the summer, a few more 1.3.x releases may appear but the current plan is to aim for a SWIG-2.0 release in September. This release is really moving towards the design principles described above and will be a very major enhancement over SWIG-1.1. As for the future, a number of interesting ideas are on the table. I want to add support for contracts/assertions in order to solve some reliability issues that arise when retrofitting legacy codes with a scripting interface. Support for an extension language has been promoted by David Fletcher and was suggested by someone else on the mailing list rather recently. I have a graduate student working on SWIG support for the Microsoft CLR and .NET languages. Other work might include support for alternative parsers, dynamically loadable language modules, and so forth. However, none of this is really going to materialize if we can't get the 2.0 release stablized. In fact, I see SWIG-2.0 as a necessary step for moving forward with these ideas. We need your help! Yes, you. ---------------------------- Nobody gets paid to work on SWIG. The developers are volunteers who work in their spare time. Furthermore, SWIG is not supported by investors, a large corporation, or research grants. I work on it because it's fun, challenging, and useful. I presume that other developers do the same. However, we only have limited resources and we need your help. - If you like SWIG and find it useful, we need you to try new versions. We want you to torture test the releases and to break them. We need bug reports. No bug is too obscure or unimportant---we *will* fix it if we can. We also need feedback about things that are annoying or compatibility features that might help in going from 1.1 to 2.0. - We need help with documentation, examples, testing, libraries, and all sorts of other aspects of the release. Even if you have never written a SWIG language module or dived into its implementation, there are many ways that you can help. Consider writing a case study about how you wrapped a big library. Contribute tests that break the implementation in horrible ways. Help with the web page or FAQ. - Most of the SWIG-1.3.x work has focused on the SWIG core. However, as the 2.0 release nears, we will be working on a variety of enhancements to the language modules. If there are things you would like to see in any of the language modules, you need to let us know. - There are SWIG language modules that have not made it into the distribution. Examples that I know about include ITCL, Swig-Eiffel, and Swig-Lua. We would gladly make these part of the standard SWIG distribution. However, we also need help to do it. Porting from SWIG-1.1 is no easy task, but we're more than willing to help. It's not as bad as one might imagine. - We are always looking for developers. Subscribe to swig-dev@cs.uchicago.edu (http://mailman.cs.uchicago.edu/listinfo/swig-dev) or send me email to get involved. Acknowledgements ---------------- I'd just like to thank everyone who has submitted feedback, bugs, made contributions, and put up with my occasional thrashing over the years. I welcome any comments about this document and how we can make SWIG even better. Dave Beazley (beazley@cs.uchicago.edu) June 2, 2002 cableswig-0.1.0+git20150808.orig/SWIG/configure.in0000644000175000000620000013167212561312227020121 0ustar stevestaffdnl 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],[1.3.22],[http://www.swig.org]) AC_PREREQ(2.54) AC_CONFIG_SRCDIR([Source/Swig/swig.h]) AC_CONFIG_AUX_DIR([Tools/config]) AC_CONFIG_HEADERS([Source/Include/swigconfig.h]) AC_CANONICAL_HOST AM_INIT_AUTOMAKE dnl Some extra defines for the config file AH_BOTTOM([ /* Default language */ #define SWIG_LANG "-tcl" /* Values returned by SWIG when invoked with the -ldflags option */ #define SWIG_GUILE_RUNTIME "-L" LIBDIR " -lswigguile" RELEASE_SUFFIX #define SWIG_GUILESCM_RUNTIME "-L" LIBDIR " -lswigguilescm" RELEASE_SUFFIX #define SWIG_MZSCHEME_RUNTIME "-L" LIBDIR " -lswigmz" RELEASE_SUFFIX #define SWIG_PERL_RUNTIME "-L" LIBDIR " -lswigpl" RELEASE_SUFFIX #define SWIG_PIKE_RUNTIME "-L" LIBDIR " -lswigpike" RELEASE_SUFFIX #define SWIG_PHP_RUNTIME "-L" LIBDIR " -lswigphp4" RELEASE_SUFFIX #define SWIG_PYTHON_RUNTIME "-L" LIBDIR " -lswigpy" RELEASE_SUFFIX #define SWIG_RUBY_RUNTIME "-L" LIBDIR " -lswigrb" RELEASE_SUFFIX #define SWIG_TCL_RUNTIME "-L" LIBDIR " -lswigtcl" RELEASE_SUFFIX #define SWIG_CHICKEN_RUNTIME "-L" LIBDIR " -lswigchicken" RELEASE_SUFFIX ]) dnl Checks for programs. AC_PROG_CC AC_PROG_CXX AC_PROG_YACC AC_EXEEXT AC_OBJEXT AM_PROG_CC_C_O # Needed for subdir-objects in AUTOMAKE_OPTIONS AC_CHECK_PROGS(AR, ar aal, ar) AC_SUBST(AR) AC_LIBTOOL_WIN32_DLL # On Mac OS-X, static runtime libraries don't seem to build (and are # probably a bad idea anyways). This turns this off in libtool. case $host in *-*-darwin*) AC_DISABLE_STATIC;; *);; esac AC_PROG_LIBTOOL AC_COMPILE_WARNINGS # Increase warning levels AC_DEFINE_UNQUOTED(SWIG_CXX, ["$CXX"], [Compiler that built SWIG]) AC_DEFINE_UNQUOTED(SWIG_PLATFORM, ["$build"], [Platform that SWIG is built for]) AC_DEFINE_DIR(LIBDIR, libdir, [Runtime library installation directory]) dnl Checks for header files. AC_HEADER_STDC dnl How to specify include directories that may be system directories. # -I should not be used on system directories (GCC) if test "$GCC" = yes; then ISYSTEM="-isystem " else ISYSTEM="-I" fi dnl Checks for types. AC_LANG_PUSH([C++]) AC_CHECK_TYPES([bool]) AC_LANG_POP([C++]) # Set info about shared libraries. AC_SUBST(SO) AC_SUBST(LDSHARED) AC_SUBST(CCSHARED) AC_SUBST(CXXSHARED) AC_SUBST(TRYLINKINGWITHCXX) AC_SUBST(LINKFORSHARED) # SO is the extension of shared libraries `(including the dot!) AC_MSG_CHECKING(SO) if test -z "$SO" then case $host in *-*-hp*) SO=.sl;; *-*-darwin*) SO=.bundle;; *-*-cygwin* | *-*-mingw*) SO=.dll;; *) SO=.so;; esac fi AC_MSG_RESULT($SO) # 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 $host in *-*-aix*) LDSHARED="\$(srcdir)/ld_so_aix \$(CC)";; *-*-cygwin* | *-*-mingw*) if test "$GCC" = yes; then LDSHARED="$CC -shared" else if test "cl" = $CC ; then # Microsoft Visual C++ (MSVC) LDSHARED="$CC -nologo -LD" else # Unknown compiler try gcc approach LDSHARED="$CC -shared" fi fi ;; *-*-irix5*) LDSHARED="ld -shared";; *-*-irix6*) LDSHARED="ld ${SGI_ABI} -shared -all";; *-*-sunos4*) LDSHARED="ld";; *-*-solaris*) LDSHARED="ld -G";; *-*-hp*) LDSHARED="ld -b";; *-*-osf*) LDSHARED="ld -shared -expect_unresolved \"*\"";; *-sequent-sysv4) 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";; *-*-freebsd3*) LDSHARED="gcc -shared";; *-*-freebsd* | *-*-openbsd*) LDSHARED="ld -Bshareable";; *-*-netbsd*) if [[ "`$CC -dM -E - ], , not_really_there="yes") else if test ! -r $x_includes/X11/Intrinsic.h; then not_really_there="yes" fi fi fi if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then AC_MSG_CHECKING(for X11 header files) XINCLUDES="# no special path needed" AC_TRY_CPP([#include ], , XINCLUDES="") if test -z "$XINCLUDES"; then dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/include/X11R4 /usr/X11R5/include /usr/include/X11R5 /usr/openwin/include /usr/X11/include /usr/sww/include /usr/X11R6/include /usr/include/X11R6" for i in $dirs ; do if test -r $i/X11/Intrinsic.h; then AC_MSG_RESULT($i) XINCLUDES=" -I$i" break fi done fi else if test "$x_includes" != ""; then XINCLUDES=-I$x_includes else XINCLUDES="# no special path needed" fi fi if test -z "$XINCLUDES"; then AC_MSG_RESULT(couldn't find any!) XINCLUDES="# no include files found" fi if test "$no_x" = yes; then AC_MSG_CHECKING(for X11 libraries) XLIBSW= dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/lib/X11R4 /usr/X11R5/lib /usr/lib/X11R5 /usr/X11R6/lib /usr/lib/X11R6 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib" for i in $dirs ; do if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl; then AC_MSG_RESULT($i) XLIBSW="-L$i -lX11" break fi done else if test "$x_libraries" = ""; then XLIBSW=-lX11 else XLIBSW="-L$x_libraries -lX11" fi fi if test -z "$XLIBSW" ; then AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow) fi if test -z "$XLIBSW" ; then AC_MSG_RESULT(couldn't find any! Using -lX11.) XLIBSW=-lX11 fi AC_SUBST(XINCLUDES) AC_SUBST(XLIBSW) #-------------------------------------------------------------------- # Try to locate the Tcl package #-------------------------------------------------------------------- TCLINCLUDE= TCLLIB= TCLPACKAGE= AC_ARG_WITH(tclconfig,[ --with-tclconfig=path Set location of tclConfig.sh], with_tclconfig="$withval") AC_ARG_WITH(tcl,[ --with-tcl=path Set location of Tcl package],[ TCLPACKAGE="$withval"], [TCLPACKAGE=]) AC_ARG_WITH(tclincl,[ --with-tclincl=path Set location of Tcl include directory],[ TCLINCLUDE="$ISYSTEM$withval"], [TCLINCLUDE=]) AC_ARG_WITH(tcllib,[ --with-tcllib=path Set location of Tcl library directory],[ TCLLIB="-L$withval"], [TCLLIB=]) AC_MSG_CHECKING([for Tcl configuration]) # First check to see if --with-tclconfig was specified. if test x"${with_tclconfig}" != x ; then if test -f "${with_tclconfig}/tclConfig.sh" ; then TCLCONFIG=`(cd ${with_tclconfig}; pwd)` else AC_MSG_ERROR([${with_tcl} directory doesn't contain tclConfig.sh]) fi fi # check in a few common install locations if test x"${TCLCONFIG}" = x ; then for i in `ls -d /usr/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` ; do if test -f "$i/tclConfig.sh" ; then TCLCONFIG=`(cd $i; pwd)` break fi done fi if test x"${TCLCONFIG}" = x ; then AC_MSG_RESULT(no) else AC_MSG_RESULT(found $TCLCONFIG/tclConfig.sh) . $TCLCONFIG/tclConfig.sh if test -z "$TCLINCLUDE"; then TCLINCLUDE=$ISYSTEM$TCL_PREFIX/include fi if test -z "$TCLLIB"; then TCLLIB=$TCL_LIB_SPEC fi fi if test -z "$TCLINCLUDE"; then if test -n "$TCLPACKAGE"; then TCLINCLUDE="$ISYSTEM$TCLPACKAGE/include" fi fi if test -z "$TCLLIB"; then if test -n "$TCLPACKAGE"; then TCLLIB="-L$TCLPACKAGE/lib -ltcl" fi fi AC_MSG_CHECKING(for Tcl header files) if test -z "$TCLINCLUDE"; then AC_TRY_CPP([#include ], , TCLINCLUDE="") if test -z "$TCLINCLUDE"; then dirs="/usr/local/include /usr/include /opt/local/include" for i in $dirs ; do if test -r $i/tcl.h; then AC_MSG_RESULT($i) TCLINCLUDE="$ISYSTEM$i" break fi done fi if test -z "$TCLINCLUDE"; then AC_MSG_RESULT(not found) fi else AC_MSG_RESULT($TCLINCLUDE) fi AC_MSG_CHECKING(for Tcl library) if test -z "$TCLLIB"; then dirs="/usr/local/lib /usr/lib /opt/local/lib" for i in $dirs ; do if test -r $i/libtcl.a; then AC_MSG_RESULT($i) TCLLIB="-L$i -ltcl" break fi done if test -z "$TCLLIB"; then AC_MSG_RESULT(not found) fi else AC_MSG_RESULT($TCLLIB) fi # Cygwin (Windows) needs the library for dynamic linking case $host in *-*-cygwin* | *-*-mingw*) TCLDYNAMICLINKING="$TCLLIB";; *)TCLDYNAMICLINKING="";; esac AC_SUBST(TCLINCLUDE) AC_SUBST(TCLLIB) AC_SUBST(TCLDYNAMICLINKING) #---------------------------------------------------------------- # Look for Python #---------------------------------------------------------------- PYINCLUDE= PYLIB= PYPACKAGE= # I don't think any of this commented stuff works anymore #PYLINK="-lModules -lPython -lObjects -lParser" #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_ARG_WITH(python,[ --with-python=path Set location of Python executable],[ PYBIN="$withval"], [PYBIN=]) # First figure out the name of the Python executable if test -z "$PYBIN"; then AC_CHECK_PROGS(PYTHON, python python2.4 python2.3 python2.2 python2.1 python2.0 python1.6 python1.5 python1.4 python) else PYTHON="$PYBIN" fi if test -n "$PYTHON"; then AC_MSG_CHECKING(for Python prefix) PYPREFIX=`($PYTHON -c "import sys; print sys.prefix") 2>/dev/null` AC_MSG_RESULT($PYPREFIX) AC_MSG_CHECKING(for Python exec-prefix) PYEPREFIX=`($PYTHON -c "import sys; print sys.exec_prefix") 2>/dev/null` AC_MSG_RESULT($PYEPREFIX) # Note: I could not think of a standard way to get the version string from different versions. # This trick pulls it out of the file location for a standard library file. AC_MSG_CHECKING(for Python version) # Need to do this hack since autoconf replaces __file__ with the name of the configure file filehack="file__" PYVERSION=`($PYTHON -c "import string,operator,os.path; print operator.getitem(os.path.split(operator.getitem(os.path.split(string.__$filehack),0)),1)")` AC_MSG_RESULT($PYVERSION) # Set the include directory AC_MSG_CHECKING(for Python header files) if test -r $PYPREFIX/include/$PYVERSION/Python.h; then PYINCLUDE="-I$PYPREFIX/include/$PYVERSION -I$PYEPREFIX/lib/$PYVERSION/config" fi if test -z "$PYINCLUDE"; then if test -r $PYPREFIX/include/Py/Python.h; then PYINCLUDE="-I$PYPREFIX/include/Py -I$PYEPREFIX/lib/python/lib" fi fi AC_MSG_RESULT($PYINCLUDE) # Set the library directory blindly. This probably won't work with older versions AC_MSG_CHECKING(for Python library) dirs="$PYVERSION/config $PYVERSION/lib python/lib" for i in $dirs; do if test -d $PYEPREFIX/lib/$i; then PYLIB="$PYEPREFIX/lib/$i" break fi done if test -z "$PYLIB"; then AC_MSG_RESULT(Not found) else AC_MSG_RESULT($PYLIB) fi # Check for really old versions if test -r $PYLIB/libPython.a; then PYLINK="-lModules -lPython -lObjects -lParser" else PYLINK="-l$PYVERSION" fi fi # Cygwin (Windows) needs the library for dynamic linking case $host in *-*-cygwin* | *-*-mingw*) PYTHONDYNAMICLINKING="-L$PYLIB $PYLINK" PYINCLUDE="-DUSE_DL_IMPORT $PYINCLUDE" ;; *)PYTHONDYNAMICLINKING="";; esac AC_SUBST(PYINCLUDE) AC_SUBST(PYLIB) AC_SUBST(PYLINK) AC_SUBST(PYTHONDYNAMICLINKING) #---------------------------------------------------------------- # Look for Perl5 #---------------------------------------------------------------- PERLBIN= 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, perl perl5.6.1 perl5.6.0 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}, "\n";') 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" break; fi done if test "$PERL5EXT" = none; then PERL5EXT="$PERL5DIR/CORE" AC_MSG_RESULT(could not locate perl.h...using $PERL5EXT) fi AC_MSG_CHECKING(for Perl5 library) PERL5LIB=`($PERL -e 'use Config; $_=$Config{libperl}; s/^lib//; s/$Config{_a}$//; print $_, "\n"') 2>/dev/null` if test "$PERL5LIB" = "" ; then AC_MSG_RESULT(not found) else AC_MSG_RESULT($PERL5LIB) fi AC_MSG_CHECKING(for Perl5 compiler options) PERL5CCFLAGS=`($PERL -e 'use Config; print $Config{ccflags}, "\n"' | sed "s/-I/$ISYSTEM/") 2>/dev/null` if test "$PERL5CCFLAGS" = "" ; then AC_MSG_RESULT(not found) else AC_MSG_RESULT($PERL5CCFLAGS) fi else AC_MSG_RESULT(unable to determine perl5 configuration) PERL5EXT=$PERL5DIR fi else AC_MSG_RESULT(could not figure out how to run perl5) fi # Cygwin (Windows) needs the library for dynamic linking case $host in *-*-cygwin* | *-*-mingw*) PERL5DYNAMICLINKING="-L$PERL5EXT -l$PERL5LIB";; *)PERL5DYNAMICLINKING="";; esac AC_SUBST(PERL) AC_SUBST(PERL5EXT) AC_SUBST(PERL5DYNAMICLINKING) AC_SUBST(PERL5LIB) AC_SUBST(PERL5CCFLAGS) #---------------------------------------------------------------- # Look for java #---------------------------------------------------------------- AC_ARG_WITH(java, [ --with-java=path Set location of Java executable],[JAVABIN="$withval"], [JAVABIN=]) AC_ARG_WITH(javac, [ --with-javac=path Set location of Javac executable],[JAVACBIN="$withval"], [JAVACBIN=]) if test -z "$JAVABIN" ; then AC_CHECK_PROGS(JAVA, java kaffe guavac) else JAVA="$JAVABIN" fi if test -z "$JAVACBIN" ; then AC_CHECK_PROGS(JAVAC, javac) else JAVAC="$JAVACBIN" fi AC_MSG_CHECKING(for java include file jni.h) AC_ARG_WITH(javaincl, [ --with-javaincl=path Set location of Java include directory], [JAVAINCDIR="$withval"], [JAVAINCDIR=]) if test -z "$JAVAINCDIR"; then JAVAINCDIR="/usr/j2sdk*/include /usr/local/j2sdk*/include /usr/jdk*/include /usr/local/jdk*/include /opt/j2sdk*/include /opt/jdk*/include /usr/java/include /usr/java/j2sdk*/include /usr/java/jdk*/include /usr/local/java/include /opt/java/include /usr/include/java /usr/local/include/java /usr/lib/java/include /usr/include/kaffe /usr/local/include/kaffe" # Add in default installation directory on Windows for Cygwin case $host in *-*-cygwin* | *-*-mingw*) JAVAINCDIR="c:/j2sdk*/include d:/j2sdk*/include c:/jdk*/include d:/jdk*/include $JAVAINCDIR";; *-*-darwin*) JAVAINCDIR="/System/Library/Frameworks/JavaVM.framework/Headers $JAVAINCDIR";; *);; esac fi JAVAINC="" for d in $JAVAINCDIR ; do if test -r $d/jni.h ; then AC_MSG_RESULT($d) JAVAINCDIR=$d JAVAINC="-I$d" break fi done if test "$JAVAINC" = "" ; then AC_MSG_RESULT(not found) else # now look for /jni_md.h AC_MSG_CHECKING(for java include file jni_md.h) JAVAMDDIR=`find $JAVAINCDIR -follow -name jni_md.h -print` if test "$JAVAMDDIR" = "" ; then AC_MSG_RESULT(not found) else JAVAMDDIR=`dirname $JAVAMDDIR` JAVAINC="${JAVAINC} -I$JAVAMDDIR" AC_MSG_RESULT($JAVAMDDIR) fi fi # java.exe on Cygwin requires the Windows standard (Pascal) calling convention as it is a normal Windows executable and not a Cygwin built executable case $host in *-*-cygwin* | *-*-mingw*) if test "$GCC" = yes; then JAVADYNAMICLINKING=" -mno-cygwin -Wl,--add-stdcall-alias" else JAVADYNAMICLINKING="" fi ;; *-*-darwin*) JAVADYNAMICLINKING="-dynamiclib -framework JavaVM";; *)JAVADYNAMICLINKING="";; esac # Java on Windows platforms including Cygwin doesn't use libname.dll, rather name.dll when loading dlls case $host in *-*-cygwin* | *-*-mingw*) JAVALIBRARYPREFIX="";; *)JAVALIBRARYPREFIX="lib";; esac # Java on Mac OS X tweaks case $host in *-*-darwin*) JAVASO=".jnilib" JAVALDSHARED='$(CC)' JAVACXXSHARED='$(CXX)' ;; *) JAVASO=$SO JAVALDSHARED='$(LDSHARED)' JAVACXXSHARED='$(CXXSHARED)' ;; esac AC_SUBST(JAVA) AC_SUBST(JAVAC) AC_SUBST(JAVAINC) AC_SUBST(JAVADYNAMICLINKING) AC_SUBST(JAVALIBRARYPREFIX) AC_SUBST(JAVASO) AC_SUBST(JAVALDSHARED) AC_SUBST(JAVACXXSHARED) #---------------------------------------------------------------- # Look for Guile #---------------------------------------------------------------- GUILEPACKAGE= GUILEINCLUDE= GUILE= GUILELIB= GUILELINK= AC_ARG_WITH(guile-config,[ --with-guile-config=path Set location of guile-config],[ GUILE_CONFIG="$withval"], [GUILE_CONFIG=]) if test -z "$GUILE_CONFIG" ; then AC_PATH_PROG(GUILE_CONFIG, guile-config) fi if test -n "$GUILE_CONFIG" ; then GUILEPACKAGE="`$GUILE_CONFIG info prefix`" GUILEINCLUDE="`$GUILE_CONFIG info includedir`" GUILELIB="`$GUILE_CONFIG info libdir`" GUILE="`$GUILE_CONFIG info bindir`/guile" GUILELINK="`$GUILE_CONFIG link`" fi AC_ARG_WITH(guilepackage,[ --with-guile-prefix=path Set location of Guile tree],[ GUILEPACKAGE="$withval"]) if test -z "$GUILE"; then if test -n "$GUILEPACKAGE"; then GUILE="$GUILEPACKAGE/bin/guile" fi fi if test -z "$GUILEINCLUDE"; then if test -n "$GUILEPACKAGE"; then GUILEINCLUDE="$GUILEPACKAGE/include" fi fi if test -z "$GUILELIB"; then if test -n "$GUILEPACKAGE"; then GUILELIB="$GUILEPACKAGE/lib" fi fi AC_ARG_WITH(guile,[ --with-guile=path Set location of Guile executable],[ GUILE="$withval"]) AC_ARG_WITH(guileincl,[ --with-guileincl=path Set location of Guile include directory],[ GUILEINCLUDE="$withval"]) AC_ARG_WITH(guilelib,[ --with-guilelib=path Set location of Guile library directory],[ GUILELIB="$withval"]) AC_MSG_CHECKING(for Guile header files) dirs="$GUILEINCLUDE" for i in $dirs ; do if test -r $i/guile/gh.h; then AC_MSG_RESULT($i) GUILEINCLUDE="$ISYSTEM$i" break fi done if test -z "$GUILEINCLUDE"; then AC_MSG_RESULT(not found) fi AC_MSG_CHECKING(for Guile library) dirs="$GUILELIB" for i in $dirs ; do if test -r $i/libguile.so; then AC_MSG_RESULT($i) GUILELIB="$i" break fi done if test -z "$GUILELIB"; then AC_MSG_RESULT(not found) fi if test -z "$GUILELINK"; then GUILELINK="-L$GUILELIB -lguile" fi AC_SUBST(GUILE) AC_SUBST(GUILEINCLUDE) AC_SUBST(GUILELIB) AC_SUBST(GUILELINK) guilesafe_CFLAGS=$CFLAGS guilesafe_LDFLAGS=$LDFLAGS CFLAGS="$CFLAGS $GUILEINCLUDE" LDFLAGS="$LDFLAGS $GUILELINK" AC_MSG_CHECKING(whether Guile's gh_ API works) AC_LINK_IFELSE([#include int main() { SCM s; return gh_scm2int(s); }], GUILE_GH_INTERFACE=1, ) if test -n "$GUILE_GH_INTERFACE" ; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi AC_MSG_CHECKING(whether Guile's SCM_ API works) AC_LINK_IFELSE([#include int main() { SCM s; scm_slot_exists_p(SCM_BOOL_F, SCM_BOOL_F); return SCM_STRING_LENGTH(s); }], GUILE_SCM_INTERFACE=1, ) if test -n "$GUILE_SCM_INTERFACE" ; then AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) fi CFLAGS=$guilesafe_CFLAGS LDFLAGS=$guilesafe_LDFLAGS AM_CONDITIONAL(GUILE_GH_INTERFACE, test -n "$GUILE_GH_INTERFACE") AC_SUBST(GUILE_GH_INTERFACE) AM_CONDITIONAL(GUILE_SCM_INTERFACE, test -n "$GUILE_SCM_INTERFACE") AC_SUBST(GUILE_SCM_INTERFACE) #---------------------------------------------------------------- # Look for MzScheme #---------------------------------------------------------------- AC_PATH_PROG(MZC, mzc) AC_PATH_PROG(MZSCHEME, mzscheme) if test -n "$MZSCHEME"; then AC_MSG_CHECKING(for MzScheme dynext object) MZDYNOBJ=`$MZSCHEME --mute-banner --version --eval '(begin (require (lib "link.ss" "dynext")) (with-handlers (((lambda args #t) (lambda args #f))) (for-each (lambda (x) (display x) (display " ")) ((current-make-standard-link-libraries)))) (with-handlers (((lambda args #t) (lambda args #f))) (for-each (lambda (x) (display x) (display " ")) (expand-for-link-variant (current-standard-link-libraries)))))'` AC_MSG_RESULT($MZDYNOBJ) fi AC_SUBST(MZDYNOBJ) #---------------------------------------------------------------- # Look for Ruby #---------------------------------------------------------------- RUBYBIN= AC_ARG_WITH(ruby,[ --with-ruby=path Set location of Ruby executable],[ RUBYBIN="$withval"], [RUBYBIN=]) # First figure out what the name of Ruby is if test -z "$RUBYBIN"; then AC_CHECK_PROGS(RUBY, ruby) else RUBY="$RUBYBIN" fi AC_MSG_CHECKING(for Ruby header files) if test -n "$RUBY"; then RUBYDIR=`($RUBY -rmkmf -e 'print Config::CONFIG[["archdir"]] || $archdir') 2>/dev/null` if test "$RUBYDIR" != ""; then dirs="$RUBYDIR" RUBYINCLUDE=none for i in $dirs; do if test -r $i/ruby.h; then AC_MSG_RESULT($i) RUBYINCLUDE="-I$i" break; fi done if test "$RUBYINCLUDE" = none; then RUBYINCLUDE="-I$RUBYDIR" AC_MSG_RESULT(could not locate ruby.h...using $RUBYINCLUDE) fi # Find library and path for linking. AC_MSG_CHECKING(for Ruby library) RUBYLIB="" rb_libdir=`($RUBY -rrbconfig -e 'print Config::CONFIG[["libdir"]]') 2>/dev/null` rb_bindir=`($RUBY -rrbconfig -e 'print Config::CONFIG[["bindir"]]') 2>/dev/null` dirs="$dirs $rb_libdir $rb_bindir" rb_libruby=`($RUBY -rrbconfig -e 'print Config::CONFIG[["LIBRUBY_A"]]') 2>/dev/null` RUBYLINK=`($RUBY -rrbconfig -e ' c = Config::CONFIG if c.has_key? "LIBRUBYARG_STATIC" # 1.8.x if c[["LIBRUBY"]] == c[["LIBRUBY_A"]] link = c[["LIBRUBYARG_STATIC"]] else link = c[["LIBRUBYARG_SHARED"]] end else # 1.6.x link = "-l" + c[["RUBY_INSTALL_NAME"]] end puts link') 2>/dev/null` if test "$rb_libruby" != ""; then for i in $dirs; do if (test -r $i/$rb_libruby;) then RUBYLIB="$i" break; fi done fi if test "$RUBYLIB" = ""; then RUBYLIB="$RUBYDIR" AC_MSG_RESULT(not found... using $RUBYDIR) else AC_MSG_RESULT($RUBYLINK in $RUBYLIB) fi else AC_MSG_RESULT(unable to determine ruby configuration) RUBYINCLUDE="-I$RUBYDIR" RUBYLIB="$RUBYDIR" fi RUBYLINK="$RUBYLINK `($RUBY -rrbconfig -e 'print Config::CONFIG[["LIBS"]]') 2>/dev/null`" RUBYCCDLFLAGS=`($RUBY -rrbconfig -e 'print Config::CONFIG[["CCDLFLAGS"]]') 2>/dev/null` else AC_MSG_RESULT(could not figure out how to run ruby) RUBYINCLUDE="-I/usr/local/lib/ruby/1.4/arch" RUBYLIB="/usr/local/lib/ruby/1.4/arch" RUBYLINK="-lruby -lm" fi case $host in *-*-cygwin* | *-*-mingw*) RUBYDYNAMICLINKING="-L$RUBYLIB $RUBYLINK";; *) RUBYDYNAMICLINKING="";; esac AC_SUBST(RUBYINCLUDE) AC_SUBST(RUBYLIB) AC_SUBST(RUBYLINK) AC_SUBST(RUBYCCDLFLAGS) AC_SUBST(RUBYDYNAMICLINKING) #------------------------------------------------------------------------- # Look for Php4 #------------------------------------------------------------------------- PHP4BIN= AC_ARG_WITH(php4,[ --with-php4=path Set location of PHP4 executable],[ PHP4BIN="$withval"], [PHP4BIN=]) if test -z "$PHP4BIN"; then AC_CHECK_PROGS(PHP4, php php4) else PHP4="$PHP4BIN" fi AC_SUBST(PHP4) AC_MSG_CHECKING(for PHP4 header files) PHP4CONFIG="${PHP4}-config" PHP4INC="`$PHP4CONFIG --includes 2>/dev/null`" if test "$PHP4INC"; then AC_MSG_RESULT($PHP4INC) else dirs="/usr/include/php /usr/local/include/php /usr/include/php4 /usr/local/include/php4 /usr/local/apache/php" for i in $dirs; do echo $i if test -r $i/php_config.h -o -r $i/php_version.h; then AC_MSG_RESULT($i) PHP4EXT="$i" PHP4INC="-I$PHP4EXT -I$PHP4EXT/Zend -I$PHP4EXT/main -I$PHP4EXT/TSRM" break; fi done fi if test -z "$PHP4INC"; then AC_MSG_RESULT(not found) fi AC_SUBST(PHP4INC) ( cd $srcdir/Examples/php4 ; for dir in `sed '/^#/d' check.list` ; do test -f $dir/Makefile || ( cd $dir ; ln -s ../Makefile.php Makefile ) done ) #---------------------------------------------------------------- # Look for ocaml #---------------------------------------------------------------- AC_ARG_WITH(ocaml,[ --with-ocaml=path Set location of ocaml executable],[ OCAMLBIN="$withval"], [OCAMLBIN=]) AC_ARG_WITH(ocamlc,[ --with-ocamlc=path Set location of ocamlc executable],[ OCAMLC="$withval"], [OCAMLC=]) AC_ARG_WITH(ocamldlgen,[ --with-ocamldlgen=path Set location of ocamldlgen],[ OCAMLDLGEN="$withval" ], [OCAMLDLGEN=]) AC_ARG_WITH(ocamlfind,[ --with-ocamlfind=path Set location of ocamlfind],[OCAMLFIND="$withval"],[OCAMLFIND=]) AC_ARG_WITH(ocamlmktop,[ --with-ocamlmktop=path Set location of ocamlmktop executable],[ OCAMLMKTOP="$withval"], [OCAMLMKTOP=]) AC_MSG_CHECKING(for Ocaml DL load generator) if test -z "$OCAMLDLGEN"; then AC_CHECK_PROGS(OCAMLDLGEN, ocamldlgen, ocamldlgen) else OCAMLDLGEN="$OCAMLDLGEN" fi AC_MSG_CHECKING(for Ocaml package tool) if test -z "$OCAMLFIND"; then AC_CHECK_PROGS(OCAMLFIND, ocamlfind, ocamlfind) else OCAMLFIND="$OCAMLFIND" fi AC_MSG_CHECKING(for Ocaml compiler) if test -z "$OCAMLC"; then AC_CHECK_PROGS(OCAMLC, ocamlc, ocamlc) else OCAMLC="$OCAMLC" fi AC_MSG_CHECKING(for Ocaml interpreter) if test -z "$OCAMLBIN"; then AC_CHECK_PROGS(OCAMLBIN, ocaml, ocaml) else OCAMLBIN="$OCAMLBIN" fi AC_MSG_CHECKING(for Ocaml toplevel creator) if test -z "$OCAMLMKTOP"; then AC_CHECK_PROGS(OCAMLMKTOP, ocamlmktop, ocamlmktop) else OCAMLMKTOP="$OCAMLMKTOP" fi AC_MSG_CHECKING(for Ocaml header files) dirs="/usr/lib/ocaml/caml /usr/local/lib/ocaml/caml" dir="`$OCAMLC -where 2>/dev/null`" if test "$dir"; then dirs="$dir/caml $dirs" fi for i in $dirs; do if test -r $i/mlvalues.h; then AC_MSG_RESULT($i) OCAMLEXT="$i" OCAMLINC="-I$OCAMLEXT" break; fi done if test -z "$OCAMLINC"; then AC_MSG_RESULT(not found) fi export OCAMLINC export OCAMLBIN export OCAMLC export OCAMLDLGEN export OCAMLFIND export OCAMLMKTOP AC_SUBST(OCAMLINC) AC_SUBST(OCAMLBIN) AC_SUBST(OCAMLC) AC_SUBST(OCAMLDLGEN) AC_SUBST(OCAMLFIND) AC_SUBST(OCAMLMKTOP) #---------------------------------------------------------------- # Look for Pike #---------------------------------------------------------------- # Identify the name of the Pike executable PIKEBIN= AC_ARG_WITH(pike,[ --with-pike=path Set location of Pike executable],[ PIKEBIN="$withval"], [PIKEBIN=]) if test -z "$PIKEBIN"; then AC_CHECK_PROGS(PIKE, pike) else PIKE="$PIKEBIN" fi # Check for a --with-pikeincl option to configure PIKEINCLUDE= AC_ARG_WITH(pikeincl,[ --with-pikeincl=path Set location of Pike include directory],[ PIKEINCLUDE="-I$withval"], [PIKEINCLUDE=]) AC_MSG_CHECKING(for Pike header files) if test -z "$PIKEINCLUDE"; then if test -n "$PIKE"; then PIKEPATH=`which $PIKE` PIKEINCLUDE=`$PIKE Tools/check-include-path.pike $PIKEPATH` AC_MSG_RESULT($PIKEINCLUDE) PIKEINCLUDE="-I$PIKEINCLUDE" fi if test -z "$PIKEINCLUDE"; then AC_MSG_RESULT(not found) fi else AC_MSG_RESULT($PIKEINCLUDE) fi AC_SUBST(PIKEINCLUDE) AC_SUBST(PIKECCDLFLAGS) AC_SUBST(PIKEDYNAMICLINKING) #---------------------------------------------------------------- # Look for CHICKEN #---------------------------------------------------------------- CHICKEN= CHICKEN_CONFIG= CHICKENHOME= CHICKENOPTS= CHICKENLIB= AC_ARG_WITH(chicken,[ --with-chicken=path Set location of CHICKEN executable],[ CHICKEN="$withval"], [CHICKEN=]) if test -z "$CHICKEN"; then AC_CHECK_PROGS(CHICKEN, chicken) else CHICKEN="$CHICKEN" fi AC_ARG_WITH(chickencfg,[ --with-chickencfg=path Set location of chicken-config],[ CHICKEN_CONFIG="$withval"], [CHICKEN_CONFIG=]) if test -z "$CHICKEN_CONFIG"; then AC_CHECK_PROGS(CHICKEN_CONFIG, chicken-config) else CHICKEN_CONFIG="$CHICKEN_CONFIG" fi if test -n "$CHICKEN_CONFIG" ; then AC_ARG_WITH(chickenhome,[ --with-chickenhome=path Set location of CHICKEN home directory],[ CHICKENHOME="$withval"], [CHICKENHOME=]) AC_ARG_WITH(chickensharedopts,[ --with-chickensharedopts=path Set compiler options for shared CHICKEN generated code],[ CHICKENSHAREDOPTS="$withval"], [CHICKENSHAREDOPTS=]) AC_ARG_WITH(chickenopts,[ --with-chickenopts=path Set compiler options for static CHICKEN generated code],[ CHICKENOPTS="$withval"], [CHICKENOPTS=]) AC_ARG_WITH(chickensharedlib,[ --with-chickensharedlib=path Set linker options for shared CHICKEN generated code],[ CHICKENSHAREDLIB="$withval"], [CHICKENSHAREDLIB=]) AC_ARG_WITH(chickenlib,[ --with-chickenlib=path Set linker options for static CHICKEN generated code],[ CHICKENLIB="$withval"], [CHICKENLIB=]) AC_MSG_CHECKING(for CHICKEN home directory) dirs="$CHICKENHOME `chicken-config -home | sed s/CHICKEN_HOME=//`" for i in $dirs ; do if test -d $i; then AC_MSG_RESULT($i) CHICKENHOME="$i" break fi done if test -z "$CHICKENHOME"; then AC_MSG_RESULT(not found) fi AC_MSG_CHECKING(for compiler options for shared CHICKEN generated code) if test -z "$CHICKENSHAREDOPTS"; then CHICKENSHAREDOPTS="`chicken-config -shared -cflags`" else CHICKENSHAREDOPTS="`chicken-config -shared -cflags` $CHICKENSHAREDOPTS" fi if test -z "$CHICKENSHAREDOPTS"; then AC_MSG_RESULT(not found) else AC_MSG_RESULT($CHICKENSHAREDOPTS) fi AC_MSG_CHECKING(for compiler options for static CHICKEN generated code) if test -z "$CHICKENOPTS"; then CHICKENOPTS="`chicken-config -cflags`" else CHICKENOPTS="`chicken-config -cflags` $CHICKENOPTS" fi if test -z "$CHICKENOPTS"; then AC_MSG_RESULT(not found) else AC_MSG_RESULT($CHICKENOPTS) fi AC_MSG_CHECKING(for linker options for shared CHICKEN generated code) dirs="$CHICKENSHAREDLIB `chicken-config -shared -libs -extra-libs | sed s/-L//g` /usr/lib" for i in $dirs ; do if test -r $i/libchicken.a; then AC_MSG_RESULT(libraries found in $i) CHICKENSHAREDLIB="$CHICKENSHAREDLIB `chicken-config -shared -extra-libs`" CHICKENSHAREDLIB="$CHICKENSHAREDLIB `chicken-config -shared -libs`" break fi done if test -z "$CHICKENSHAREDLIB"; then AC_MSG_RESULT(not found) fi AC_MSG_CHECKING(for linker options for static CHICKEN generated code) dirs="$CHICKENLIB `chicken-config -libs -extra-libs | sed s/-L//g` /usr/lib " for i in $dirs ; do if test -r $i/libchicken.a; then AC_MSG_RESULT(libraries found in $i) CHICKENLIB="$CHICKENLIB `chicken-config -extra-libs`" CHICKENLIB="$CHICKENLIB `chicken-config -libs`" break fi done if test -z "$CHICKENLIB"; then AC_MSG_RESULT(not found) fi fi # have CHICKEN_CONFIG AC_SUBST(CHICKEN) AC_SUBST(CHICKEN_CONFIG) AC_SUBST(CHICKENHOME) AC_SUBST(CHICKENOPTS) AC_SUBST(CHICKENSHAREDOPTS) AC_SUBST(CHICKENLIB) AC_SUBST(CHICKENSHAREDLIB) #---------------------------------------------------------------- # Look for csharp #---------------------------------------------------------------- AC_ARG_WITH(cil-interpreter, [ --with-cil-interpreter=path Set location of CIL interpreter for CSharp],[CSHARPBIN="$withval"], [CSHARPBIN=]) AC_ARG_WITH(csharp-compiler, [ --with-csharp-compiler=path Set location of CSharp compiler],[CSHARPCOMPILERBIN="$withval"], [CSHARPCOMPILERBIN=]) if test -z "$CSHARPCOMPILERBIN" ; then case $host in *-*-cygwin* | *-*-mingw*) AC_CHECK_PROGS(CSHARPCOMPILER, mcs.bat cscc csc);; *)AC_CHECK_PROGS(CSHARPCOMPILER, mcs cscc);; esac else CSHARPCOMPILER="$CSHARPCOMPILERBIN" fi CSHARPPATHSEPARATOR="/" CSHARPCYGPATH_W=echo if test -z "$CSHARPBIN" ; then CSHARPCILINTERPRETER="" if test "cscc" = "$CSHARPCOMPILER" ; then AC_CHECK_PROGS(CSHARPCILINTERPRETER, ilrun) else if test "mcs" = "$CSHARPCOMPILER"; then # Check that mcs is the C# compiler and not the Unix mcs utility by examining the output of 'mcs --version' # The Mono compiler should emit: Mono C# compiler version a.b.c.d csharp_version_raw=`(mcs --version) 2>/dev/null` csharp_version_searched=`(mcs --version | sed -n "/C#\|Mono/p") 2>/dev/null` CSHARPCOMPILER=""; if test -n "$csharp_version_raw" ; then if test "$csharp_version_raw" = "$csharp_version_searched" ; then CSHARPCOMPILER="mcs" fi fi # mono interpreter (ver 0.26 doesn't seem to work on Windows platforms) case $host in *-*-cygwin* | *-*-mingw*) ;; *)AC_CHECK_PROGS(CSHARPCILINTERPRETER, mint);; esac else if test "csc" = "$CSHARPCOMPILER"; then CSHARPPATHSEPARATOR="\\\\" CSHARPCYGPATH_W='cygpath -w' fi fi fi else CSHARPCILINTERPRETER="$CSHARPBIN" fi # Cygwin requires the Windows standard (Pascal) calling convention as it is a Windows executable and not a Cygwin built executable case $host in *-*-cygwin* | *-*-mingw*) if test "$GCC" = yes; then CSHARPDYNAMICLINKING=" -mno-cygwin -Wl,--add-stdcall-alias" else CSHARPDYNAMICLINKING="" fi ;; *)CSHARPDYNAMICLINKING="";; esac # CSharp on Windows platforms including Cygwin doesn't use libname.dll, rather name.dll when loading dlls case $host in *-*-cygwin* | *-*-mingw*) CSHARPLIBRARYPREFIX="";; *)CSHARPLIBRARYPREFIX="lib";; esac AC_SUBST(CSHARPCILINTERPRETER) AC_SUBST(CSHARPPATHSEPARATOR) AC_SUBST(CSHARPCYGPATH_W) AC_SUBST(CSHARPCOMPILER) AC_SUBST(CSHARPDYNAMICLINKING) AC_SUBST(CSHARPLIBRARYPREFIX) # Is this going to be used? #---------------------------------------------------------------- # Determine which languages to use for examples/test-suite and runtime lib #---------------------------------------------------------------- SKIP_TCL= if test -z "$TCLINCLUDE" || test -z "$TCLLIB" ; then SKIP_TCL="1" fi AM_CONDITIONAL(SKIP_TCL, test -n "$SKIP_TCL") AC_SUBST(SKIP_TCL) SKIP_PERL5= if test -z "$PERL" || test -z "$PERL5EXT" ; then SKIP_PERL5="1" fi AM_CONDITIONAL(SKIP_PERL5, test -n "$SKIP_PERL5") AC_SUBST(SKIP_PERL5) SKIP_PYTHON= if test -z "$PYINCLUDE" || test -z "$PYLIB" ; then SKIP_PYTHON="1" fi AM_CONDITIONAL(SKIP_PYTHON, test -n "$SKIP_PYTHON") AC_SUBST(SKIP_PYTHON) SKIP_JAVA= if test -z "$JAVA" || test -z "$JAVAC" || test -z "$JAVAINC" ; then SKIP_JAVA="1" fi AM_CONDITIONAL(SKIP_JAVA, test -n "$SKIP_JAVA") AC_SUBST(SKIP_JAVA) SKIP_GUILE= if test -z "$GUILEINCLUDE" || test -z "$GUILELIB" || test -z "$GUILE_GH_INTERFACE"; then SKIP_GUILE="1" fi AM_CONDITIONAL(SKIP_GUILE, test -n "$SKIP_GUILE") AC_SUBST(SKIP_GUILE) SKIP_GUILESCM= if test -z "$GUILEINCLUDE" || test -z "$GUILELIB" || test -z "$GUILE_SCM_INTERFACE"; then SKIP_GUILESCM="1" fi AM_CONDITIONAL(SKIP_GUILESCM, test -n "$SKIP_GUILESCM") AC_SUBST(SKIP_GUILESCM) SKIP_MZSCHEME= if test -z "$MZC" ; then SKIP_MZSCHEME="1" fi AM_CONDITIONAL(SKIP_MZSCHEME, test -n "$SKIP_MZSCHEME") AC_SUBST(SKIP_MZSCHEME) SKIP_RUBY= if test -z "$RUBY" || test -z "$RUBYINCLUDE" || test -z "$RUBYLIB" ; then SKIP_RUBY="1" fi AM_CONDITIONAL(SKIP_RUBY, test -n "$SKIP_RUBY") AC_SUBST(SKIP_RUBY) SKIP_PHP4= if test -z "$PHP4" || test -z "$PHP4INC" ; then SKIP_PHP4="1" fi AM_CONDITIONAL(SKIP_PHP4, test -n "$SKIP_PHP4") AC_SUBST(SKIP_PHP4) SKIP_OCAML= if test -z "$OCAMLBIN" || test -z "$OCAMLINC" ; then SKIP_OCAML="1" fi AM_CONDITIONAL(SKIP_OCAML, test -n "$SKIP_OCAML") AC_SUBST(SKIP_OCAML) SKIP_PIKE="1" # Always skipped! if test -z "$PIKE" || test -z "$PIKEINCLUDE" ; then SKIP_PIKE="1" fi AM_CONDITIONAL(SKIP_PIKE, test -n "$SKIP_PIKE") AC_SUBST(SKIP_PIKE) SKIP_CHICKEN= if test -z "$CHICKEN" || test -z "$CHICKENHOME" || test -z "$CHICKENLIB" ; then SKIP_CHICKEN="1" fi AM_CONDITIONAL(SKIP_CHICKEN, test -n "$SKIP_CHICKEN") AC_SUBST(SKIP_CHICKEN) SKIP_CSHARP= if test -z "$CSHARPCOMPILER" ; then SKIP_CSHARP="1" else if test "cscc" = "$CSHARPCOMPILER" && test -z "$CSHARPCILINTERPRETER" ; then SKIP_CSHARP="1" fi fi AM_CONDITIONAL(SKIP_CSHARP, test -n "$SKIP_CSHARP") AC_SUBST(SKIP_CSHARP) #---------------------------------------------------------------- # Miscellaneous #---------------------------------------------------------------- # Root directory # Translate path for native Windows compilers for use with 'make check' ROOT_DIR=`pwd` case $host in *-*-cygwin* | *-*-mingw*) if (cygpath --mixed $ROOT_DIR) >/dev/null 2>/dev/null; then ROOT_DIR=`cygpath --mixed $ROOT_DIR` fi # Extra files generated by some Windows compilers EXTRA_CLEAN="*.stackdump *.exp *.lib" ;; esac AC_SUBST(ROOT_DIR) AC_SUBST(EXTRA_CLEAN) AC_SUBST(ac_aux_dir) # Configure SWIG_LIB path AC_ARG_WITH(swiglibdir,[ --with-swiglibdir=DIR Put SWIG system-independent libraries into DIR.], [swig_lib="$withval"], [swig_lib="${libdir}/swig1.3"]) AC_SUBST(swig_lib) AC_DEFINE_DIR(SWIG_LIB, swig_lib, [Directory for SWIG system-independent libraries]) # Configure RELEASESUFFIX (for setups having both SWIG 1.1 and 1.3 on a system...) AC_ARG_WITH(release-suffix, [ --with-release-suffix=SUFFIX Attach SUFFIX to the binary and the runtime libs. ], [release_suffix="$withval"], [release_suffix=""]) AC_SUBST(release_suffix) AC_DEFINE_UNQUOTED(RELEASE_SUFFIX, "$release_suffix", [Executable and runtime libraries release suffix for co-existence with older versions]) release_suffix_libtool= if test -n "$release_suffix"; then release_suffix_libtool="-release `echo $release_suffix | sed s/^-//`" fi AC_SUBST(release_suffix_libtool) AC_CONFIG_FILES([ \ Makefile \ Runtime/Makefile \ Source/Makefile \ Examples/Makefile \ Examples/guile/Makefile \ Examples/GIFPlot/Makefile \ Examples/GIFPlot/Lib/Makefile \ Examples/test-suite/chicken/Makefile \ Examples/test-suite/csharp/Makefile \ Examples/test-suite/guile/Makefile \ Examples/test-suite/guilescm/Makefile \ Examples/test-suite/java/Makefile \ Examples/test-suite/mzscheme/Makefile \ Examples/test-suite/ocaml/Makefile \ Examples/test-suite/perl5/Makefile \ Examples/test-suite/php4/Makefile \ Examples/test-suite/pike/Makefile \ Examples/test-suite/python/Makefile \ Examples/test-suite/ruby/Makefile \ Examples/test-suite/tcl/Makefile \ ]) AC_CONFIG_FILES([preinst-swig], [chmod +x preinst-swig]) AC_OUTPUT dnl configure.in ends here cableswig-0.1.0+git20150808.orig/SWIG/Win/0002755000175000000620000000000012561312227016335 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Win/README.txt0000644000175000000620000000023112561312227020025 0ustar stevestaffPlease see the Doc/Manual/Windows.html file in the main manual for instructions for using and installing SWIG on Windows including running the examples. cableswig-0.1.0+git20150808.orig/SWIG/autogen.sh0000755000175000000620000000145112561312227017600 0ustar stevestaff#! /bin/sh # Bootstrap the development environment - add extra files needed to run configure. # Note autoreconf should do what this file achieves, but it has a bug when working with automake! # The latest config.guess and config.sub should be copied into Tools/config and checked into CVS # when upgrading the autotools. Otherwise this script will ensure the latest is copied from # your autotool installation. set -x test -d Tools/config || mkdir Tools/config aclocal -I Tools/config autoheader # Note: on Mac OS X there is a different program 'libtoolize' that is definitely not # what we want to run. Instead, we want to use 'glibtoolize' if test -x /usr/bin/glibtoolize; then glibtoolize --force --copy else libtoolize --force --copy fi automake --add-missing --copy --force-missing autoconf cableswig-0.1.0+git20150808.orig/SWIG/CHANGES0000644000175000000620000162277312561312226016612 0ustar stevestaffSWIG (Simplified Wrapper and Interface Generator) Version 1.3.21 (January 11, 2004) ================================== 01/10/2004: cheetah (William Fulton) The output format for both warnings and errors can be selected for integration with your favourite IDE/editor. Editors and IDEs can usually parse error messages and if in the appropriate format will easily take you directly to the source of the error. The standard format is used by default except on Windows where the Microsoft format is used by default. These can be overridden using command line options, for example: $ swig -python -Fstandard example.i example.i:4: Syntax error in input. $ swig -python -Fmicrosoft example.i example.i(4): Syntax error in input. 01/09/2004: beazley Fixed [ 871909 ] simple namespace problem. This was a problem using anonymous structures in a namespace. For example: namespace ns { typedef struct { int n; } S; }; Reported by Josh Cherry. 01/09/2004: beazley Fixed some broken Perl examples. 12/28/2003: cheetah (William Fulton) [Java and C#] Fixes for wrapping covariant (polymorphic) return types. For example: struct Base { virtual ~Base(); virtual Base* copy() const = 0; }; struct Derived : Base { virtual Derived* copy() const; }; The Derived::copy proxy method returns Base not Derived. A warning is issued about this. Previously the pointer used by the proxy class was incorrectly treated as a Base* instead of a Derived*. 12/18/2003: cheetah (William Fulton) Fix so that Windows paths are displayed correctly when reporting errors. An error previously would have been shown something like: .?xample.i:14: Syntax error in input. instead of: .\example.i:14: Syntax error in input. Version 1.3.20 (December 17, 2003) ================================== 12/17/2003: beazley Last minute modifications. Perl5 module now generates shadow classes by default like all of the other modules. PHP4 wrappers no longer include "config.h". 12/14/2003: beazley Weakened warning message related to constructor names so that an unusual nested-class wrapping technique would work again (apparently it worked in some older SWIG releases). For example: class Scope { class ClassA; class ClassB; }; class Scope::ClassA { ... }; class Scope::ClassB { ... } Note: There is still some odd interaction with the SWIG symbol table/type system that will need to be looked at in a future release. Reported by Gustavo Niemeyer. 12/11/2003: cheetah (William Fulton) [Java] Protected class methods are wrapped as protected Java methods when using the dirprot director feature. This can be changed using %javamethodmodifiers to something else should the need arise, for example, private or package access. 12/11/2003: cheetah (William Fulton) [Java, C#] %javamethodmodifiers (Java) and %csmethodmodifiers (C#) operate slightly differently. Previously this feature had to be present to set the method modifiers. Now it is only used if it exists for the method being wrapped. The default is "public" as previous however, when wrapping protected director methods it is "protected". This change will not affect existing use of the %javamethodmodifiers or %csmethodmodifiers. 12/11/2003: mmatus (Marcelo Matus) This fix some recurring reports about keywords not been properly identified and warned, and it solves the problem of how to add a test file to the test-suite such that it doesn't use any keyword of all the supported languages (and doing it without compiling the test for all the supported languages, thing that is not always possible, and without requiring you to know all the supported language keywords, thing that is always impossible). So these are the changes globally speaking: - Uniform the definition of the keyword warnings through the supported languages: all the languages has now a separate file that defines the keywords or bad names: python/pythonkw.swg chicken/chickenkw.swg .... - Added keyword list for most of the languages that didn't have one (using the new separated file). - Added the "All keywords" warning support: -Wallkw option. This option allows you to include all the known keywords for all the supported languages, and can be used as: swig -Wallkw .... This will help to the process of adding a test-suite file that can be compiled in all the swig supported languages, and it will be also helpful for users who want to create multi-language libraries. And these are the detailed changes (mostly file addition): - For the languages that already have some sort of keyword warning list, move it to an external languagekw.swg file, ie: move keywords from python.swg -> pythonkw.swg move keywords from chicken.swg -> chickenkw.swg move keywords from tcl8.swg -> tclkw.swg and re-include languagekw.swg from language.swg. - For the language that didn't have a keyword list, and for the ones that I could find a list, add the languagekw.swg file, ie: csharp/csharpkw.swg java/javakw.swg php4/phpkw.swg pike/pikekw.swg ruby/rubykw.swg also add a line in language.swg to include languagekw.swg, but now it is commented!!!, like in java.swg: /* java keywords */ /* please test and activate */ //%include "javakw.swg" ie, there will be no change in how swig runs normally until the language maintainer test and uncomment that line. So, please check each languagekw.swg file (I left the link to the keyword list source for checking), and after testing, uncomment the %include line. - Added the file allkw.swg, which includes all the languagekw.swg files. For the languages that has no languagekw.swg file right now, and if they need one, add the file into the language directory, and add the corresponding include line into the allkw.swg file. - Added the -Wallkw that includes the allkw.swg file. Note that the old -lallkw.swg option couldn't be used since it include the file after it would be needed. Hopefully, the -Wallkw option will be added to the default rules in the related test-suite Makefiles, so, when creating a new test, or adding a new swig library file (like _std_deque.i), swig will warn you if you are using a bad name, considering all the language where it needs to run. Right now you can test it by using: make check-python-test-suite SWIG="swig -Wallkw" or using your favorite target language, it doesn't matter. And yes, there are several examples that are using reserved keywords, specially from csharp. *** Remember ****: the new keyword warning lists are not included by default in any of language that before didn't have one. To enable the keyword warnings as the default behavior, the inclusion of the languagekw.swg file has to be uncommented at each language.swg file. So, all the language maintainers, please check the keywords list. Also, you can add buit-in names, and not only keywords, like 'True/False' in python. Remember that you can be more specific and refer only to member names, like *::configure or *::cget (see an example in the tcl8/tcl8kw.swg file), or only global names, like ::range (see an example in the python/pythonkw.swg file. Just to be consistent, use the following codes: - Use code 314 for keyword and/or fatal bad names. - Use code 321 for buit-in and/or not fatal bad names. so, they can't be disabled/enabled independently (see python/pyhtonkw.swg for examples). **** And don't add any new test file without checking it with the -Wallkw option!! (that includes me) *****. 12/11/2003: cheetah (William Fulton) SF bug #854634 Added support for accepting the Unix directory separator '/' on Windows and the Mac in addition to the native one ( '\' on Windows). This can be used in %import, %include and commandline options taking a path, for example -I. On Cygwin, both the Windows and Unix directory separator can now be used (was '/' only). 12/10/2003: mmatus (Marcelo Matus) [python] Implementing the runtime "reprotected" director members, if you have: %feature("director") B; class Bar { public: virtual ~Bar(); virtual int hello() { return do_hello();) protected: virtual int do_hi() {return 0;} virtual int do_hello() {return 0;} }; then, at the python side import my_module class Foo(my_module.Bar): def do_hello(self): return 1 pass b = Bar() # Pure C++ Director class f = Foo() # C++ Director + python methods b.hello() # Ok, and it calls C++ Bar::do_hello() f.hello() # Ok, and it calls Python Foo::do_hello() b.do_hi() # RuntimeError, do_hi() is protected!! f.do_hi() # RuntimeError, do_hi() is protected!! b.do_hello() # RuntimeError, do_hello() is protected!! f.do_hello() # Ok, since it its redefined in python. Here Bar.do_hello is always protected, but Foo.do_hello is "public", because it is redefined in python. Before, all the 'do_hello' methods were public. This seems to be a good compromise between C++ and python philosophies, ie, all the director protected methods keep protected at the user side (C++ way) until they are redefined (python way, were all defined methods are always public). And this is not only a good compromise, it also seems to be the only way to do it :). Now ruby has native director protected members, and python pure runtime support. I guess these are the two possible extreme cases. And hopefully, they could be used as templates to modify the other languages that support directors, so they can "reprotect" the protected director members at the target language side. This finished the director protected support for the python language. Ocalm will need to add the "reprotection" later. 12/10/2003: mmatus (Marcelo Matus) The following case (reported by Lyle Johnson) was fixed: %rename(x) Foo::y(); class Foo { public: void y(); protected: int x; }; swig warned that the symbol 'x' was already defined, and the renaming fails. 'x' was not emitted, since it is protected, but it was kept in the symbol table with too much information. Now swig works for all the cases (plain, director and dirprot) again. This was fixed by allowing the parser.y to decide much closer what to do with 'x'. Before all the discarding or generation was resolved at the lang.cxx stage. Also the changes in parser.y to implement the director protected mode are now much more encapsulated, and they get disabled if the mode is not enabled. Before the deactivation was done at the generation stage (lang.cxx). By the other hand, if the director mode is enabled, and %rename is done, reusing a protected member name, there is a pathological case: %rename(x) Foo::y(); class Foo : public A { public: void y(); protected: int x; /* works */ static int x; /* works */ static void x(); /* works */ typedef void x(); /* works */ virtual void x(); /* always fails, as it should, since Foo::x() will be emitted in the director */ void x(); /* always fails, but sometimes it shouldn't, since the Foo::x() will not be emitted if it is not virtual */ }; The last case is not always right because at the parser.py stage it is not possible to decide if the protected member Foo::x() could or not conflict with the renamed Foo::y(), since Foo::x() could be virtual by inheritance. I guess this just an intrinsic limitation, and no much can be done about it without resorting into larger changes to postpone, under certain conditions, the multiply symbol detection (lang.cxx stage). So, by now, it is just considered a well known "feature" in the director protected mode. The good news is that it seems to be a rare case, and it can be avoided by the user by hiding 'x' before renaming 'y': %rename(_x) Foo::x(); %rename(x) Foo::y(); 12/08/2003: mmatus (Marcelo Matus) The virtual method detections now properly treats the following cases: namespace foo { typedef int Int; } struct A {}; typedef A B; struct Foo { virtual ~Foo() {} virtual Foo* cloner() = 0; virtual int get_value() = 0; virtual A* get_class() = 0; virtual void just_do_it() = 0; }; struct Bar : Foo { Bar* cloner(); foo::Int get_value(); B* get_class(); void just_do_it(); }; All the Foo and Bar methods are virtual. A new attribute "virtual:type" record the base polymorphic type. In the previous cases we have: type : Bar virtual:type : Foo type : foo::Int virtual:type : int type : B virtual:type : A type : void virtual:type : void This attribute is useful in languages (java+directors) that could have problems redefining Bar* Bar::cloner(). If you never had code like the above, you will see no effects. But if you have some code like that, you will see some effects since some methods that before were not properly treated as virtual, will start to act like that. This could enlarge your director classes. 12/08/2003: mmatus (Marcelo Matus) The director protected member support (dirprot) is disabled by default. It can be enable by using '-dirprot' or by adding the option to the module declaration, like: %module(directors="1",dirprot="1") my_module This module option was added to properly compile the director_protected.i and director_nested.i examples. The feature has been tested with python[2.2,2.3] and ruby[1.6.7], both at compilation and runtime, and java[j2sdk1.4.1_01], but only at compilation (my java installation doesn't run any of the director examples, olds nor news). Please test for ocaml and java. The errors reported by William and Scott were fixed, except for a warning about SWIG_JavaThrowExecption() multiply defined. I can't reproduce this error with my examples. We will wait for Scott to send us a minimal case. 12/07/2003: mmatus (Marcelo Matus) The director protected member support has been completly moved out from python.cxx, and now resides in the common lang.cxx, emit.cxx and allocate.cxx files. This means it should work for all the other languages that currently support directors, ie, python, java, ocalm and ruby. The change has been tested with python (compilation+runtime) and java (just compilation). Please add runtime tests for the missing languages and test it. The '-nodirprot' option was moved to the principal main, and can be used from all the languages. 12/07/2003: cheetah (William Fulton) [Java] Fixed and improved error checking of STRING_OUT typemaps in various.i. 12/04/2003: mmatus (Marcelo Matus) - Now the virtual members with no explicit declarator are properly identified: struct A { virtual int f() = 0; }; struct B : A { int f(); }; Here, B::f() is virtual, and the director and the virtual elimination mechanism now recognize that. - [C#] This fix also fixes the problem where 'override' was not being used on any overridden virtual method, so for struct B above, this C# code is generated: public class B : A { ... public override int f() { ... } ... } - Initial support for protected virtual methods. They are now properly emitted when using with director (python only by now). %feature("director") A; struct A { protected: virtual int f1() = 0; }; %feature("director") B; struct B : A{ protected: int f1(); virtual f2(); }; This can be dissabled by using the '-nodirprot' option. - The feature 'nodirector' is working now at the top level, so, it must work for all the languages: %feature("director") A; %feature("nodirector") A::f2; struct A { virtual int f1(); virtual int f2(); }; in this case, only 'f1' is exported to the director class. - Added director support for const TYPE& arguments (python). 12/02/2003: cheetah (William Fulton) [Java] Fix for INOUT and OUTPUT typemaps in typemaps.i for when the JNI type is bigger than the C type. For example, unsigned long (32bits on most systems) is mapped to jlong (64bits). Returned value was incorrect. Bug reported by Brian Hawley. 12/02/2003: cheetah (William Fulton) [C# and Java] Better fix for entry dated 05/11/2003. Fixes the following typemaps: Java: javabase, javainterfaces, javaimports, javaclassmodifiers, javaptrconstructormodifiers, javafinalize, javagetcptr & javacode. C#: csbase, csinterfaces, csimports, csclassmodifiers, csptrconstructormodifiers, csfinalize, csgetcptr & cscode. It also fixes bug in using arrays of C structs with arrays_java.i as reported Scott Michel. 12/02/2003: beazley [Perl] Fixed [ 852119 ] recursive inheritance in output .pm, perl5. Reported by William Dowling. 12/02/2003: beazley [Tcl] Fixed [ 755382 ] calling func(const vector& p) evaluates p[0] in interp. The Tcl type checker was improperly handling the interpreter result when type violations were supposed to be ignored. Reported by Flaviu Popp-Nowak. 11/30/2003: cheetah (William Fulton) Fixed [ 545058 ] configure's --with-tclincl has no effect 11/30/2003: cheetah (William Fulton) [Java] Fixed [ 766409 ] missing symbol SWIG_JavaThrowException during module load SWIGs internal functions are all static as there is no need for different SWIG generated modules to share any code at runtime. 11/30/2003: beazley [Tcl] Added support for C++ pointers to members. 11/28/2003: cheetah (William Fulton) Fixed [ 848335 ] Directors: #include wrapper .h file - was incorrectly adding a directory to the generated #include "foo_wrap.h" statement in some situations. 11/28/2003: cheetah (William Fulton) [Java] Fixed [ 849064 ] JAVA : Access modifier for derived class wrong. The delete() method is always public now. It used to be protected whenever a destructor was non public. An UnsupportedOperationException runtime exception is thrown instead of making delete() protected now. 11/28/2003: beazley [Perl5] Added support for C++ pointers to members. 11/28/2003: beazley Fixed [ 850151 ] PYVERSION with python2.3 in configure of SWIG 1.3.19 (Maybe). 11/28/2003: beazley Fixed [ 850666 ] #include extra line added. This should fix some problems with getting correct line numbers on error messages. 11/26/2003: beazley Fixed another one of Marcelo's evil template bugs (infinite recursion). [ 849504 ] template and typedef -> inf. recursion. 11/26/2003: beazley Fixed parsing problem with declarations like this: int *x = &somearray[0]; 11/25/2003: beazley Fixed [ 756552 ] missing default argument class scope with "|". This is really only a band-aid fix for use of class-enums in expressions. For example: class A { public: enum Flag { flag1 = 0x1, flag2 = 0x2 }; void foo(int x = flag1 | flag2); }; Note: there are still some (more subtle) cases that are broken, but hard to fix due to an issue with template expansion. Will address later. Reported by Dmitry Mironov. 11/25/2003: beazley Incorporated [ 840878 ] support for %inline { ... } (PATCH). This adds support for the following: %inline { ... some code ... } The difference between this and %inline %{ ... %} is that the enclosed text is processed by the SWIG preprocessor. This allows special macros and other processing to be used in conjunction with %inline. Contributed by Salvador Fandino Garcia. 11/25/2003: beazley Fixed [ 836903 ] C++ inconsistency (with void arguments). SWIG was having difficulty with f() vs f(void) in C++ programs. For instance: class A { public: virtual void f(void) = 0; }; class B { public: virtual void f(); // Not matched to f(void) correctly }; The parser now normalizes all declarations of the form f(void) in C++ classes to f(). This should fix a variety of subtle problems with inheritance, optimizations, overloading, etc. Problem reported by Partho Bhowmick. 11/25/2003: beazley [Perl5] Incorporated [ 841074 ] better croaking (PATCH). This fixes some problems with strings and provides some new error functions. Contributed by Salvador Fandino Garcia. 11/25/2003: beazley Fixed [ 791835 ] Default argument with cast: txt = (char *)"txt" syntax Error. The parser should now accept things like this: void foo(char *s = (char *) "Hello"); Problem reported by Claudius Schnorr. 11/24/2003: beazley [Tcl] Fixed problem with cross module linking. Previously modules referred to base classes through a global variable. Now, the module looks up base classes through the type system itself---avoiding the need to link to a global like before. Caveat: modules with base classes must be loaded before modules with derived classes. 11/24/2003: mkoeppe (Matthias Koeppe) [Guile] In -scm mode, use () to represent null pointers, as it is done in -gh mode. 11/23/2003: mkoeppe (Matthias Koeppe) Add a generated script "preinst-swig", which can be used to invoke SWIG before it has been installed. It arranges that the runtime libraries from the source directory are used. 11/23/2003: mkoeppe (Matthias Koeppe) [Guile] In -gh mode, don't forget to call SWIG_Guile_Init. Add a SWIG_contract_assert macro. 11/23/2003: mkoeppe (Matthias Koeppe) [MzScheme] Update the configure check for the dynext object to work with MzScheme 205. 11/20/2003: mmatus Fixed the include/import error reported by Kerim Borchaev, where two files with names like 'dir1/hello.i' 'dir2/hello.i' can not be include at the same time. Swig was including just the first one, assuming the second one was not a different one, since it was checking/keeping just the basename 'hello.i'. 11/19/2003: beazley Changes to the SWIG runtime library support. - The -c command line option has been renamed to -noruntime - New command line option: -runtime. When supplied, this inserts the symbol SWIG_GLOBAL into the wrapper code. This, in turn, makes all of the runtime support functions globally visible. - New library file: swigrun.i. Used to create modules for runtime library (if needed). 11/18/2003: cheetah (William Fulton) 'make srcrpm' rpmbuild fix - patch from Joe Cooper 11/18/2003: mkoeppe (Matthias Koeppe) [Guile] Change meaning of configure option --with-guile to the name of the Guile executable. The new option --with-guile-prefix can be used to specify the tree where Guile is installed. (However, usually it suffices to use the single option --with-guile-config.) When running the run tests test-suite, make sure to use the version of Guile that SWIG was configured for. 11/17/2003: mkoeppe (Matthias Koeppe) [Guile] Improvements to object-ownership management in "-scm" mode. (They do not apply to the default "-gh" mode.) * Renamed the smob type that indicates that the object can be garbage collected from "collected swig" to "collectable swig", which is more precise. * Export the destructor functions again. It is now allowed to explicitly call destructors, even for garbage-collected pointer objects. A pointer object that has been passed to a destructor is marked in a special way using a new smob type, "destroyed swig". (This helps avoid nasty memory bugs, where references to dead C objects are still held in Scheme. Moreover, the garbage collector will not try to free a destroyed object once more.) * Destructor-like functions can also mark their arguments as destroyed by applying the typemap SWIGTYPE *DESTROYED. (It calls the function SWIG_Guile_MarkPointerDestroyed.) * Functions that "consume" their objects (or that "own" them after the call) can mark their arguments as not garbage collectable. This can be done by applying the typemap SWIGTYPE *CONSUMED. (It calls the function SWIG_Guile_MarkPointerNoncollectable.) * The macro TYPEMAP_POINTER_INPUT_OUTPUT from library pointer-in-out.i creates additional typemaps PTRTYPE *INPUT_CONSUMED, PTRTYPE *INPUT_DESTROYED. They mark the passed pointer object likewise. The typemap PTRTYPE *OUTPUT creates a garbage-collectable pointer object, like %newobject does for a returned pointer. Use the new typemap PTRTYPE *OUTPUT_NONCOLLECTABLE to create a pointer object that will not be garbage collected. 11/17/2003: mkoeppe (Matthias Koeppe) [Guile] Handle $input in "freearg" typemaps. Never qualify GOOPS slot names with the class name. Handle optional arguments properly in the GOOPS methods. 11/16/2003: cheetah (William Fulton) Fixes for installation to work with the upcoming Automake-1.8. mkinstalldirs was being used by a non-Automake makefile. mkinstalldirs is being phased out and so was not being created by Automake. install-sh used instead. 11/16/2003: cheetah (William Fulton) [Java] Numerous director improvements, tweaks and bug fixes since the initial implementation have been contributed by Scott Michel. 11/12/2003: beazley [Python] When %feature("shadow") is used to add code to shadow classes, the special variable $action expands to the name of the underlying wrapper function that would have been called normally. 11/12/2003: beazley [Python] When generating proxy class code, SWIG emits a few default methods for __repr__() and other Python special methods. Some of these methods are emitted after all of the contents of a class. However, this makes it hard to override the methods using %pythoncode and some other directives that allow code to be inserted into a class. These special methods are now emitted into the code *before* all of the other methods. Suggested by Eric Jones. 11/11/2003: beazley Preprocessor enhancement. For include statements like this: %include "foo/bar.i" the directory "foo" is now added to the search path while processing the contents of bar.i. Thus, if bar.i includes other files in the same directory, they will be found. Previously, you would have to add additional directories using -I to make this work correctly. Note: the C preprocessor seems to behave in an identical manner on many (most? all?) systems. Suggested by Kerim Borchaev. 11/11/2003: beazley Configuration changes to make SWIG work on Mac OSX 10.3.x (Panther). Tested with Python, Tcl, Perl, and Ruby---all of which seem to work. 11/08/2003: cheetah (William Fulton) [Java] Fixed the typemaps in various.i which were mostly broken. char **STRING_IN and char **STRING_RET typemaps replaced with STRING_ARRAY. float *FLOAT_ARRAY_RETURN typemap removed. 11/08/2003: beazley [Tcl] Tcl module now emits a safe module initialization function by default. It can be removed by running 'swig -nosafe'. 11/04/2003: mkoeppe (Matthias Koeppe) [Guile] Only use the SCM_ API when the function `scm_slot_exists_p' exists (needed for GOOPS support). This function was renamed during the Guile 1.5 series from `scm_slots_exists_p'. Report the right runtime library when invoked with -scm -ldflags. 11/03/2003: mkoeppe (Matthias Koeppe) [Chicken] Fix #782052. The --with-chickencfg configure option (and others) were not accepted. 11/02/2003: mkoeppe (Matthias Koeppe) [Guile] Merge new set of GOOPS changes by John Lenz. GOOPS objects are now manipulated directly by the C code. Some fixes to typemap-GOOPS interaction. 11/02/2003: mkoeppe (Matthias Koeppe) [Guile] Remove the file argument to -scmstub and -goops. The Scheme files are now always called MODULE.scm or MODULE-primitive.scm, where MODULE is the module name and "primitive" can be changed by the -primsuffix option. The Scheme files are now placed in the directory given by the -outdir option, or the current directory. (Patch by John Lenz, slightly modified.) *** INCOMPATIBILITY [Guile] *** 11/02/2003: mkoeppe (Matthias Koeppe) Unify the pointer-conversion runtime API. The standard functions are: * SWIG_NewPointerObj (POINTER, TYPE, FLAGS) -- Create an scripting object that represents a typed pointer. FLAGS are language specific. * SWIG_ConvertPtr (INPUT, RESULT, TYPE, FLAGS) -- Get a pointer from the scripting object INPUT and store it in the place RESULT. When a type mismatch occurs, return nonzero. * SWIG_MustGetPtr (INPUT, TYPE, ARGNUM, FLAGS) -- Get a pointer from the scripting object INPUT and return it. When a type mismatch occurs, throw an exception. If ARGNUM > 0, report it as the argument number that has the type mismatch. [Guile]: No changes. [MzScheme]: No changes. [Perl]: Add the function SWIG_NewPointerObj. The function SWIG_MakePtr is kept. The function SWIG_MustGetPtr is currently not supported. [Python]: Add the function SWIG_MustGetPtr. [Ruby]: Add the function SWIG_MustGetPtr. [Tcl]: Remove the "interp" argument of SWIG_NewInstanceObj, SWIG_ConvertPtr, SWIG_ConvertPacked, and SWIG_ConvertPtrFromString. The function SWIG_MustGetPtr is currently not supported. No changes to Pike because its pointer conversion code did not look complete. No changes to PHP4, because I did not understand its runtime code. No changes to Chicken because major changes are expected soon anyway. No changes to Java, OCaml, C# because they do not seem to have a pointer-conversion runtime API. *** INCOMPATIBILITY [Tcl] *** 11/02/2003: mkoeppe (Matthias Koeppe) [Perl5, PHP4, Pike, Python, Ruby, Tcl]: Use the preprocessor to rename external functions of the SWIG runtime API to follow the naming convention SWIG__. This should allow linking more than one interpreter into a program. 10/31/2003: cheetah (William Fulton) [C#] Fix since introducing the exception and std::string delegates. The fix overcomes linker errors when using more than one SWIG module. Problem reported by Andreas Schörk. 10/31/2003: beazley Incorporated patch: [ 823302 ] Incr Tcl support. Contributed by Alexey Dyachenko. Note: needs documentation. 10/31/2003: beazley Incorporated patch: [ 829325 ] new Python Module options and features. Robin Dunn writes: This patch makes a number of changes to the SWIG python module. 1. Add -apply option, and change the default code output to use the foo(*args, **kw) calling syntax instead of using apply(). If the -apply option is given then code is generated as before. This is very similar to Patch #737281 but the new -modern option makes the second half of that patch unnecessary so it is not included here. 2. Add -new_repr option. This is the same as my Patch #797002 which I will mark as closed since it is no longer needed. When this new option is used then the __repr__ methods that are generated for proxy classes will be more informative and give details about the python class and the C++ class. 3. Add %feature("addtofunc"). It allows you to insert one or more lines of code inside the shadow method or function that is already generated, instead of replacing the whole thing like %feature("shadow") does. For __init__ it goes at the end, for __del__ it goes at the begining and for all others the code generated is expanded out to be like def Bar(*args, **kwargs): val = _module.Foo_Bar(*args, **kwargs) return val and the "addtofunc" code is inserted just before the return statement. If the feature is not used for a particular method or function then the shorter code is generated just like before. 4. A little bit of refactoring to make implementing addtofunc a little easier. 5. Added a -modern command-line flag that will cause SWIG to omit the cruft in the proxy modules that allows it to work with versions of Python prior to 2.2. The result is a simpler, cleaner and faster python proxy module, but one that requires Python 2.2 or greater. 10/31/2003: beazley Incorporated patch: [ 829319 ] XML module tweaks. This adds a new command line option -xmllite that greatly reduces the amount of emitted XML code by eliminating some fields mostly used in SWIG's internal processing. Contributed by Robin Dunn. 10/31/2003: beazley Incorporated patch: [ 829317 ] Adds DohSplitLines function. Contributed by Robin Dunn. 10/29/2003: beazley Fixed [ 827907 ] argout objects not being wrapped properly (PATH). Patch contributed by Salvador Fandiño García. 10/29/2003: beazley Fixed [ 826996 ] perl type checking ignores perl subclasses. This enhancement makes it so wrapped classes and structs can be subclassed in Perl and used normally. Patch contributed by Salvador Fandiño García. 10/16/2003: cheetah (William Fulton) [C#] IntPtr marshalled with a void* instead of int in C function declarations. The casts thus look more conventional, for example: // old DllExport double SWIGSTDCALL CSharp_get_Shape_x(int jarg1) { ... Shape *arg1 = (Shape *) 0 ; arg1 = *(Shape **)&jarg1; ... } // new DllExport double SWIGSTDCALL CSharp_get_Shape_x(void * jarg1) { ... Shape *arg1 = (Shape *) 0 ; arg1 = (Shape *)jarg1; ... } 10/14/2003: beazley Fixed a subtle problem with overloaded methods and smart pointers. If a class has overloaded methods like this: class Foo { public: int bar(int x); static int bar(int x, int y); }; and the class is used as a smart pointer: class FooPtr { public: Foo *operator->(); }; The SWIG would try to expose the static member Foo::bar through FooPtr---resulting bogus wrapper code and a compiler error. Due to the way in which overloading is handled, it is extremely difficult to eliminate the static method in this case. Therefore, it is still exposed. However, the generated code now compiles and works. 10/05/2003: mkoeppe (Matthias Koeppe) [Guile, MzScheme, Chicken]: Remove symbol clashes between the runtime libraries by renaming all extern common.swg functions with the preprocessor. 10/05/2003: mkoeppe (Matthias Koeppe) [Guile] Added basic GOOPS support, contributed by John Lenz. See the documentation for details. *** NEW FEATURE *** 10/04/2003: mkoeppe (Matthias Koeppe) [Guile] New option, -only-setters, which disables traditional getter and setter procedures for structure slots. 10/03/2003: mkoeppe (Matthias Koeppe) [Guile] Added run test for reference_global_vars by John Lenz. 09/30/2003: beazley Partial solution to [ 792180 ] C++ smart-pointer/namespace mixup revisited. The problem is not easy to fix (at least it doesn't seem so), but is related to the instantiation of qualified templates inside of other namespaces. SWIG now generates an error message in this case rather than generating broken wrappers. 09/30/2003: beazley Fixed [ 800012 ] ENTER macro from CORE/scope.h clashes with libc search.h. Reported by Britton Leo Kerin. 09/30/2003: beazley Fixed [ 811518 ] Casting ints to doubles (w/ solution?) Addresses a problem with overloading in the Perl module. Reported by Gerald Dalley. 09/28/2003: mkoeppe [Guile with -scm option] Fix typo in generated code for procedures-with-setters. Reported by John Lenz. 09/26/2003: beazley Fixed [ 812528 ] externs not correct when throw is in signature. Reported by Joseph Winston. 09/23/2003: cheetah (William Fulton) SWIG was generating a number of symbols that didn't comply with the ISO C/C++ standard, in particular ISO/IEC 14882:1998(E) 17.4.3.1.2 where double underscores are forbidden as well as symbols starting with an underscore followed by an upper case letter. Most of these have been rooted out. See new section added to internals.html development manual 'Symbol Naming Guidelines for Generated C/C++ Code'. 09/23/2003: cheetah (William Fulton) Director typemap name changes: inv => directorin outv => directorout argoutv => directorargout *** POTENTIAL INCOMPATIBILITY *** 09/19/2003: mrose (Mark Rose) [Python] Director constructors now default to __disown = 0, which is the intended behavior and fixes the director_finalizer test case under python. 09/12/2003: cheetah (William Fulton) [C#] - Typemaps added for std::string and const std::string &. - New delegate for creating a C# string given a char *. It can be used by calling SWIG_csharp_string_callback as shown in the std::string 'out' typemap. Useful if the return type is mapped to a C# string and the calling function is responsible for cleaning up memory as the C# garbage collector doesn't free the memory created in C/C++ and then returned as a C# string. - The exception delegates have moved into an inner class in the intermediate class, thereby freeing up the static constructor. 09/11/2003: beazley (Internals) Major refactoring of iteration over lists and hashes. The DOH library now uses iterators. They work like this: List *l = (some list); Iterator i; for (i = First(l); i.item; i = Next(i)) { // i.item contains the actual list item. // i.item is NULL at end of list ... } Hash *h = (some hash); Iterator j; for (j = First(h); j.item; j = Next(j)) { // j.item contains hash table item // j.key contains hash table key // Both j.item and j.key are NULL at end ... } The old iteration functions Firstitem(), Nextitem(), Firstkey(), and Nextkey() are gone. The new iterators are simpler, result in better memory use, and may be faster. Also, there are no longer any problems iterating over the same list/hash in multiple places at the same time. For example, this is fine: Iterator i,j; for (i = First(l); i.item; i = Next(i)) { for (j = First(l); j.item; j = Next(j)) { ... } } (This never worked in previous versions). *** POTENTIAL INCOMPATIBILITY ***. This will probably break third party extensions to SWIG (or give them further encouragement to join the SWIG CVS-tree :-). 09/10/2003: mkoeppe (Matthias Koeppe) [Guile] Fix memory leaks in the "list-vector.i" typemaps. 09/09/2003: mkoeppe (Matthias Koeppe) [Chicken] Use C_mk_bool rather than C_mkbool. This fixes the wrapping of boolean values for Chicken 1.10 and newer. Reported by Dave / Felix Winkelmann . 09/05/2003: cheetah (William Fulton) [Java] Directors implemented for Java. In summary this is a big new feature which supports upcalls from C++ to Java. Code is generated to support C++ callbacks to call into Java and true polymorphic behaviour for Java classes derived from C++ classes. See java.html for details. Contributed by Scott Michel. 09/05/2003: Tiger Created contract example directory at /SWIG/Examples/contract Added simple contract examples (simple_c & simple_cxx) Modified contract module's output format *** NEW FEATURE *** 09/01/2003: cheetah (William Fulton) Test-suite build improvements: - Multiple build directories working for the test suite, so it is now possible to run configure in multiple subdirectories and run the test suite in each of these sub directories. - 'make distclean' fixed so it doesn't bomb out on the Examples directory when using multiple subdiretory builds. Required the following directories to be moved: Examples/GIFPlot/Perl -> Examples/GIFPlot/Perl5 Examples/GIFPlot/Php -> Examples/GIFPlot/Php4 These new directories used to be symbolic links to the old directory. Also the Examples/test-suite/Perl symbolic link has been removed. - Running the test-suite, other than from the root directory, say in Examples/test-suite/python will now display all the code being executed. - The following 3 C# compilers are detected during configure and work with the test-suite: Mono, Portable.NET and Microsoft. 09/01/2003: Tiger Added inheritance support for design by contract feature. 09/01/2003: beazley Fixed [ 794914 ] Wrong types in template specialization. SWIG was not handling arguments correctly in template partial specialization. For example, template class Foo { public: T *blah(); }; %template(FooInt) Foo; in this class, the return type of blah was set to 'int **', but it should really be 'int *'. This has been fixed, but it will affect all prior uses of partial specialization. 09/01/2003: beazley Fixed [ 786394 ] Patch for generated perl code does not compile under RedHat9. Reported by Scott Finneran. 09/01/2003: beazley Fixed [ 791579 ] (unsigned) long long handled incorrectly (Tcl). This was an error in the Tcl typemaps.i file. Reported by Kjell Wooding. 09/01/2003: beazley Fixed [ 797573 ] no way to rename classes coming from C structures. This problem relates to renaming of anonymous structures with a typedef. For example: %rename(Bar) Foo; typedef struct { ... } Foo; Reported by Britton Leo Kerin. 09/01/2003: beazley Fixed [ 797576 ] -help seems to imply that only tcl-specific options exist. Added a comment to alert user to other options. Reported by Britton Leo Kerin. 09/01/2003: beazley Fixed [ 798205 ] Segfault in SWIG_ConvertPtr. Reported by Prabhu Ramachandran. 08/30/2003: mrose (Mark Rose) Modified the director typemaps in python/std_complex.i to use the new-style macro and conversion functions, which eliminated some redundant code. Fixed a few bugs in these typemaps as well, although more testing is needed. 08/29/2003: mrose (Mark Rose) Completed initial support for wrapping abstract classes with directors. Constructor wrappers will be generated for abstract classes that have directors, and instances of the director classes will be created regardless of whether the proxy class has been subclassed in the target language. No checks are made during construction to ensure that all pure virtual methods are implemented in the target language. Instead, calls to unimplemented methods will throw SWIG_DIRECTOR_PURE_VIRTUAL_EXCEPTION exceptions in C++. Integrated Prabhu Ramachandran's typemap patches, which provide director typemap support for enums and std::size_t, and fix a couple bugs in the director std::vector<> typemaps. 08/29/2003: cheetah (William Fulton) [C#] Implemented exception handling for throwing C# exceptions from C/C++ code. A few delegate functions are available for calling which then throw the C# exception. Use the SWIG_CSharpThrowException function from C/C++ typemaps. See the generated wrapper code or csharphead.swg for all available exceptions. Example: SWIG_CSharpThrowException(SWIG_CSharpException, "exception description"); The 'throws' typemaps are also now implemented, so code is automatically generated to convert any C++ exception into a C# System.Exception when the C++ method declares an exception specification such as: int foo() throw(Bar); Also any parameters that are references to a C++ class or a class passed by value and are passed as a C# null will now throw a C# NullReferenceException. 08/29/2003: cheetah (William Fulton) [C#] Fix to match the calling convention of all pinvoke methods so that they match the calling convention used by default in the C# 'static extern' declarations (__stdcall is used on Windows). 08/19/2003: cheetah (William Fulton) [Java] Reworked std::string typemaps. Fixes a number of string in std namespace problems. For example %template vector. The templated class' get method wasn't returning a Java String, but a SWIGTYPE_p_string. Reported by Zach Baum. 08/15/2003: beazley Fixed [ 763522 ] 1.3.19 segfault in SwigType_add_pointer/DohInsertitem. Related to problem with unnamed class handling in Perl module. 08/15/2003: beazley Fixed [ 763563 ] Missing indication of optional arguments. Tcl module. Reported by Krzysztof Kozminski. 08/15/2003: beazley Fixed [ 787432 ] long param handled as int. Tcl module now uses Tcl_GetLongFromObj to convert integer values. 08/11/2003: beazley Fixed [ 775989 ] numeric template parameters. There were some errors in template expansion related to the use of arrays where the array dimension was a template parameter. It should work now. Reported by Bryan Green. 08/10/2003: mrose (Mark Rose) Added a director typemap (outv) for return by value and cleaned up up a few of the commented director typemaps. 08/10/2003: mrose (Mark Rose) Fixed constructor generation for director classes to ignore private constructors. Protected constructors are also ignored for now, pending a solution to the problem of wrapping classes that only define protected constructors. 08/07/2003: cheetah (William Fulton) New commandline option -outdir

to specify where the language specific files are to be generated. This is useful for target languages like Python, Java etc which generate proxy files in the appropriate language. This option does not apply to the C/C++ wrapper file. 08/07/2003: cheetah (William Fulton) On Windows the generated files (other than the _wrap.c or _wrap.cxx files) were sometimes incorrectly being generated into the current directory unless the input file used the Unix path separator. The Windows path separator should now be used. Bug reported by Robert Davies. 08/07/2003: beazley Added array variable set typemap to Perl module. 08/07/2003: beazley Fixed [ 775677 ] Array init causes codegen bug.. 08/07/2003: beazley Fixed [ 779062 ] Class"\n"::foo not supported. SWIG should now correctly handle whitespace in between namespace qualifiers. For example "A :: Foo :: Bar". 07/31/2003: cheetah (William Fulton) Fixes for parameters which are classes that are passed by value and have a default value. A copy constructor for SwigValueWrapper is required (SF #780056). Also fixed memory leak in these circumstances. These mods also fix SF #780054. 07/28/2003: beazley Improved run-time error message for pointers in Python module. Contributed by Zooko. 07/10/2003: ballabio (Luigi Ballabio) [Almost all languages] Wrappers for std::pair added. Typemaps for Python, Ruby, Guile and MzScheme. 07/01/2003: mkoeppe (Matthias Koeppe) [Chicken] Handle the case of more than one argout typemap per function. 06/29/2003: cheetah (William Fulton) [Java, C#] SF #670949 request. The destructor wrapper function name is now configurable. A new attribute called methodname in the javadestruct/javadestruct_derived (Java) or csdestruct/csdestruct_derived (C#) typemaps specifies the method name. For example in Java the destructor is wrapped by default with the delete method: %typemap(javadestruct, methodname="delete") SWIGTYPE {...} 06/27/2003: cheetah (William Fulton) [Java, C#] The throws attribute for adding exception classes to the throws clause also now works with the following typemaps: newfree javain, javaout (Java) csin, csout (C#) For example, the 'AnException' will be added to the throws clause in the proxy function: %typemap(javaout, throws="AnException") int { int returnValue=$jnicall; if (returnValue==0) throw new AnException("Value must not be zero"); return returnValue; } 06/25/2003: mrose (Mark Rose) [Python] Director typemap marshalling checks for null pointers when walking the parameter list instead of relying soley on the parameter count. Cures a segfault that occured for multiple argument inv typemaps. Someone with more Swig experience should probably review this code. 06/24/2003: mkoeppe (Matthias Koeppe) [Chicken] Don't emit calls to "C_check_for_interrupt", which may result in an endless loop. Patch by felix@proxima-mt.de. 06/20/2003: cheetah (William Fulton) [C#] Finalizers now use destructor syntax as the override which was used in the Finalize method is not in the ECMA standards, spotted by the MS compiler. 06/10/2003: cheetah (William Fulton) [C#] A number of changes have been made to remove the Java naming that was used in the C# module. Typemap name changes: jni -> ctype jtype -> imtype jstype -> cstype javain -> csin javaout -> csout javainterfaces -> csinterfaces javabase -> csbase javaclassmodifiers -> csclassmodifiers javacode -> cscode javaimports -> csimports javaptrconstructormodifiers -> csptrconstructormodifiers javagetcptr -> csgetcptr javafinalize -> csfinalize Feature name changes: javaconst -> csconst javamethodmodifiers -> csmethodmodifiers Pragma changes: pragma(java) -> pragma(csharp) jniclassbase -> imclassbase jniclassclassmodifiers -> imclassclassmodifiers jniclasscode -> imclasscode jniclassimports -> imclassimports jniclassinterfaces -> imclassinterfaces Special variable name changes: $javaclassname -> $csclassname $javainput -> $csinput $jnicall -> $imcall This will break SWIG interface files that use these typemaps, features and pragmas. Please update your code or use macros for backwards compatibility. *** POTENTIAL INCOMPATIBILITY FOR C# MODULE *** 06/10/2003: mkoeppe (Matthias Koeppe) [MzScheme] Applied MzScheme module updates contributed by John Lenz . - Updated mzscheme to use SWIG's common runtime type system from common.swg. - The Lib/mzscheme directory has been reorganized to standardize names across the language modules: mzscheme.i was moved to mzscheme.swg, mzscheme.swg and mzschemedec.swg have been removed, mzrun.swg (which contains the runtime code) has been added. - The swig_proxy structure was renamed to swig_mz_proxy. swig_mz_proxy now contains a pointer to a swig_type_info structure. - Added varin and varout typemaps for SWIGTYPE [] and SWIGTYPE &. - Garbage collection by calling scheme_add_finalizer() has been added. *** NEW FEATURE [MzScheme] *** 06/10/2003: cheetah (William Fulton) [Java] New typemaps: javadestruct and javadestruct_derived for the C++ destructor wrapper. The javadestruct version gets used by classes at the top of an inheritance chain and the javadestruct_derived version gets used by other classes. [C#] cildispose and cildisposeoverride typemaps replaced by csdestruct and csdestruct_derived typemaps. The delete() method has been removed and its functionality put into these typemaps designed for the Dispose() method. - New typemaps csinterfaces and csinterfaces_derived replace the javainterfaces typemap. Also fixes the peculiarity of all classes in an inheritance chain individually deriving from the IDisposable interface. - New typemap csfinalize for finalizers. C++ destructors are now called by garbage collector during finalization. Problem reported by Andreas Schörk. 06/10/2003: Tiger Modified contract code for error message output. Contract code can now print out simple error message. Modified contract code to prepare for inheritance 06/03/2003: mkoeppe [Guile] Applied Guile module updates contributed by John Lenz . - SWIG currently uses Guile's gh_ API, which is marked as deprecated in Guile 1.6 and will be removed in Guile 1.9. This change introduces a command-line flag "-scm" which causes SWIG to generate wrappers that use Guile's SCM API instead; this requires Guile >= 1.6. - The Lib/guile directory has been reorganized to standardize names across language modules: guiledec.swg and guile.swg have been moved into guile_gh_run.swg, guile.i has been moved to guile_gh.swg, guile_scm.swg and guile_scm_run.swg which contain the SCM API stuff have been added - ghinterface.i, which contains the defines from the gh_ functions to the scm_functions has been added - The API for dealing with pointer objects is now SWIG_ConvertPtr, SWIG_MustGetPtr, SWIG_NewPointerObj. - Added varin and varout typemaps for SWIGTYPE [] and SWIGTYPE & - Garbage collection has been added. *** NEW FEATURE [Guile] *** 06/01/2003: cheetah (William Fulton) Dimensionless arrays such as int foo[] = {1, 2}; extern int bar[]; produce a warning that the variable is read-only. Depending on the target language, this used to cause compile errors or generate a setter that generated a runtime error. A setter cannot be automatically generated because the array size cannot be determined by SWIG. A varin, globalin or memberin typemap (depending on the target language) must be written by the user. 05/29/2003: beazley Refinement to default typemap matching and arrays. When an array is declared like this: int foo[4]; The default typemap now resolves to SWIGTYPE [ANY] If no match is found for that, it then resolves to SWIGTYPE [] If no array dimension is specified in the original declaration, the SWIGTYPE [] is used right away. Note: This change has been made to resolve problems related to arrays with and without dimensions. For example, sometimes SWIG was generating setter functions for array variables with no dimensions (an error). Likewise, SWIG sometimes made arrays with dimensions read-only (also an error). This fixes the arrays_global test problem. 05/28/2003: beazley Fixed subtle type handling bug with references and pointers. If you had functions like this: typedef Foo Bar; Foo *func1(); void func2(Bar &x); Then func2() wouldn't accept objects returned by func1() because of a type error. It should work now. Reported by Brian Yang. 05/21/2003: cheetah (William Fulton) Fixes to some of the Visual C++ example project files which would not work with spaces in the paths held in the environment variables used to point to the target language's library / include directory. SF bug #740769 05/21/2003: songyanf (Tiger) Added -contracts option. First try of the idea of "Wrap by Contract": build up realiable cross-language module by wrapping with SWIG. Implemented basic assertion (preassertion & postassertion & invariant) for simple C/C++ functions. Current format of contracts are: %contract class_name :: func_name (paras...) { require: boolean exprs; exprs; ensure: boolean expr; exprs; invariant: boolean expr; exprs; } *** NEW FEATURE *** 05/19/2003: cheetah (William Fulton) Build tweaks. There were a few preprocessor definitions which were specified in the Makefile for passing on the commandline when compiling. These are now all defined in swigconfig.h. Autoconf doesn't normally allow installation directories to be defined in this config header file, but an autoconf archive macro enables this. This macro along with future autoconf macros are going to be put in the Tools/config directory. 'swig -version' now reports the target build platform. 05/11/2003: cheetah (William Fulton) [C# and Java] Fix to the following typemaps: javabase, javainterfaces, javaimports, javaclassmodifiers, javaptrconstructormodifiers, javafinalize, javagetcptr & javacode. These are the typemaps for modifying/generating proxy classes. Previously the typemaps would use the proxy class name and not the C++ type, which was inconsistent with all other typemaps. In most circumstances the proxy class name and the C++ class name/type is the same except for classes in namespace, templated classes etc. so this shouldn't affect most cases. *** POTENTIAL INCOMPATIBILITY FOR JAVA and C# MODULES *** 05/09/2003: cheetah (William Fulton) Visual C++ Project files have been added so that the runtime libraries can be built on Windows (for Tcl, Perl, Python and Ruby). 05/01/2003: beazley Fixed problem with return by value, const, and private constructors. For example: class B { private: B(); public: B(const B&); }; class A { ... const B returnB() const; ... }; Problem and patch suggestion reported by Bill Hoffman. 04/29/2003: cheetah (William Fulton) Build changes: - Single autoconf invocation - autoconf in the Tools directory has gone. - Libtool bootstrapped when running autogen.sh. This requires anyone using the cvs version of SWIG to have libtool installed on their machine. Suggest version 1.4.2 or higher, preferably the latest - 1.5. - Automake is now used to build the runtime libraries in conjunction with libtool. - Runtime libraries are now successfully built as DLLs on Cygwin. - Skipping languages is no longer just determined in the top level makefile but in configure.in. This info is used for building the runtime libraries and for running the examples and test-suite. - These changes have fixed multiple build directory builds, that is building from directories other than the top level directory. Installation from multiple build directories also working. An initial configure in the top level directory is no longer needed as described in 04/02/2003 entry. A 'make distclean' will be needed before building in a directory other than the top level directory if the autotools have been run from this top level directory at some point, but autoconf will tell you this. Note that 'make check' only works from the top level directory at the moment. 04/28/2003: beazley Fixed [ 723471 ] Wrapper_print() fails with preprocessor directives. 04/28/2003: beazley Minor refinement of const static member variable handling described in CHANGES 08/11/2002. Previously, SWIG merely checked to see if there was an initializer in the declaration. Now, SWIG additionally checks to make sure the static member is const. 04/25/2003: ljohnson (Lyle Johnson) [Ruby] Added a kind of limited support for multiple inheritance, activated using the -minherit command-line option. I've also updated the "C++ Inheritance" section of the Ruby documentation to discuss how this works, and its limitations. Also also modified the minherit.i test case to run against this. 04/25/2003: ljohnson (Lyle Johnson) [Ruby] Added the -globalmodule command-line option for the Ruby module, for wrapping stuff into the global module (Kernel) instead of a nested module. Updated documentation accordingly. 04/23/2003: mrose (Mark Rose) Fixed symname error in director calls to Python methods that extend C++ operators. Stopped director destructor wrappers from calling __set_up, which was leaving the director flag in an inconsistent state. 04/23/2003: beazley Fixed problem with namespace resolution and nested namespaces. Reported by Alfred Lorber (and Marcelo Matus). 04/16/2003: cheetah (William Fulton) Patch for Java examples and test-suite to run on Mac OS X. 04/15/2003: ljohnson (Lyle Johnson) [Ruby] Incorporated Nobu Nakada's patches for supporting the Ruby 1.8 allocation framework. 04/15/2003: ljohnson (Lyle Johnson) [Ruby] Replaced all uses of the deprecated STR2CSTR() macro with the safer StringValuePtr() macro. For more information, see ruby-talk:67059 and follow-ups to that post. 04/11/2003: beazley Fixed problem with preprocessor macro expansion. For example: #define min(x,y) ((x) < (y)) ? (x) : (y) int f(int min); Reported by Sebastien Recio. 04/10/2003: cheetah (William Fulton) [Java] Added a runtime check to typemaps in arrays_java.i library to check that the Java array passed in is the same size as the C array and throw an exception if not. Also fix to use delete instead of free for arrays created using new. 04/07/2003: cheetah (William Fulton) Remove GCC3 warning when compiling the examples and test-suite: cc1plus: warning: changing search order for system directory "/usr/include" cc1plus: warning: as it has already been specified as a non-system directory See SF patch #715531 submitted by Gerald Williams 04/03/2003: cheetah (William Fulton) [C#] Improved wrapping of enums and constants. These were previously wrapped as C# variables rather than constants. Either these are wrapped as readonly (runtime) constants or compile time constants, depending on the %javaconst directive (The directive is likely to change name soon). For example wrapping: %javaconst(0); #define ABC 22 %javaconst(1) XYZ; #define XYZ 33 is now: public static readonly int ABC = examplePINVOKE.get_ABC(); public const int XYZ = 33; 04/03/2003: cheetah (William Fulton) [Java] Global constants and enums are put in their own interface called xxxConstants, where xxx is the module name. This is an improvement as it is possible to derive (implement) a Java class from the xxxConstants interface to improve the syntax; namely when wrapping: enum {ONE=1, TWO, THREE}; accessing these from a Java class implementing xxxConstants is neater: int number = ONE; than the previous: int number = xxx.ONE; Patch submitted by Dave Dribin. 04/02/2003: cheetah (William Fulton) Build improvements for multiple builds. This allows one to build the SWIG executable and runtime libraries for different platforms/compilers etc by running configure in different directories. This isn't 100% just yet and won't be until libtool is better configured... a 'configure' and 'make distclean' needs to be run in the root directory before it all works. For example: $ ./configure $ make distclean $ mkdir config1; cd config1; ../configure CC=gcc CXX=g++; make; cd .. $ mkdir config2; cd config2; ../configure CC=cc CXX=c++; make; cd .. To be improved. A 'make check' does not work yet either. 04/01/2003: beazley Fixed template partial specialization argument expansion bug. This showed up when trying to use std_vector.i with vectors of pointers. 03/31/2003: cheetah (William Fulton) Fix for parallel make builds of SWIG, for example make -j 4 Build failure reported by Bill Clarke. 03/28/2003: beazley Released 1.3.19. Version 1.3.19 (March 28, 2003) =============================== 03/28/2003: beazley Variety of minor bug fixes to the 1.3.18 release including: - Segmentation fault with %extend directive. - Typemap variable substitution bug. - Expression evaluation bug. - Large memory leak with template expansion. Version 1.3.18 (March 23, 2003) =============================== 03/21/2003: beazley Fixed two problems with the %extend directive, overloading, and template expansion. See the 'template_extend_overload' and 'template_extend_overload_2' tests in Examples/test-suite for details. 03/20/2003: cheetah (William Fulton) [C#] Added some typemaps as suggested by Andreas Schoerk for handling parameters that are passed as pointers or by reference. These have been put in typemaps.i. 03/20/2003: beazley Fixed a C++ scoping bug related to code like this: class Foo { public: int Foo::bar(); }; Previously, SWIG just tossed out the Foo::bar() declaration. Now, the declaration is wrapped provided that the prefix is exactly the same as the current scope (including any enclosing namespaces). Reported by Bruce Lowery. 03/20/2003: beazley Incorporated [ 696516 ] Enabling exception processing for data member access. In some compilers, attribute access can generate exceptions. However, SWIG ordinarily assumes that no exceptions will be raised. To disable this, use the %feature("allowexcept"). For example: %feature("allowexcept") Foo::x; ... class Foo { public: int x; /* Exception handling enabled */ ... }; Patch contributed by Yakov Markovitch. 03/20/2003: beazley Incorporated Patch. [ 701860 ] Improve Performance (python proxies). Gives a performance boost to proxy class code and the management of the .this and .thisown attributes. Contributed by Mike Romberg. 03/19/2003: cheetah (William Fulton) [C# and Java] Added missing vararg support. 03/18/2003: mrose (Mark Rose) Removed code related to tagging individual methods for directors. The concept of having directors for some but not all virtual methods of a class is deeply flawed. The %feature("nodirector") tag is also gone. Directors are off by default. To enable them for a class, issue %feature("director") classname; which will create director methods for every virtual method in the hierarchy of the class. 03/17/2003: beazley Fixed a subtle problem with passing arguments of type function. For example: int foo(int x(int, int)); or typedef int binop_t(int, int); int foo(binop_t x); In old versions, this would produce code that wouldn't compile. Now, SWIG merely adds an extra pointer, making these declarations the same as: int foo(int (*x)(int, int)); typedef int binop_t(int, int); int foo(binop_t *x); Reported by Garth Bushell. 03/17/2003: mrose (Mark Rose) Fixed the return statement for director base class calls that have no return value. 03/15/2003: beazley Fixed a problem with const smart-pointer wrapping. For example: class Foo { public: int x; void bar() const; void spam(); }; class Blah { ... const Foo *operator->(); ... }; In this case, only "x" and "bar" are visible from Blah (since application of spam violates constness). Moreover, access to "x" is read-only. 03/15/2003: mrose (Mark Rose) Cleaned up two signed versus unsigned comparisons in python/std_vector.i. 03/15/2003: cheetah (William Fulton) [C#] Global variables are wrapped using properties instead of get and set methods. Member variable wrapping bug fixes, for example wrapping pointers work now. Typemaps are used for all variable wrapping to generate the property code. 03/13/2003: mrose (Mark Rose) Fixed a bug in the virtual method unrolling for directors. The order of unrolling is now from base to derived, to ensure that the most derived implementation of a director method is found. Director methods for pure virtual methods now throw DIRECTOR_PURE_VIRTUAL_EXCEPTION if _up is set. 03/12/2003: cheetah (William Fulton) [C#] Polymorphism fix: virtual functions now use the appropriate keyword in the C# proxy class, virtual or override. Some 'using System;' statement fixes needed by the Mono compiler. 03/11/2003: beazley Fixed subtle bug in the application of SwigValueWrapper<> to template classes with default constructors. Reported by Bruce Lowery. 03/11/2003: beazley The $descriptor(type) variable is now expanded in code supplied to %extend. This is useful for certain kinds of advanced wrapping (especially container classes). 03/11/2003: luigi Support for std::map. (a) Integration with scripting language (a la std::vector) for Python, Ruby, MzScheme, and Guile; (b) Simple wrapper for other languages 03/10/2003: beazley Fixed problem with escape sequences in string and character constants. SWIG wasn't parsing certain octal codes correctly. 03/07/2003: beazley Fixed a variety of subtle preprocessor problems reported by Sebastien Recio. (a) Empty preprocessor values no longer generate "bad constant value" errors. For example: #define FOO #define FOO BAR (b) Macro names can now span multiple lines (technically valid, although questionable practice). For example: #define A_LONG_MACRO_\ NAME 42 (c) Whitespace is no longer required before certain macro values. For example: #define FOO"Hello" #define BAR\ "Hello" 03/07/2003: ljohnson (Lyle Johnson) [Ruby] Added missing long long and unsigned long long typemaps in the Lib/ruby/typemaps.i library file. 03/07/2003: mrose (Mark Rose) Added Examples/python/callback to demostrate how directors can be used to implement callbacks in Python Added Examples/python/extend to demonstrate virtual method calls from C++ to Python (really the same as the callback example, just a different context). Added four tests for very basic director functionality. These have runtime tests under python. The Python module now emits #define SWIG_DIRECTORS near the top of the output file if directors are enabled. This is useful for disabling parts of tests in target languages that don't support directors. 03/06/2003: mrose (Mark Rose) Added a section to Doc/Manual/Python.html on cross language polymorphism (directors). 03/06/2003: mrose (Mark Rose) The short-lived "-fdirectors" command line option has been removed. To enable directors, instead use the extended %module directive as follows: %module(directors="1") modulename 03/06/2003: cheetah (William Fulton) The long long typemaps have been rewritten so that they can be more easily used with non ISO compilers, like Visual C++. For example if you are wrapping the Windows 64 bit type __int64 the long long typemaps can be used with %apply: %apply long long { __int64 }; __int64 value1(__int64 x); __int64 will now appear in the generated code instead of long long. 03/06/2003: beazley *** DEVELOPER CHANGE *** Swig module mutation has been changed slightly. When a language class method wants to save node attributes, it now uses one of the following functions: Swig_require() Swig_save() The first argument to these functions is a namespace in which saved attributes are placed. For example,this code Node *n; Swig_save("cDeclaration",n,"type","parms","name",NIL); saves the attributes as "cDeclaration:type", "cDeclaration:parms", and so forth. If necessary, a language module can refer to old values by using this special namespace qualifier. In addition to this, a special attribute "view" contains the name of the last namespace used to save attributes. In the above example, "view" would have the value "cDeclaration". The value of "cDeclaration:view" would have the previous view and so forth. Swig_restore(n) restores a node to the state before the last Swig_require() or Swig_save() call. Note: This change makes it easier for language modules to refer to old values of attributes. 03/06/2003: mrose (Mark Rose) Merged the cross-language polymorphism patch. When enabled, C++ "proxy" classes (called directors) are generated for each specified C++ class. Directors pass method calls from C++ to Python, similar to the way the usual proxy (shadow) classes pass method calls from Python to C++. Together, these two types of proxies allow C++ classes that are extended in Python to behave just like ordinary C++ classes and be used in C++ like native objects. This feature is still very experimental and is disabled by default. To enable director support, specify '-fdirectors' on the SWIG command line or in the SWIG_FEATURES environment variable. In the interface file, add %feature("director") to generate directors for all classes that have virtual methods. See http://stm.lbl.gov/~tm2/swig/ProxyDoc.html for more details. 03/03/2003: beazley Fixed a small glitch in typemap local variable replacement. If you had a typemap like this: %typemap(in) type ($1_type temp) { ... temp = ...; ... } and no occurrence of "$1_type" appeared in the body, then the local variable type wouldn't be substituted. 03/03/2003: cheetah (William Fulton) [C#] New version of the CSharp module which is typemap based. It also uses ECMA C# and no longer uses Microsoft Visual C++.NET glue. This means that it will work on non-Windows platforms. Contributed by Neil Cawse. 02/27/2003: beazley Fixed [ 653548 ] error parsing casting operator definition. SWIG now ignores casting operators declared outside of a class. For example: inline A::operator char *() { ... } Bug reported by Martin Casado. 02/27/2003: beazley Added support for anonymous bit-fields. For example: struct Foo { int x : 4; int : 4; int y : 8; }; Anonymous bit-fields are ignored by SWIG. Problem reported by Franz Höpfinger. 02/26/2003: cheetah (William Fulton) [Java] Better typemaps in the Examples/java/typemap example and also fixes subtle bug when using the StringBuffer typemaps more than once. 02/26/2003: beazley Fixed [ 642112 ] Constants char bug. 02/26/2003: beazley Fixed [ 675337 ] Partial template specialization not entirely working. There was a subtle problem related to the naming and ordering of template partial specialization arguments. Matching worked okay, the resulting templates weren't expanded correctly. 02/25/2003: beazley Fixed problem with parsing (and generating code) for references to arrays. For example: int foo(int (&x)[10]); 02/25/2003: beazley Fixed [ 635347 ] Compilation warning from libpy.c. Reported by Daniel L. Rall. 02/25/2003: beazley Fixed a subtle problem with virtual method implementation checking and typedef. typedef int *intptr; struct A { virtual int *foo() = 0; }; struct B : public A { virtual intptr foo() { }; }; SWIG was treating these declarations as different even though they are the same (via typedef). 02/25/2003: ljohnson (Lyle Johnson) [Ruby] Added range checking for the NUM2USHRT macro, per [ 675353 ]. 02/24/2003: beazley Fixed a subtle problem with the code that determined if a class is abstract and can be instantiated. If you had classes like this: struct A { virtual int foo(int) = 0; }; struct B : virtual A { virtual int foo(int); }; struct C : virtual A { }; /* Note order of base classes */ struct D : B, C { }; /* Ok */ struct E : C, B { }; /* Broken */ then SWIG determined that it could instantiate D(), but not E(). This inconsistency arose from the depth-first search of the inheritance hierarchy to locate the implementations of virtual methods. This problem should now be fixed---SWIG will attempt to locate any valid implementation of a virtual method by traversing over the entire hierarchy. 02/22/2003: cheetah (William Fulton) [Java] Fix for using enum typemaps. The Java final static variable type can be set using the jstype typemap, enabling enums to be mapped to something other than int. Bug reported by Heiner Petith. 02/21/2003: songyanf (Tiger) Added CSharp (C#) module prototype i.e. csharp.cxx & csharp.h at Source/Modules/. They are for test usage only now and need improvement. The interface also need to be modified. *** NEW FEATURE *** 02/20/2003: songyanf (Tiger) Fixed problem with typedef with -fvirtual. Similar as beazley's modification today. 02/20/2003: beazley Added support for gcc-style variadic preprocessor macros. Patch [ 623258 ] GCC-style vararg macro support. Contributed by Joe Mason. 02/20/2003: beazley Fixed [ 605162 ] Typemap local variables. Reported by Lyle Johnson. 02/20/2003: beazley Fixed problem with abstract classes and typedef. For example: class Foo { public: virtual void foo(int x) = 0; }; typedef int Integer; class Bar : public Foo { public: virtual void foo(Integer x); }; SWIG was getting confused about the latter method---making Bar abstract. Reported by Marcelo Matus. 02/19/2003: cheetah (William Fulton) [Java] %javaconst(flag) can also be used on enums as well as constants. This feature enables true Java compiler constants so that they can be used in Java switch statements. Thanks to Heiner Petith for patches. 02/19/2003: songyanf (Tiger) Modified -fcompact feature to deal with PP lines 02/18/2003: beazley Fixed [ 689040 ] Missing return value in std_vector.i. Reported by Robert H. de Vries. 02/18/2003: beazley Fixed a few evil scoping problems with templates, namespaces, and the %extend directive. Problem reported by Luigi Ballabio. 02/18/2003: cheetah (William Fulton) [Ruby] Improved support for Visual C++ and other native Windows compilers. It is no longer necessary to specify "/EXPORT:Init_", where is the swig module name when linking using these native Windows compilers. 02/15/2003: songyanf (Tiger) Added -fvirtual option. Reduce the lines and size of the wrapper file by omitting redifined virtual function in children classes. Modified -compact option to -fcompact option Added -small option. -small = -fvirtual -fcompact And it can be extended by future feature options, which are used to reduce wrapper file szie. Added SWIG_FEATURES environment variable check. To dynamically set the feature options such as -fcompact & -fvirtual *** NEW FEATURE *** 02/13/2003: lenz Updated Doc/Manual/Perl5.html to talk about C++ compile problems configure.in now checks for PERL5_CCFLAGS Runtime/Makefile.in and Example/Makefile.in now use PERL5_CCFLAGS Added Lib/perl5/noembed.h which contains all the known macro conflicts 02/12/2003: beazley Fixed [ 685410 ] C++ Explicit template instantiation causes SWIG to exit. Fixes a syntax error with declarations similar to this: template class std::vector; SWIG now ignores the instantiation and generates a warning message. We might do more later. Reported by Thomas Williamson. 02/11/2003: cheetah (William Fulton) Rewrote bool typemaps to remove performance warning for compiling generated code under Visual C++. 02/11/2003: cheetah (William Fulton) Fix for wrapping reference variables (const non-primitive and all non-const types) for example: int& i; Class& c; const Class& c; 02/11/2003: beazley Fixed more very subtle preprocessor corner cases related to recursive macro expansion. For example: #define cat(x,y) x ## y cat(cat(1,2),3) // Produces: cat(1,2)3 #define xcat(x,y) cat(x,y) xcat(xcat(1,2),3) // Produces 123 See K&R, 2nd Ed. p. 231. 02/10/2003: cheetah (William Fulton) Fixed [ 683882 ] - patch submitted by F. Postma for SWIG to compile on HP-UX. 02/10/2003: beazley Fixed subtle preprocessor argument expansion bug. Reported by Marcelo Matus. 02/10/2003: songyanf Added -compact option. Reduce the lines and size of the wrapper file by omitting comments and combining short lines. *** NEW FEATURE *** 02/07/2003: beazley Fixed [ 651355 ] Syntax error with cstring.i Reported by Omri Barel. 02/07/2003: beazley Fixed [ 663632 ] incompatibility with standard cpp. This is a refinement that fixes this problem: // Some macro with an argument #define FOO(x) x int FOO; /* Not a macro---no arguments */ 02/05/2003: beazley Fixed [ 675491 ] parse error with global namespace qualification. Submitted by Jeremy Yallop. 02/04/2003: beazley Fixed bug in varargs processing introduced by the numinputs typemap parameter. 01/08/2003: ttn [xml] Fix string-replacement ordering buglet. Thanks to Gary Herron. 12/23/2002: cheetah (William Fulton) Further build changes: - The SWIG executable is now built using a single Makefile. - This makefile is generated by Automake (Source/Makefile.am). - Dependency tracking and tags support are in this makefile. - Automake 1.7.2 and Autoconf 2.54 minimum versions are needed to build SWIG from CVS. - Running ./autogen.sh now installs Autoconf/Automake support files into Tools/config and these files are no longer stored in CVS. - Bug fixes in 'make install' for systems using .exe executable extension and ./configure --with-release-suffix=whatever 12/16/2002: cheetah (William Fulton) More build changes: - Autoconf's AC_CANONICAL_HOST replaces proprietary approach for detecting build host. - Autoconf support files moved to Tools/config. 12/16/2002: cheetah (William Fulton) Modifications to run on MacOS, submitted by Bernard Desgraupes. Mainly ensuring generated files are output in the appropriate directory for some modules. 12/11/2002: cheetah (William Fulton) Various build modifications and bug fixes: - Simplification of version string. Use autoconf's PACKAGE_VERSION instead. - Build time removed from SWIG version. - Using standard autoconf config header generation. - Updated old autoconf macros as reported by autoupdate. - Removed $prefix in autoconf from search paths as autoconf won't expand them. - Subtle bug fix where 'make prefix=/somewhere; make clean; make prefix=/somwhere/else' produced an executable using the incorrect library directories. - Added -ldflags commandline option for MzScheme, Ocaml, Pike and PHP. - Fixed reporting of compiler used when using -version commandline option. - SWIG web address added to -version commandline option. 12/11/2002: beazley Minor fix to Tcl dynamic cast typemaps. Reported by Kristopher Blom. 12/10/2002: beazley Fixed subtle template argument replace bug. Reported by Chris Flatley. 12/10/2002: beazley Reverted CHANGES 09/03/2002, preprocessor argument evaluation. Arguments are not evaluated during collection, K&R, p. 230. 12/06/2002: beazley Fixed [ 649022 ] Compilation problems with KAI/KCC 12/02/2002: beazley SWIG 'rel-1-3' CVS branch merged back into the main branch. Version 1.3.17 (November 22, 2002) ================================== 11/19/2002: beazley Fixed [ 613922 ] preprocessor errors with HAVE_LONG_LONG. 11/19/2002: beazley Fixed [ 615480 ] mzscheme SWIG_MustGetPtr_. 11/19/2002: beazley Fixed [ 635119 ] SWIG_croak causes compiler warning. 11/16/2002: cheetah (William Fulton) [Java] Added typemaps for pointers to class members. 11/15/2002: cheetah (William Fulton) [Java] Bug fix: Overloaded C++ functions which cannot be overloaded in Java once again issue a warning. 11/14/2002: cheetah (William Fulton) [Java] Handling of NULL pointers is improved. A java null object will now be translated to and from a NULL C/C++ pointer by default. Previously when wrapping: class SomeClass {...}; void foo(SomeClass *s); and it was called from Java with null: modulename.foo(null) a Java NullPointerException was thrown. Extra typemaps had to be written in order to obtain a NULL pointer to pass to functions like this one. Now the default wrapping will detect 'null' and translate it into a NULL pointer. Also if a function returns a NULL pointer, eg: SomeClass *bar() { return NULL; } Then this used to be wrapped with a SomeClass proxy class holding a NULL pointer. Now null is returned instead. These changes are subtle but useful. The original behaviour can be obtained by using the original typemaps: %typemap(javaout) SWIGTYPE { return new $&javaclassname($jnicall, true); } %typemap(javaout) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { return new $javaclassname($jnicall, $owner); } %typemap(javagetcptr) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] %{ protected static long getCPtr($javaclassname obj) { return obj.swigCPtr; } %} *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** 11/12/2002: beazley Fixed problem with abstract methods and signatures. For example: class abstract_foo { public: virtual int meth(int meth_param) = 0; }; class abstract_bar : public abstract_foo { public: int meth(int meth_param_1, int meth_param_2) { return 0; } }; In this case, abstract_bar is still abstract. Fixes [ 628438 ] Derived abstract class not abstract. Reported and patched by Scott Michel. 11/11/2002: beazley Fixed a matching problem with typemaps and array dimensions. For example, if you had this: typedef char blah[20]; and a typemap: %typemap() char [ANY] { ... $1_dim0 ... } then $1_dim* variables weren't be expanded properly. It should work now. Problem reported by Pankaj Kumar Goel. 11/07/2002: mkoeppe Added an experimental new module that dumps SWIG's parse tree as (Common) Lisp s-expressions. The module is invoked with SWIG's -sexp command-line switch. The output can be read into Common Lisp. There is (prototype) example Lisp code that generates Foreign Function Interface definitions for use with Kevin Rosenberg's UFFI. *** EXPERIMENTAL NEW FEATURE *** 11/07/2002: mkoeppe Removed duplicate declaration of "cpp_template_decl" in parser.y; bison 1.75 complained. 11/06/2002: cheetah (William Fulton) [Java] Default primitive array handling has changed like arrays of classes. C primitive arrays are no longer wrapped by a Java array but with a pointer (type wrapper class). Again the changes have been made for efficiency reasons. The original typemaps have been moved into arrays_java.i, so the original behaviour can be obtained merely including this file: %include "arrays_java.i" The array support functions are no longer generated by default. They are only generated when including this file, thus this often unused code is only generated when specifically requiring this type of array support. *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** 11/05/2002: ljohnson (Lyle Johnson) [Ruby] Added support for nested module declarations (as was previously added for the Perl module). So a %module directive of the form: %module "Outer::Inner::Foo" will nest everything as (in Ruby code): module Outer module Inner module Foo # stuff goes here end end end 11/05/2002: mkoeppe [MzScheme] Add an argument (-declaremodule) that generates code to correctly declare a primitive module extension. Patch submitted by Bruce Butterfield. 11/02/2002: cheetah (William Fulton) [Java] Added patch submitted by Michael Cahill to remove unused parameter warnings for the jenv and cls parameters. This patch also also allows one to use "void" in the jni typemap for any type without code being generated attempting to return a value. 10/29/2002: cheetah (William Fulton) [Java] Array handling is different. Arrays of classes are no longer wrapped with proxy arrays, eg wrapping class X {...}; X foo[10]; used to be wrapped with these Java getters and setters: public static void setFoo(X[] value) {...} public static X[] getFoo() {...} This approach is very inefficient as the entire array is copied numerous times on each invocation of the getter or setter. These arrays are now wrapped with a pointer so it is only possible to access the first array element using a proxy class: public static void setFoo(X value) {...} public static X getFoo() {...} Arrays of enums have also been similarly changed. This behaviour is now like the other SWIG language's implementation and the array library should be used to access the other elements. The original behaviour can be achieved using the macros and typemaps in arrays_java.i, for example: %include "arrays_java.i" JAVA_ARRAYSOFCLASSES(X) class X {...}; X foo[10]; *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** 10/29/2002: cheetah (William Fulton) [Java] Two new typemaps javain and javaout for generating the proxy class and type wrapper class method calls to the JNI class. The new typemaps are really used for transforming the jstype (used in proxy class and type wrapper classes) to the jtype (used in the JNI class) and visa versa. A javain typemap is required whenever an in typemap is written and similarly javaout for an out typemap. An example is probably best to show them working: %typemap(javain) Class "Class.getCPtr($javainput)" %typemap(javain) unsigned short "$javainput" %typemap(javaout) Class * { return new Class($jnicall, $owner); } %inline %{ class Class {}; Class * bar(Class cls, unsigned short ush) { return new Class(); }; %} The generated proxy code is then: public static Class bar(Class cls, int ush) { return new Class(exampleJNI.bar(Class.getCPtr(cls), ush), false); } Some new special variables have been introduced in order to use these typemaps. Here $javainput has been replaced by 'cls' and 'ush'. $jnicall has been replaced by the native method call, 'exampleJNI.bar(...)' and $owner has been replaced by 'false'. $javainput is analogous to the $input special variable. It is replaced by the parameter name. $jnicall is analogous to $action in %exception. It is replaced by the call to the native method in the JNI class. $owner is replaced by either true if %newobject has been used otherwise false. The java.swg file contains default javain and javout typemaps which will produce the same code as previously. This change is only of concern to those who have written their own typemaps as you will then most likely have to write your own javain and javaout typemaps. The javaout typemap also makes it possible to use a Java downcast to be used on abstract proxy base classes. See the Java documentation on dynamic_cast. *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** 10/24/2002: ttn [Methodology] Upgaded to libtool 1.4.3, presumably w/ better support for newish platforms (like MacOS X). 10/21/2002: ttn Fixed Runtime/Makefile.in bug -- thanks to Richard Calmbach. 10/18/2002: ttn Fixed typo in doh.h -- thanks to Max Horn. Version 1.3.16 (October 14, 2002) ================================= 10/13/2002: beazley Fixed bug with %extend directive and %feature reported by William Fulton. 10/13/2002: beazley Added OpenVMS build directory (vms). Contributed by Jean-François Pieronne. 10/09/2002: cheetah (William Fulton) [Java] Added throws clause to the native functions in the JNI class. The throws clause is the same as the one generated for proxy functions and module class functions. 09/27/2002: beazley Fixed some problems with the %import directive and classes that were defined but not wrapped. Problem reported by Leslie Brooks, Gerry Woods, and others. 09/23/2002: cheetah (William Fulton) [Java] Some error checking added: 1) OutOfMemoryException check in the char * typemaps. 2) As SWIG treats pointers, references and passing by value all the same, it is possible to pass a NULL pointer to a function that expects an object passed by value or by reference. A NullPointerException is now thrown under this scenario. 09/20/2002: ttn [Methodology] Reworked "make clean" and "make install" to be more table driven. [Docs] Explain how to extend "make install" w/ extra-install.list. 09/15/2002: beazley Deprecation of the "ignore" typemap. The "ignore" typemap has been deprecated in favor of a generalization of the "in" typemap. To ignore an argument, use something like this instead: %typemap(in,numinputs=0) int *output (int temp) { $1 = &temp; } This change fixes a number of subtle bugs related to the interaction of the "in" and "ignore" typemaps (which were supposed to be mutually exclusive). The use of the numinputs argument is reserved for future expansion. Currently, values >1 will generate an error. However, future releases of SWIG may utilize that to support multi-input typemaps. %typemap(ignore) still works, but generates a warning message and is translated to %typemap(in,numinputs=0). *** POTENTIAL INCOMPATIBILITY *** *** NEW FEATURE *** 09/15/2002: beazley Fixed segmentation fault for unnamed structures. For example: typedef struct { } *blah; Reported by Roger Gibson. Note: we might be able to generate wrappers in special cases. 09/13/2002: beazley Minor modification to generated wrapper functions. Pointer arguments are now always set to an initial value of 0. Simplifies typemap writing and cleanup code (since you can rely on zero-value initialization). This also greatly reduces the need to ever write an "arginit" typemap. 09/12/2002: beazley Minor enhancement to smart-pointer support. If operator->() is part of an ignored base class like this, %ignore Bar; class Foo { public: int blah(); }; class Bar { /* Ignored */ public: ... Foo *operator->(); ... }; class Spam : public Bar { }; then methods from Foo are still available. For example, >>> s = Spam() >>> s.blah() 0 >>> The only catch is that the operator->() itself is not available (since it wasn't wrapped). Therefore, there won't be any __deref__() operation unless it is explicitly added to Spam (either using %extend or just placing operator->() in the definition of Spam). 09/11/2002: ttn [Methodology] Reworked "make check" to be more table driven. [Docs] Docuemented methodology in Manual/Extending.html. 09/11/2002: ttn [Docs] Prefixed Manual/*.html with "" to pander dotingly to (over-)sensitive editors. 09/10/2002: ttn [Guile] Converted Examples/guile/simple "make check" behavior to actually check execution results. Reduced iteration counts so that the test doesn't take too long. 09/10/2002: beazley SWIG-1.3.15 released. Version 1.3.15 (September 9, 2002) ================================== 09/09/2002: beazley Fixed nasty runtime type checking bug with subtypes and inheritance and templates. 09/09/2002: cheetah (William Fulton) [Java] Java exception classes for a method's throws clause can be generated by specifying them in a comma separated list in the throws attribute in any one of the following typemaps: in, out, check, freearg, argout and throws. A classic example would be to convert C++ exceptions into a standard Java exception: %typemap(throws, throws="java.io.IOException") file_exception { jclass excep = jenv->FindClass("java/io/IOException"); if (excep) jenv->ThrowNew(excep, _e.what()); return $null; // or use SWIG_fail } class file_exception {...}; void open(const char *filename) throw(file_exception); The Java method will then be declared with a throws clause: public static void open(String filename) throws java.io.IOException {...} 09/08/2002: mkoeppe * [Guile] Improved the documentation system. The arglist no longer gets cluttered with type specification, making it more readable. (Also the ILISP function C-u M-x `arglist-lisp' RET works better this way.) The types of arguments are explained in an extra sentence after the arglist. There are now two documentation-related typemap arguments: %typemap(in, doc="$NAME is a vector of integers", arglist="$name") int *VECTOR { ... } The "arglist" texts of all arguments of a function make up its arglist in the documentation. The "doc" texts of all arguments are collected to make a sentence that describes the types of the arguments. Reasonable defaults are provided. As usual, $name is substituted by the name of the argument. The new typemap variable $NAME is like $name, but marked-up as a variable. This means that it is upper-cased; in TeXinfo mode ("-procdocformat texinfo") it comes out as @var{name}. The directives %values_as_list, %values_as_vector, %multiple_values now also have an effect on the documentation. (This is achieved via the new pragmas return_nothing_doc, return_one_doc, return_multi_doc.) Documentation has also improved for variables that are wrapped as procedures-with-setters (command-line switch "-emit-setters"). * [Guile] Emit constants as _immutable_ variables. (This was broken recently.) 09/07/2002: mkoeppe [Guile] Updated the typemaps in list-vector.i. 09/07/2002: mkoeppe Short-circuit the typechecks for overloaded functions. (The changes in code generation are visible in the new testcase "overload_complicated".) 09/06/2002: cheetah (William Fulton) [Java] Solution for [ 596413 ] New typemap so that the Java proxy classes and type wrapper classes wrapper constructor modifier can be tailored by users. The default value is protected. Normally SWIG generates a constructor like this which can only be accessed within one package: protected Bar(long cPtr, boolean cMemoryOwn) { ... } If you are using SWIG across multiple packages or want to use this constructor anyway, it can now be accessed outside the package. To modify use for example: %typemap(javaptrconstructormodifiers) SWIGTYPE "public" to change to public for all proxy classes and similarly for all type wrapper classes: %typemap(javaptrconstructormodifiers) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] "public" 09/06/2002: cheetah (William Fulton) [Java] Added throws typemaps for the Java module. C++ exceptions get converted into java.lang.RuntimeException Java exceptions. Warning: This may change from java.lang.Runtime exception in the future. 09/05/2002: cheetah (William Fulton) [Java] Fix for variables declared as references. 09/05/2002: beazley Fixed [ 605162 ] Typemap local variables. Reported by Lyle Johnson. 09/05/2002: ljohnson (Lyle Johnson) [Ruby] More updates to the Ruby module documentation, including a new typemap example that demonstrates how to collect key-value pairs from an argument list into a Hash. 09/05/2002: beazley Fixed bug with template expansion and constructors. template class Foo { public: Foo() { } }; The extra in the constructor was carried through in the name--causing runtime problems in generated modules. Reported by Jordi Arnabat Benedicto. 09/05/2002: mkoeppe [Guile] Support overloading. 09/04/2002: ljohnson (Lyle Johnson) [Ruby] Updated typemaps for long long and unsigned long long types to use Ruby 1.7 support for these types when available. 09/04/2002: ljohnson (Lyle Johnson) [Ruby] Added output typemaps for const reference to primitive types. 09/04/2002: mkoeppe [Guile] Fix pass-by-value typemaps. Reported by Arno Peters via Debian bugtracking (#156902), patch by Torsten Landschoff . 09/03/2002: samjam (Sam Liddicott) Better reference support. Functions that want a void** can take a NULL by reference and the void* will be made for you and then passed-by-reference Also all integer-class native types can be passed by reference where an int* or int& etc is needed 09/03/2002: beazley Changed the evaluation order of preprocessor macro arguments. Arguments are now expanded by the preprocessor *before* they are passed to macro expansion. This fixes a subtle expansion bug reported by Anthony Heading. 09/03/2002: beazley Fixed the file include order (again, apparently). See 2/27/99. 09/02/2002: beazley [Perl] Better exception handling support. Since Perl error handling relies on setjmp/longjmp, wrapper functions have been modified slightly to provide an extra block scope: XS(foo) { char _swigmsg[SWIG_MAX_ERRMSG] = ""; const char *_swigerr = _swigmsg; { /* Normal wrapper function here */ ... SWIG_croak("An error occurred\n"); ... XSRETURN(argvi); /* Successful return */ fail: /* cleanup code */ } croak(_swig_err); } The macro SWIG_croak(x) sets the value of _swigerr to x and executes a "goto fail". The whole wrapper function is enclosed block scope to provide proper cleanup of C++ objects. Since croak executes a longjmp(), there is no way to properly reclaim resources if this executes in the same scope as the wrapper function. The _swigmsg[] variable is normally unused, but can be used to store small error messages using sprintf or snprintf. It has a capacity of at least 256 bytes (SWIG_MAX_ERRMSG). 09/02/2002: beazley [Tcl] Added better support for exceptions. Instead of returning TCL_ERROR, use the macro SWIG_fail to return with an error. This ensures that arguments are properly cleaned up. Exception specifiers are now handled by default. 09/02/2002: ljohnson (Lyle Johnson) [Ruby] The type-checking system for the Ruby module has had a flaw in that some types which should be considered equivalent weren't. This bug was best demonstrated by the inherit_missing.i test suite case, which defines a base class "Foo" that is subclassed by "Bar". The "Foo" class isn't actually wrapped (i.e. it's not directly accessible from Ruby) but we'd still like to be able to pass "Bar" instances to functions expecting Foos and have that work; it wasn't. The revised implementation (similar to that used for some other language modules) adds a new instance variable (__swigtype__) to each object that indicates its SWIG type; that is, each "Bar" instance will now have a string instance variable called "__swigtype__" whose value is "_p_Bar". Unless developers were taking advantage of this low-level implementation detail, they shouldn't notice any compatibility problems; nevertheless, I'm marking it as a "potential incompatibility". *** POTENTIAL INCOMPATIBILITY *** 09/01/2002: ljohnson (Lyle Johnson) [Ruby] Fixed SF Bug #603199. 08/08/2002: cheetah (William Fulton) [Java] Added OUTPUT, INPUT and INOUT typemaps in typemaps.i for C++ references. 08/27/2002: mkoeppe [Guile] Fixed error in "lib_std_vector" testcase and compiler warning in "lib_cdata" testcase. 08/27/2002: ljohnson (Lyle Johnson) [Ruby] Added the "%mixin" directive, which allows the user to specify a comma-separated list of module names to mix-in to a class. So, for example, if you'd like to specify that Ruby's Enumerable module should be mixed-in to your class Foo, you'd write: %mixin Foo "Enumerable"; or to specify that the modules Fee, Fie and Fo should be mixed in to Foo: %mixin Foo "Fee,Fie,Fo"; *** NEW FEATURE *** 08/27/2002: ljohnson (Lyle Johnson) [Ruby] Modified the %alias directive so that multiple aliases can be specified for an instance method by using a comma-separated list of aliases. 08/27/2002: ljohnson (Lyle Johnson) [Ruby] Added "throw" typemaps for the Ruby module. 08/26/2002: beazley Two new command line options for printing dependencies. 'swig -M' lists all file dependencies. 'swig -MM' lists dependencies, but excludes files in the SWIG library. Example: % swig -M -python example.i example_wrap.cxx: \ /u0/beazley/Projects/lib/swig1.3/swig.swg \ /u0/beazley/Projects/lib/swig1.3/python/python.swg \ example.i \ example.h % swig -MM -python example.i example_wrap.cxx: \ example.i \ example.h *** NEW FEATURE *** 08/26/2002: beazley Fixed [ 597599 ] union in class: incorrect scope. Reported by Art Yerkes. 08/26/2002: beazley Fixed [ 600132 ] Default argument with namespace. Reported by Shibukawa Yoshiki. 08/24/2002: beazley Automatic C++ exception handling enabled for all language modules. This is pretty simple. If you have a class like this: class Foo { }; class Bar { public: void blah() throw(Foo); } then the generated wrapper code looks like this: wrap_Bar_blah() { ... try { arg1->blah(); } catch (Foo &_e) { /* "throw" typemap code inserted. $1 = _e */ } catch (...) { throw; } } The "throw" typemap can be used to raise an error in the target language. It can do anything. Here is a very simple example: %typemap("throw") Foo { PyErr_SetString(PyExc_RuntimeError, "Foo exception"); return NULL; } To make this work in each language module, simply define a few default "throw" typemaps for SWIGTYPE, SWIGTYPE *, int, const char *, and a few common exception types. That's all there is to it. Automatic exception handling can be disabled using -noexcept or setting the NoExcept global variable to 1. *** NEW FEATURE *** 08/23/2002: beazley [ Python ] Automatic translation of C++ exception specifications into error handling code. For example: class Foo { }; class Bar { public: void blah() throw(Foo); } In this case, Foo is wrapped as a classic-style class (compatible with exception handling). Furthermore, you can write Python code like this: b = Bar() try: b.blah(); except Foo,e: # Note use of exception class here! # Handle Foo error ... The object "e" in the exception handler is just a wrapped Foo object. Access it like a normal object. If an exception is not wrapped as a class, a RuntimeError exception is raised. The argument to this exception is the exception object. For example: class Bar { public: void blah() throw(int); } b = Bar() try: b.blah(); except RuntimeError,e: print e.args[0] # Integer exception value Comments: - If a class is used as an exception, it *must* be wrapped as a Python classic-style class (new classes don't work). - Automatic exception handling is compatible with %exception. - Use -noexcept to turn off this feature. - The newly introduced "throw" typemap is used to raise Python errors (naturally). *** EXPERIMENTAL NEW FEATURE *** 08/23/2002: beazley Information from throw() specifiers is now stored in the parse tree. For example: class Foo { public: int blah() throw(spam,bar); } The stored information is fully corrected for namespaces and works with templates. Uses will follow. 08/22/2002: beazley Exception handling code is no longer applied to member access function. For example, in this code %exception { try { $action } catch(whatever) { ... } } class Foo { public: int x; ... } The exception handling code is not applied to accessor functions for Foo::x. This should reduce the amount of extra code generated. Caveat: Exception handling code *is* used when attributes are accessed through a smart-pointer or a synthesized attributed added with %extend is used. 08/22/2002: beazley Made more patches to hopefully eliminate problems when compiling SWIG as a 64-bit executable. 08/22/2002: beazley Fixed a bug with const reference members, variables, and static members. For example: class Foo { public: static const int &ref; }; SWIG was trying to generate "set" functions which wouldn't compile. 08/21/2002: beazley Made the warning message for "Class X might abstract" off by default. Enable with -Wall. 08/21/2002: beazley Refined handling of const and non-const overloaded methods. If a class defines a method like this: class Foo { public: int bar(int); int bar(int) const; } Then the non-const method is *always* selected in overloading and the const method silently discarded. If running with -Wall, a warning message will be generated. 08/19/2002: beazley Better support for using declarations and inheritance. Consider this: class Foo { public: int blah(int x); }; class Bar { public: double blah(double x); }; class FooBar : public Foo, public Bar { public: char *blah(char *x); using Foo::blah; using Bar::blah; }; Now SWIG wraps FooBar::blah as an overloaded method that uses all accessible versions of blah(). See section 15.2.2 in Stroustrup, 3rd Ed. SWIG also supports access change through using declarations. For example: class Foo { protected: int x; int blah(int x); }; class Bar : public Foo { public: using Foo::x; using Foo::blah; }; Caveat: SWIG does not actually check to see if declarations imported via 'using' are in the inheritance hierarchy. If this occurs, the wrapper code won't compile anyways---not sure it's worth worrying about. 08/18/2002: beazley Modified overloading dispatch to not include nodes with an "error" attribute. A language module can set this if a node couldn't be wrapped and you don't want it included in the dispatch function. 08/18/2002: beazley Enhancement to overloaded function dispatch. The dispatcher is now aware of inheritance relationships. For example: class Foo { }; class Bar : public Foo { }; void spam(Foo *f); void spam(Bar *b); In this case, the dispatcher re-orders the functions so that spam(Bar *b) is checked first---it is more specific than spam(Foo *f). 08/17/2002: beazley Added -Werror command line option. If supplied, warning messages are treated as errors and SWIG will return a non-zero exit code. 08/17/2002: beazley Fixed [ 596135 ] Typedef of reference can't compile. For example: typedef int &IntRef; void foo(IntRef i); SWIG-1.3.14 generated code that wouldn't compile. Version 1.3.14 (August 12, 2002) ================================ 08/11/2002: mmatus Static const members initialized during declaration, and only them, ie: struct A { static const int a = 1 ; // this one static const int b; // not this one }; are emitted like constants (equivalent to enums or explicit %constant). This is because they cannot be added directly to 'cvar' since they lack the needed reference (well, you can force them to have a real reference, but in an ugly way which goes completely again the original purpose of initialize them during declaration, you also have to deal with extra linking matters, and it take a while to figure out what is the problem and how to solve it). Please test it with your preferred target language, and not only the code generation, but really run the example in the test-suite (static-const-member-2.i) because the problem and the solution cannot be "fully" appreciated until you try to load the module and run it. In some target languages (python specially), this can produces a difference in the way that the static constant members 'a' and 'b' are internally wrapped. Hopefully, they still can be accessed in the same way. 08/11/2002: mmatus [python] Now static const members can be accessed in a more natural way, ie, if you have struct A { typedef unsigned int viewflags; static const viewflags forward_field = 0; static const viewflags backward_field; }; now you can do: print A.backward_field and also a = A() print a.forward_field Note that if the static const members don't have an initializer (like backward_field), still you can access them in the same way in the python side, but the implementation is a quite different: backward_field will still appear in the cvar entity, and also, you are responsible to initialize it in some code unit, and link it properly. forward_field, by the other hand, will not appear in the cvar entity but only as a A member, similar to what happen with enum or %constant members. 08/11/2002: mmatus [python] Common code in the __setattr__/__getattr__ now goes to two "free" methods at the beginning of the proxy file, from where each class use it. This change reduces the size of the proxy file, specially if you wrap a lot of small classes in one module (up to 33% in some cases), making it faster to load too. 08/09/2002: beazley [Perl5] If a function that returns char * returns NULL, undef is returned to the Perl interpreter. 08/09/2002: beazley Fix to conversion operators and namespaces. For example: namespace ns { struct Foo { }; struct Bar { operator Foo*(); }; } In the wrapper code, SWIG was using ->operator Foo*() when it should have been using ->operator ns::Foo*(). Note: if using %rename with a conversion operator, you might have to do this: %rename(toFooPtr) ns::operator ns::Foo*(); // ^^^^ note extra qualifier namespace ns { ... 08/09/2002: beazley [Python] Minor enhancement to 'const' variable declarations. Normally const declarations are wrapped as read-only variables accessible only through the cvar attribute (see SWIG.html for a discussion of why). However, in many programs, "const" declarations may just be constants---making the cvar. access awkward. To fix this, "const" declarations are now available both through cvar. and as a simple name. For example: const int FOO = 42; In Python: >>> print example.cvar.FOO 42 >>> print example.FOO 42 Note: There are cases where the value of a "const" variable might change. For example: char *const BAR = "Hello World"; In this case, the pointer itself can not change, but the data being pointed to could be modified. In these situations, cvar.BAR should be accessed to obtained the current value. 08/08/2002: beazley [Python] Fixed generation of the proxy code (.py files) to more closely follow the order of declarations as they appear in the .i file. In the past, all of the class wrappers appeared first, followed by function stubs, inserted Python code, and other details. 08/08/2002: cheetah (William Fulton) [Java] Proxy method _delete() changed to delete(). There shouldn't ever be a wrapped function called delete() as it is a C++ keyword and there is no such thing as a member function in C. *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** Backwards compatibility can be achieved by adding the function back in for all proxy classes: %typemap(javacode) SWIGTYPE %{ public void _delete() { delete(); } %} Java backwards compatibility summary ------------------------------------ There are a number of changes that have been made in improving the Java module for ver 1.3.14. If at all possible change your code to take advantages of the improvements. If you were using proxy classes you may not notice any backwards compatibility issues. Here is an example which will help with most backwards compatibility problems where it is not possible to modify the code that uses the generated output: Replace: %module modulename With: %module (jniclassname="modulename") modulename; %typemap(javacode) SWIGTYPE %{ public long getCPtr$javaclassname() { return swigCPtr; } public void _delete() { delete(); } %} %pragma(java) jniclassclassmodifiers="public"; The proxy constructors that took parameters (long cPtr, boolean cMemoryOwn) were public and are now protected. If you were making use of these then you'll have to modify your code and the best solution would be to use the new type wrapper classes. The other main areas are the pragmas and global variable wrapping. Replace the pragmas with one of the new directives or typemaps mentioned below and use %rename on the variables. If you were not using proxy classes, you will have to define a jstype typemap as well as a jtype typemap. 08/08/2002: cheetah (William Fulton) [Java] Fix for wrapping two dimension array variables. 08/07/2002: beazley [Python,Tcl] Object management now has a much better sense of ownership. Ownership bits is changed whenever an object is stored in a global variable or structure member. For example: struct Foo { int val; Foo *next; }; Now in Python >>> f = Foo() >>> f.thisown 1 >>> g = Foo() >>> g.next = f # Assign a pointer >>> f.thisown # Notice ownership change 0 >>> This scheme is mostly a conservative heuristic designed to provide segmentation faults. It could cause a memory leak if ownership is changed unnecessarily. In this case, you can either write a typemap (that doesn't change ownership), or manually set the thisown attribute back to 1. 08/07/2002: beazley [Tcl] Major usability improvements to the object interface. Suppose you had code like this: struct Foo { int x; int spam(); }; void blah(Foo *f); In past versions of SWIG, you could create objects and use them like this: % Foo f % f configure -x 3 % f spam 37 The only problem is that if you tried to call blah(), it didn't work: % blah f Type Error. Expected _p_Foo % Instead, you had to do this: % blah [f cget -this] SWIG now automatically extracts the -this pointer, avoiding this problem. This means that saying "blah f" is perfectly legal and everything will still work normally. Caveat: Since pointer strings start with a leading underscore (_), don't use this in object names. For example: % Foo _f % blah _f # Potential crash Objects now have a -thisown attribute that shows the ownership. This builds upon the CHANGES 11/24/2001 entry. 08/07/2002: samjam, Sam Liddicott Properly implemented pointer system using php resources. Still need to work out whether or not to let script-users call destructors directly 08/06/2002: beazley Upgraded mzscheme module to support version 201 and added overloading support. 08/05/2002: beazley Added parsing support for extra grouping (in very limited cases). For example: typedef int (FuncPtr)(int, double); *** EXPERIMENTAL *** 08/03/2002: ljohnson (Lyle Johnson) [Ruby] Updates to typemaps.i as those done previously for Perl, Python and Tcl modules. Now supports reference types with INPUT, OUTPUT and INOUT typemaps. 08/02/2002: beazley New library file cstring.i added. Provides macros for manipulating char * data. 08/02/2002: beazley Deprecated the %new directive. Use %newobject instead. For example: %newobject foo; ... char *foo(); %newobject follows the same rules as %rename, %ignore, %feature, etc. *** POTENTIAL INCOMPATIBILITY *** 08/01/2002: cheetah (William Fulton) [Java] New attribute 'jniclassname' for the module directive allows a way of changing the JNI class name from the default which uses the modulename with JNI appended after it. %module (jniclassname="name") modulename If 'name' is the same as 'modulename' then the module class name gets changed from 'modulename' to modulenameModule. 08/01/2002: beazley Fixed problem with file include order. Language specific directories should take precedence over generic directories. For example: "swig_lib/python/foo.i" should be loaded before "swig_lib/foo.i". I thought this was the case already, but apparently it has been broken for quite some time. 08/01/2002: beazley Added std_deque.i library file. Work in progress. 08/01/2002: beazley [Python,Tcl,Perl] Improvements to typemaps.i. INPUT/INOUT typemaps perform better error checking. Typemaps are now supplied for references like int &OUTPUT, double &INOUT, etc. 08/01/2002: beazley [Python] Deprecated the T_* and L_* typemaps in typemaps.i. Multiple return values are always placed in a tuple. Deprecated the BOTH typemaps. This is now INOUT (e.g., int *INOUT). *** POTENTIAL INCOMPATIBILITY FOR PYTHON MODULE *** 08/01/2002: beazley Deprecated the array.i, carray.i, and timer.i library files. 08/01/2002: beazley Deprecated the pointer.i library file. Use cpointer.i instead. *** POTENTIAL INCOMPATIBILITY *** 08/01/2002: cheetah (William Fulton) [Java] For consistency the global variable getters and setters use the JavaBean property design pattern like member variables always have. This means if you are wrapping a variable called foo, the getter is called getFoo() and the setter is called setFoo(). Before the recent changes to the Java module the getters and setters were called get_foo() and set_foo(). If you really want the original function names use the %rename directive like this: %rename(_foo) Foo; 07/31/2002: beazley Fixed casting problem with multiple inheritance. If you had this, class foo {}; class bar : public foo {}; class baz : public foo {}; class spam : public bar, public baz {}; then the wrappers wouldn't compile due to an ambiguous cast. Reported by Art Yerkes. 07/30/2002: cheetah (William Fulton) [Java] Due to new static typechecking all pointers held in a Java long are part of the internal workings and this pointer value in the Java long has become abstracted data. The type wrapper constructor and getCPtr() methods are as such protected. If you need to mess around with pointers from Java or for example create a proxy class or type wrapper class around a null pointer, add a function/constructor to do so with the %javacode typemap. You can also make getCPtr() public again with the %javagetcptr typemap. 07/30/2002: cheetah (William Fulton) [Java] Fixes for %typemap(ignore). In particular when ignoring the last parameter in a function. Also for all parameters in constructors. These mods have also fixed multi-argument typemaps for proxy classes - SF 581791. 07/30/2002: cheetah (William Fulton) [Java] %newobject (replacement for %new) now implemented for Java. 07/29/2002: beazley Fixed problem with typemap copies, %apply, and %clear inside C++ namespaces. 07/28/2002: cheetah (William Fulton) [Java] The JNI class now has package access as the class modifier has been changed from "public" to nothing. This has been done as this class is now more for the internal workings of SWIG since the module class has static type checking for all types. *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** Backwards compatibility can be achieved by using the %jniclassclassmodifier pragma to change it back to "public". 07/28/2002: cheetah (William Fulton) [Java] Proxy/Shadow classes are generated by default. The -proxy and -shadow command line options are deprecated. If you want to use the low-level functional interface then use the new -noproxy commandline option. *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** 07/28/2002: cheetah (William Fulton) [Java] Remaining pragmas shakeup. These were the remaining pragmas and their new names where changed: modulebase modulecode moduleclassmodifiers moduleimport => moduleimports moduleinterface => moduleinterfaces The moduleimports works slightly differently to how the moduleimport pragma worked. Now it actually takes code which gets placed before the class definition so the whole import statement has to be given, for example: %pragma(java) moduleimports=%{ import java.io.*; import java.math.*; %} The moduleinterfaces is slightly different to the old moduleinterface in that if more than one interface is required they must be comma separated in one use of the pragma, for example: %pragma(java) moduleinterfaces="Serializable, MyInterface" These last two pragmas are consistent with the javainterfaces and javaimports typemap. A similar set of pragmas has been introduced, namely: jniclassbase jniclasscode jniclassclassmodifiers jniclassimport jniclassinterface These work in the same way as their module counterparts. Note that previously the moduleXXX pragmas worked on the old module class which is now called the JNI class (the class with the native functions). The jniclassXXX pragmas now work on the new module class (the class that has all the global functions and global variable getters and setters when using proxy classes, plus all other remaining functions when using the low-level procedural interface). In summary the contents of the pragmas make up a class like this: class modulename extends implements { ... SWIG generated functions ... } } *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** 07/28/2002: cheetah (William Fulton) [Java] Deprecated modulemethodmodifiers pragma and replaced with a better %feature based directive called %javamethodmodifiers. A useful example would be for synchronisation in multi-threaded apps: %javamethodmodifiers foo(int a) "public synchronized"; Changes this function from the default ("public") to "public synchronized". *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** 07/26/2002: beazley Several directives now allow optional configuration parameters. These include: %module(name="value", name="value", ...) modulename %import(name="value", ...) "filename.i" %extend(name="value", ...) classname { ... } These currently have no effect and are reserved for future expansion. 07/26/2002: beazley Enhancements to smart-pointer handling. SWIG only provides extra support for a smart-pointer if operator->() returns a proper pointer. For example: Foo *operator->(); If operator->() returns an object by value or reference, then SWIG examines the returned object to see if it also implements operator->(). If so, SWIG chases operator->() until it can find one that returns a pointer. This allows cases like this to work: class Foo { public: void blah(); }; class Bar { ... Foo *operator->(); ... }; class Spam { ... Bar operator->(); ... }; For example: >>> s = Spam() >>> s.blah() # Invokes Foo::blah() The s.blah() call actually invokes: ((s.operator->()).operator->())->blah(); 07/26/2002: beazley Fixed a bug with typedef and references. For example: typedef Foo & FooRef; FooRef blah(); Previous versions of SWIG generated code that wouldn't compile. 07/25/2002: beazley Wrapping of static methods has been improved in proxy classes. In older versions of SWIG, if you had this: class Foo { public: static void bar(); }; The static method was only available as a function Foo_bar(). For example: >>> Foo_bar() Now, the static method can also be invoked through an instance like this: >>> f = Foo() >>> f.bar() # Invokes static method This works with all versions of Python. Additionally, for Python-2.2, the static method can be invoked as: >>> Foo.bar() The old-style function is still support for backwards compatibility. If you care about making your code across different versions of Python, either use Foo_bar() or access the method through an instance. 07/25/2002: beazley Changes to the Python module. Proxy classes now utilize new Python-2.2 features including properties and static methods. However, these features are supported in a way that provides backwards compatibility with older Python versions. In other words, proxy classes work with all versions of Python and only use new features when running on Python-2.2. 07/25/2002: beazley Modified %extend so that overloaded methods can be added. For example: %extend Foo { void bar(int x) { }; void bar(char *s) { }; ... } This works with both C++ *and* C. 07/24/2002: cheetah (William Fulton) [Java] More new typemaps so that the Java proxy classes and type wrapper classes can be further tailored by users. These are the default code for generating the finalize() methods (proxy classes only) and the getCPtr() methods for proxy classes and type wrapper classes: %typemap(javafinalize) SWIGTYPE %{ protected void finalize() { _delete(); } %} %typemap(javagetcptr) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] %{ public static long getCPtr($javaclassname obj) { return obj.swigCPtr; } %} The javagetcptr typemap will enable users to handle Java null by overriding this typemap - a requested feature. The -nofinalize commandline option has been deprecated. The javafinalize typemap is more powerful as it will allow the removal of the finalize methods for all or any one or more particular proxy class. 07/23/2002: cheetah (William Fulton) [Java] The getCPtrXXX() function has been changed to a static function and is now of the form: protected static long getCPtr(XXX obj) {...} This is a requested change which will allow Java null pointers to be used as null can be passed in for obj. However, to achieve this the appropriate code must be written using the new javagetcptr typemap directive. *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** Backwards compatibility can be achieved by adding this function back in using the new javacode typemap: %typemap(javacode) SWIGTYPE %{ // SWIG-1.3.12 and SWIG-1.3.13 public long getCPtr$javaclassname() { return swigCPtr; } // SWIG-1.3.11 and earlier public long getCPtr() { return swigCPtr; } %} 07/23/2002: cheetah (William Fulton) [Java] New directive to control constant code generation - %javaconst. The default handling for handling constants is to get the value through a JNI call, eg #define YELLOW 5 #define BIG 1234LL results in: public final static int YELLOW = modulename.get_YELLOW(); public final static long BIG = modulename.get_BIG(); Earlier versions of the Java module initialised the value using the C value: public final static int YELLOW = 5; public final static long BIG = 1234LL; This works in most cases, but the value for BIG won't compile as 1234LL is not valid Java code and this is one of the reasons why the default is now to get the values through a JNI call. The side effect is that these 'constants' cannot be used in switch statements. The %javaconst directive allows one to specify the way the constant value is initialised and works like other %feature directives, eg %javaconst(0); // all constants from this point on are initialised using the C value %javaconst(1) BIG; // just BIG initialised using JNI call (must be parsed before BIG is defined) 07/23/2002: beazley *** IMPORTANT CHANGES TO THE PYTHON MODULE *** (1) The Python module now enables shadow/proxy classes by default. This means that two files are always created by SWIG. For instance, if you have this: // file: foo.i %module foo ... Then swig generates two files "foo_wrap.c" and "foo.py". (2) The name of the low-level C extension module has been changed to start with a leading underscore. This means that you have to compile the module as follows: $ cc -c -I/usr/local/include/python2.2 foo_wrap.c $ cc -shared foo_wrap.o $(OBJS) -o _foo.so ^^^^ note extra underscore This naming scheme is consistent with other Python modules that utilize extension code. For instance, the socket module consists of "_socket.so" and "socket.py". In previous versions of SWIG, the shared object file was named "foocmodule.so". (3) A new directive can be used to insert Python code into the corresponding .py file. For example: %pythoncode %{ def foo(): print "Hello World" %} This directive allows you to create modules as a mix of C and Python. Python code is seamlessly added to the module. (4) The -shadow command line option is deprecated. This is turned on by default. (5) To disable the generation of the extra python file, use the "-noproxy" command line option. *** POTENTIAL INCOMPATIBILITY *** This change will likely break the build environment of projects that utilize shadow classes. To fix this, you probably only need to change the name of the target .so file. For example, if you have Makefile information like this: TARGET = examplecmodule.so Just change it to: TARGET = _example.so *** DOCUMENTATION UPDATE *** The file Doc/Manual/Python.html has been updated to describe these changes. 07/23/2002: beazley Added -noextern option. If supplied, SWIG will not generate extra extern declarations. This is sometimes an issue on non-unix platforms. 07/23/2002: beazley Added a warning for ignored friend functions. 07/23/2002: beazley Fixed [ 574498 ] -proxy and %include "pointer.i" clash. Reported by David Creasy. 07/23/2002: beazley Fixed [ 576103 ] global destruction warning with shadow. Perl extensions should no longer report the warning "Use of uninitialized value during global destruction." when running with "perl -w". Reported by Brett Williams. 07/23/2002: beazley In C++ mode, SWIG now always defines namespace std. By default, it's empty. However, this will silence errors from programs that include statements such as "using namespace std;". This fixes Bug [ 584017 ] using namespace std generates error. Reported by Joseph Winston. 07/22/2002: beazley Added a new warning message for %apply. If you use %apply but no typemaps are defined, you will get a warning message. This should help with problems like this: %apply char *OUTPUT { ... }; In old versions of SWIG, this silently did nothing. Now you get an error like this: file:line. Warning. Can't apply (char *OUTPUT). No typemaps are defined. 07/22/2002: cheetah (William Fulton) [Java] Started Java pragma deprecation. Replacements use %typemap based directives and enable proxy classes and the new type wrapper classes to be tailored in various ways. These are the new typemaps: %typemap(javabase) - base (extends) for Java class %typemap(javaclassmodifiers) - class modifiers for the Java class: default is "public" %typemap(javacode) - java code is copied verbatim to the Java class %typemap(javaimports) - import statements for Java class %typemap(javainterfaces) - interfaces (extends) for Java class And these are the %pragma directives being deprecated: allshadowbase allshadowclassmodifiers allshadowcode allshadowimport allshadowinterface shadowbase shadowclassmodifiers shadowcode shadowimport shadowinterface Note that it is possible to target a particular proxy class: %typemap(javaimports) Foo "import java.util.*"; or a particular type wrapper class: %typemap(javaimports) double* "import java.math.*"; Note that $javaclassname in these typemaps are substituted with either the proxy classname when using proxy classes or the SWIGTYPE class name. 07/18/2002: cheetah (William Fulton) [Java] Java module overhaul to implement static type checking of all types. 1) Changes when using Java Proxy classes ---------------------------------------- Previously when wrapping global functions: class SomeClass{}; void foo(SomeClass* s); SomeClass* bar(); The native method prototypes used a long for pointers and looked like this: public class modulename { ... public final static native void foo(long jarg1); public final static native long bar(); } and unlike member functions of a C++ class there was no wrapper around the native calls to make the use of them more user friendly. They would be used from Java like this: SomeClass s = new SomeClass(modulename.bar(), false); modulename.foo(s.getCPtrSomeClass()); Note that the following will have the same effect, but then it would not have been possible to call any proxy member functions in SomeClass: long s = modulename.bar(); modulename.foo(s); Now wrapper functions are generated: public class modulename { public static void foo(SomeClass s) { // calls the native function } public static SomeClass bar() { // calls the native function } } Which means these functions can now be used more naturally with proxy classes: SomeClass s = modulename.bar(); modulename.foo(s); 2) Changes when not using Java Proxy classes -------------------------------------------- The so called low-level interface was rather low-level indeed. The new static type checking implementation makes it less so but it remains a functional interface to the C/C++ world. Proxy classes are the obvious way to use SWIG generated code, but for those who want a functional interface all non-primitive types now have a simple Java class wrapper around the C/C++ type. Pointers and references to primitive types are also wrapped by type wrapper classes. The type wrapper classnames are based on the SWIG descriptors used by the other language modules. For example: C/C++ type Java type wrapper class name ---------- ---------------------------- int* SWIGTYPE_p_int double** SWIGTYPE_p_p_double SomeClass* SWIGTYPE_p_SomeClass SomeClass& SWIGTYPE_p_SomeClass SomeClass SWIGTYPE_p_SomeClass Note that everything wrapped by SWIG is accessed via a pointer even when wrapping functions that pass by value or reference. So the previous example would now be used like this: SWIGTYPE_p_SomeClass s = example.bar(); example.foo(s); Note that typedefs that SWIG knows about are resolved, so that if one has class Foo{}; typedef Foo Bar; then any use of Bar will require one to use SWIGTYPE_p_Foo; Some considerations: Make sure you make a firm decision to use either proxy classes or the functional interface early on as the classnames are different. 3) Pointers and non-parsed types -------------------------------- Sometimes SWIG cannot generate a proxy class. This occurs when the definition of a type is not parsed by SWIG, but is then used as a variable or a parameter. For example, void foo(Snazzy sds); If SWIG has not parsed Snazzy it handles it simply as a pointer to a Snazzy. The Java module gives it a type wrapper class around the pointer and calls it SWIGTYPE_p_Snazzy. In other words it handles it in the same manner as types are handled in the low-level functional interface. This approach is used for all non-proxy classes, eg all pointer to pointers and pointers to primitive types. 4) Backwards compatibility ----------------------- Backwards compatibility is not an issue if you have been using proxy classes and no global variables/functions. Otherwise some changes will have to be made. The native methods still exist but they are now in a JNI class, which is called modulenameJNI. As this class is really part of the internal workings, it should not be required so the class has become protected. Some pragmas/directives will hopefully be added to help with backwards compatibility. *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** 07/18/2002: beazley Modified wrapping of uninstantiated templates returned by value. Just to be safe, they are now wrapped by SwigValueWrapper<> just in case they don't define a default constructor. This would be used if you had code like this Foo blah(); void moreblah(Foo x); but you didn't instantiate Foo using %template. We should probably add a warning for this. 07/17/2002: beazley Added an error check to detect shadowed template paramaters. For example: template class Foo { public: int T; }; This results in an error, not a warning. This warning is also needed to fix some rather insidious problems like this: struct T { int blah; }; template class Foo { public: typedef T Traits; // Which T is this???? }; In this case, the template parameter T shadows the outer structure (which is what you want). 07/16/2002: beazley Improved support for templates with integer arguments. SWIG is much more aware of situations such as this: const int Size = 100; %template(Foo100) Foo<100>; void bar(Foo *x); // Knows that Foo is the same as Foo<100>; 07/15/2002: beazley Fixed bug with %feature/%ignore/%rename and namespaces. For example: %ignore Foo::Bar namespace Foo { class Bar { ... }; } Reported by Marcelo Matus. 07/09/2002: beazley Added parsing support for constructors that try to catch exceptions in initializers. For example: class Foo { Bar b; public: Foo(int x) try : b(x) { ... } catch(int) { ... } } This has no effect on the generated wrappers. However, the try and catch parts of the declaration are ignored. See Stroustrup, 3rd Ed, section 14.4.6.1 for details. 07/06/2002: beazley Fixed bug in template symbol table management. This fixes two bugs. First, mixing abstract methods, templates, and inheritance no longer generates a failed assertion. template class A { public: virtual void foo() = 0; }; template class B : public A { }; %template(A_int) A; %template(B_int) B; This fix also fixes a subtle problem with default values and templates. For example: template struct B { typedef unsigned int size_type; static const size_type nindex = static_cast(-1); void foo(size_type index = nindex); }; Bugs reported by Marcelo Matus. 07/05/2002: ljohnson (Lyle Johnson) [Ruby] Changed the definition of the SWIG_ConvertPtr() function for the SWIG/Ruby runtime support so that it looks like the Python version. If the last argument (flags) is non-zero, SWIG_ConvertPtr() will raise an exception for type mismatches as before. If flags is zero, this function will return -1 for type mismatches without raising an exception. *** POTENTIAL INCOMPATIBILITY FOR RUBY MODULE *** 07/04/2002: beazley Overloaded functions/methods/constructors now work in many language modules. The support is completely transparent--just call the function normally and SWIG will dispatch to the correct implementation. There are a variety of issues associated with this. Please refer to the overloading section of Doc/Manual/SWIGPlus.html for details. *** NEW FEATURE *** 07/04/2002: beazley Fixed a bug with namespaces, enums, and templates. For example: namespace hello { enum Hello { Hi, Hola }; template struct traits { typedef double value_type; }; traits::value_type say_hi() { return traits::value_type(1); } } SWIG wasn't generating wrappers that properly qualified traits. Reported by Marcelo Matus. 06/30/2002: beazley Supplied array variable typemaps for Tcl module. If you have a variable like this: int foo[10]; then a set function like this is generated: void foo_set(int *x) { memmove(foo,x,10*sizeof(int)); } 06/30/2002: beazley New %fragment directive. When writing typemaps, it can be easy to get carried away and write a lot of code. However, doing so causes tremendous code bloat. A common way to solve this is to write helper functions. For example: %{ void some_helper_function() { ... } %} %typemap(in) type { some_helper_function(...); } The only problem with this is that the wrapper file gets polluted with helper functions even if they aren't used. To fix this, a new fragment directive is available. For example: %fragment("type_helper","header") %{ void some_helper_function() { ... } %} %typemap(in, fragment="type_header") type { some_helper_function(...); } In this case, the code fragment is only emitted if the typemap is actually used. A similar capability is provided for declaration annotation and the %feature directive. For example: %feature("fragment","type_header") SomeDeclaration; The first argument to %fragment is the fragment name. The second argument is the file section where the fragment should be emitted. The primary use of this directive is for writers of language modules and advanced users wanting to streamline typemap code. *** EXPERIMENTAL NEW FEATURE *** 06/30/2002: beazley Supplied memberin typemaps for all arrays in an attempt to eliminate confusion about their use. 06/29/2002: beazley Experimental support for smart-pointers. When a class defines operator->() like this class Foo { ... Bar *operator->(); ... }; SWIG locates class Bar and tries to wrap its member variables and methods as part of Foo. For example, if Bar was defined like this: class Bar { public: int x; int spam(); }; You could do this (in the target language): f = Foo() f.x = 4 # Accesses Bar::x f.spam() # Accesses Bar::spam The primary use of this feature is to emulate the behavior of C++ smart-pointers---which allow attributes to accessed transparently through operator->. This feature is supported automatically in SWIG---no special directives are needed. To disable this behavior. Use %ignore to ignore operator->. *** NEW FEATURE *** 06/26/2002: beazley Deprecated the %except directive. %exception should be used instead. 06/25/2002: beazley Major cleanup of the modules directory. Eliminated most header files, consolidated module code into single files. 06/24/2002: beazley Reworked the instantiation of language modules. All language modules must now define a factory function similar to this: extern "C" Language * swig_python(void) { return new PYTHON(); } This function is then placed in a table and associated with a command line option in swigmain.cxx. This approach has a number of benefits. It decouples the SWIG main program from having to know about the class definitions for each module. Also, by using a factory function, it will be easier to implement dynamic loading of modules (simply load the file and invoke the factory function). 06/24/2002: beazley Fixed syntax error for reference conversions. For example: operator Foo &(); 06/24/2002: beazley Fixed syntax error for operator new[] and operator delete[]. 06/24/2002: beazley Fixed code generation problem for constants and default arguments involving templates. 06/19/2002: ljohnson (Lyle Johnson) [Ruby] Fixed a bug for the '-feature' command line argument; that setting was effectively being ignored and so the feature name was always set equal to the module name. 06/17/2002: beazley Fixed problems with static members and enums in templates. Version 1.3.13 (June 17, 2002) ============================== 06/16/2002: beazley Fixed a bug with __FILE__ expansion in the preprocessor. On Windows, the backslash (\) is now converted to (\\) in the string literal used for __FILE__. Reported by Steve Glaser. 06/14/2002: beazley Fixed warning message about 'name private in this context'. The warning is only generated for public methods. Reported by Scott Michel. 06/14/2002: beazley Fixed some problems related to template instantiation and namespaces. When SWIG expands a template, it does so with fully resolved types. For example, if you have this: template class foo { }; typedef double Double; %template(foo_d) foo; then, it is handled as foo in the typesystem. This fixes a number of subtle problems with inheritance and templates. 06/14/2002: ljohnson (Lyle Johnson) [Ruby] Added missing bool typemaps for INPUT, OUTPUT and INOUT in Lib/ruby/typemaps.i. 05/29/2002: cheetah (William Fulton) [Java] Fix for a couple of broken pragmas. 05/29/2002: cheetah (William Fulton) Fix for unnecessary cast when wrapping global variable where the type is not parsed by SWIG - Java variables example failure as reported by Larry Virden. 06/10/2002: beazley Modified %template to allow for empty instantiations. %template() foo; This registers foo with the type system, but doesn't wrap it (same as %ignore). This may only be a temporary measure. SWIG might be able to automatically instantiate templates in certain cases. 06/10/2002: beazley Fixed function prototype problems with Tcl 8.4 06/09/2002: beazley Fixed problem with templates and location of base classes. This one is a little mind-bending, but here is an example that illustrates: template struct traits { typedef ArgType arg_type; typedef ResType res_type; }; template struct Function { }; template struct Class : Function::arg_type, typename traits::res_type> { }; %template(traits_dd) traits ; %template(Function_dd) Function ; %template(Class_dd) Class ; In this example, the base class of 'Class' is determined from the Function template, but the types are obtained through typedefs. Because of this, SWIG could not locate the wrapped base class (Function). Should be fixed in 1.3.13 even though I can think of a million other things that might also be broken. 06/07/2002: beazley Fixed a problem with conversion operators. If you had an operator like this, operator double() const; SWIG was ommitting the "const" qualifier. This affected %rename and other directives. Reported by Zhong Ren. 06/07/2002: beazley Lessened the strictness of abstract class checking. If you have code like this: class Foo { public: virtual int method() = 0; }; class Bar : public Foo { public: Bar(); ~Bar(); }; SWIG will go ahead and generate constructor/destructors for Bar. However, it will also generate a warning message that "Bar" might be abstract (since method() isn't defined). In SWIG-1.3.12, SWIG refused to generate a constructor at all. 06/07/2002: beazley Change to %template directive. If you specify something like this: %template(vi) std::vector; It is *exactly* the same as this: namespace std { %template(vi) vector; } SWIG-1.3.12 tried to instantiate the template outside of the namespace using some trick. However, this was extremely problematic and full holes. This version is safer. 06/07/2002: beazley Fixed bug with scope qualification and templates. For example: A::DD Before, this was separated as scopes A, and DD. Fixed now. 06/06/2002: beazley Allow the following syntax: class A { }; struct B : A { ... }; A base class without a specifier is assumed to be public for a struct. 06/06/2002: beazley Fixed syntax error with template constructor initializers. Reported by Marcelo Matus. 06/06/2002: beazley Fixed bug with default template arguments. Reported by Marcelo Matus. 06/05/2002: beazley Fixed subtle problems with %rename directive and template expansion. Code like this should now work: %rename(blah) foo::method; ... template class foo { public: void method(); }; %template(whatever) foo; 06/05/2002: beazley Resolved some tricky issues of multi-pass compilation and and inheritance. The following situation now generates an error: class Foo : public Bar { ... }; class Bar { ... }; The following code generates a warning about incomplete classes. class Bar; class Foo : public Bar { }; The following code generates a warning about an undefined class. class Foo : public Bar { }; // Bar undefined This fixes a failed assertion bug reported by Jason Stewart. 06/05/2002: ljohnson [Ruby] Added a warning message for the Ruby module about the lack of support for multiple inheritance. Only the first base class listed is used and the others are ignored. (Reported by Craig Files). 06/03/2002: beazley Fixed a bug with struct declarations and typedef. For example: typedef struct Foo Foo; struct Foo { ... }; A few other subtle struct related typing problems were also resolved. Version 1.3.12 (June 2, 2002) ============================= 05/30/2002: beazley Fixed problem related to forward template class declarations and namespaces. Bug reported by Marcelo Matus. 05/30/2002: beazley Added 'make uninstall' target. Contributed by Joel Reed. 05/29/2002: beazley Fixed rather insidious bug with %rename, %feature and template specialization. For example: %exception vector::__getitem__ { ... some exception ... } template class vector { ... T __getitem__(int index); // Fine ... }; template<> class vector { ... T __getitem__(int index); // Oops. ... }; Now, the %exception directive (and other features) should correctly apply to both vector and specializations. 05/29/2002: beazley Subtle changes to %template() directive. Template arguments are now reduced to primitive types in template matching. For example: template class vector { ... partial specialization ... } typedef int *IntPtr; // Gross typedef // Gets the above partial specialization %template(vectorIntPtr) vector; This change is extremely subtle, but it fixes a number of potential holes in Luigi's STL library modules. For example: typedef int Integer; %template(vectori) vector; 05/29/2002: beazley Fixed rather insidious typemap bug related to const. const was being discarded through typedefs. 05/29/2002: ljohnson (Lyle Johnson) [Ruby] Added input typemaps for const references to primitive types (in Lib/ruby/ruby.swg). 05/29/2002: cheetah (William Fulton) [Java] The java arrray support functions are enclosed by a SWIG_NOARRAYS #define. Useful if not using arrays and it is desirable to minimise the amount of compiled code. 05/29/2002: cheetah (William Fulton) [Java] Enums were not renamed when using %name or %rename fix. 05/28/2002: ljohnson [Ruby] Modified the name of the wrapper functions for the "new" singleton method and "initialize" instance method for consistency with the other language modules. The wrapper name for the function that implements "new" is alloc_classname and the wrapper name for the function that implements "initialize" is new_classname. 05/27/2002: beazley Changes to runtime. Pointer conversion/creation functions now almost always have an extra "flags" argument. For example: SWIG_ConvertPtr(obj, void **, swig_type_info *ty, int flags); ^^^^^^^^^^ This extra parameter is reserved for future expansion and will be used for more control over pointers in future versions. 05/27/2002: beazley Fix for C++ classes with private assignment operators. It is now possible to safely return objects like this by value. Caveat: the class must provide a copy constructor. 05/26/2002: beazley -proxy option added to many language modules. This is the same as -shadow. We are merely changing terminology. 05/26/2002: beazley [perl] Fixed some inconsistencies in the -package option. -package merely sets the package name to be used on the wrappers. It does not change the name of the shared library file or the name of the generated .pm file. This was broken at some point, but works again now. 05/25/2002: beazley [perl] Fixed [ 475452 ] memory leak in return-by-value. Problem related to static member variables returning newly allocated objects. Reported by Roy Lecates. 05/25/2002: beazley [perl] Fixed [ 513134 ] %BLESSEDMEMBERS isn't always right. Reported by Fleur Diana Dragan. 05/25/2002: beazley Fixed [ 540735 ] -importall and the -I option. 05/25/2002: beazley [guile] Fixed [ 532723 ] Default arg for char* can SegV. Error in guile module. Reported by Brett Williams. 05/25/2002: beazley Subtle change to typemap application code. The "freearg" typemap must exactly match up with the "in" or "ignore" typemap. For example: %typemap(in) (char *data, int len) { ... }; %typemap(freearg) char *data { ... }; void foo(char *data, int len); In this case, the "in" typemap is applied, but the freearg typemap is not. This is because the freearg typemap doesn't match up with the input argument sequence. 05/25/2002: beazley Fixed [ 548272 ] Default argument code missing braces. Reported by Brett Williams. 05/25/2002: beazley Fixed [ 547730 ] SwigValueWrapper needed for constructors. Reported by William Fulton. 05/25/2002: beazley Undefined identifiers now evaluate to 0 when evaluating preprocessor expressions. For example: #if !FOO ... #endif where FOO is undefined or set to some non-numeric value. Fixes [ 540868 ] #if defined whatever - not parsed. Reported by Adam Hupp. 05/24/2002: beazley SWIG now ignores the C++ 'export' keyword. 05/23/2002: beazley Some refinement of type-name mangling to account for pointers, arrays, references, and other embedded type constructs. 05/23/2002: beazley Initial attempt at supporting template partial specialization. At the very least, it is parsed and the classes are stored. Matching of instantiations to specialized version is more limited and based on the SWIG default typemap rules: SWIGTYPE * SWIGTYPE [] SWIGTYPE & Now, why in the world would you want to use this feature? Other than allowing for slightly modified class APIs, this capability is primarily used to provide advanced wrapping support for STL-like objects. It can also be mixed with typemaps. Here is an example: /* Generic version */ template class vector { %typemap(in) vector * { // A container of objects } }; /* Partial specialization (pointers) */ template class vector { %typemap(in) vector * { // A container of pointers to objects. } }; /* Specialization (integers). */ template<> class vector { %typemap(in) vector * { // A container of integers. } }; *** EXPERIMENTAL FEATURE *** 05/23/2002: beazley Enhancement to typemaps. Normally, typemap variables are renamed to avoid conflicts. For example: %typemap(in) int * (int temp) { $1 = &temp; } This results in code that creates and uses variables "temp1","temp2", "temp3" and so forth depending on how many times the typemap is used. Sometimes you want a single variable instead. To do that, using the following naming scheme: %typemap(in) int *(int _global_temp) { } Is this case, a single variable _global_temp is emitted in the wrapper functions. It is shared across all typemaps. Repeated typemaps do not replicate the variable---they use the first one emitted. *** NEW FEATURE *** 05/23/2002: beazley Minor enhancement to typemaps. If you have this code, %typemap(in) Foo (int somevar = 3) { ... } the default value for somevar is now emitted into the wrapper code. 05/22/2002: beazley Fixed %extend to be better behaved in namespaces. If you have code like this: namespace foo { struct bar { %extend { void blah(); }; }; } SWIG matches the blah() method to a C function named void foo_bar_blah(foo::bar *self). This is consistent with the non-namespace version. Bug reported by Marcelo Matus. 05/22/2002: beazley New library files: cpointer.i, carrays.i, cmalloc.i. These provide access to C pointers and memory allocation functions. See Doc/Manual/Library.html for details. 05/22/2002: cheetah (William Fulton) [Java] C type char no longer maps to Java type byte, but to Java type char. It is now treated as a character rather than a signed number. This fits in with the other language modules and is a more natural mapping as char* is mapped as a string of characters. Note that the C signed char type is still mapped to a Java byte. *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** 05/22/2002: cheetah (William Fulton) [Java] Improved constants wrapping. Constants (#define and %constant) values are now obtained through a JNI call. Previously the value was compiled as Java code, but this didn't work for all cases, eg #define 123ULL. 05/22/2002: beazley Fixed bogus error message with %extend directive and C++ access specifiers. Reported by Marcelo Matus. 05/22/2002: beazley Namespaces and enums now work correctly. For example: namespace Foo { enum Bar { A, B }; } Bug reported by Marcelo Matus. 05/21/2002: beazley The %types directive can now be used to specify inheritance relationships in the runtime type system. For example, %types(Foo = Bar); specifies that Foo isa Bar. Using this is potentially quite dangerous. However, this is useful in certain cases (and in the SWIG library). 05/20/2002: beazley %nodefault and %makedefault directives now require a trailing semicolon. For example: %nodefault; ... %makedefault; In addition both directives can take a class name. For example: %nodefault Foo; class Foo { /* No default constructor/destructor */ }; class Bar { /* Default constructor/destructor generated */ }; *** POTENTIAL INCOMPATIBILITY *** If you don't use the trailing semicolon, things will mysteriously break. 05/20/2002: beazley More improvements to type system handling. SWIG now correctly handles template names and parameters in a namespace. For example: namespace foo { template class bar { }; typedef int Integer; void blah(bar *x); }; In the generated code, all of the typenames are properly qualified. 05/17/2002: cheetah (William Fulton) [Java] deprecated broken -jnic and -jnicpp commandline options. The C or C++ JNI calling convention is now determined from the -c++ commandline option. 05/16/2002: cheetah (William Fulton) [Java] The JCALL macros which exist so that the same typemaps can be used for generating both the C and C++ JNI calling conventions no longer appear in the generated code. This is because the output is now passed through the SWIG preprocessor which does the macro expansion for either C or C++ (depending on whether -c++ is passed on the SWIG commandline). The generation of the functions used in the array typemaps have been adjusted to take account of this. The side effect is that any typemaps which contained JCALL macros within %{ %} brackets will have to be moved within {} brackets so that the SWIG preprocessor can expand the macros. *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** 05/13/2002: beazley Class templates may now be used as template parameters. For example: template class C> class Foo { ... }; template class Bar { ... }; %template(Fooi) Foo; SWIG doesn't really do anything special with this---it's just another way of specifying a template parameter. 05/13/2002: beazley Minor refinement of template support. Template parameter names are no longer required for types. For example: template class Foo { }; Obviously, names are required for template; 05/12/2002: beazley New macro expansion in typemaps. The sequence: $descriptor(type) Will expand into the SWIG type descriptor structor for the given type. Type may be any abstract datatype. For example: $descriptor(int *) $descriptor(int (*)(int,double)) $descriptor(vector *) Caveat: It is *NOT* currently legal to use other typemap substitution variables in the macro. For example $descriptor($1_type). The primary purpose of this modification is to better support typemaps for container objects or to allow typemaps that might be performing type conversions. *** NEW FEATURE *** 05/11/2002: beazley The wrapping of references to primitive types has been changed as follows: Arguments of type 'const primitive &' are now passed by value as opposed to pointers. Return values of type 'const primitive &' are returned as values instead of pointers. 'primitive' is any one of int, short, long, long long, char, float, double, bool (as well as unsigned variants). This change is being made to better support C++ wrapping--especially code that makes use of templates and the STL. 05/11/2002: beazley The %template directive can now be used to access templates in a namespace. For example: namespace std { template class complex { T re, im; public: complex(T _r = T(), T _i = T()) : re(_r), im(_i) { } T real() { return re; } T imag() { return im; } }; } %template(complex) std::complex; Note: There are some very subtle namespace/symbol table management issues involved in the implementation of this. It may not work in certain cases. 05/10/2002: beazley Member template constructor support added. For example: template struct pair { _T1 first; _T2 second; pair() : first(_T1()), second(_T2()) { } template pair(const pair<_U1,_U2> &x); }; To instantiate the template, use %template and %extend. For example, this expands the constructor into a default copy constructor: %extend pair { %template(pair) pair<_T1,_T2>; } Highly experimental. Other uses may be broken. 05/10/2002: beazley The %extend (%addmethods) directive no longer works unless it appears in the public section of a class. An error message is now generated (as opposed to a segmentation fault). 05/09/2002: beazley New %warnfilter() directive. This directive attaches a warning filter to specific declarations and has the same semantics as %rename, %ignore, %feature, and so forth. For example: %warnfilter(501) foo; // Suppress overloaded warning int foo(int); int foo(double); or %warnfilter(501) Object::foo(double); class Object { public: int foo(int); int foo(double); }; This feature only suppresses warnings in later stages of code generation. It does not suppress warnings related to preprocessing or parsing. *** NEW FEATURE *** 05/09/2002: beazley SWIG now supports C99 variadic preprocessor macros. For example: #define debugf(fmt,...) fprintf(stderr,fmt,__VA_ARGS__) The argument "..." is used to indicate variable arguments which are all placed into the special argument name __VA_ARGS__ in the macro expansion. SWIG also implements the GNU (##) extension for swallowing the preceding comma when __VA_ARGS__ is empty. For example: #define debugf(fmt,...) fprintf(stderr,fmt, ##__VA_ARGS__) Here is how this is expanded: debugf("%d", 3) --> fprintf(stderr,"%d",3) debugf("Hello") --> fprintf(stderr,"Hello" ) (notice the deleted comma). *** NEW FEATURE *** 05/08/2002: samjam (Sam Liddicott) Many changes to php module. Shadow classes are now implemented entirely in native C and no need for php-code shadow wrappers Populated template config.m4 and Makefile.in as needed by phpize are generated. 05/08/2002: ljohnson (Lyle Johnson) [Ruby] A copy constructor is now turned into a "clone" instance method (see Dave's change for copy constructors dated 4/7/2002). This seems like the appropriate thing to do for Ruby code. 05/08/2002: ljohnson (Lyle Johnson) [Ruby] Fixed [ 553864 ] Inline destructor code not written. 05/08/2002: beazley %ignore behaves better with constructors, destructors, and the type system in general. For constructors and destructors, %ignore now suppresses the creation of a default constructor or destructor. For example: %ignore ~Foo; class Foo { public: Foo(); ~Foo(); ... }; In SWIG-1.3.11, ~Foo() simply "disappeared" and the code generator created a wrapper for a default destructor (as if it was never declared in the interface). In SWIG-1.3.12, %ignore suppresses the creation of a destructor if one is actually defined. Similarly, even though a declaration is ignored, information may still be needed to properly handle types. For example, here is a very subtle error that is fixed by this change: %ignore std::string; // Prevent class wrapping namespace std { class string { ... }; %typemap(in) string * { ... } } void foo(std::string *s); // Broken. Before this fix, %ignore would cause the class definition to disappear. This, in turn, would cause the typemap to be misapplied. 05/08/2002: beazley Minor changes to %rename, %ignore, %feature, and related directives for better support of destructors. Destructors can now be precisely tagged. For example: %ignore Foo::~Foo; %feature("action") ~Bar { ... } *Developer warning* Operations such as renaming and feature attachment for classes used to be applied to destructors as well. For instance, if you did this: %rename(Bar) Foo; The operation applied to the class itself, the constructor, and the destructor. This is no longer the case. Now such operations will only apply to the class and the constructor. Note: if you were relying on this for class renaming, be aware that renamed classes should really only be handled at the level of the class itself and not the level of individual declarations in the class (although they can be renamed individually if needed). As far as I know, the Language class is already taking care of this case correctly. 05/07/2002: beazley New set of tests. The Examples/test-suite/errors directory contains tests that try to exercise all of SWIG's error and warning messages. 05/07/2002: beazley Start of a warning framework. Warning messages are now assigned numeric values that are shown in warning messages. These can be suppressed using the -w option. For example: swig -w302 example.i swig -w302,305 example.i Alternatively, the #pragma preprocessor directive can be used to disable this: #pragma SWIG nowarn=302 #pragma SWIG nowarn=302,305 Note: Since SWIG is a multi-pass compiler, this pragma should only be used to change global settings of the warning filter. It should not be used to selectively enable/disable warnings in an interface file. The handling of #pragma occurs in the C++ preprocoessor and affects all subsequent stages of compilation. The -Wall option turns on all warnings and overrides any filters that might have been set. Warnings can be issued from an interface using %warn. For example: %warn "110:%section is deprecated" The first part of a warning message is an optional warning number. A complete set of warning numbers is found in Source/Include/swigwarn.h. *** NEW FEATURE *** 05/07/2002: beazley Internal parsing change. Directives to include files now use brackets [ ... ] instead of { ... }. %includefile "foo.i" [ ... ] The use of { ... } was a bad choice because they were included implicitly by the preprocessor and made it impossible to properly detect legitimate missing '}' errors. 04/16/2002- 05/02/2002: beazley SWIG European Tour: Paris-Amsterdam-Bath. 04/23/2002: beazley The %addmethods directive has been renamed to %extend. For example: class Foo { ... }; %extend Foo { int blah() { ... }; int bar() { ... }; ... }; Motivation: the %addmethods directive can be used for many other tasks including adding synthesized attributes, constructors, and typemaps. Because of this, "addmethods" is somewhat misleading. %extend more precisely describes this operation---extension of a class or structure. *** POTENTIAL INCOMPATIBILITY *** %addmethods still works via a macro definition. However, a warning message may be generated. Errors involving %addmethods will actually refer to the %extend directive. 04/23/2002: beazley Further refinement of the type system. Typedef now propagates through functions, pointers to functions, and pointers to member functions. For example: typedef int Integer; void foo(int (*x)(int), Integer (*y)(Integer)); In this case, arguments 'x' and 'y' have exactly the same type (and would obviously accept objects of either type). Similarly, consider this: class Foo { }; typedef Foo Bar; void bar(int (Foo::*x)(int), int (Bar::*y)(int)); In this case, arguments x and y are the same type (via typedef). 04/22/2002: beazley SWIG now generates a warning message if any part of an expression involves values from a private part of a class. For example: class Foo { private: static int X; public: void blah(int a, int b = X); // Warning }; In this case, the default argument is ignored. There are workarounds, but they are rather clumsy. For instance, you might do this: %feature("action") blah(int,int) { if ($nargs == 1) { result = blah(arg1); } else { result = blah(arg1,arg2); } } void blah(int a, int b = 0); 04/21/2002: beazley Use of the %inline directive inside a namespace is forbidden and now generates an error message. This is not allowed since the inlined code that is emitted is not placed inside a namespace. This confuses other stages of parsing. 04/21/2002: beazley Some bug fixes to casting operations and expression parsing. Due to some parsing issues, it is not currently possible to use casts for all possible datatypes. However, the common cases work. 04/20/2002: beazley (Amsterdam) Member templates now work. Simply use the %template directive inside a class or %addmethods to create instantiations (see Doc/Manual/SWIGPlus.html). Supporting this was easy---earlier changes to templates made it possible using only a two-line modification to the parser and a few minor modifications elsewhere. Hmmm, come to think of it, the smoke was rather thick in that Internet "cafe". *** NEW FEATURE *** 04/19/2002: beazley (TGV) Improved handling of non-type template parameters. For example: vector; Simple numbers and strings can be used with the %template directive as well. For example: %template(vecint100) vector; Note: Arithmetic expressions are not currently allowed. Default template arguments now work and do not have to be given to %template. 04/18/2002: beazley (Paris) Change in internal template handling. Template parameters are now fully integrated into the type system and are aware of typedefs, etc. This builds upon the change below. *** DEVELOPER WARNING *** Word of caution to language module writers. The "name" parameter of certain parse tree nodes (classes, functions, etc.) may be parameterized with types. This parameterization is done using SWIG type-strings and not the underlying C version. For example, int max(int *,int *) has a name of "max<(p.int)>". If you use the name directly, you may get syntax errors in the generated code. To fix this, use SwigType_namestr(name) to convert a parameterized name to a C name with valid syntax. The internal version is used to reduce template types to a common representation and to handle issues of typedef. 04/16/2002: beazley (somewhere over the Atlantic) Enhancement of typedef resolution. The type system is now aware of template arguments and typedef. For example: typedef int Integer; foo(vector *x, vector *y); In this case, vector and vector are the same type. There is some interaction between this mechanism and the implementation of typemaps. For example, a typemap defined for vector * would apply to either type. However, a typemap for vector * would only apply to that type. Typedefs and typemaps and matched by left-most expansion. For example: vector --> vector --> vector 04/24/2002: cheetah (William Fulton) [Java] Changes to Java shadow classes. Overcomes a bug where the module assumed that a pointer to a derived class could be used in place of a pointer to a base class. Thanks to Stephen McCaul for analysing the bug and submitting patches. A consequence is that the getCPtr() method in each shadow class has disappeared and has been replaced with a getCPtrXXX(), where XXX is the shadow class name. If you have code that previously used getCPtr(), and the associated class is wrapping a C struct or a C++ class that is not involved in an inheritance chain, just use the new method. If however, the class is involved in an inheritance chain, you'll have to choose which pointer you really want. Backwards compatibility has been broken as not using the correct pointer can lead to weird bugs through ill-defined behaviour. If you are sure you want the old methods, you could add them back into all shadow classes by adding this at the beginning of your interface file: %pragma(java) allshadowcode=%{ public long getCPtr(){ return swigCPtr; } %} Please see entry dated 07/23/2002 to see how to do this after the deprecation of the allshadowcode pragma. *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** 04/13/2002: beazley Fixed problem with default arguments and references. Declarations such as this should now work: void foo(const string &x = "Hello"); 04/12/2002: beazley Added typemap $* substitutions for typemaps involving arrays. Requested by William Fulton. 04/11/2002: beazley Template specialization is now supported. For example: template<> class vector { ... }; When the %template directive is used, it will use a specialization if one is defined. There are still some limitations. Partial specialization is not supported. A template of type does not match all pointers. *** NEW FEATURE *** 04/11/2002: beazley Major change to template wrapping internals. Template declarations are no longer processed as macros but now result in real parse-tree nodes. The %template directive expands these nodes into a specific instantiation. This change enables a number of new and interesting capabilities: Directives such as %rename, %feature, and %addmethods can now be applied to uninstantiated templates. For example: %rename(barsize) vector::bar(char *buf, int len); ... template class vector { public: ... void bar(char *buf); void bar(char *buf, int len); // Renamed ... }; %template(intvector) vector; // Renaming carries through By parsing templates into an internal data structure, it will be possible to support specialization (and maybe partial specialization). This is highly experimental and a work in progress. *** POTENTIAL INCOMPATIBILITY *** In SWIG-1.3.11, template declarations were simply processed as weird macros. No other information was retained. This made it impossible to support more advanced features and complicated many other parts of the implementation. 04/09/2002: beazley Change to template class wrapping. There were a variety of "issues" with the old approach related to parsing, the type system, and namespaces. These changes are meant to rectify some of these problems: A specific instantiation of a template can now be specified by including the class inline like this: class vector { public: vector(); ~vector(); ... whatever ... }; This is template specialization, but partial specialization is not yet implemented. The %template directive has been modified to expand roughly as follows: %template(vecint) vector; becomes %rename(vecint> vector; class vector { public: vector(); ... }; Note that this simply builds upon the code above (templates included inline). This modified approach to wrapping fixes some subtle type issues. For instance, you can now define typemaps and typedefs like this: %typemap(in) vector * { ... } typedef vector intvector; ... void blah(intvector *v); // Gets the above typemap This did not work in SWIG-1.3.11 due to a peculiarity of the template implementation. %template(name) no longer installs the template as a class with name "name". This might break %addmethods as described in the manual. For example: %template(vecint) vector; %addmethods vecint { // Fails. vecint not a class ... }; To fix this, just use the template name instead: %addmethods vector { ... } Note: This technique might be a way to implement some bizarre template specialization techniques. For example: %addmethods vector { // Only applied if vector instantiated later %typemap(in) vector * { ... } ... }; *** POTENTIAL INCOMPATIBILITY *** 04/08/2002: beazley Fixed [ 540868 ] #if defined whatever - not parsed. SWIG should now correctly handle preprocessor directives like this: #if defined __cplusplus ... #endif Note: was implemented previously, but there was a minor bug. Reported by Adam Hupp. 04/07/2002: beazley %readonly and %readwrite are deprecated due to a change in the implementation. Instead of being pragmas, mutability is now controlled as a "feature" using the following two directives: %immutable; int x; // read-only variable int y; // read-only variable %mutable; int z; // Modifiable %immutable and %mutable are much more powerful than their older counterparts. They can now pinpoint a specific declaration like this: %immutable x; /* Any x */ %immutable Foo::x; /* x in class Foo */ In fact, the matching algorithm is the same as for %rename, %ignore, and other directives. This means that the declaration %immutable Foo::x; would not only apply to class Foo but to all derived classes as well. *** POTENTIAL INCOMPATIBILITY *** %immutable and %mutable must be terminated by a semi-colon. This differs slightly from the older %readonly and %readwrite directives. Since %immutable and %mutable can be applied to declarations the semicolon is needed to distinguish between a global feature and one targeted to a single declaration. Note: this incompatibility is the primary reason for changing the name of the directive. 04/07/2002: beazley New handling of copy constructors. If a class defines constructors like this: class Foo { public: Foo(); Foo(const Foo &); // Copy constructor ... }; SWIG now generates a function copy_Foo() for the copy constructor. In previous verions, this generated a name-clash and an error message. To preserve backwards compatibility, SWIG does not change the behavior if %rename is used to resolve the name conflict. However, if no name resolution is made, this new approach is used. Copy constructors may be handled as a special case in the target language. However, this is up to the language module itself. 04/07/2002: beazley The %template directive is now namespace aware. This allows code like this: namespace foo { template max(T a, T b) { return a > b ? a : b; } } using namespace foo; %template(maxint) max; // Ok namespace bar { using foo::max; %template(maxdouble) max; // Ok } Caveat: the template name supplied to %template must be defined in the same scope in which the %template directive appears. This code is illegal: %template(maxint) foo::max; 04/07/2002: beazley Minor enhancement to preprocessor. The preprocessor can now perform string comparison. For example: #define A "hello" ... #if A == "hello" ... #endif The primary use of this is in SWIG macros. For example: %define FOO(x) #if #x == "int" /* Special handling for int */ ... #endif %enddef Normal users can probably safely ignore this feature. However, it may be used in parts of the SWIG library. 04/07/2002: beazley Further refinement of default constructor/destructor wrapper generation. SWIG is now much more aware of pure virtual methods. For instance: class A { /* Abstract */ public: virtual void method1() = 0; virtual void method2() = 0; }; class B : public A { /* Abstract */ public: virtual void method1() { }; }; class C : public B { /* Ok */ public: virtual void method2() { }; }; In this case, SWIG will only generate default constructors for C. Even though B looks fine, it's missing a required method and is abstract. 04/04/2002: beazley Subtle change to structure data member access. If you have a structure like this: struct Foo { Bar b; }; The accessor functions for b are generated as follows: (1) If b is *not* defined as a structure or class: Bar Foo_b_get(Foo *self) { return self->b; } void Foo_b_set(Foo *self, Bar value) { self->b = value; } (2) If b *is* defined as a structure or class: Bar *Foo_b_get(Foo *self) { return &self->b; } void Foo_b_set(Foo *self, Bar *value) { self->b = *value; } See the "Structure data members" section of Doc/Manual/SWIG.html for further details. *** POTENTIAL INCOMPATIBILITY *** This may break interfaces that relied on a lot of a undeclared structure and class names. To get the old behavior, simply use a forward declaration such as "struct Bar;" 04/04/2002: beazley C++ namespace support added. SWIG supports all aspects of namespaces including namespace, using, and namespace alias declarations. The default behavior of SWIG is to flatten namespaces in the target language. However, namespaces are fully supported at the C++ level and in the type system. See Doc/Manual/SWIGPlus.html for details on the implementation. 04/02/2002: cheetah (William Fulton) [Java] Sun has modified javac in jdk1.4 to no longer compile an import of an unnamed namespace. To fix this SWIG no longer generates the import for packageless classes. http://developer.java.sun.com/developer/bugParade/bugs/4361575.html As reported SF #538415. 03/27/2002: ljohnson (Lyle Johnson) [Ruby] Added support for pointer-to-member, similar to that for the Python module. Remarkably similar. Also added a new example for this (Examples/ruby/mpointer), which is remarkably similar to the Python example of the same name. 03/26/2002: ljohnson (Lyle Johnson) [Ruby] Made a few minor edits to the "Advanced Topics" chapter of the SWIG manual and added a new major section about how to create multi-module Ruby packages with SWIG. 03/26/2002: ljohnson (Lyle Johnson) [Ruby] Removed all of the old Ruby pragmas. If any of this functionality is truly missed we can resurrect it, preferably with some kind of feature-based directive. 03/25/2002: ljohnson (Lyle Johnson) [Ruby] Fixed SWIG exception library support for Ruby, which has apparently been broken for some time. Luckily, no one seems to have noticed. 03/23/2002: beazley C++-namespace support in SWIG directives. %addmethods: The %addmethods directive now accepts a fully qualified classname and can be used inside C++ namespace declarations. For example: // Attaches to the class Foo::Bar below %addmethods Foo::Bar { int somemethod() { ... } }; namespace Foo { class Bar { public: ... }; // Attaches to the class Bar above %addmethods Bar { int othermethod() { ... }; } } %feature, %rename, %ignore, %exception, and related directives: Namespaces are fully integrated into the the renaming and declaration matcher. For example: %rename(display) Foo::print; // Rename in namespace Foo %ignore Foo::Bar::blah; // Ignore a declaration %rename directives can be placed inside namespace blocks as well. For example: namespace Foo { %rename(display) print; // Applies to print below void print(); }; Most other SWIG directives should work properly inside namespaces. No other changes are needed. 03/22/2002: beazley Some changes to internal symbol table handling. SWIG no longer manages structures and unions in a separate namespace than normal declarations like ANSI C. This means you can't have a structure with the same name as a function. For example: struct Foo { ... } int Foo() { ... } This approach is more like C++. It's not clear that SWIG ever really supported the ANSI C anyways---using the same name would almost certainly generate a name-clash in the target language. 03/22/2002: ljohnson (Lyle Johnson) [Ruby] Fixed [ 517302 ] for handling of renamed overloaded constructors. Now, renamed overloaded constructors are converted into class singleton methods (basically acting as "factory" methods). 03/21/2002: beazley Fixed [ 532957 ] %ignore parse error and casting operator. Reported by William Fulton. 03/18/2002: beazley (** ADVANCED USERS ONLY **) Added support for dynamic casting in return values. A somewhat common problem in certain C++ programs is functions that hide the identity of underlying objects when they are returned from methods and functions. For example, a program might include some generic method like this: Node *getNode(); However, Node * may just be base class to a whole hierarchy of different objects. Instead of returning this generic Node *, it might be nice to automatically downcast the object into the appropriate type using some kind dynamic cast. Assuming you understand the peril involved, a downcast can now be performed using the following function in the run-time type checker: swig_type_info *SWIG_TypeDynamicCast(swig_type_info *, void **ptr); This function checks to see if the type can be converted to another type. If so, a different type descriptor (for the converted type) is returned. This type descriptor would then be used to create a pointer in the target language. To use this, you would write a typemap similar to this: %typemap(out) Node * { swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor, (void **) &$1); $result = SWIG_NewPointerObj($1, ty); } Alternatively, %typemap(out) Node * = SWIGTYPE *DYNAMIC; To make the typemap have any effect, you have to write a supporting function that knows how to perform downcasting. For example: %{ static swig_type_info * Node_dynamic_cast(void **ptr) { Node **nptr = (Node **) ptr; Element *e = dynamic_cast(*nptr); if (e) { *ptr = (void *) e; return SWIGTYPE_p_Element; } Data *d = dynamic_cast(*nptr); if (d) { *ptr = (void *) d; return SWIGTYPE_p_Data; } return 0; } %} There is no restriction on how types are determined. dynamic_cast<> uses C++ RTTI. However, if you had some other mechanism for determining the type, you could use that here. Note: it is important to save the new pointer value back into the argument as shown. When downcasting, the value of the pointer could change. Finally, to make the casting function available, you have to register it with the run-time type checker. Put this macro in your interface file. DYNAMIC_CAST(SWIGTYPE_p_Node, Node_dynamic_cast); Note: this feature does not introduce a performance penalty on normal SWIG operation. The feature is only enabled by writing a new typemap that explicitly calls SWIG_TypeDynamicCast() to make a conversion. Examples/test-suite/dynamic_cast.i contains a simple example. This feature is not supported in the Java module due to differences in the type-checking implementation. *** EXPERIMENTAL FEATURE *** 03/17/2002: beazley Small change to type-name handling of unnamed structures and typedef. If a structure of this form appears: typedef struct { ... } Foo; Then 'Foo' is used as the proper typename for the structure. Furthermore, Foo can now be used as a name in C++ inheritance. SWIG was already kind of doing this, but this modification refines the implementation to more closely follow the C++ ARM, section 7.1.3, p. 106. This fixes a couple of obscure corner cases. 03/16/2002: beazley Modified C++ inheritance with a few enhancements. First, type information needed for casting and type-equivalence is generated even when base-classes aren't defined in the interface. For example: class Foo : public Bar { /* Bar unspecified */ public: ... }; void blah(Bar *b); In this case, the blah() function still accepts Foo * even though nothing is really known about Bar. Previous SWIG versions would just generate a type error. Inheritance has also been modified to work through typedef. For example: class Bar { }; typedef Bar OtherBar; class Foo: public OtherBar { } In this case, the base class of OtherBar is correctly resolved back to Bar. The use of the name OtherBar is lost in this resolution (the wrappers will simply use Bar instead of the typedef name OtherBar). 03/13/2002: beazley %typemap, %apply, and related directives can now appear inside class definitions. 03/13/2002: beazley Fixed a variety of problems related to compiling SWIG on 64-bit platforms. 03/12/2002: beazley Fixed problem with "ignore" and "in" typemaps. Local variables associated with "in" were being added to the wrapper function even though they were never used. Mostly harmless, but it would lead to a variety of compilation warnings. 03/12/2002: beazley Some changes to the internal type system and handling of nested C++ types. In previous versions of SWIG, if you had the following: class Foo { public: typedef int Blah; }; class Bar : public Foo { public: void somemethod(Blah x); }; The argument type in somemethod() would implicitly be set to Bar::Blah. Although this is technically allowed, it breaks typemaps. For example: %typemap(in) Foo::Blah { ... } doesn't match like you expect. This has been changed in SWIG-1.3.12. Now, types are expanded using the class in which they were defined. So, the argument type in somemethod() will be Foo::Blah---since the type Blah was defined in Foo. 03/10/2002: beazley Fixed some subtle type scoping problems with typedef and C++ classes. For example: typedef int Blah; class Bar { public: typedef double Blah; void foo(Blah x, ::Blah y); ... } 03/10/2002: beazley Highly experimental change to handle variable length arguments. First, there is no portable or reliable way to wrap a varargs function in full generality. However, you *can* change the function signature using %varargs. %varargs(char *) fprintf; ... void fprintf(FILE *f, char *fmt, ...); In this case, the variable length parameter "..." is simply replaced by the parameters given in %varargs. This results in a function like this: void fprintf(FILE *f, char *fmt, char *s); More than one argument can be used and default values can be defined. For example, this code specifies a maximum of four arguments. %varargs(char *x1 = 0, char *x2 = 0, char *x3 = 0, char *x4 = 0) fprintf; *** EXPERIMENTAL NEW FEATURE *** 03/10/2002: beazley Change to handling of variable length arguments. varargs is now handled as a proper parameter and is passed to the code generator. However, it still can't be handled correctly (and will generate a typemap warning). This change has been made to better incorporate variable length arguments with other directives such as %ignore, %rename, %feature, and so forth. 03/10/2002: beazley Fixed [ 522555 ] Syntax error parsing "define" construct. SWIG is a little more restrictive in determining #define statements that will be wrapped as constants. Also added a better parser error rule for handling bad constants. 03/08/2002: cheetah (William Fulton) [Java] Bug fix: Classes renamed with %rename that are derived from another class generate more appropriate shadow class code. 03/08/2002: cheetah (William Fulton) [Java] Fixed SF [ #523632 ] and [ #513335 ] both reported by Israel Tanner. Support for types that are used which are in a typedef. The appropriate shadow class name is generated. Also generated correct shadow classname when a templated class is used within another templated class. See the cpp_typedef.i testcase. 03/08/2002: cheetah (William Fulton) [Java] Bug fix: No type was generated in shadow classes for types that weren't wrapped by SWIG. The type is treated as a raw pointer, ie no shadow class. 02/22/2002: beazley Refined the matching algorithm used by %rename, %ignore, and %feature. If a type signature is supplied, it must exactly match that used in the declaration---including any use of const. For example: %rename(foo1) foo(int); %rename(bar1) bar(int) const; class Blah { public: void foo(int); // Matched --> foo1 void foo(int) const; // Not matched void bar(int); // Not matched void bar(int) const; // Matched --> bar1 } In previous versions, a non-const specification would match both the non-const and const declarations. However, the whole point of %rename and related directives is that they be able to precisely pinpoint exact declarations in an interface. This fixes the problem. 02/21/2002: beazley Reworked the handling of default constructor and destructors. SWIG now makes a preliminary pass over the parse tree to discover which classes support default allocation. This fixes a number of very subtle issues in code generation and call/return by value. 02/18/2002: cheetah (William Fulton) Improved support on Cygwin: Perl, Python, Tcl, Ruby and Java should work out of the box, barring the runtime library. Removed dllwrap and replaced with newly working gcc -shared instead for Cygwin. All this will require the new improved binutils 20010802 and later, but the latest Cygwin is usually the best recommendation. 02/15/2002: beazley Fixed some problems related to wrapping of global variables and Perl shadow classes. Reported by Chia-liang Kao. 02/15/2002: ljohnson (Lyle Johnson) [Ruby] Made a fix to the code generation for C++ class constructors so that we get both a "new" singleton method and an "initialize" instance method for each class. This change enables developers to derive new Ruby classes from SWIG-wrapped C++ classes and then override their initialize methods to provide subclass-specific instance initialization. 02/15/2002: ljohnson (Lyle Johnson) [Ruby] Massive documentation update for the Ruby module, contributed by Craig Files. 02/14/2002: ljohnson (Lyle Johnson) [Ruby] Bug fix: An error in the SWIG runtime support for Ruby was causing several of the examples to fail. Reported by William Fulton. 02/14/2002: ljohnson (Lyle Johnson) [Ruby] Bug fix: Enumerations defined within a class (such as those seen in the Examples/ruby/enum example) were not being exported with the correct names. Reported by William Fulton. 02/13/2002: ljohnson (Lyle Johnson) [Ruby] Added a warning message when we run across overloaded class constructors for C++ code, that this is currently not supported (even if the overloads have been %renamed). For an example of where this doesn't work, see Examples/ruby/operator. 02/13/2002: ljohnson (Lyle Johnson) [Ruby] Added an "ignored" warning message when the parser runs across an operator!=() declaration for C++ code. 02/11/2002: ljohnson (Lyle Johnson) [Ruby] Added the "import", "import_template", "operator" and "template" examples. 02/11/2002: ljohnson (Lyle Johnson) [Ruby] Added multi-module support. 02/09/2002: ljohnson (Lyle Johnson) [Ruby] Added the missing "#define SWIG_NOINCLUDE" at the top of the wrapper code when the '-c' option is used. 02/09/2002: ljohnson (Lyle Johnson) Corrected a minor off-by-one error for the size of the swig_types[] array that's generated in the wrapper code. 02/08/2002: beazley Fixed SF [ #515058 ] Wrong code for C++ templates. Reported by Israel Taller. Version 1.3.11 (January 31, 2002) ================================= 01/30/2002: beazley Fix to pass/return by value for C++ objects that define no default constructor. Changes to the typemap system made it impossible to wrap C++ objects with no default constructor. This has been fixed, but the solution involves some clever template magic contributed by William Fulton. Please see the comments in the file Lib/swig.swg for further details. This solution is experimental and may be refined in a future release. 01/30/2002: beazley Global variables and member data of type "const char *" can be set, but the old value is silently discarded without any garbage collection. This may generate a memory leak. This change is needed to more safely handle variables like this: const char *foo = "Hello World\n"; In this case, it's not safe to free the old value. However, SWIG can dynamically allocate a new value and make foo point to it. To fix this memory leak, you can probably do this: %clear const char *foo; %apply char * {const char *foo}; *** POTENTIAL INCOMPATIBILITY *** 01/30/2002: beazley Two minor typemap enhancements have been added. First, typemaps can issue a warning message by including a special warning attribute. For example: %typemap(in,warning="I'm going to do something dangerous") ... The warning message will show up whenever the typemap is applied. Second, a typemap can force a no-match by defining %typemap(in) sometype "pass"; If this is used, the typemap system will *not* record a typemap match for "sometype". This can be used to block selected typemaps. For example, if you wanted to disable a typemap feature for some type, you could do this. // Do not allow global variables of type 'const char *' to be set. %typemap(varin) const char * "pass"; It might also be possible to use this to do subtle and strange things with typemaps. For example, if you wanted to make 'blah *' an output value and 'const blah *' an input parameter, you might do this: %typemap(ignore) blah *(blah temp) { $1 = &temp; } %typemap(argout) blah * { ... return a value ... } /* Block unqualified typemaps defined above */ %typemap(ignore) const blah * "pass"; %typemap(argout) const blah * "pass"; %typemap(in) const blah * { ... get input value ... } (This potential applications of typemaps suggested by Greg Stein). *** NEW FEATURE *** 01/29/2002: cheetah (william fulton) [Java] Bug fix: No enumerations were wrapped when the -shadow commandline option was not specified. Reported by Israel Taller. 01/28/2002: cheetah (william fulton) [Java] Global arrays are successfully wrapped. In fact they started mostly working in SWIG-1.3.10. 01/28/2002:richardp Added first attempt at C++ and -shadow support for PHP4 module, please test and mail me if any problems/ideas on improving it. There is a known problem with uninitialized member variables, please see Examples/php4/sync/README for details. Also more PHP documentation added to Doc/Manual/Php.html 01/27/2002:beazley The ANSI C size_t type is now recognized as an integer by default. 01/26/2002:beazley long long and unsigned long long support added to many language modules. This is not a portable feature and will require compiler support for the long long type. In target languages that do not support long long (e.g., Tcl and Perl), numbers are converted to a string of digits. This prevents their use in arithmetic calculations, but still allows values to be set from a string. long long support requires the use of the strtoll() and strtoull() functions as well as the 'lld' and 'llu' format specifiers of sprintf(). 01/26/2002:beazley Fixed [ #501827 ] Delete method is not called. The Tcl module wasn't correctly calling destructors when they were defined using %addmethods. This has been fixed. Reported by Reinhard Fobbe. 01/26/2002: beazley Better support for long long and unsigned long long. Typemaps have been included in a number of modules for handling these types. In addition, the parser has been modified to accept long long literals such as 1234LL and 1234ULL. 01/27/2002: cheetah (william fulton) [Java] A C char[] is mapped to a Java String which is the default SWIG handling of char[] and char*. It used to be mapped to byte[]. Note that a C signed char[] array is mapped to byte[]. *** POTENTIAL INCOMPATIBILITY *** 01/25/2002: beazley Fixed a problem with return-by-value, C++, and objects that define no default constructor. Reported by Joel Reed. 01/25/2002: cheetah (william fulton) [Java] Overhaul of the Java module. The C code generation is now done from typemaps. 01/24/2002: cheetah (william fulton) [Java] Support for arrays of enum pointers 01/20/2002: cheetah (william fulton) [Java] Error checking for null Java objects being passed to native functions. Exception thrown now whereas before the JVM crashed. 01/18/2002: cheetah (william fulton) [Java] Corrected behaviour for functions that take arrays. For example, when this c function: void arrayfn(int array[]); is wrapped the corresponding native function public final static native void arrayfn(int[] array); is produced. Previously if the C function made any changes to the array elements, these were not reflected back into the Java array. This has now been corrected so that the changes are propogated back to Java and the calling function will see these changes. This is how pure Java functions work, ie arrays are passed by reference. 01/15/2002:mkoeppe [Guile] New file cplusplus.i with C++ typemaps contributed by Marcio Luis Teixeira . 01/11/2002: cheetah (william fulton) [Java] Changed mapping of C long to Java type. Was mapped to Java long, now mapped to Java int. If you want the previous mapping to Java long use this approach in your interface file: %clear long; %typemap(jni) long "jlong" %typemap(jtype) long "long" %typemap(jstype) long "long" %clear long[ANY]; %typemap(jni) long[ANY] "jlongArray" %typemap(jtype) long[ANY] "long[]" %typemap(jstype) long[ANY] "long[]" %typemap(in) long[ANY] {write me for array support} %typemap(out) long[ANY] {write me for array support} %typemap(argout) long[ANY] {write me for array support} %typemap(freearg) long[ANY] {write me for array support} *** POTENTIAL INCOMPATIBILITY *** This new mapping is more appropriate when interfacing to 32 bit applications which are used in the current 32-bit JVMs. For future 64-bit JVMs you may have to change these mappings - eg on Unix LP64 systems, but not on Microsoft 64bit Windows which will be using a P64 IL32 model. This may be automated in a future version of SWIG. 01/10/2002:beazley Fixed [ 501677 ] %init block in wrong place. Reported by Luigi Ballabio. 01/09/2002: cheetah (william fulton) [Java] Default support for the long long type. signed long long is mapped to a Java long. unsigned long long is mapped to BigInteger. 01/09/2002:beazley Experimental change to parser to better support mixing of int, long, short, unsigned, float, and double. The parser should now support types like this: short unsigned int int unsigned short unsigned short int unsigned int short This change also enables a type of 'long double' (previously unsupported) to be used. *** NEW FEATURE *** 01/05/2002: cheetah (william fulton) [Java] Casting fix for when function return type is a pointer as reported by Gary Pennington 2002-01-05. The upper 32bits of the 64 bit jlong will have contained junk for 32bit pointers. 01/05/2002: cheetah (william fulton) [Java] Better pointer handling in Java is possible as the INPUT, OUTPUT and INOUT typemaps have been added into typemaps.i. 01/05/2002: cheetah (william fulton) [Java] $null can be used in input typemaps to return early from JNI functions that have either void or a non-void return type. Example: %typemap(check) int * %{ if (error) { SWIG_exception(SWIG_IndexError, "Array element error"); return $null; } %} If the typemap gets put into a function with void as return, $null will expand to nothing: void jni_fn(...) { if (error) { SWIG_exception(SWIG_IndexError, "Array element error"); return ; } ... } otherwise $null expands to zero, where javareturntype is either a pointer or a primitive type: javareturntype jni_fn(...) { if (error) { SWIG_exception(SWIG_IndexError, "Array element error"); return 0; } ... } 01/02/2002: cheetah (william fulton) [Java] The Java module incorrectly used argout typemaps for strings. This is now corrected and the code now resides in the freearg typemap. The argout array typemaps have been split into argout and freearg typemaps. This correction may require some user written typemaps to be modified. *** POTENTIAL INCOMPATIBILITY *** 12/28/2001: cheetah (william fulton) [Java] Multi typemaps now working for Java see multimap example. [Java] Fix for recently introduced bug - freearg typemap code was appearing before the function call. 12/28/2001: cheetah (william fulton) [Java] JCALL macro for JNI calls that work in both C and C++ typemaps have been replaced with JCALL0, JCALL1, JCALL2, JCALL3 and JCALL4 macros. *** POTENTIAL INCOMPATIBILITY *** 12/22/2001:beazley Resolved some inconsistent behavior with %rename and class renaming. If you specify the following: %rename(Foo) Bar; class Bar { public: Bar(); ~Bar(); } Then the %rename directive applies to the class itself, the constructor, and the destructor (all will be renamed to Foo). If a class defines more than one constructor, the overloaded variants can still be renamed by specifying parameters to %rename. For example: %rename(Bar_copy) Bar(Bar &); class Bar { public: Bar(); Bar(Bar &); ~Bar(); }; There are still some odd corner cases. If you specify %rename(Foo) ::Bar; then only the name of the class is changed and the constructor/destructor names are left unmodified. If you specify %rename(Foo) *::Bar; then the names of the constructor/destructor functions are modified but the name of the class is not. 12/21/2001: cheetah (william fulton) [Java] jni, jtype and jstype typemaps no longer hardcoded but real typemaps. New variable substitution, $javaclassname, can be used in the jstype typemaps. It is replaced with the Java shadow class name where applicable. [Java] Fix for recently introduced bug to do with inheritance when using %import. [Java] A few more bug fixes, todo with %rename and using the kind with the type, eg void fn(union uni myuni, struct str mystr, class cl mycl); 12/20/2001:beazley Fixed [ #494524 ] Preprocessor bug - apostrophe and #subst. 12/20/2001:beazley Added SWIG_VERSION preprocessor symbol. This is a hexadecimal integer such as 0x010311 (corresponding to SWIG-1.3.11). This can be used in the interface as follows: #if SWIG_VERSION >= 0x010311 /* Use some fancy new feature */ #endif Note: The version symbol is not defined in the generated SWIG wrapper file. *** NEW FEATURE *** 12/20/2001:mkoeppe [MzScheme]: Renamed mzswig_make_boolean to swig_make_boolean, as the latter is used in the typemaps. Reported by Luigi Ballabio. 12/17/2001:mkoeppe [Guile]: Rewrote list-vector.i using multi-dispatch typemaps. Updated pointer-in-out.i. Make the deprecated typemap-substitution of "$source" in "argout" work as before. 12/16/2001:mkoeppe [Guile]: Fixed macros %values_as_list, %values_as_vector, %multiple_values to use the proper %pragma syntax. New Guile example/test "multivalue"; new Guile run-test for test-suite item "list-vector" (currently broken). 12/14/2001:mkoeppe [Guile]: Fixed typemap-substition bug for "varin". Relaxed valid-identifier check to allow all R5RS identifiers. Version 1.3.10 (December 10, 2001) ================================== 12/08/2001:beazley Modified %typemap so that %{ ... %} can also be used as a code block (mostly for completeness). For example: %typemap(in) blah %{ ... %} This form does not introduce a new block scope. Also, the code enclosed in %{ ... %} is not processed by the preprocessor. 12/08/2001:beazley Fixed [ #459614 ] SWIG with multiple TCL interpreters. 12/08/2001:beazley Fixed [ #417141 ] rubydec.swg is wrong Reported by Paul Brannan. 12/08/2001:beazley Fixed [ #410557 ] Problem with %addmethods on NT. Reported by Magnus Ljung. 12/08/2001:beazley Fixed [ #445233 ] Enhancement: handle access change. SWIG now parses (but ignores) C++ access changes for the the following: class A { protected: void something() { } public: A() {} }; class B : private A { public: B() : A() { } protected: A::something; <---- Parsed, but ignored }; Suggested by Krzysztof Kozminski. 12/08/2001: cheetah (william fulton) Fix for Ruby to work using Visual C++. 12/06/2001:beazley Fixed [ #465687 ] unsigned short parameters fail. Reported by Gerald Williams. 12/06/2001:beazley Fixed SF [ #489594 ] PyString_FromString can't take NULL arg. Reported by John Merritt. SWIG now converts string values to Python using code like this: resultobj = result ? PyString_FromString(result) : Py_BuildValue(""); 12/06/2001:beazley Fixed SF [ #463561 ] Type conversions not generated. Reported by Gerald Williams. 12/04/2001:beazley Fixed SF [ #470217 ] Tcl default argument handling. Reported by Shaun Lowry. 12/04/2001:beazley Fixed SF [ #472088 ] defined(MACRO) expanded everywhere. Embedded preprocessor directives such as %#if defined(FOO) are not expanded by the SWIG preprocessor. Reported by Gerald Williams. 12/04/2001:beazley Fixed SF [ #476467 ] Problems with #define & commas. 12/04/2001:beazley Fixed SF [ #477547 ] wrong declaration of pointer functions. Bad prototypes in Lib/tcl/ptrlang.i. 12/04/2001:beazley Fixed SF [ #483182 ] Constants can take args by mistake. When swig -perl5 -const is used, constants are declared with a void prototype. For example: sub ICONST () { $examplec::ICONST } Patch submitted by Rich Wales. 12/03/2001:beazley New %exception directive. This is intended to replace %except. It works in exactly the same manner except it does not accept a language specifier. For example: %exception { try { $action } catch(SomeError) { error } } %exception is also name aware---allowing it to be applied to specific declarations in an interface. For example: %exception foo { ... exception for any function/method foo ... } %exception Foo::bar { ... exception for method bar in class Foo ... } %exception Foo::bar(double) { ... exception for method bar(double) in class Foo ... } The semantics of this name matching is exactly the same as for %rename. *** NEW FEATURE *** 12/03/2001:beazley Substantial cleanup of the Python shadow class code. Shadow classes used to be created in this rather complicated manner involving about a half-dozen strings created in bits and pieces. Shadow classes are now generated in a more straightforward manner--in the same order that appears in the interface file. *** POTENTIAL INCOMPATIBILITY *** The order in which declarations appear in the shadow file may differ. 12/03/2001:beazley The %insert directive (%{ ... %}, %runtime, %header, %wrapper, etc.) can now be used inside of a class definition. This has potential uses when generating shadow class code. For example: class Foo { ... %insert("shadow") %{ # Some python code def blah(self): print "I'm blah!" %} ... }; The support for class code insertion depends on the language module. However, the intent of this feature is to simplify the task of extending shadow class code. In the Python module, this inserts code with the proper level of indendation (regardless of what was used in the SWIG interface). *** NEW FEATURE *** 11/29/2001: cheetah (william fulton) Modifications for Java and Python modules to work on cygwin. Unfortunately a lot of the python module has started to produces code which cannot be auto-imported using cygwin libtools so most of it is still broken. 11/28/2001:beazley The %rename and %feature directive can now be used inside of a class definition. For example: class Foo { %rename(foo_i) foo(int); %rename(foo_d) foo(double); public: ... void foo(int); void foo(double); ... }; When used in this manner, the %rename directive only applies to members of the class in which it appears as well as all derived classes. In fact, this is really just the same as saying: %rename(foo_i) Foo::foo(int); %rename(foo_d) Foo::foo(double); class Foo { ... }; *** NEW FEATURE *** 11/26/2001:beazley Added the experimental %feature directive. %feature can be used to attach arbitrary string attributes to parse tree nodes. For example: %feature("except") blah { try { $function } catch (Error) { whatever; } } or %feature("set") *::x_set "x"; or %feature("blah") Foo::bar(int,double) const "spam"; The syntax is borrowed from the %rename directive. In fact, the exact same semantics apply (inheritance, matching, etc.). %feature is a very powerful low-level primitive that can be used to customize individual language modules and to provide hints to any stage of code generation. Features are attached to parse tree nodes as attributes with names like "feature:*" where * is replaced by the feature name (e.g., "feature:except", "feature:set", etc.). Language modules can then look for the features using a simple attribute lookup. %feature is intended to be a replacement for a number of older SWIG directives including %except and specialized pragmas. It is more powerful (due to its parameterized name matching) and it provides very precise control over how customization features are attached to individual declarations. There are future expansion plans that will build upon this capability as well. It's not certain that %feature will ever be used directly by SWIG users. Instead, it may be a low-level primitive that is used in high-level macro definitions. For instance, to support properties, you might define a macro like this: %define %property(name, setf, getf) %feature("set") setf #name; %feature("get") getf #name; %enddef Which allows a user to specify things like this: %property(p, get_p, set_p); class Blah { public: int get_p(); void set_p(int); }; *** EXPERIMENTAL NEW FEATURE *** 11/24/2001:beazley The Tcl module has been expanded with some new features for managing object ownership. For example: set c [Circle -args 20] $c area # Invoke a method $c -disown # Releases ownership of the object $c -acquire # Acquires ownership of the object If Tcl owns the object, its destructor is invoked when the corresponding object command is deleted in Tcl. To simplify the destruction of objects, the following syntax can be used: $c -delete # Delete an object This is an alternative for the more obscure variant of rename $c {} These features also add functionality at the C API level. The following functions manage ownership from C and can be used in typemaps. SWIG_Acquire(void *ptr); SWIG_Disown(void *ptr); A new function for constructing instances is also available: Tcl_Obj * SWIG_NewInstanceObj(Tcl_Interp *interp, void *ptr, swig_type_info *type, int own); When used in a typemap, this creates a pointer object and an interpreter command that can be used to issue methods and access attributes as shown above. *** NEW FEATURE *** 11/23/2001:beazley All Python-related %pragma operations have been eliminated. Most of these were written for older SWIG versions in order to compensate for limitations in earlier releases. In an effort to reduce the amount of code-clutter and potential for errors, it is easier to simply eliminate the pragmas and to start over (if needed). To be honest, I'm not even sure the pragmas worked in 1.3.9 and recent releases. Note: If you need to insert code into the shadow class file created by SWIG, simply use the %shadow directive like this: %shadow %{ def some_python_code(): print "blah!" %} *** POTENTIAL INCOMPATIBILITY *** 11/22/2001:beazley Sweeping changes to the way in which the Python module handles shadow classes. In early implementations, shadow classes were merely Python wrappers around typed pointer objects. However, some users actually wanted to receive the shadow class object in C. To accomodate this, the dereferencing of the "this" pointer in a shadow class was moved to C as described in CHANGES [8/8/99]. However, the process of returning pointers to Python was still somewhat problematic. Specifically, shadow classes never worked in situations such as these: - Use of any kind of output typemap ('out' or 'argout') - Global variables (broken as far as I can tell). In the past, some users have dealt with this by manually trying to create shadow class objects themselves from C/C++. However, this was difficult because the C wrappers don't really know how to get access to the corresponding Python class. The Python module has now been modified to automatically attach shadow class objects to pointers when they are returned to Python. This process occurs in the function SWIG_NewPointerObj() so the process is completely transparent to users. As a result, shadow classes are now more seamlessly integrated with typemaps and other features of SWIG. This change may introduce a number of incompatibilities. The SWIG_NewPointerObj() now takes an extra parameter "own" to indicate object ownership. This can be used to return a pointer to Python that Python should destroy. In addition, older code that tries to manually construct shadow class objects or which expects bare pointers may break---such pointers may already be encapsulated by a shadow class. *** POTENTIAL INCOMPATIBILITY *** 11/20/2001:beazley Modified the %insert directive to accept single braces { ... }. For example: %insert("header") { ... some code ... } This works exactly like %{ ... %} except that the code in the braces is processed using the preprocessor. This can be useful in certain contexts such as low-level code generation in language modules. *** NEW FEATURE *** 11/20/2001:beazley Command line options are now translated into preprocessor symbols. For example: ./swig -python -shadow -module blah interface.i Creates the symbols: SWIGOPT_PYTHON 1 SWIGOPT_SHADOW 1 SWIGOPT_MODULE blah Modules can look for these symbols to alter their code generation if needed. *** NEW FEATURE *** 11/20/2001:beazley Massive overhaul of the Perl5 module. A lot of code generation is now driven by tables and typemaps. The generated wrapper code also makes use of tables to install constants, variables, and functions instead of inlining a bunch of procedure calls. The separate variable initialization function is gone. Most code generation is controlled via the perl5.swg file in the library. *** POTENTIAL INCOMPATIBILITY *** 11/13/2001:beazley Added parsing support for the C++ typename keyword. Primarily this is added to better support templates. For example: template void blah(C& v) { typename C::iterator i = v.begin(); } Note: typename is supported in the parser in the same way as 'struct' or 'class'. You probably shouldn't use it anywhere except in templates. *** NEW FEATURE *** 11/11/2001:beazley Massive overhaul of the language module API. Most functions now use a common, very simple, API. There are also a number of interesting semantic side-effects of how code is actually generated. Details will be forthcoming in Doc/Manual/Extending.html. *** POTENTIAL INCOMPATIBILITY *** Language modules written for previous versions of SWIG will no longer work, 11/10/2001:beazley Fixed a very subtle bug due to unnamed class wrapping. For example, if you did this typedef struct { int x,y; } gdPoint, *gdPointPtr; void foo(gdPointPtr x); Then the foo function would get a type-error. The problem has to do with internal typedef handling and the fact that the typedef declarations after the struct appear later in the parse tree. It should work now. Problem reported by Vin Jovanovic. 11/09/2001:beazley Subtle change to "out" typemaps (and related variations). The name that is attached to the typemap is now the raw C identifier that appears on a declaration. This changes the behavior of member functions. For example: %typemap(out) int foo { ... } class Blah { public: int foo(); // typemap gets applied } Previous versions never really specified how this was supposed to work. In SWIG1.1, you could probably write a typemap for the wrapper name like this: %typemap(out) int Blah_foo { ... } However, this old behavior is now withdrawn and not supported. Just use the member name without any sort of special prefix. *** POTENTIAL INCOMPATIBILITY *** 11/06/2001:beazley Changes to Tcl module initialization: (1) SWIG now automatically includes the code needed to work with Tcl stubs. Simply compile with -DUSE_TCL_STUBS. (2) SWIG now automatically calls Tcl_PkgProvide to register a package name. The package name is the same as the name specified with the %module directive. The version number is set to "0.0" by default. To change the version number, use swig -pkgversion 1.2 interface.i. *** POTENTIAL INCOMPATIBILITY *** Modules that provided stubs and Tcl_PkgProvide on their own might break. Simply remove that code. 11/05/2001:beazley Changed code generation of constants in the Tcl module. Constants are now stored in a large table that get installed at module startup. There are also no longer any static variables so it should generate somewhat less code. 11/04/2001:beazley The "const" typemap has been renamed to "constant" in many language modules. "const" is a C keyword which made the handling of the typemap directive somewhat awkward in the parser. *** POTENTIAL INCOMPATIBILITY *** 11/04/2001:beazley %typemap directive can now accept nearly arbitrary keyword parameters. For example: %typemap(in,parse="i",doc="integer") int "..."; The purpose of the keyword parameters is to supply code generation hints to the target language module. The intepretation of the parameters is language specific. *** NEW FEATURE *** 11/04/2001:beazley Slight semantic change to internal call/return by value handling. In previous versions of SWIG, call-by-value was translated into pointers. For example: double dot_product(Vector a, Vector b); turned into this: double wrap_dot_product(Vector *a, Vector *b) { return dot_product(*a,*b); } This translation was normally performed by the SWIG core, outside of the control of language modules. However, a side effect of this was a lot of bizarre typemap behavior. For example, if you did something like this: %typemap(in) int32 { ... } You would find that int32 was transformed into a pointer everywhere! (needless to say, such behavior is unexpected and quite awkward to deal with). To make matters worse, if a typedef was also used, the pointer behavior suddenly disappeared. To fix this, the pointer transformation is now pushed to the language modules. This produces wrappers that look roughly like this: double wrap_dot_product(Vector *a, Vector *b) { Vector arg1 = *a; Vector arg2 = *b; return dot_product(arg1,arg2); } This change also makes it easy to define typemaps for arbitrary undefined types. For example, you can do this (and it will work regardless what int32 is): %typemap(in) int32 { $1 = (int32) PyInt_AsLong($input); } *** POTENTIAL IMCOMPATIBILITY *** This change may break call/return by value code generation in some language modules. 11/03/2001:beazley Changed the name of the default typemaps to the following: %typemap() SWIGTYPE { ... an object ... } %typemap() SWIGTYPE * { ... a pointer ... } %typemap() SWIGTYPE & { ... a reference ... } %typemap() SWIGTYPE [] { ... an array ... } %typemap() enum SWIGTYPE { ... an enum value ... } %typemap() SWIGTYPE (CLASS::*) { ... pointer to member ... } These types are used as the default for all types that don't match anything else. See CHANGES log entry for 8/27/2000 for the old behavior. The role of these types is also described in Doc/Manual/Typemaps.html *** POTENTIAL INCOMPATIBILITY *** 10/25/2001:beazley Modified Guile and Mzscheme modules to support multi-argument typemaps. 10/25/2001: cheetah (william fulton) [Java] Fix to handle pointers to arrays. 10/24/2001:beazley Defining a typemap rule for enum SWIGENUM can now be used to define default behavior for enum variables. 10/22/2001:beazley Ruby module modified to support multi-argument typemaps. 10/22/2001:beazley The Ruby module can now handle functions with an arbitrary number of arguments. Previous versions were limited to to functions with only 9 or 16 arguments depending on the use of default arguments. Note: from some inspection of the Ruby interpreter source, the new approach might be a little faster as well. 10/18/2001:beazley Fixed a bug with forward class declarations and templates. class Foo ; Bug reported by Irina Kotlova. 10/16/2001:beazley Support for multivalued typemaps added. The typemaps are specified using the syntax below. Within each typemap, variable substitution is handled as follows: %typemap(in) (int argc, char *argv[]) { $arg; // The input object in the target language $1; // C local variable for first argument $2; // C local variable for second argument // These variables refer to either argument $1_type, $1_ltype, $1_basetype, etc... (argc) $2_type, $2_ltype, $2_basetype, etc... (argv[]) // Array dimension of argv $2_dim0 } Basically any variable that was available in normal typemaps is available for either argument by prefacing the variable name by '$n_' where n is the argument position. Notes: (1) Multi-valued typemaps can only be applied to a single object in the target scripting language. For example, you can split a string into a (char *, int) pair or split a list into a (int, char []) pair. It is not possible to map multiple objects to multiple arguments. (2) To maintain compatibility with older SWIG versions, the variables such as $target and $type are preserved and are mapped onto the first argument only. (3) This should not affect compatibility with older code. Multi-valued typemaps are an extension to typemap handling. Single valued typemaps can be specified in the usual way. The old $source and $target variables are officially deprecated. Input variables are referenced through $arg$ and output values are reference through $result$. *** NEW FEATURE *** 10/16/2001:beazley Added parsing support for multivalued typemaps. The syntax is a little funky, but here goes: // Define a multivalued typemap %typemap(in) (int argc, char *argv[]) { ... typemap code ... } // Multivalued typemap with locals %typemap(in) (int argc, char *argv[])(int temp) { ... typemap code ... } // Copy a multivalued typemap %typemap(in) (int argcount, char **argv) = (int argc, char *argv[]); // Apply a multivalued typemap %apply (int argc, char *argv[]) { (int argcount, char **argv) }; Note: this extra parsing support is added for future extension. No language modules currently support multi-valued typemaps. 10/11/2001:beazley Modified the typemap matching code to discard qualifiers when checking for a match. For example, if you have a declaration like this: void blah(const char *x); The typemap checker checks for a match in the following order: const char *x const char * char *x char * If typedef's are involved, qualifier stripping occurs before typedef resolution. So if you had this, typedef char *string; void blah(const string x); typemap checking would be as follows: const string x const string string x string const char *x const char * char *x char * The primary reason for this change is to simplify the implementation of language modules. Without qualifier stripping, one has to write seperate typemaps for all variations of const and volatile (which is a pain). *** POTENTIAL INCOMPATIBILITY *** Typemaps might be applied in places where they weren't before. 10/9/2001: beazley SWIG now generates wrappers that properly disambiguate overloaded methods that only vary in constness. For example: class Foo { ... void blah(); void blah() const; ... }; To handle this, the %rename directive can be used normally. %rename(blah_const) blah() const; In the resulting wrapper code, method calls like this are now generated: (obj)->blah() // Non-const version ((Foo const *)obj)->blah() // const version This should force the right method to be invoked. Admittedly, this is probably obscure, but we might as well get it right. 10/8/2001: beazley The preprocessor now ignores '\r' in the input. This should fix the following bug: [ #468416 ] SWIG thinks macro defs are declarations? 10/8/2001: beazley Added support for ||, &&, and ! in constants. This fixes SF [ #468988 ] Logical ops break preprocessor. However, at this time, constants using these operators are not supported (the parser will issue a warning). 10/4/2001: beazley Added -show_templates command line option. This makes SWIG display the code it actually parses to generate template wrappers. Mostly useful for debugging. *** NEW FEATURE *** 10/4/2001: beazley Change to semantics of %template directive. When using %template, the template arguments are handled as types by default. For example: %template(vecint) vector; %template(vecdouble) vector; To specify a template argument that is *not* a type, you need to use default-value syntax. For example: %template(vecint) vector; %template(vecdouble) vector; In this case, the type name doesn't really matter--only the default value (e.g., 50, 100) is used during expansion. This differs from normal C++, but I couldn't figure out a better way to do it in the parser. Might implement an alternative later. *** POTENTIAL INCOMPATIBILITY *** 10/4/2001: beazley Major changes to template handling in order to provide better integration with the C++ type-system. The main problem is as follows: Suppose you have a template like this: template void blah(const T x) { stuff }; Now suppose, that you instantiate the template on a type like this in SWIG: %template(blahint) blah; In C++, this is *supposed* to generate code like this: void blah(int *const x) { stuff }; However, in SWIG-1.3.9, the template substitution gets it wrong and produces void blah(const int *x) { stuff }; (notice the bad placement of the 'const' qualifier). To fix this, the SWIG parser now generates implicit typedefs for template type arguments that produces code roughly equivalent to doing this: typedef int *__swigtmpl1; %template(blahint) blah<__swigtmpl1>; which generates code like this: void blah(const __swigtmpl1 x) { stuff }; Since this is correct in both C++ and SWIG, it provides the right semantics and allows everything to compile properly. However, to clean up the generated code a little bit, the parser keeps track of the template types and performs back-substitution to the original type when building the parse tree. Thus, even though the implicit typedef is used in the input and may appear in the generated wrapper file (for proper compilation), the parse tree will hide a lot of these details. For example: void blah(const __swigtmpl1 x) { stuff }; will look like it was declared as follows (which is what you want): void blah(int *const x) { stuff } The only place you are likely to notice the typedef hack is in bodies of template functions. For example, if you did this, template class blah { ... %addmethods { void spam() { T tempvalue; ... } } } you will find that 'T tempvalue' got expanded into some strange typedef type. This *still* compiles correctly so it's not a big deal (other than looking kind of ugly in the wrapper file). 10/4/2001: beazley Fixed some inheritance problems in Tcl Object interface. 10/1/2001: beazley Tcl module has changed to use byte-backed pointer strings. This implementation should be safe on 64-bit platforms. However, the order in which digits appear in pointer values no longer directly corresponds to the actual numerical value of a pointer (on little-endian machines, pairs of digits appear in reverse order). 10/1/2001: beazley Perl5 module is now driven by a configuration file 'perl5.swg' in the SWIG library. 10/1/2001: beazley The perl5 module no longer tries to apply the "out" typemap in code generated for magic variables. I'm surprised that this ever worked at all (since all of the code that was there was wrong anyways). Use the "varout" typemap to handle global variables. 10/1/2001: beazley Fixed a bug related to character array members of structures. For example: struct Foo { char name[32]; }; SWIG is normally supposed to return a string, but this was broken in 1.3.9. The reason it was broken was actually due to a subtle new feature of typemaps. When a data member is set to an array like this, the return type of the related accessor function is actually set to an array. This means that you can now write typemaps like this: %typemap(python,out) char [ANY] { $target = PyString_FromStringAndSize($source,$dim0); } This functionality can be used to replace the defunct memberout typemap in a more elegant manner. 9/29/2001: beazley Some further refinement of qualified C++ member functions. For example: class Foo { ... void foo() const; ... }; (i) The SWIG parser was extended slightly to allow 'volatile' and combinations of 'const' and 'volatile' to be used. This is probably rare, but technically legal. Only added for completeness. (ii) For the purposes of overloading, qualified and non-qualified functions are different. Thus, when a class has methods like this: void foo(); void foo() const; Two distinct methods are declared. To deal with this, %rename and similar directives have been extended to recognize const. Thus, one can disambiguate the two functions like this: %rename(fooconst) Foo::foo() const; or simply ignore the const variant like this: %ignore Foo::foo() const; Note: SWIG currently has no way to actually invoke the const member since the 'const' is discarded when generating wrappers for objects. 9/27/2001: beazley New directive. %namewarn can be used to issue warning messages for certain declaration names. The name matching is the same as for the %rename directive. The intent of this directive is to issue warnings for possible namespace conflicts. For example: %namewarn("print is a python keyword") print; The name matching algorithm is performed after a name has been resolved using %rename. Therefore, a declaration like this will not generate a warning: %rename("Print") print; ... void print(); /* No warning generated */ Since the warning mechanism follows %rename semantics, it is also to issue warnings for specific classes or just for certain member function names. (Dave - I've been thinking about adding something like this for quite some time. Just never got around to it) *** NEW FEATURE *** 9/27/2001: beazley Enhanced the %ignore directive so that warning messages can be issued to users. This is done using %ignorewarn like this: %ignorewarn("operator new ignored") operator new; The names and semantics of %ignorewarn is exactly the same as %ignore. The primary purpose of this directive is for module writers who want to ignore certain types of declarations, but who also want to alert users about it. A user might also use this for debugging (since messages will appear whenever an ignored declaration appears). *** NEW FEATURE *** 9/26/2001: beazley Super-experimental support for overloaded operators. This implementation consists of a few different parts. (i) Operator names such as 'operator+' are now allowed as valid declarator names. Thus the 'operator' syntax can appear *anyplace* a normal declarator name was used before. On the surface, this means that operators can be parsed just like normal functions and methods. However, it also means that operator names can be used in many other SWIG directives like %rename. For example: %rename(__add__) Complex::operator+(const Complex &); (ii) Operators are wrapped *exactly* like normal functions and methods. Internally, the operator name is used directly meaning that the wrapper code might contain statements like this: arg0->operator*((Complex const &)*arg1); This all seems to parse and compile correctly (at least on my machine). (iii) SWIG will no longer wrap a declaration if its symbol table name contains illegal identifier characters. If illegal characters are detected, you will see an error like this: Warning. Can't wrap operator* unless renamed to a valid identifier. The only way to fix this is to use %rename or %name to bind the operator to a nice name like "add" or something. Note: the legal identifier characters are determined by the target language. There are certain issues with friend functions and operators. Sometimes, friends are used to define mixed operators such as adding a Complex and a double together. Currently, SWIG ignores all friend declarations in a class. A global operator declaration can probably be made to work, but you'll have to rename it and it probably won't work very cleanly in the target language since it's not a class member. SWIG doesn't know how to handle operator specifications sometimes used for automatic type conversion. For example: class String { ... operator const char*(); ... }; (this doesn't parse correctly and generates a syntax error). Also: operators no longer show up as separate parse-tree nodes (instead they are normal 'cdecl' nodes). I may separate them as a special case later. See Examples/python/operator for an example. *** SUPER-EXPERIMENTAL NEW FEATURE *** Version 1.3.9 (September 25, 2001) ================================== 9/25/2001: beazley Fixed parsing problem with type declarations like 'char ** const'. SWIG parsed this correctly, but the internal type was represented incorrectly (the pointers and qualifiers were in the wrong order). 9/25/2001: beazley Withdrew experimental feature (noted below) that was causing serious parsing problems. Version 1.3.8 (September 23, 2001) ================================== 9/23/2001: beazley Included improved distutils setup.py file in the Tools directory (look for the setup.py.tmpl file). Contributed by Tony Seward. 9/23/2001: beazley Included two new RPM spec files in the Tools directory. Contributed by Tony Seward and Uwe Steinmann. 9/21/2001: beazley Fixed SF Bug [ #463635 ] Perl5.swg does not compile in Visual C++ 9/21/2001: beazley Two new directives control the creation of default constructors and destructors: %nodefault %makedefault These replace %pragma nodefault and %pragma makedefault. (old code will still work, but documentation will only describe the new directives). 9/21/2001: beazley Fixed SF Bug [ #462354 ] %import broken in 1.3.7. 9/20/2001: beazley Parser modified to ignore out-of-class constructor and destructor declarations. For example: inline Foo::Foo() : Bar("foo") { } inline Foo::~Foo() { } Suggested by Jason Stewart. *** EXPERIMENTAL FEATURE *** 9/20/2001: beazley Modified the parser to ignore forward template class declarations. For example: template class MapIter; Suggested by an email example from Irina Kotlova. 9/20/2001: beazley Fixed problem with undeclared tcl_result variable in the "out" typemap for Tcl. Reported by Shaun Lowry. 9/20/2001: beazley Incorporated changes to make SWIG work with ActivePerl. Contributed by Joel Reed. 9/20/2001: beazley Slight change to the parsing of C++ constructor initializers. For example: class Foo : public Bar { public: Foo() : Bar(...) {...} }; SWIG now discards the contents of the (...) regardless of what might enclosed (even if syntactically wrong). SWIG doesn't need this information and there is no reason to needless add syntax rules to handle all of the possibilities here. 9/20/2001: beazley Change to typemaps for structure members. If you have a structure like this: struct Vector { int *bar; }; The member name 'bar' is now used in any accessor functions. This allows the "in" typemap to be used when setting the value. For example, this typemap %typemap(python,in) int *bar { ... } now matches Vector::bar. It should be noted that this will also match any function with an argument of "int *bar" (so you should be careful). *** NEW FEATURE. POTENTIAL INCOMPATIBILITY *** 9/20/2001: beazley Fixed SF bug #462642 setting string values in structures 9/20/2001: beazley Fixed SF bug #462398 problem with nested templates. 9/20/2001: beazley Fixed SF bug #461626 problem with formatting and C++ comments. 9/20/2001: beazley Fixed SF bug #462845 Wrong ownership of returned objects. 9/19/2001: beazley Fixed SF bug #459367. Default constructors for classes with pure virtual methods. 9/19/2001: beazley Fixed problem with default arguments and class scope. For example: class Foo { public: enum bar { FOO, BAR }; void blah(bar b = FOO); ... } SWIG now correctly generates a default value of "Foo::FOO" for the blah() method above. This used to work in 1.1, but was broken in 1.3.7. Bug reported by Mike Romberg. Version 1.3.7 (September 3, 2001) ================================== 9/02/2001: beazley Added special %ignore directive to ignore declarations. This feature works exactly like %rename. For example: %ignore foo; // Ignore all declarations foo %ignore ::foo; // Only ignore foo in global scope %ignore Spam::foo; // Only ignore in class Spam %ignore *::foo; // Ignore in all classes %ignore can also be parameterized. For example: %ignore foo(int); %ignore ::foo(int); %ignore Spam::foo(int); %ignore *::foo(int); *** NEW FEATURE *** 9/02/2001: cheetah (william fulton) [Java] shadowcode pragma modified so that the code that is output in the shadow file is placed relative to where it is placed in the c/c++ code. This allows support for JavaDoc function comments. 9/01/2001: beazley Fixed SF Patch [ #447791 ] Fix for python -interface option. Submitted by Tarn Weisner Burton. 9/01/2001: beazley SWIG no longer generates default constructors/destructors for a class if it only defines a private/protected constructor or destructor or if any one of its base classes only has private constructors/destructors. This was reported in SF Patch [ #444281 ] nonpublic/default/inhereted ctor/dtor by Marcelo Matus. 9/01/2001: beazley Added patch to Perl5 module that allows constants to be wrapped as constants that don't require the leading $. This feature is enabled using the -const option. Patch contributed by Rich Wales. *** NEW FEATURE *** 8/31/2001: beazley Added parsing support for the 'volatile' type qualifier. volatile doesn't mean anything to SWIG, but it is needed to properly generate prototypes for declarations that use it. It's also been added to make the SWIG type system more complete. *** NEW FEATURE *** 8/30/2001: beazley Added support for parameterized %rename directive. *** This new feature can be used to greatly simplify the task of resolving overloaded methods and functions. *** In prior versions of SWIG, the %rename directive was used to consistently apply an identifier renaming. For example, if you said this: %rename foo bar; Every occurrence of 'foo' would be renamed to 'bar'. Although this works fine for resolving a conflict with a target language reserved word, it is useless for for dealing with overloaded methods. This is because all methods are simply renamed to the same thing (generating the same conflict as before). Therefore, the only way to deal with overloaded methods was to go through and individually rename them all using %name. For example: class Foo { public: virtual void bar(void); %name(bar_i) virtual void bar(int); ... }; To make matters worse, you had to do this for all derived classes too. class Spam : public Foo { public: virtual void bar(void); %name(bar_i) virtual void bar(int); ... }; Needless to say, this makes it extremely hard to resolve overloading without a lot of work and makes it almost impossible to use SWIG on raw C++ .h files. To fix this, %rename now accepts parameter declarators. The syntax has also been changed slightly. For example, the following declaration renames all occurrences of 'bar(int)' to 'bar_i', leaving any other occurrence of 'bar' alone. %rename(bar_i) bar(int); Using this feature, you can now selectively rename certain declarations in advance. For example: %rename(bar_i) bar(int); %rename(bar_d) bar(double); // Include raw C++ header %include "header.h" When %rename is used in this manner, all occurrence of bar(int) are renamed wherever they might occur. More control is obtained through explicit qualification. For example, %rename(bar_i) ::bar(int); only applies the renaming if bar(int) is defined in the global scope. The declaration, %rename(bar_i) Foo::bar(int); applies the renaming if bar(int) is defined in a class Foo. This latter form also supports inheritance. Therefore, if you had a class like this: class Spam : public Foo { public: void bar(int); } The Spam::bar(int) method would also be renamed (since Spam is a subclass of Foo). This latter feature makes it easy for SWIG to apply a consistent renaming across an entire class hierarchy simply by specifying renaming rules for the base class. A class wildcard of * can be used if you want to renaming all matching members of all classes. For example: %rename(bar_i) *::bar(int); will rename all members bar(int) that are defined in classes. It will not renamed definitions of bar(int) in the global scope. The old use of %rename is still supported, but is somewhat enhanced. %rename(foo) bar; // Renames all occurrences of 'bar'. %rename(foo) ::bar; // Rename all 'bar' in global scope only. %rename(foo) *::bar; // Rename all 'bar' in classes only. %rename(foo) Foo::bar; // Rename all 'bar' defined in class Foo. *** NEW FEATURE *** 8/30/2001: beazley Added support for data-member to member-function transformation. For example, suppose you had a structure like this: struct Vector { double x,y; }; Now suppose that you wanted to access x and y through a member function interface instead of the usual SWIG behavior. For example: f.set_x(3.4) # instead of f.x = 3.4 x = f.get_x() # instead of x = f.x To do this, simply use the new %attributefunc directive. For example: %attributefunc(get_%s,set_%s) struct Vector { double x,y; }; %noattributefunc The arguments to %attributefunc are C-style printf format strings that determine the naming convention to use. %s is replaced with the actual name of the data member. SWIG provides a number of printf extensions that might help. For example, if you wanted to title case all of the attributes, you could do this: %attributefunc(get%(title)s,set%(title)s); This will turn an attribute 'bar' to 'getBar()' and 'setBar()'. (someone requested this long ago, but I finally figured how to implement it in a straightforward manner). *** EXPERIMENTAL NEW FEATURE *** 8/30/2001: beazley SWIG now automatically generates default constructors and destructors if none are defined. This used to be enabled with a command line switch -make_default, but most people want these functions anyways. To turn off this behavior use the -no_default option or include the following pragma in the interface file: %pragma no_default; This may break certain interfaces that defined their own constructors/destructors using the same naming convention as SWIG. If so, you will get duplicate symbols when compiling the SWIG wrapper file. *** POTENTIAL INCOMPATIBILITY *** 8/29/2001: beazley Changes to Perl5 shadow class code generation. Iterators are no longer supported (FIRSTKEY, NEXTKEY). Also, attribute access has been changed to rely on inheritance in order to provide better behavior across modules. 8/28/2001: beazley Various obscure improvements to the type system and classes. Strange declarations like this are now wrapped correctly (i.e., the generated wrapper code doesn't cause the C++ compiler to die with a type error). class Foo { public: typedef double Real; Real foo(Real (*op)(Real,Real), Real x, Real y); }; Inheritance of types is also handled correctly. 8/28/2001: beazley Changes to class wrappers. When SWIG sees two classes like this, class X { public: void foo(); ... } class Y : public X { public: void bar(); ... } it now only generates two wrapper functions: X_foo(X *x) { x->foo(); } Y_bar(Y *y) { y->bar(); } Unlike SWIG1.15, the foo() method does *not* propagate to a wrapper function Y_foo(). Instead, the base class method X_foo() must be used. This change should not affect modules that use shadow classes, but it might break modules that directly use the low-level C wrappers. This change is being made for a number of reasons: - It greatly simplifies the implementation of SWIG--especially with anticipated future changes such as overloaded methods. - It results in substantially less wrapper code--especially for big C++ class hierarchies (inherited declarations are no longer copied into every single derived class). - It allows for better code generation across multiple SWIG generated modules (code isn't replicated in every single module). *** POTENTIAL INCOMPATIBILITY *** 8/22/2001: cheetah (william fulton) Provided some Windows documentation in the Win directory and some Visual C++ project files for running examples on Windows. 8/28/2001: mkoeppe [Guile] Handle renamed overloaded functions properly; thanks to Marc Zonzon for the patch. See the new test case name_cxx. 8/27/2001: mkoeppe [Tcl] Removed lots of warnings issued by the Sun Forte compilers, which were caused by mixing function pointers of different linkages (C++/C). 8/23/2001: mkoeppe Improved the MzScheme module by porting Guile's pointer type checking system and making type dispatch typemap-driven. 8/22/2001: beazley Entirely new symbol table processing. SWIG should be able to report much better error messages for multiple declarations. Also, the new symbol table allows for overloaded functions (although overloading isn't quite supported in the language modules yet). 8/22/2001: cheetah (william fulton) * [Java] %new support added. * [Java] Package JNI name refixed! 8/19/2001: beazley Python module modified to support pointers to C++ members. This is an experimental feature. *** NEW FEATURE *** 8/19/2001: beazley Added limited parsing and full type-system support for pointers to members. None of SWIG's language modules really know how to deal with this so this is really only provided for completeness and future expansion. Note: SWIG does not support pointers to members which are themselves pointers to members, references to pointers to members, or other complicated declarations like this. *** NEW FEATURE *** 8/19/2001: beazley SWIG is much better at parsing certain C++ declarations. Operators and friends generally don't cause anymore syntax errors. However, neither are really supported. 8/18/2001: beazley Added *highly* experimental support for wrapping of C++ template declarations. Since C++ templates are essentially glorified macros and SWIG has a fully operational C preprocessor with macro support, the parser now converts template declarations to macros. For example, a function template like this template T max(T a, T b); is internally converted into a macro like this: %define %_template_max(__name,T) %name(__name) T max(T a, T b); %enddef To instantiate a version of the template, a special %template declaration is used like this: %template(maxint) max; %template(maxdouble) max; The parameter to the %template directive must be proper C identifier that's used to uniquely name the resulting instantiation. When used, the the expanded macro looks like this: %name(maxint) int max(int a, int b); %name(maxdouble) double max(double a, double b); A similar technique is used for template classes. For instance: template class vector { T *data; int sz; public: vector(int nitems); T *get(int n); ... }; Gets converted into a macro like this: %define %_template_vector(__name, T) %{ typedef vector __name; %} class __name { T *data; int sz; public: __name(int nitems); T *get(int n); ... }; typedef __name vector; %enddef An a specific instantiation is created in exactly the same way: %template(intvec) vector; The resulting code parsed by SWIG is then: %{ typedef vector intvec; %} class intvec { int *data; int sz; public: intvec(int nitems); int *get(int n); ... }; typedef intvec vector; Note: the last typedef is non-standard C and is used by SWIG to provide an association between the name "intvec" and the template type "vector". CAUTION: This is an experimental feature and the first time SWIG has supported C++ templates. Error reporting is essential non-existent. It will probably break in certain cases. *** EXPERIMENTAL NEW FEATURE **** 8/15/2001: beazley Change to wrapping of multi-dimensional arrays. Arrays are now properly mapped to a pointer to an array of one less dimension. For example: int [10]; --> int * int [10][20]; --> int (*)[20]; int [10][20][30]; --> int (*)[20][30]; This change may break certain SWIG extensions because older versions simply mapped all arrays into a single pointer such as "int *". Although possibly unusual, the new version is correct in terms of the C type system. *** POTENTIAL INCOMPATIBILITY *** 8/06/2001: cheetah (william fulton) * [Java] Array setters generated for struct/class array members. 8/13/2001: beazley Many improvements to Tcl/Perl/Python modules to better work with multiple interface files and the %import directive. 8/13/2001: beazley Fixed up the behavior of %import in the Python module. SWIG no longer pollutes the module namespace by using 'from module import *' to refer to the other module. Instead, it does a proper 'import module'. Also, SWIG may work a lot better when importing modules that include references to other imported modules. 8/13/2001: mkoeppe Added new typemap substitutions, generalizing those of the Guile-specific 5/27/2001 changes: * $descriptor is the same as SWIGTYPE$mangle, but also ensures that the type descriptor of this name gets defined. * $*type, $*ltype, $*mangle, $*descriptor are the same as the variants without star, but they REMOVE one level of pointers from the type. (This is only valid for pointer types.) * $&type, $<ype, $&mangle, $&descriptor are the same as the variants without ampersand, but they ADD one level of pointers to the type. The Guile-specific substitution $basedescriptor was removed because it was useless. 8/12/2001: beazley The %extern directive is now deprecated and withdrawn. The purpose of this directive was to import selected definitions from other interface files and headers. However, the same functionality is better handled through %import. This leaves SWIG with two file inclusion directives: %include filename - Inserts into current interface %import filename - Import types and classes from another module *** POTENTIAL INCOMPATIBILITY *** 8/09/2001: beazley Added new support for wrapping C/C++ callback functions. A common problem with some C libraries is that many functions take a function pointer as an argument. For example: int do_op(..., int (*op)(int,int), ...); Unfortunately, the only way to call such a function is to pass it a function pointer of some compatible type. In previous versions of SWIG, you had to solve this problem with some really gross hacks. For example, if you wanted to use the following function as a callback, int foo(int, int); you had to install a pointer to it as a constant. For example: %constant int (*FOO)(int,int) = foo; or const int (*FOO)(int,int) = foo; or if you had a really old SWIG version: typedef int (*OP_FUNC)(int,int); int do_op(..., OP_FUNC, ...); const OP_FUNC FOO = foo; Now, you can do one of two things: %constant int foo(int,int); This creates a constant 'foo' of type int (*)(int,int). Alternatively, you can do this: %callback("%s") int foo(int,int); int bar(int,int); %nocallback In this case, the functions are installed as constants where the name is defined by the format string given to %callback(). If the names generated by the format string differ from the actual function name, both a function wrapper and a callback constant are created. For example: %callback("%(upper)s") int foo(int,int); int bar(int,int); %nocallback Creates two wrapper functions 'foo', 'bar' and additionally creates two callback constants 'FOO', 'BAR'. Note: SWIG still does not provide automatic support for writing callback functions in the target language. *** NEW FEATURE *** 8/06/2001: cheetah (william fulton) * struct nesting fixes as per SF bug #447488. 8/03/2001: beazley The %name directive now applies to constants created with #define and %constant. However, most language modules were never written to support this and will have to be modified to make it work. Tcl, Python, and Perl modules are working now. *** NEW FEATURE *** 8/03/2001: beazley Massive changes and simplification of C declaration parsing. Although SWIG is still not a full C parser, its ability to handle complex datatypes including pointers to functions and pointers to arrays has been vastly improved. 8/03/2001: cheetah (william fulton) * Distribution fixes: autoconf no longer needed to install SWIG. 8/02/2001: beazley Removed two undocumented parsing features. SWIG no longer supports out-of-class static function or variable declarations. For example: static int Foo::bar; This feature may return if there is sufficient demand. However, since SWIG is most often used with header files, it is more likely for these definitions to be included in the class definition. *** POTENTIAL INCOMPATIBILITY *** 8/02/2001: cheetah (william fulton) * Cleanup of the GIFPlot examples. Upgraded Java GIFPlot example. 8/01/2001: cheetah (william fulton) * [Java] Efficiency changes: _cPtr used where possible rather than getCPtr(). Bug fixes for inheritance - derived class sometimes didn't delete the c memory when _delete() was called. * [Java] Abstract c++ classes are wrapped with a java abstract shadow class. Also a pure virtual function is mapped with an abstract method. * The default output file has always been _wrap.c. It is now _wrap.cxx if the -c++ commandline option is passed to swig. This has been done as otherwise c++ code would appear in a c file. *** POTENTIAL INCOMPATIBILITY *** 7/31/2001: beazley Modified the %constant directive to be more C-like in syntax. The syntax is now: %constant NAME = VALUE; %constant TYPE NAME = VALUE; For example: %constant Foo *Bar = &Spam; A more subtle case is as follows: %constant int (*FOO)(int,int) = blah; *** POTENTIAL INCOMPATIBILITY *** Modules that were using the %constant directive directly will need to be modified. 7/30/2001: beazley Removed obscure and undocumented form of the %inline directive: %inline int blah(int a, int b) { ... } *** POTENTIAL INCOMPATIBILITY *** (note: this feature was never documented and is withdrawn) 7/30/2001: beazley Removed support for functions with no explicitly declared return type. For example: foo(int); In C, such functions were implicitly assumed to return an 'int'. In C++, this is illegal. Either way, it's considered bad style. Removing support for this in SWIG will simplify certain issues in parsing. *** POTENTIAL INCOMPATIBILITY *** 7/30/2001: mkoeppe * Partial merge from the CVS trunk. The Source/DOH directory and most of the Source/Swig directory is up-to-date now. * [Guile] %scheme is now a macro for %insert("scheme"). New syntax: %scheme "FILENAME"; New syntax: %scheme %{ SCHEME-CODE %} New macros %multiple_values, %values_as_list, %values_as_vector. 7/29/2001: beazley %readonly and %readwrite have been turned into SWIG pragmas. %pragma(swig) readonly and %pragma(swig) readwrite. Macros are used to provide backwards compatibility. 7/29/2001: beazley Minor changes to %pragma directive. %pragma must always be directed to a specific language. For example: %pragma(swig) make_default; %pragma(perl5) include = "blah.i"; Also extended the pragma directive to allow code blocks %pragma(foo) code = %{ ... some code ... %} *** POTENTIAL INCOMPATIBILITY *** 7/29/2001: beazley Change to the way 'const' variables are wrapped. In previous versions of SWIG, a 'const' variable was wrapped as a constant. Now, 'const' variables are wrapped as read-only variables. There are several reasons for making this change, mostly pertaining to subtle details of how 'const' actually works. This will probably break old interfaces that used 'const' to create constants. As a replacement, consider using this: const int a = 4; ===> %constant int a = 4; *** POTENTIAL INCOMPATIBILITY *** 7/29/2001: beazley Reorganization and simplification of type parsing. Types with 'const' should work correctly now. 7/29/2001: beazley Most swig directives related to the documentation system are now deprecated. 7/29/2001: beazley Removed support for Objective-C in order to simplify parser reconstruction. Will return if there is sufficient demand. *** POTENTIAL INCOMPATIBILITY *** 7/29/2001: beazley Code inclusion has been modified in the parser. A common directive %insert is now used for everything. This inserts a file into the output: %insert(header) "foo.swg" This inserts some inline code into the output %insert(header) %{ ... some code ... %} There are five predefined targets for the insert directive: "header" - Header section of wrapper file "runtime" - Runtime section of wrapper file "wrapper" - Wrapper section "init" - Initialization function "null" - Nothing. Discard. The following directives are still supported, but are now defined in terms of macros: %{ ... %} -> %insert(header) %{ ... %} %init %{ ... %} -> %insert(init) %{ ... %} %wrapper %{ ... %} -> %insert(wrapper) %{ ... %} %runtime %{ ... %} -> %insert(runtime) %{ ... %} Language modules can define new named targets by using the C API function Swig_register_filebyname() (see main.cxx). For example, if you wanted to expose a shadow class file, you could do this: Swig_register_filebyname("shadow", f_shadow); Then in the interface file: %insert(shadow) %{ ... %} Note: this change should not affect any old interfaces, but does open up new possibilities for enhancements. 7/29/2001: beazley SWIG now always includes a standard library file 'swig.swg'. This file defines a large number of macro definitions that define the behavior of various SWIG directives. Previously, all SWIG directives were handled as special cases in the parser. This made the parser a large bloated mess. Now, the parser is stripped down to a few simple directives and macros are used to handle everything else. 7/26/2001: cheetah (william fulton) * Fixes for Sourceforge bug #444748 - new testcase cpp_static: [TCL] Class with just static member variable/function fix [Java] Fixed static variables support [Ruby] Static variables workaround removed 7/27/2001: mkoeppe * stype.c (SwigType_default): Strip qualifiers first. The default type of "int * const" is now "SWIGPOINTER *". * main.cxx: Define "__cplusplus" in SWIG's preprocessor if in C++ mode. * [Guile]: Added some support for arrays and C++ references, fixing the "constant_pointers" test case. * Moved most tests from the old Guile-specific test-suite to the new test-suite. Also moved perl5/pointer-cxx example there. 7/26/2001: cheetah (william fulton) * Test-suite added. * Initial testcases: constant_pointers cpp_enum defines sizeof_pointers unions virtual_destructor * Make clean improvements. 7/24/2001: cheetah (william fulton) * [Java] Underscores in the package name and/or module name no longer give linking problems. 7/17/2001: cheetah (william fulton) * More parser bug fixes for constant pointers 7/19/2001: mkoeppe * [Guile] Aesthetic improvement in variable wrappers. 7/18/2001: beazley * Fixed core-dump problem in pointer library when freeing character arrays. SF Bug [ #415837 ] pointer lib core dump 7/18/2001: beazley * Fixed problem with default destructors and shadow classes. SF bug #221128. 7/18/2001: beazley * To provide better line-number tracking in interfaces with lots of macros, special locator comments are now generated by the SWIG preprocessor. For example: /*@foo.i,42,BLAH@*/expanded macro/*@@*/ The first /*@...@*/ sequence sets the context to point to the macro code. The /*@@*/ comment terminates the context. The SWIG parser should ignore all of the locator comments as should the C compiler (should such comments end up in generated wrapper code). 7/18/2001: mkoeppe * The parser now handles severely constified types in typemaps. This introduced a new shift/reduce conflict, but only with a heuristic function-pointer catch-all rule. * [Guile]: Added typemaps for severely constified types. * Fixed the "template-whitespace" problem by canonicalizing whitespace, especially around angle brackets and commas. 7/17/2001: mkoeppe * [Guile]: A Scheme file is emitted if the -scmstub FILE.SCM command-line option is used. The %scheme directive (implemented as a macro for a pragma) allows to insert arbitrary code here. In "simple" and "passive" linkage, the file gets filled with define-module and export declarations. 7/17/2001: cheetah (william fulton) * Parser bug fix to support constant pointers, eg int* const ptr. Fixed everywhere - variables, parameters, return types etc. Note that when wrapping a constant pointer variable only the getter is generated. 7/17/2001: mkoeppe * Fixed SF bug #441470 (#define X "//" would not be parsed, see test-suite entry "preproc-1"), reported by T. W. Burton . * Changed the type of character constants to "char", rather than "char *". Changed the individual language modules to keep the old behaviour, except for the Guile module, where it is desired to make them Scheme characters. This fixes SF bug #231409, test-suite entry "char-constant". * Applied patch for DOH/Doh/memory.c by Les Schaffer (avoid required side effects in assert). 7/17/2001: cheetah (william fulton) * Bug fix in parser for virtual destructor with void as parameter * Bug fix in parser #defines embedded within classes/structs/unions Consequently %constant can now also be placed within a struct/class/union. * Bug fix in parser to allow sizeof(*I_am_a_pointer) within a #define 7/16/2001: mkoeppe * Added changes for the Macintosh contributed by Luigi Ballabio . * Some "const" fixes in the code. * [Guile]: Made the constant-wrapper functions much shorter. 7/13/2001: mkoeppe * [Guile]: Some "const" fixes for Guile version 1.3.4. * Handle anonymous arguments with default values and static array members of classes. Both bugs reported by Annalisa Terracina ; see the files Examples/guile/test-suite/static-array-member.i and anonymous-arg.i. Version 1.3.6 (July 9, 2001) ============================= 7/09/2001: cheetah (william fulton) * GIFPlot examples: FOREGROUND and BACKGROUND definition missing after TRANSPARENT #define fix in GIFPlot 7/03/2001: beazley Fixed up the version numbers so that the release is known as 1.3.6. All future releases should have a similar version format. 7/02/2001: mkoeppe * [Python]: Prevent the problem of self.thisown not being defined if the C++ class constructor raised an exception. Thanks to Luigi Ballabio . 6/29/2001: mkoeppe * More portability fixes; fixed "gcc -Wall" warnings. 6/29/2001: cheetah (william fulton) * GIFPlot examples: TRANSPARENT #define multiple times on Solaris (clashes with stream.h). * Multiple definition bug fix for shadow classes. The perl and python modules had workarounds which have been replaced with fixes in the core. Many of the Language::cpp_xxxx functions now set a flag which the derived classes can access through is_multiple_definition() to see whether or not code should be generated. The code below would have produced varying degrees of incorrect shadow class code for the various modules: class TestClass { public: TestClass() {}; TestClass(int a) {}; ~TestClass() {}; unsigned long xyz(short k) {}; unsigned long xyz(int n) {}; static void static_func() {}; static void static_func(int a) {}; }; void delete_TestClass(int a); 6/27/2001: mkoeppe * [Perl] Another const-related portability fix. 6/26/2001: cheetah (william fulton) * [Java] Added in cpp_pragma() support with a host of new pragmas - see jswig.html. These are designed for better mixing of Java and c++. It enables the user to specify pure Java classes as bases and/or interfaces for the wrapped c/c++. * [Java] Old pragmas renamed. Warning given for the moment if used. *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** 6/25/2001: mkoeppe * Incorporated more build changes contributed by Wyss Clemens for swig/ruby on cygwin. 6/20/2001: cheetah (william fulton) * Makefile mods so that 'make check' uses the swig options in the makefiles * [Java] Removed Generating wrappers message * [Java] NULL pointer bug fix * [Java] Bug fix for Kaffe JVM 6/20/2001: mkoeppe * SWIG_TypeQuery from common.swg now returns a swig_type_info* rather than a void*. This fixes a problem when using pointer.i and C++, as illustrated by the new test-suite example perl5/pointer-cxx. * Portability fixes (const char *). * Incorporated build changes contributed by Wyss Clemens , which make swig runnable on cygwin. 6/19/2001: cheetah (william fulton) * [Java] Bug fix for SF bug #211144. This fix is a workaround until fixed in the core. 6/19/2001: mkoeppe * [Guile]: Portability fixes for use with the Sun Forte compilers. * [Tcl]: Portability fix (const char *). * [Tcl]: Configure now first tries to find a tclConfig.sh file in order to find the Tcl include directory, library location and library name. * [Python]: Added a few possible library locations. 6/18/2001: mkoeppe * [Guile]: Don't call scm_c_export if nothing is to be exported. Don't warn on %module if module has been set already (this frequently occurs when %import is used). 6/16/2001: mkoeppe * [Guile]: New "passive" linkage, which is appropriate for multi-module extensions without Guile module magic. 6/15/2001: mkoeppe * [Guile]: Fixed printing of smobs (space and angle were missing). * Properly generate type information for base classes imported with the %import directive. Thanks to Marcelo Matus for the report and the patch; this closes SF bug #231619; see also Examples/guile/test-suite/import*. * [Guile]: Fix casting between class and base class; the runtime type system had it the wrong way around; see Examples/guile/test-suite/casts.i * Make typemaps for SWIGPOINTER * with arg name take precedence over those without arg name, to match normal typemap precedence rules. * Fixed the random-line-numbers problem reported as SF bug #217310; thanks to Michael Scharf . * [Guile]: Handle the %name and %rename directives. * New syntax: %name and %rename now optionally take double quotes around the scripting name. This is to allow scripting names that aren't valid C identifiers. 6/14/2001: beazley Made a minor change to the way files are loaded in order to get file/line number reporting correct in the preprocessor. 6/14/2001: mkoeppe * The parser now understands the (non-standard) "long long" types. It is up to the individual language modules to provide typemaps if needed. Reported by Sam Steingold, SF bug #429176. * The parser now understands arguments like "const int * const i". This fixes SF bug #215649. * Fixed the Guile test-suite. 6/13/2001: mkoeppe Partial merge from the CVS trunk at tag "mkoeppe-merge-1". This covers the following changes: | 01/16/01: ttn | Wrote table of contents for Doc/engineering.html. Added section | on CVS tagging conventions. Added copyright to other docs. | 9/25/00 : beazley | Modified the preprocessor so that macro names can start with a '%'. | This may allow new SWIG "directives" to be defined as macros instead | of having to be hard-coded into the parser. | | *** Also a yet-to-be-documented quoting mechanism with backquotes | *** has been implemented? 6/13/2001: mkoeppe * When configure does not find a language, don't use default paths like /usr/local/include; this only causes build problems. * New directory: Examples/Guile/test-suite, where a few bugs in 1.3a5 are demonstrated. * Handle C++ methods that have both a "const" and a "throw" directive (see Examples/Guile/test-suite/cplusplus-throw.i); thanks to Scott B. Drummonds for the report and the fix. * Handle C++ pointer-reference arguments (like "int *& arg") (see Examples/Guile/test-suite/pointer-reference.i, reported as SF bug #432224). * [Ruby] Fixed typo in rubydec.swg; thanks to Lyle Johnson! * Don't stop testing when one test fails. * [Guile, MzScheme] Don't print "Generating wrappers...". 6/12/2001: mkoeppe [Guile] VECTORLENINPUT and LISTLENINPUT now have separate list length variables. TYPEMAP_POINTER_INPUT_OUTPUT attaches argument documentation involving SCM_TYPE to the standard pointer typemaps. INOUT is now an alias for BOTH. 6/12/2001: cheetah (william fulton) Some Java documentation added. [Java] Fixed bugs in import pragma and shadow pragma. 6/12/2001: mkoeppe Fix declarations of SWIG_define_class (Lib/ruby/rubydec.swg) and SWIG_TypeQuery (Lib/common.swg). Thanks to Lyle Johnson for the patches. 6/11/2001: mkoeppe [Guile] Use long instead of scm_bits_t; this makes the generated wrapper code compatible with Guile 1.3.4 again. Thanks to Masaki Fukushima for pointing this out. 6/11/2001: cheetah (william fulton) The generic INSTALL file from autoconf added. Few changes to README file. 6/11/2001: mkoeppe Fixed typo in Makefile.in; thanks to Greg Troxel . 6/08/2001: cheetah (william fulton) make check works again. Examples/GIFPlot configure generated by top level autoconf now. 6/08/2001: mkoeppe Another build change: The new script autogen.sh runs autoconf in the appropriate directories. The top-level configure also configures in Examples/GIFPlot. 6/07/2001: mkoeppe Made the Makefile work with non-GNU make again. 6/07/2001: cheetah (william fulton) [Java] Class/struct members that are arrays of pointers to classes/structs - Shadow class's get/set accessors now use Java classes instead of longs (pointers). [Java] Shadow classes will now clean up memory if function return type is a class/struct. [Java] New example called reference based on the same example from other modules. 6/06/2001: mkoeppe New configure option --with-release-suffix allows for attaching a suffix to the swig binary and the swig runtime libraries. Minor changes to the build system. "swig -swiglib" works again. If invoked with the new option "-ldflags", SWIG prints a line of linker flags needed to link with the runtime library of the selected language module. 6/06/2001: mkoeppe [Guile] gswig_list_p is an int, not a SCM. This typo caused warnings when compiling with a Guile configured with strict C type checking. In INPUT and BOTH typemaps generated by the SIMPLE_MAP macro, use the SCM_TO_C function to convert from Guile to C (rather than C_TO_SCM). Use scm_intprint to print pointers (rather than sprintf). Allow using "-linkage" instead of "-Linkage". 6/05/2001: cheetah (william fulton) [Java] Mods for using inherited c++ classes from Java [Java] New example called class based on the same example from other modules 6/05/2001: cheetah (william fulton) [Java] destructor (_delete()) was not aware of %name renaming [Java] extends baseclass did not know about %name renaming [Java] extends baseclass did extend even when the baseclass was not known to swig [Java] sometimes enum-declarations occured before the Java class declaration [Java] unrelated enum initialisations no longer appear in Java class [Java] if module ends in '_' correct JNI names are now produced 6/04/2001: cheetah (william fulton) [Java] Shadow class mods - Modified constructor replaces newInstance(). _delete() now thread safe. getCPtr() replaces _self. _selfClass() removed as now redundant. *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** [Java] Not all output java files had SWIG banner. New banner. [Java] Shadow class finalizers are output by default: Command line option -finalize deprecated and replaced with -nofinalize. *** POTENTIAL INCOMPATIBILITY FOR JAVA MODULE *** 6/ 1/2001: mkoeppe [Guile] Cast SCM_CAR() to scm_bits_t before shifting it. This is required for compiling with a Guile configured with strict C type checking. 6/ 1/2001: mkoeppe Added configure option "--with-swiglibdir". 5/31/2001: mkoeppe [Guile] Support multiple parallel lists or vectors in the typemaps provided by list-vector.i. New typemaps file, pointer-in-out.i. 5/25/2001: cheetah (william fulton) [Java] HTML update for examples. 5/28/2001: mkoeppe Minor changes to the build system. Added subdirectory for Debian package control files. 5/28/2001: mkoeppe [Guile] Build a runtime library, libswigguile. 5/28/2001: mkoeppe [Guile] New typemap substitution $*descriptor. Use the {} syntax, rather than the "" syntax for the standard typemaps, in order to work around strange macro-expansion behavior of the SWIG preprocessor. This introduces some extra braces. 5/27/2001: mkoeppe [Guile] Handle pointer types with typemaps, rather than hard-coded. New typemap substitutions $descriptor, $basedescriptor; see documentation. Some clean-up in the variable/constants wrapper generator code. New convenience macro SWIG_Guile_MustGetPtr, which allows getting pointers from smobs in a functional style. New typemap file "list-vector.i", providing macros that define typemaps for converting between C arrays and Scheme lists and vectors. 5/25/2001: cheetah (william fulton) [Java] STL string moved into its own typemap as it is c++ code and it break any c code using the typemaps.i file. - Fixes for wrappers around global variables - applies to primitive types and user types (class/struct) and pointers to these. - Structure member variables and class public member variables getters and setters pass a pointer to the member as was in 1.3a3 and 1.1 (1.3a5 was passing by value) - Parameters that were arrays and return types were incorrectly being passed to create_function() as pointers. - Fix for arrays of enums. [Java] Updated java examples and added two more. [Java] Java module updated from SWIG1.3a3 including code cleanup etc. [Java] enum support added. [Java] Array support implemented [Java] Shadow classes improved - Java objects used rather than longs holding the c pointer to the wrapped structure/c++class 5/22/2001: mkoeppe [Guile] Fixed extern "C" declarations in C++ mode. Thanks to Greg Troxel . 5/21/2001: mkoeppe [Guile] New linkage "module" for creating Guile modules for Guile versions >= 1.5.0. 4/18/2001: mkoeppe [MzScheme] Added typemaps for passing through Scheme_Object pointers. 4/9/2001 : mkoeppe [MzScheme] Added typemaps for `bool'. Inclusion of headers and support routines is now data-driven via mzscheme.i. Headers come from the new file mzschemdec.swg. Don't abort immediately when a type-handling error is reported. When searching for typemaps for enums, fall back to using int, like the Guile backend does. Support char constants. Emit correct wrapper code for variables. 3/12/2001: mkoeppe [Guile] Fixed typemaps for char **OUTPUT, char **BOTH. 3/2/2001 : mkoeppe [Guile] Every wrapper function now gets a boolean variable gswig_list_p which indicates whether multiple values are present. The macros GUILE_APPEND_RESULT, GUILE_MAYBE_VALUES and GUILE_MAYBE_VECTOR use this variable, rather than checking whether the current return value is a list. This allows for typemaps returning a list as a single value (a list was erroneously converted into a vector or a multiple-value object in this case). 3/1/2001 : mkoeppe [Guile] Added support for returning multiple values as vectors, or passing them to a muliple-value continuation. By default, multiple values still get returned as a list. 3/1/2001 : mkoeppe [Guile] Added a "beforereturn" pragma. The value of this pragma is inserted just before every return statement. 3/1/2001 : mkoeppe [Guile] Added support for Guile 1.4.1 procedure documentation formats, see internals.html. 2/26/2001: mkoeppe [Guile] Made the wrapper code compile with C++ if the "-c++" command-line switch is given. Thanks to . 2/26/2001: mkoeppe [Guile] Now two type tables, swig_types and swig_types_initial, are used, as all other SWIG language modules do. This removes the need for the tricky construction used before that the broken Redhat 7.0 gcc doesn't parse. Reported by . 2/26/2001: mkoeppe [Guile] Fixed typemaps for char *OUTPUT, char *BOTH; a bad free() would be emitted. Added typemap for SCM. Version 1.3 Alpha 5 =================== 9/19/00 : beazley [Python] Python module generates more efficient code for creating the return value of a wrapper function. Modification suggested by Jon Travis. 9/19/00 : beazley Library files specified with the -l option are now included at the end of the interface file (reverting to the old behavior). 9/19/00 : beazley Fixed some problems with enum handling. enums are now manipulated as 'int', but cast into the enum type when values are passed to the corresponding C function. 9/19/00 : mkoeppe [Guile] Removed "-with-smobs" command-line option, as this is the default now. Added "-emit-setters" command-line option, which turns on generating procedures-with-setters; see internals.html. 9/18/00 : mkoeppe Incorporated patch #101430, fixing bugs in the Guile module: 1. Some arguments were erroneously taken as *optional* arguments when ignored arguments were present. 2. Guile 1.3.4 was not supported since functions introduced in Guile 1.4 were used. 3. Added handling of `const char *'. 9/17/00 : beazley Fixed problem with failed assertion and large files. 9/17/00 : beazley Fixed problem with the '%' character appearing in added methods and function bodies. Preprocessor bug. Version 1.3 Alpha 4 (September 4, 2000) ====================================== 9/3/00 : ttn Added instructions for maintainers in Examples/README on how to make examples also be useful in the testing framework. Also, "make check" now uses ./Lib by via env var `SWIG_LIB'. This is overridable like so: make chk-swiglib=/my/experimental/swig/Lib check 9/3/00 : beazley Added $typemap variable to typemaps. This gets replaced with a string indicating the typemap that is applied. Feature request from rsalz. 9/3/00 : beazley Experimental optimization to code generation for virtual member functions. If you have two classes like this: class A() { virtual void foo(); } class B() : public A { virtual void foo(); } Swig now will generate a single wrapper function for this A_foo(A *a) { a->foo(); } and use it as the implementation of both A_foo() and B_foo(). This optimization only takes place if both methods are declared as virtual and both take identical parameters. *** EXPERIMENTAL FEATURE *** 9/3/00 : beazley Restored the "memberin" typemap for setting structure members. Unlike the old version, the new version is expanded inline in the wrapper function allowing access to scripting language internals (a sometimes requested feature). The "memberout" typemap is gone. Use the "out" typemaps instead. *** POTENTIAL INCOMPATIBILITY *** 9/3/00 : beazley Attribute set methods no longer return the value of a member. For example: struct Foo { int x; ... } now gets set as follows: void Foo_x_set(Foo *f, int x) { f->x = x; } In SWIG1.1 it used to be this: int Foo_x_set(Foo *f, int x) { return (f->x = x); } This has been changed due to the complexity created by trying to do this with more exotic datatypes such as arrays. It also complicates inlining and handling of the "memberin" typemap. *** POTENTIAL INCOMPATIBILITY *** 9/2/00 : beazley Removed the ptrcast() and ptrmap() functions from the pointer.i library file. Old implementation is incompatible with new type system. *** POTENTIAL INCOMPATIBILITY *** 9/2/00 : beazley New runtime function SWIG_TypeQuery(const char *name) added. This function can be used to extract the type info structure that is used for type-checking. It works with either the nice C name or mangled version of a datatype. For example: swig_type_info *ty = Swig_TypeQuery("int *"); swig_type_info *ty = Swig_TypeQuery("_p_int"); This is an advanced feature that has been added to support some exotic extension modules that need to directly manipulate scripting language objects. *** NEW FEATURE *** 9/2/00 : beazley New directive %types() added. This is used to explicitly list datatypes that should be included in the runtime type-checking code. Normally it is never necessary to use this but sometimes advanced extensions (such as the pointer.i library) may need to manually add types to the type-checker. *** NEW FEATURE *** 8/31/00 : beazley Improved handling of string array variables. For example, a global variable of the form "char name[64]" is automatically managed as a 64 character string. Previously this didn't work at all or required the use of a special typemap. *** NEW FEATURE (Tcl, Perl, Python) *** 8/31/00 : ttn Added Makefile target `check-c++-examples', which uses new files under Examples/C++ contributed by Tal Shalif. Now "make check" also does "make check-c++-examples". Also, expanded actions in `check-gifplot-example' and `check-aliveness'. 8/30/00 : mkoeppe Major clean-up in the Guile module. Added typemap-driven documentation system. Changed to handle more than 10 args. Updated and extended examples. *** NEW FEATURE *** 8/29/00 : beazley Added new %insert directive that inserts the contents of a file into a portion of the output wrapper file. This is only intended for use by writers of language modules. Works as follows: %insert(headers) "file.swg"; %insert(runtime) "file.swg"; %insert(wrappers) "file.swg"; %insert(init) "file.swg"; *** NEW FEATURE *** 8/29/00 : beazley Added new %runtime directive which includes code into the runtime portion of the wrapper code. For example: %runtime %{ ... some internal runtime code ... %} There is no practical reason for ordinary users to use this feature (almost everything can be done using %{ ... %} instead). However, writers of language modules may want to use this in language configuration files. *** NEW FEATURE *** 8/28/00 : beazley Typemaps can now be specified using string literals like this: %typemap(in) int "$target = SvIV($source);"; When code is specified like this, it is *NOT* enclosed inside a local scope (as with older typemap declarations). Note: character escape sequences are interpreted in the code string so if you want to include a quote or some other special character, make sure you use a (\). *** NEW FEATURE *** 8/27/00 : beazley Typemaps have been modified to follow typedef declarations. For example, if you have this: typedef int Number; %typemap(in) int { ... get an integer ... } void foo(Number a); The typemap for 'int' will be applied to the argument 'Number a'. Of course, if you specify a typemap for 'Number' it will take precedence (nor will it ever be applied to an 'int'). *** POTENTIAL INCOMPATIBILITY *** 8/27/00 : beazley Default typemap specification has changed. In older versions of swig, you could do this: %typemap(in) int SWIG_DEFAULT_TYPE { ... } To specify the default handling of a datatype. Now that SWIG follows typedef declarations, this is unnecessary. Simply specifying a typemap for 'int' will work for all variations of integers that are typedef'd to 'int'. Caveat, specifying the default behavior for pointers, references, arrays, and user defined types is a little different. This must be done as follows: %typemap() SWIGPOINTER * { ... a pointer ... } %typemap() SWIGREFERENCE & { ... a reference ... } %typemap() SWIGARRAY [] { ... an array ... } %typemap() SWIGTYPE { ... a user-defined type (by value) ... } *** POTENTIAL INCOMPATIBILITY *** 8/15/00 : dustin The file swig-1.3a1-1.spec has been added to the Tools directory. It can be used to build a redhat package for SWIG, although it will need to be updated for the next public release. 8/15/00 : beazley Typemaps have been completely rewritten. Eventually they may be replaced with something better, but for now they stay. However, there are a number of a significant changes that may trip some people up: 1. Typemap scoping is currently broken. Because of this, the following code won't work. %typemap(in) blah * { ... } class Foo { ... int bar(blah *x); } %typemap(in) blah *; /* Clear typemap */ (this breaks because the code for the class Foo is actually generated after the entire interface file has been processed). This is only a temporary bug. 2. In SWIG1.1, the %apply directive worked by performing a very complex type-aliasing procedure. From this point on, %apply is simply a generalized typemap copy operation. For example, %apply double *OUTPUT { double *x, double *y }; Copies *ALL* currently defined typemaps for 'double *OUTPUT' and copies them to 'double *x' and 'double *y'. Most people probably won't even notice this change in %apply. However, where it will break things is in code like this: %apply double *OUTPUT { double *x }; %typemap(in) double *OUTPUT { ... whatever ... } void foo(double *x); In SWIG1.1, you will find that 'foo' uses the 'double *OUTPUT' rule even though it was defined after the %apply directive (this is the weird aliasing scheme at work). In SWIG1.3 and later, the 'double *OUTPUT' rule is ignored because it is defined after the %apply directive. 3. The %clear directive has been modified to erase all currently defined typemaps for a particular type. This differs from SWIG1.1 where %clear only removed rules that were added using the %apply directive. 4. Typemap matching is now performed using *exact* types. This means that things like this %typemap(in) char * { } %typemap(in) const char * { } are different typemaps. A similar rule applies for pointers, arrays, and references. For example: %typemap(in) double * { } used to apply to 'double &', 'double []', Now, it only applies to 'double *'. If you want a 'double &', you'll need to handle that separately. 5. Array matching has been simplfied. In SWIG1.1, array matching was performed by trying various combinations of dimensions. For example, 'double a[10][20]' was matched as follows: double [10][20] double [ANY][20] double [10][ANY] double [ANY][ANY] In SWIG1.3, only the following matches are attempted: double [10][20] double [ANY][ANY] On the positive side, typemap matching is now *significantly* faster than before. *** POTENTIAL INCOMPATIBILITY *** 8/15/00 : beazley Secret developer feature. Since datatypes are now represented as strings internally, you can bypass limitations of the parser and create a wild datatype by simply enclosing the raw string encoding in backticks (``) and sticking it in the interface file anywhere a type is expected. For example, `a(20).a(10).p.f(int,int)`. This feature is only intended for testing (i.e., you want to see what happens to your language module if it gets a reference to a pointer to an array of pointers to functions or something). *** SICK HACK *** 8/14/00 : beazley Completely new type-system added to the implementation. More details later. 8/11/00 : beazley Cleaned up some of the I/O handling. SWIG no longer generates any temporary files such as _wrap.wrap, _wrap.ii, _wrap.init. Instead, these "files" are kept around in memory as strings (although this is transparent to language modules). 8/4/00 : ttn Added Makefile target "check" and variants. This can be used like "make check" or, to explicitly skip a language LANG: "make skip-LANG=true check". LANG is skipped automatically if ./configure determines that LANG support is insufficient. Currently, the check is limited to doing the equivalent of "make all" in some of the Examples directories. This should be expanded both horizontally (different types of tests) and vertically (after "make all" in an Examples subdir succeeds, do some additional tests with the resulting interpreter, etc). 8/4/00 : ttn Added Makefile target "distclean", which deletes all the files ./configure creates, including config.status and friends. 8/3/00 : harcoh java changes??? [todo: document changes] 7/23/00 : beazley Typemaps have been modified to key off of the real datatypes used in the interface file. This means that typemaps for "const char *" and "char *" will be difference as will typemaps for "Vector" and "Vector *." *** POTENTIAL INCOMPATIBILITY *** This is likely to break interfaces that rely on the odd type handling behavior of typemaps in SWIG1.1--especially with respect to interfaces involving pass-by-value. 7/23/00 : beazley New %constant directive. This directive can be used to create true constants in the target scripting language. It's most simple form is something like this: %constant FOO 42; In this case, the type is inferred from the syntax of the value (in reality, all #define macros are translated into directives of this form). An expanded version is as follows: %constant(Foo *) FOO = &FooObj; In this case, an explicit type can be specified. This latter form may be useful for creating constants that used to be specified as const Foo *FOO = &FooObj; (which are now treated as variables). *** EXPERIMENTAL FEATURE *** The syntax may change in the final release. 7/23/00 : beazley Modified the parser so that variable declarations of the form "const type *a" are handled as variables, not constants. Note: SWIG1.1 handled this case erroneously because const char *a is a pointer variable that can be reassigned. *** POTENTIAL INCOMPATIBILITY *** Note: just because this is the "right" way to do things, doesn't mean it's the most appropriate interpretation. I suspect that many C programmers might use 'const char *' with the intent of creating a constant, without realizing that they've created a reassignable global variable. 7/23/00 : beazley The C/C++ wrapping layer has been completely redesigned and reimplemented. This change should iron out a few rough spots with the handling of datatypes. In addition, the wrapper code is somewhat cleaner. *** POTENTIAL INCOMPATIBILITY *** This change may break interfaces that involve subtle corner-cases with typemaps and the %addmethods directive since some of these features had somewhat type handling behavior in SWIG1.1. 7/23/00 : beazley The "memberin" and "memberout" typemaps are gone for the moment, but they might return as soon as I figure out how to integrate them with some of the streamlined C wrapper functions. *** POTENTIAL INCOMPATIBILITY *** 7/22/00 : beazley A variety of old type handling functions such as print_type(), print_full(), print_mangle(), etc... are gone and have been replaced with a smaller set of functions. See the file Doc/internals.html for details. This will break all third party language modules. *** POTENTIAL INCOMPATIBILITY *** 7/20/00 : beazley Deprecated the %val and %out directives. These directives shouldn't really be necessary since typemaps can be used to achieve similar results. This also cleans up the handling of types and parameters quite a bit. *** POTENTIAL INCOMPATIBILITY *** 7/20/00 : ttn Fixed unspecified-module bug in Guile support and removed more non-"with-smobs" functionality using patches submitted by Matthias Koeppe. Re-enable recognition of "-with-smobs" (with no effect since we use smobs by default now) for the time being. After the 1.3a4 release, this option will signal an error. 7/17/00 : ttn Fixed NULL-input bug in parameter list handling. Reported by Matthias Koeppe. 7/12/00 : beazley Fixed memory leak in Python type-checking code. Reported by Keith Davidson. Bug #109379. 7/10/00 : beazley Changed internal data structures related to function parameters. 7/10/00 : beazley Fixed some bugs related to the handling of the %name() directive and classes in the Tcl module. Problem reported by James Bailey. 7/10/00 : beazley Fixed parsing and enum handling problems with character constants. Reported by Greg Kochanski. 7/10/00 : beazley Removed WrapperFunction class from the core and updated the language module. This will break third party modules. *** POTENTIAL INCOMPATIBILITY *** 7/9/00 : beazley Implementation of SWIG no longer makes use of C++ operator overloading. This will almost certainly break *all* third party language modules that are not part of the main SWIG CVS tree. Sorry. *** POTENTIAL INCOMPATIBILITY *** 7/8/00 : beazley Removed the experimental and undocumented "build" typemap that was intended to work with multiple arguments. Simply too weird to keep around. Besides, a better replacement is in the works. 7/6/00 : ttn Removed non-"with-smobs" functionality (Guile support), i.e., "-with-smobs" is now the default and no longer needs to be specified on the command-line. 7/5/00 : ttn Incorporated Ruby support contributed by Masaki Fukushima. 6/28/00 : ttn Applied more-than-10-args bugfix patch contributed by Matthias Koeppe. 6/27/00 : beazley Rewrote some of the string handling and eliminated the C++ implementation (which is now just a wrapper). 6/27/00 : ttn Added Doc/index.html and Doc/internals.html. The target audience for the latter is new SWIG developers. Version 1.3 Alpha 3 (June 18, 2000) =================================== 6/18/00 : beazley Removed the naming.cxx, hash.cxx, and symbol.cxx files from the SWIG1.1 directory. Continued to migrate things away from the C++ base (although there's still a lot of work to do). 6/17/00 : beazley Added a few more examples to the Examples directory. Still need to do a lot of work on this. 6/16/00 : beazley Added -includeall to follow all #include statements in the preprocessor. 6/15/00 : beazley Tried to fix as many C++ warnings as possible when compiling with the Sun Workshop C++ compiler. Unfortunately, this means that there are a lot of statements that contain string literals of the form (char*)"Blah". 6/15/00: beazley A variety of cleanup and performance optimization in the low-level DOH library. This seems to result in a speedup of 50-100% for preprocessing and other related tasks. 5/10/00 : ttn Applied variable-wrapping bugfix patch contributed by Matthias Koeppe. 4/17/00 : ttn Updated MzScheme support contributed by Oleg Tolmatcev. We now use a `Scheme_Type'-based structure to wrap pointers. 4/11/00 : ttn Incorporated further Guile-support patch by Matthias Koeppe. Typemaps previously deleted have been re-added. There is now exception handling (see Doc/engineering.html). `SWIG_init' is now declared extern only for simple linkage. Some bugs were fixed. 4/06/00 : ttn Incorporated MzScheme support contributed by Oleg Tolmatcev. This includes new directories Lib/mzscheme and Examples/mzscheme. 4/03/00 : ttn Added Examples/guile and children. This is an adaptation of the same-named directory from the SWIG-1.1p5 distribution. Added Guile-specific section to Doc/engineering.html. 4/02/00 : ttn Incorporated new guilemain.i by Martin Froehlich. Incorporated Guile-support rewrite patch by Matthias Koeppe. The command line option "-with-smobs" enables implementation of pointer type handling using smobs, the canonical mechanism for defining new types in Guile. Previous implementation (using strings) is at the moment still supported but deprecated. At some point, "-with-smobs" will be the default and no longer required. 3/13/00 : beazley Added purify patches submitted by Ram Bhamidipaty. 3/02/00 : ttn Added support for different Guile "linkage" schemes. Currently, "-Linkage hobbit" works. Version 1.3 Alpha 2 (March 1, 2000) =================================== 2/29/00 : beazley Made SWIG ignore the 'mutable' keyword. 2/29/00 : beazley Incorporated some patches to the Perl5 module related to the -hide option and the destruction of objects. Patch submitted by Karl Forner. 2/27/00 : ttn Incorporated Guile support contributed by Matthias Koeppe. This includes a cpp macro in Lib/guile/guile.swg and the entire file Lib/guile/typemaps.i. 2/25/00 : ttn Modified configure.in and Makefile.in files to support non-local build (useful in multi-arch environments). 2/24/00 : ttn Incorporated Guile support contributed by Clark McGrew. This works with Guile 1.3, but since it depends heavily on the gh_ interface, it should work for all later versions. It has not been tested with versions before 1.3. WARNING: Code is unstable due to experimentation by ttn. 2/16/00 : beazley A variety of performance improvements to the Python shadow class code generation. Many of these result in substantial runtime performance gains. However, these have come at a cost of requiring the use of Python 1.5.2. For older versions, use 'swig -noopt -python' to turn off these optimization features. Version 1.3 Alpha 1 (February 11, 2000) ======================================= 2/11/00 : Added 'void' to prototype of Python module initializer. Reported by Mark Howson (1/20/00). 2/11/00 : beazley Modified the Python shadow class code to discard ownership of an object whenever it is assigned to a member of another object. This problem has been around for awhile, but was most recently reported by Burkhard Kloss (12/30/99). 2/11/00 : beazley Added braces around macros in the exception.i library. Reported by Buck Hodges (12/19/99) 2/11/00 : beazley Fixed bug in the constraints.i library. Reported by Buck Hodges (12/14/99) 2/11/00 : beazley The %native directive now generates Tcl8 object-style command calls. A full solution for Tcl7 and Tcl8 is still needed. Patch suggested by Mike Weiblen (11/29/99) 2/11/00 : beazley Modified the typemap code to include the $ndim variable for arrays. Patch provided by Michel Sanner (11/12/99). 2/11/00 : beazley Modified the Python module to raise a Runtime error if an attempt is made to set a read-only member of a shadow class. Reported by Michel Sanner (11/5/99). 2/10/00 : The documentation system has been removed. However, it is likely to return at some point in the future. 2/1/00 : Added a number of performance enhancements to the Python shadow classing and type-checking code. Contributed by Vadim Chugunov. 1. Remove _kwargs argument from the shadow wrappers when -keyword option is not specified. This saves us a construction of keyword dictionary on each method call. def method1(self, *_args, **_kwargs): val = apply(test2c.PyClass1_method1, (self,) + _args, _kwargs) return val becomes def method1(self, *_args): val = apply(test2c.PyClass1_method1, (self,) + _args) return val 2. Incorporate self into the _args tuple. This saves at least one tuple allocation per method call. def method1(self, *_args): val = apply(test2c.PyClass1_method1, (self,) + _args) return val becomes def method1(*_args): val = apply(test2c.PyClass1_method1, _args) return val 3. Remove *Ptr classes. Assume that we are SWIGging a c++ class CppClass. Currently SWIG will generate both CppClassPtr class that hosts all methods and also CppClass that is derived from the former and contains just the constructor. When CppClass method is called, the interpreter will try to find it in the CppClass's dictionary first, and only then check the base class. CppClassPtr functionality may be emulated with: import new _new_instance = new.instance def CppClassPtr(this): return _new_instance(CppClass, {"this":this,"thisown":0}) This saves us one dictionary lookup per call. The new module was first added in Python-1.5.2 so it won't work with older versions. I've implemented an alternative that achieves the same thing 4. Use CObjects instead of strings for pointers. Dave: This enhancements result in speedups of up to 50% in some of the preliminary tests I ran. 2/1/00 : Upgraded the Python module to use a new type-checking scheme that is more memory efficient, provides better performance, and is less error prone. Unfortunately, it will break all code that depends on the SWIG_GetPtr() function call in typemaps. These functions should be changed as follows: if (SWIG_GetPtr(string,&ptr,"_Foo_p")) { return NULL; } becomes if (SWIG_ConvertPtr(pyobj, &ptr, SWIG_TYPE_Foo_p) == -1) { return NULL; } Note: In the new implementation SWIG_TYPE_Foo_p is no longer a type-signature string, but rather an index into a type encoding table that contains type information. *** POTENTIAL INCOMPATIBILITY *** 1/30/00 : loic Conditionaly compile experimental code with --enable-experiment configure flag. Fix .cvsignore to ignore configrue & yacc generated files 1/28/00 : loic Apply automake everywhere Keep configure scripts so that people are not *forced* to autoconf Keep sources generated by yacc so that compilation without yacc is possible. Source/LParse/cscanner.c: change lyacc.h into parser.h to please default yacc generation rules. Use AC_CONFIG_SUBDIRS in configure.in instead of hand made script. Update all relevant .cvsignore to include .deps Fixed missing ; line 136 Source/Swig/swig.h 1/13/00 : beazley Fixed a number of minor end-of-file parsing problems in the preprocessor. 1/13/00 : beazley Added -freeze option that forces SWIG to freeze upon exit. This is only used as a debugging tool so that I can more easily examine SWIG's memory footprint. 1/13/00 : beazley Added patch to guile module for supporting optional arguments Patch contributed by Dieter Baron. 1/13/00 : loic Added .cvsignore, Examples/.cvsignore, Source/DOH/Doh/.cvsignore Source/SWIG1.1/main.cxx: Fixed -I handling bug Source/Modules1.1/java.cxx: fixed char* -> const char* warnings that are errors when compiling with gcc-2.95.2 Source/SWIG1.1/main.cxx: cast const char* to char* for String_replace token and rep should really be const. 1/12/00 : beazley Added Harco's Java modules. 1/12/00 : beazley Revoked the %ifdef, %ifndef, %endif, %if, %elif, and %else directives. These are no longer needed as SWIG now has a real preprocessor. *** POTENTIAL INCOMPATIBILITY *** 1/12/00 : beazley Moved the documentation modules from the SWIG directory to the Modules directory (where they really should have been to begin with). 1/12/00 : beazley Removed the -stat option for printing statistics. The statistics reporting was inadequate and mostly broken anyway. *** POTENTIAL INCOMPATIBILITY *** 1/12/00 : beazley Removed the -t option for reading a typemap file. More trouble than it's worth. Just include typemaps at the top of the interface file. *** POTENTIAL INCOMPATIBILITY *** 1/12/00 : beazley Removed the %checkout directive. *** POTENTIAL INCOMPATIBILITY *** 1/12/00 : beazley Removed the -ci option for file checkin. Too problematic to implement. Probably better to just put your SWIG library under CVS instead. *** POTENTIAL INCOMPATIBILITY ***. 1/11/00 : beazley Deleted the LATEX module. Sorry... Didn't know anyone who was using it. Besides, I'm looking to simplify the documentation system. *** POTENTIAL INCOMPATIBILITY *** 1/11/00 : beazley Modified the ASCII documentation module to use a .txt suffix for its output file instead of .doc. 1/11/00 : beazley Added the long-lost SWIG preprocessor back to the system. It should be enabled by default. Raw preprocessed output can be viewed using swig -E file.i. *** NEW FEATURE *** 1/11/00 : beazley and djmitche Completely reorganized the SWIG directory structure. The basic organization is now: Source/ SWIG source code Lib/ SWIG library files (swig_lib) Doc/ Documentation Examples/ Examples More directories will be added as needed. 12/08/99: Loic Dachary (loic@senga.org) Enhanced package handling for perl5 and c++. With new option -hide Foo::Bar, every perl5 object (Frob) is qualified by Foo::Bar::Frob. The package name is solely used to encapsulate C/C++ wrappers output in _wrap.c and the corresponding perl package in .pm. Note that a package name may contain :: (Frob::Nitz) and will be relative to the package name provided by -hide (Foo::Bar::Frob::Nitz). In *_wrap.c, SWIG_init macro is used. Was previously defined but not used and simplifies code. Added typemap(perl5,perl5in) and typemap(perl5,perl5out) that do the equivalent of typemap(perl5,in) and typemap(perl5,out) but contain perl code and applies to wrappers generated by -shadow. Lacking proper regression tests I used Examples/perl5/{c++,constraint,defarg,except, graph/graph[1234],multinherit,nested,shadow,simple,tree, typemaps/{argv,argv2,arraymember,database,file,ignore,integer, output,passref,reference,return}}/. I ran swig with and without the patches, diff the generatedsources, run the .pl files and checked that the results are identical. In all those examples I had no error. 11/21/99: Modified the Tcl module to provide full variable linking capabilities to all datatypes. In previous versions, a pair of accessor functions were created for datatypes incompatible with the Tcl_LinkVar() function. Now, we simply use variable traces to support everything. This may break scripts that rely upon the older behavior. *** POTENTIAL INCOMPATIBILITY *** 11/21/99: Added slight tweak to wrapper generator to collect local variables of similar type. Produces somewhat more compact wrapper code. 11/20/99: Modified the Tcl module to use SWIG_GetArgs() to parse arguments. This is a technique borrowed from Python in which arguments are converted using a format string convention similiar to fprintf(). This results in a *substantial* reduction in the size of the resulting wrapper code with only a modest runtime overhead in going through the extra conversion function. 11/13/99: Completely rewrote the class/structure generation code for the Tcl module. Now, a small set of runtime functions are used to implement the functionality for all classes (instead of a massive amount of runtime code being generated for each class). Class specific information is simply encoded in a series of static tables. This results in a *HUGE* reduction in wrapper code size--especially for C++. 11/13/99: Removed the -tcl (Tcl 7.x) module. Tcl 8.0 is now several years old and the defacto standard--no real reason to keep supporting the old version at this point. 11/13/99: Cleaned up -c option for Python module. The pyexp.swg file is now gone. 11/13/99: Fixed external declarations to work better with static linking on Windows. Static linking should now be possible by defining the -DSTATIC_LINK option on the command line. Patch contributed by Alberto Fonseca. 11/5/99 : Fixed an obscure code generation bug related to the generation of default constructors. Bug reported by Brad Clements. 11/5/99 : Fixed a few memory problems found by purify. 11/5/99 : Officially deprecated the -htcl, -htk, and -plugin options from the Tcl and Tcl8 modules. 10/26/99: Removed unused variable from python/typemaps.i. Patch contributed by Keith Davidson. 8/16/99 : Added _WIN32 symbol to libraries to better support Windows. 8/16/99 : Deprecated the Perl4 module. It is no longer included in the distribution and no longer supported. In the entire 3 years SWIG has been around I never received a single comment about it so I'm assuming no one will miss it... 8/16/99 : Modified the type-checking code to register type mappings using a table instead of repeated calls to SWIG_RegisterMapping(). This reduces the size of the module initialization function somewhat. 8/15/99 : Cleaned up the pointer type-checking code in the Tcl module. 8/15/99 : Many changes to the libraries to support runtime libraries. 8/13/99 : Eliminated C++ compiler warning messages about extern "C" linkage. 8/13/99 : Some cleanup of Python .swg files to better support runtime libraries on Windows. 8/13/99 : Modified the %pragma directive to attach pragmas declared inside a class definition to the class itself. For example: class foo { ... %pragma(python) addtomethod = "insert:print `hello world'" ... } Most people don't need to worry about how this works. For people writing backend modules, class-based pragmas work like this: lang->cpp_open_class() // Open a class lang->cpp_pragma() // Supply pragmas ... // Emit members lang->cpp_close_class() // Close the class All of the pragmas are passed first since they might be used to affect the code generation of other members. Please see the Python module for an example. Patches contributed by Robin Dunn. 8/13/99 : Patch to Python shadow classes to eliminate ignored exception errors in destructors. Patch contributed by Robin Dunn. 8/11/99 : Minor patch to swig_lib/python/swigptr.swg (added SWIGSTATIC declaration). Patch contributed by Lyle Johnson. 8/11/99 : Added FIRSTKEY/NEXTKEY methods to Perl5 shadow classes Patch contributed by Dennis Marsa. 8/11/99 : Modified Python module so that NULL pointers are returned and passed as 'None.' Patch contributed by Tal Shalif. 8/10/99 : Fixed missing 'int' specifiers in various places. 8/10/99 : Added Windows makefile for Runtime libraries. Contributed by Bob Techentin. 8/10/99 : Fixed minor problem in Python runtime makefile introduced by keyword arguments. 8/8/99 : Changed $target of perl5(out) typemap from ST(0) to ST(argvi). Patch contributed by Geoffrey Hort. 8/8/99 : Fixed bug in typemap checking related to the ANY keyword in arrays and ignored arguments. Error reported by Geoffrey Hort. 8/8/99 : %enabledoc and %disabledoc directives can now be used inside class/structure definitions. However, no check is made to see if they are balanced (i.e., a %disabledoc directive inside a class does not have to have a matching %enabledoc in the same class). 8/8/99 : Keyword argument handling is now supported in the Python module. For example: int foo(char *bar, int spam, double x); Can be called from Python as foo(x = 3.4, bar="hello", spam=42) To enable this feature, run SWIG with the '-keyword' command line option. Mixing keyword and default arguments should work as well. Unnamed arguments are assigned names such as "arg1", "arg2", etc... *** POTENTIAL INCOMPATIBILITY *** Functions with duplicate argument names such as bar(int *OUTPUT, int *OUTPUT) will likely cause problematic wrapper code to be generated. To fix this, use different names or use %apply to map typemaps to alternate names. 8/8/99 : Handling of the 'this' pointer has been changed in Python shadow classes. Previously, dereferencing of '.this' occured in the Python shadow class itself. Now, this step occurs in the C wrappers using the following function: SWIG_GetPtrObj(PyObject *, void **ptr, char *type) This function can accept either a string containing a pointer or a shadow class instance with a '.this' attribute of appropriate type. This change allows the following: 1. The real shadow class instance for an object is passed to the C wrappers where it can be examined/modified by typemaps. 2. Handling of default/keyword arguments is now greatly simplified. 3. The Python wrapper code is much more simple. Plus, it eliminated more than 300 lines of C++ code in the Python module. *** CAVEAT : This requires the abstract object interface. It should work with Python 1.4, but probably nothing older than that. 8/8/99 : Fixed handling of "const" and pointers in classes. In particular, declarations such as class foo { ... const char *msg; const int *iptr; } are handled as assignable variables as opposed to constant values (this is the correct behavior in C/C++). Note: declarations such as "char *const msg" are still unsupported. Constants declared at the global level using const are also broken (because I have a number of interfaces that rely upon this behavior). *** POTENTIAL INCOMPATIBILITY *** This may break interfaces that mistakenly treat 'const char *' types as constant values. 8/8/99 : Modified the parser to support bit-fields. For example: typedef struct { unsigned int is_keyword : 1; unsigned int is_extern : 1; unsigned int is_static : 1; } flags; Bit-fields can only be applied to integer types and their are other restrictions. SWIG performs no such type-checking (although the C compiler will catch problems when it tries to compile the wrapper code). 8/8/99 : Removed trailing space of $basetype substitution in typemaps. This is to allow things like this: %typemap(python, argout) spam** OUTPUT{ ... char* a = "$basetype_p"; ... } (Patch suggested by Nathan Dunfield). 6/22/99 : Made a very slight tweak to the Perl5 shadow class code that allows typemaps to alter the return type of objects (to support polymorphic types). Patch contributed by Drake Diedrich. 4/8/99 : Fixed null pointer handling bug in Perl module. Patch contributed by Junio Hamano. 3/17/99 : Fixed bug in perl5ptr.swg for ActiveState Perl. Patch contributed by Greg Anderson. 2/27/99 : Eliminated segmentation fault when Swig runs on empty files. 2/27/99 : Added patch to Guile module to eliminate unused variables. Contributed by Mike Simons. 2/27/99 : Fixed problem with %addmethods returning references. 2/27/99 : Fixed Runtime/Makefile. Patch contributed by Mike Romberg. 2/27/99 : Incorporated patches to the type-checker. 2/27/99 : Fixed problem with -exportall switch and shadow classes in Perl5 module. Patch contributed by Dennis Marsa. 2/27/99 : Modified Perl5 module to recognize 'undef' as a NULL char *. Patch contributed by Junio Hamano. 2/27/99 : Fixed the Perl5 module to support the newer versions of ActiveState Perl for Win32. 2/27/99 : Fixed the include order of files specified with the -I option. 2/5/98- : Dave finishes his dissertation, goes job hunting, moves to 2/5/99 Chicago and generally thrashes about. Version 1.1 Patch 5 (February 5, 1998) ====================================== 2/4/98 : Fixed a bug in the configure script when different package locations are specified (--with-tclincl, etc...). 2/2/98 : Fixed name-clash bug related to the switch to C macros for accessor functions. The new scheme did not work correctly for objects with members such as 'obj', 'val', etc... Fixed the bug by appending the word 'swig' to macro argument names. Patch contributed by Rudy Albachten. 2/2/98 : Slight fix to the Perl5 module to eliminate warning messages about 'varname used only once : possible typo'. Fix contributed by Rudy Albachten. 1/9/98 : Fixed a bug in the Perl 5 module related to the creation of constants and shadow classes. 1/9/98 : Fixed linking bug with Python 1.5 embed.i library file. Version 1.1 Patch 4 (January 4, 1998) ===================================== 1/4/98 : Changed structured of the Examples directory to be more friendly to Borland C++. 1/4/98 : Added the function Makefile.win.bc for compiling the examples under Borland 5.2. 1/4/98 : Slight change to the perl5 module and C++ compilation. The library is now included before any Perl headers because Perl the extern "C" linkage of math.h screws alot of things up (especially on Windows). 1/2/98 : Change to the Python module that reduces the number of constants created by C++ classes, inheritance, and shadow classes. This modification may introduce a few slight incompatibilities if you attempt to use the non-shadow class interface with shadow classes enabled. Patch contributed by Mike Romberg. 1/2/98 : Support for Tcl 8.0 namespaces has been added. This *replaces* the original SWIG mechanism that assumed [incr Tcl] namespaces. To use namespaces, simply run SWIG with the following options swig -tcl -namespace foo.i This places everything in a namespace that matches the module name swig -tcl -namespace -prefix bar foo.i This places everything in the namespace 'bar' The use of namespaces is new in Tcl 8.0. However, the wrapper code generated by SWIG will still work with all versions of Tcl newer than and including Tcl 7.3/Tk3.6 even if the -namespace option is used. *** POTENTIAL INCOMPATIBILITY *** This change may break existing applications that relied on the -prefix and -namespace options. 1/2/98 : Added the following constants to the Tcl wrapper code SWIG_name - Name of the SWIG module SWIG_prefix - Prefix/namespace appended to command names SWIG_namespace - Name of the namespace SWIG library writers can use these to their advantages. 1/2/98 : Fixed a bug in the Tcl8 module related to the creation of pointer constants (the function SWIG_MakePtr was missing from the wrapper code). 1/2/98 : Added the consthash.i library file to the Tcl and Tcl8 modules. 1/1/98 : Changed and cleaned up the Python typemaps.i file. The following significant changes were made : 1. The OUTPUT typemap now returns Python tuples instead of lists. Lists can be returned as before by using the L_OUTPUT type. If compatibility with older versions is needed, run SWIG with the -DOUTPUT_LIST option. 2. The BOTH typemap has been renamed to INOUT. For backwards compatibility, the "BOTH" method still exists however. 3. Output typemaps now generate less code than before. Changes to typemaps.i may break existing Python scripts that assume output in the form of a list. *** POTENTIAL INCOMPATIBILITY *** 12/31/97: Fixed long overdue problems with the testing scripts and certain makefiles that required the use of the bash shell. Everything should work properly with the standard Bourne shell (sh) now. 12/31/97: Modified typemaps to allow $basetype as a valid local variable. This allows for all sorts of bizarre hackish typemaps that do cool things. Patch contributed by Dominique Dumont. 12/31/97: Switched accessor functions generated for member data to C preprocessor macros (except in cases involving typemaps or char *). 12/31/97: Fixed a bug related to C++ member data involving references. 12/31/97: Changed accessor functions for C++ member functions to preprocessor macros. This cleans up the wrapper code and results in fewer function definitions. 12/31/97: Changed the default C constructor to use calloc() instead of malloc() 12/30/97: Changed the creation of constants in the Perl5 module. For all practical purposes, they should work in exactly the same way as before except that they now require much less wrapper code. Modules containing large numbers of constants may see greater than a 50% reduction in wrapper code size. 12/30/97: Modified the Python module to be more intelligent about the creation of constants. SWIG no longer generates redundant global variables and the size of the module initialization function should be reduced. (Many thanks to Jim Fulton). 12/29/97: Fixed a bug in C++ code generation related to member functions, default arguments, and references. 12/29/97: Fixed configure script and a few makefiles to support Python 1.5 12/29/97: Added 'embed15.i' library file. This file should be used to staticly link versions of Python 1.5. To make it the default, simply copy 'swig_lib/python/embed15.i' to 'swig_lib/python/embed.i' Version 1.1 Patch 3 (November 24, 1997) ======================================== 11/23/97: Fixed a bug in the Perl5 module with shadow classes and static class functions that return class instances. Note : The fix for this bug requires a slight restructuring of of the .pm files created by SWIG. 11/23/97: Fixed a bug in the Tcl/Tcl8 modules related to variable linking of character arrays. If you declared a global variable 'char foo[10]', the generated wrapper code would either cause a segmentation fault immediately upon loading or weird memory corruption elsewhere. This should now be fixed although character arrays can only be read-only. 11/23/97: Fixed a bug with the %import directive that caused it to fail if files were imported from directories other than the current working directory. 11/23/97: Fixed incorrect diagnostic message in the ASCII documentation module. 11/23/97: Changed the behavior of the -o option when used with shadow classes. If -o was used to specify both the pathname and filename of SWIG's output such as swig -o /home/swig/wrapper.c -shadow -perl5 foo.i The wrapper code would be placed the file specified with -o, but the .pm file and documentation would be placed in the directory where SWIG was run. Now, these files are placed in the same directory as the file specified with the -o option. This change is also needed for proper operation on the Macintosh. 11/23/97: Added a 'this()' method to Perl5 shadow classes. This can be used to return the normal pointer value from a shadow class that is represented as a tied hash. To use just invoke as a method like this : $l = new List; # Create an object $ptr = $l->this(); # Get the normal pointer value *** NEW FEATURE *** 11/23/97: Fixed the Tcl 8 pointer.i library file (which was completely broken in 1.1p2). 11/23/97: Modified the Perl5 type-checker to fix a few problems with global variables of pointer types and to allow tied hashes to be used interchangably with normal pointer values. 11/23/97: Modified the typemap mechanism to allow output typemaps of type 'void'. These were ignored previously, but now if you specify, %typemap(lang,out) void { ... return a void ... } You can change or assign a return value to the function. 11/23/97: Fixed processing of 'bool' datatypes in the Python module. 11/23/97: Fixed minor parsing error with C++ initializers. For example, class B : public A { public: B() : A() { ... }; ... } 11/23/97: Fixed the Tcl8 module so that C functions that call back into Tcl don't corrupt the return result object (SWIG was gathering the result object too early which leads to problems if subsequent Tcl calls are made). 11/23/97: Fixed a code generation bug in the Python module when two or more output parameters were used as the first arguments of a function. For example : %include typemaps.i void foo(double *OUTPUT, double *OUTPUT, double a); Previously, doing this resulted in the creation of an extraneous comma in the output, resulting in a C syntax error. 11/22/97: Fixed a bug when template handling that was stripping whitespace around nested templates. For example : Foo > was getting munged into Foo> which is a syntax error in in the C++ compiler. 11/22/97: Fixed bugs in the Borland C++ makefiles. 11/22/97: Fixed memory corruption bug when processing integer arguments in Tcl8 module. 11/21/97: Fixed a bug in the Runtime/Makefile related to Tcl 8. 11/21/97: Fixed a bug with the %new directive and Perl5 shadow classes. No longer generates a perl syntax error. 11/9/97 : Changed a strncpy() to strcpy() in the pointer type-checker. This results in a substantial performance improvement in type-checking. 10/29/97: Fixed a bug in the code generation of default arguments and user-defined types. For example : void foo(Vector a, Vector b = d); should now work properly. Version 1.1 Patch 2 (September 4, 1997) ======================================= 9/4/97 : Fixed problem with handling of virtual functions that was introduced by some changes in the C++ module. Version 1.1 Patch 1 (August 27, 1997) ===================================== 8/26/97 : Fixed compilation and run-time bugs with Tcl 8.0 final. 8/21/97 : Fixed code generation bug with arrays appearing as arguments to C++ member functions. For example : class Foo { public: void Bar(int a[20][20]); }; There is still a bug using arrays with added methods however. 8/20/97 : Fixed a bug with generating the code for added methods involving pass-by-value. 8/19/97 : Modified the typemapper to substitute the '$arg' value when declaring local variables. For example : %typemap(in) double * (double temp_$arg) { ... do something ... } When applied to a real function such as the following : void foo(double *a, double *b, double *result); three local variables will be created as follows : double temp_a; double temp_b; double temp_result; This can be used when writing multiple typemaps that need to access the same local variables. 7/27/97 : Fixed a variety of problems with the %apply directive and arrays. The following types of declarations should now work : %apply double [ANY] { Real [ANY] }; %apply double [4] { double [10] }; A generic version of apply like this : %apply double { Real }; should now work--even if arrays involving doubles and Reals are used later. 7/27/97 : Changed warning message about "Array X has been converted to Y" to only appear if running SWIG in verbose mode. 7/27/97 : Added the variables $parmname and $basemangle to the typemap generator. $parmname is the name of the parameter used when the typemap was matched. It may be "" if no parameter was used. $basemangle is a mangled version of the base datatype. Sometimes used for array handling. 7/27/97 : Changed the behavior of output arguments with Python shadow classes. Originally, if a function returned an object 'Foo', the shadow class mechanism would create code like this : def return_foo(): val = FooPtr(shadowc.return_foo()) val.this = 1 return val The problem with this is that typemaps allow a user to redefine the output behavior of a function--as a result, we can no longer make any assumptions about the return type being a pointer or even being a single value for that matter (it could be a list, tuple, etc...). If SWIG detects the use of output typemaps (either "out" or "argout") it returns the result unmodified like this : def return_foo(): val = shadowc.return_foo() return val In this case, it is up to the user to figure out what to do with the return value (including the possibility of converting it into a Python class). 7/26/97 : Fixed a parsing problem with types like 'unsigned long int', 'unsigned short int', etc... 7/24/97 : Minor bug fix to Tcl 8 module to parse enums properly. Also fixed a memory corruption problem in the type-checker. (patch contributed by Henry Rowley. 7/24/97 : Added Python-tuple typemaps contributed by Robin Dunn. 7/24/97 : Incorporated some changes to the Python module in support of Mark Hammond's COM support. I'm not entirely sure they work yet however. Needs documentation and testing. 7/24/97 : Fixed code generation bugs when structures had array members and typemaps were used. For example : %typemap(memberin) double [20][20] { ... get a double [20][20] ... } struct Foo { double a[20][20]; } Originally, this would generate a compiler-type error when the wrapper code was compiled. Now, a helper function like this is generated : double *Foo_a_set(Foo *a, double val[20][20]) { ... memberin typemap here ... return (double *) val; } When writing typemaps, one can assume that the source variable is an array of the *same* type as the structure member. This may break some codes that managed to work around the array bug. *** POTENTIAL INCOMPATIBILITY *** 7/13/97 : Fixed bug in Perl5 module when using C global variables that are pointers. When used in function calls and other operations, the value of the pointer would be invalid---causing core dumps and other problems. SWIG implements global variables using Perl magic variables. As it turns out, the error was caused by the fact that the pointer-extraction code was somehow bypassing the procedure used to resolve magical variables (hence, leaving the value undefined). To fix the problem, SWIG now explicitly resolves magic before extracting pointer values. 7/12/97 : Eliminated the last remnants of free() and malloc() from the SWIG compiler. 7/12/97 : Fixed parsing problems with typemaps involving arrays and temporary variables of arrays. Also made it possible for SWIG to handle typemaps like this : %typemap(in) double [ANY] (double temp[$dim0]) { ... store data in temp[$dim0] ... } Not only does this typemap match any double [] array, it creates a local variable with precisely the right dimensions. (ie. $dim0 gets filled in with the real number of dimensions). Of course, off the record, this will be a way to add more functionality to the typemaps.i libraries. 7/9/97 : Fixed some problems with Perl5, static linking, and shadow classes. When statically linking multiple modules together, write a top-level interface file like this when shadow classes are not used : %module swig, foo, bar, glob; %include perlmain.i When shadow classes are used, the module names have an extra 'c' appended so it should read as : %module swig, fooc, barc, globc; %include perlmain.i When linking multiple modules, consider using the SWIG runtime library. 7/8/97 : Incorporated fixed versions of the Borland C++ Makefiles. 7/8/97 : First cut at trying to eliminate excessive compiler warnings. As it turns out, alot of warnings go away if you just make declarations like this clientData = clientData; in the resulting wrapper code. Most compilers should just ignore this code (at least would can hope). 7/8/97 : Fixed bizarre code generation bug with typemaps and C++ classes. In some cases, typemaps containing printf formatting strings such as %typemap(memberout) int * { printf("%d",42); } Would generate completely bogus code with garbage replacing the '%d'. Caused by one faulty use of printf (wasn't able to find any other occurences). 7/7/97 : Fixed bug in Python shadow class generation with non-member functions that are returning more than one value. 7/7/97 : Incorporated modifications to make SWIG work with Guile 1.2. Still need to test it out, but it is rumored to work. 7/2/97 : Fixed some bugs related to output arguments and Python shadow classes. If an output argument is detected, SWIG assumes that the result is a list and handles it appropriately. If the normal return type of an function is an object, it will be converted into a shadow class as before, but with the assumption that it is the first element of a list. *** NOTE : This behavior has been subsequently changed *** 6/29/97 : Changed EXPORT to SWIGEXPORT in all of the language modules. Should provide better compatibility with Windows. 6/29/97 : Modified Python shadow classes so that output arguments work correctly (when typemaps are used). Version 1.1 (June 24, 1997) =========================== 6/24/97 : Fixed Objective-C constructor bug when working with Perl5 shadow classes. 6/23/97 : Fixed some parsing problems with Objective-C. Declarations such as the following should work now : - foo : (int) a with: (int) b; 6/22/97 : Added SWIG Runtime library. This library contains the SWIG pointer type-checker and support functions that are normally included in every module. By using the library, it is easier to work with multiple SWIG generated modules. 6/22/97 : Fixed minor bug in Perl5 module related to static linking of multiple modules. 6/22/97 : Fixed some bugs with the %import directive. When used with Perl5 shadow classes, this generates a 'require' statement to load in external modules. 6/22/97 : Added -swiglib option. This prints out the location of the SWIG library and exits. This option is only really useful to configuration tools that are looking for SWIG and its library location (e.g. autoconf, configure, etc...). 6/21/97 : Fixed export bug with Perl5.004 on Windows-NT. 6/20/97 : Minor change to code generation of class/structure members in order to work better with typemaps. Should have no noticable impact on existing SWIG modules. 6/19/97 : Added -t option. This allows SWIG to load a typemap file before processing any declarations. For example : swig -t typemaps.i -python example.i At most, only one typemap file can be specified in this manner. *** NEW FEATURE *** 6/18/97 : Need a Makefile fast? Type swig [-tcl, -perl5, -python] -co Makefile and you will get a Makefile specific to that target language. You just need to modify it for your application and you're ready to run. 6/18/97 : Completed the -ci option. This option checks a file into the SWIG library. It should be used in conjunction with a language option. For example : swig -tcl -ci foobar.i Checks the file foobar.i into the Tcl part of the library. In order to check a file into the general library (accessible to all languages modules), do the following swig -ci -o ../foobar.i foobar.i (Admittedly this looks a little strange but is unavoidable). The check-in option is primarily designed for SWIG maintenance and library development. The command will fail if the user does not have write permission to the SWIG library. Third party library extensions can easily install themselves by simply providing a shell script that uses 'swig -ci' to install the appropriate library files. It is not necessary to know where the SWIG library is located if you use this mechanism. *** NEW FEATURE *** 6/16/97 : Fixed a bug in shadow class generation when %name() was applied to a class definition. Unfortunately, fixing the bug required a change in the Language C API by adding an extra argument to the Language::cpp_class_decl() function. This may break SWIG C++ extensions. *** POTENTIAL INCOMPATIBILITY *** 6/15/97 : Added a warning message if no module name is specified with the %module directive or -module option. 6/15/97 : Fixed line number bug when reporting errors for undefined base classes. 6/15/97 : Added new %rename directive. This allows the forward declaration of a renaming. For example : %rename OldName NewName; .... later ... int OldName(int); Unlike %name, %rename will rename any occurence of the old name. This applies to functions, variables, class members and so forth. There is no way to disable %rename once set, but you can change the name by redeclaring it to something else. *** NEW FEATURE *** 6/15/97 : Improved the implementation of the %name directive so that it could be used with conditional compilation : #ifdef SWIG %name(NewName) #endif int OldName(int); 6/15/97 : Added support for functions with no return datatype. In this case, SWIG assumes a return type of 'int'. 6/11/97 : Improved error reporting in the parser. It should be a little less sensitive to errors that occur inside class definitions now. Also reports errors for function pointers. 6/11/97 : Made '$' a legal symbol in identifiers. This is to support some Objective-C libraries. Some compilers (such as gcc) may also allow identifiers to contain a $ in C/C++ code as well (this is an obscure feature of C). When '$' appears in identifier, SWIG remaps it to the string '_S_' when creating the scripting language function. Thus a function 'foo$bar' would be called 'foo_S_bar'. 6/11/97 : Fixed bug in Python shadow classes with __repr__ method. If supplied by the user, it was ignored, but now it should work. 6/9/97 : Fixed the Tcl 8.0 module to work with Tcl 8.0b1. SWIG is no longer compatible with *any* alpha release of Tcl 8.0. *** POTENTIAL INCOMPATIBILITY *** 6/7/97 : Put a maximal error count in (currently set to 20). SWIG will bail out if it generates more errors than this (useful for preventing SWIG from printing 4000 syntax errors when it gets confused). 6/7/97 : Fixed segmentation fault when parsing variable length arguments. 6/7/97 : Minor change to Perl5 module. C++ static functions are now put in the same package as their class when using shadow classes. 6/7/97 : Centralized the naming of functions, members, wrappers etc... By centralizing the naming scheme, it should be possible to make some multi-file optimizations. Also, it should be possible to change SWIG's naming scheme (perhaps a new feature to be added later). 6/2/97 : Added 'arginit' typemap. This can be used to assign initial values to function arguments. Doing so makes it somewhat easier to detect improper argument passing when working with other typemaps. 6/2/97 : Fixed code generation bug when read-only variables were inherited into other classes. Under inheritance, the variables would become writable, but this has now been corrected. 5/30/97 : An empty %name() directive is no longer allowed or supported. This directive was originally used to strip the prefix off of a class or structure. Unfortunately, this never really seemed to work right and it complicated the C++ code generator significantly. As far as I can tell no one uses it, so it is now history. *** POTENTIAL INCOMPATIBILITY *** 5/28/97 : Fixed a parsing bug with #define and C++ comments. Declarations such as the following now work properly : #define CONST 4 // A Comment 5/28/97 : Made some performance improvements to the SWIG String class. (only affects the SWIG compiler itself). 5/28/97 : Modified the parser to skip template definitions and issue a warning message. 5/28/97 : Preliminary support for parameterized types added (ie. templates). Types such as the following should pass through the SWIG compiler void foo(vector *a, vector *b); When used, the entire name 'vector' becomes the name of the datatype. Due to space limitations in datatype representations, the name should not exceed 96 characters. Note : This is only part of what is needed for template support. Template class definitions are not yet supported by SWIG. The template notation above may also be used when specifying Objective-C protocol lists. *** NEW FEATURE *** 5/24/97 : First cut at Objective-C support added. As it turns out, almost everything can be handled with only a few minor modifications to the C++ module. *** NEW FEATURE *** 5/23/97 : Fixed repeated definition bug in multiple inheritance handling when multiple base classes share a common base class (ie. the evil diamond). 5/21/97 : Fixed rather embarrassing typo that worked its way into the Tests/Build directory. 5/19/97 : Fixed code generation bug when using native methods and shadow classes with Python and Perl5 modules. 5/19/97 : Modified the %apply directive slightly so that it would work with pointers a little better. For example : %apply unsigned long { DWORD }; Applies *all* typemaps associated with "unsigned long" to "DWORD". This now includes pointers to the two datatypes. For example, a typemap applied to "unsigned long **" would also be applied to any occurrence of "DWORD **" as well. 5/19/97 : Fixed an ownership assignment bug in the Perl5 module when class members were returning new objects belonging to different classes. 5/17/97 : Added a few more typemap variables. $name - Name of function/variable/member $basetype - Base datatype (type without pointers) $argnum - Argument number 5/16/97 : Fixed embarrassing underscore error in local variable allocator. 5/16/97 : Fixed namespace clash bug in parameterized typemaps when creating arrays as new local variables. 5/15/97 : Fixed some bugs with inheritance of added methods across multiple files. SWIG now uses names of base classes when generating such functions. 5/14/97 : Finished support for default typemaps. Primarily used internally, they can be used to match the basic built-in datatypes used inside of SWIG. You can specify them in interface files as well like this : %typemap(tcl,in) int SWIG_DEFAULT_TYPE { $target = atoi($target); } Unlike normal typemaps, this default map will get applied to *all* integer datatypes encountered, including those renamed with typedef, etc... 5/13/97 : Fixed substring bug in type checker. 5/12/97 : Fixed bug in parameterized typemaps when declaring local variables of structures. Version 1.1 Beta6 (May 9, 1997) =============================== 5/9/97 : Fixed bizarre NULL pointer handling bug in Perl5 module. 5/8/97 : Fixed mysterious segmentation fault when running SWIG on an empty file. 5/7/97 : The code generator will now replace the special symbol "$cleanup" with the cleanup code specified with the "freearg" typemap. This change needed to properly manage memory and exceptions. 5/5/97 : Added the 'typemaps.i' library file. This contains a variety of common typemaps for input values, pointers, and so on. 5/5/97 : Changed behavior of "argout" typemap in Python module. Old versions automatically turned the result into a Python list. The new version does nothing, leaving the implementation up to the user. This provides more flexibility but may break older codes that rely on typemaps. *** POTENTIAL INCOMPATIBILITY *** 5/5/97 : Fixed bug in Python module related to the interaction of "argout" and "ignore" typemaps. 5/5/97 : Fixed bug in Python module that would generate incorrect code if all function arguments are "ignored". 5/4/97 : Added %apply and %clear directives. These form a higher level interface to the typemap mechanism. In a nutshell, they can be used to change the processing of various datatypes without ever having to write a typemap. See the SWIG documentation for more details. ** NEW FEATURE ** 5/4/97 : Added a local variable extension to the typemap handler. For example : %typemap(tcl,in) double *(double temp) { temp = atof($source); $target = &temp; } In this case, 'temp' is a local variable that exists in the entire wrapper function (not just the typemap code). This mechanism provides better support for certain types of argument handling and also makes it possible to write thread-safe typemaps. Any number local variables can be declared by supplying a comma separated list. Local variables are guaranteed to be unique, even if the same typemap is applied many times in a given function. ** Not currently supported in Perl4 or Guile modules. 5/2/97 : Fixed processing of %ifdef, %endif, %if, etc... (These are SWIG equivalents of the C preprocessor directives that can pass through the C preprocessor without modification). 5/2/97 : Fixed major (but subtle) bug in the run-time type checker related to searching and type-checking for C++ inheritance. To make a long story short, if you had two classes named "Foo" and "FooObject" the type checker would sometimes get confused and be unable to locate "Foo" in an internal table. 5/2/97 : Fixed some bugs in the -co option. 4/24/97 : Pointer library added to the SWIG library. 4/19/97 : Added the %new directive. This is a "hint" that can be used to tell SWIG that a function is returning a new object. For example : %new Foo *create_foo(); This tells SWIG that create_foo() is creating a new object and returning a pointer to it. Many language modules may choose to ignore the hint, but when working with shadow classes, the %new is used to handle proper ownership of objects. %new can also be used with dynamically allocated strings. For example : %new char *create_string(); When used, all of the language modules will automatically cleanup the returned string--eliminating memory leaks. ** NEW FEATURE ** 4/19/97 : Added a new typemap "newfree". This is used in conjunction with the %new directive and can be used to change the method by which a new object returned by a function is deleted. 4/19/97 : The symbol "__cplusplus" is now defined in the SWIG interpreter when running with the -c++ option. 4/17/97 : Added support for static member functions when used inside the %addmethods directive. 4/15/97 : Added a special typemap symbol PREVIOUS that can be used to restore a previous typemap. For example : %typemap(tcl,in) int * = PREVIOUS; This is primarily used in library files. 4/13/97 : Added %pragma directive for Perl5 module. Two new pragmas are available : %pragma(perl5) code = "string" %pragma(perl5) include = "file.pl" Both insert code into the .pm file created by SWIG. This can be used to automatically customize the .pm file created by SWIG. 4/13/97 : Scanner modified to only recognize C++ keywords when the -c++ option has been specified. This provides support for C programs that make use of these keywords for identifiers. SWIG may need to be explicitly run with the -c++ option when compiling C++ code (this was allowed, but not recommended in previous versions). **POTENTIAL INCOMPATIBILITY** 4/11/97 : Fixed a rather nasty bug in the Perl5 module related to using variable linking with complex datatypes and pointers. On Unix, code would work (somehow), but would cause an access violation under Windows-NT. The fix should correct the problem, but there may still be a problem using global variables of complex datatypes in conjunction with shadow classes. Fortunately, this sort of thing seems to be relatively rare (considering that the bug has been around for more than a year - yikes!). 4/11/97 : Fixed bizarre constant evaluation bug in Perl5 code generation when running under Windows-NT. 4/8/97 : Bug when using default arguments and C++ references fixed. 4/8/97 : Fixed code generation bugs in Python and Perl5 modules related to using class renaming (applying the %name directive to a class definition) and shadow classes. 4/7/97 : Fixed minor bugs in swigptr.swg, tcl8ptr.swg, and perl5ptr.swg to prevent infinite loops when weird datatypes are passed. 3/29/97 : 'Makefile.win' added. This is used to build most of the examples in the Examples directory under Windows NT/95. 3/27/97 : Fixes to SWIG's error return codes. SWIG now returns non-zero exit codes for certain kinds of errors (which makes it more friendly to makefiles). An overhaul of the error handling is on the to-do list and will probably show up in a later release. 3/25/97 : Bug fix. "freearg" and "argout" typemaps have been fixed in the Perl5 module. In previous versions, function input parameters and function output parameters shared the same memory space--causing all sorts of nasty problems when trying to pass perl values by reference. SWIG now internally makes a "copy" (which is really just a pointer) of affected parameters and uses that. This is done transparently so there is no noticable impact on any SWIG generated modules. This change is probably only noticable to expert users. 3/25/97 : Added type-check to verbose and stat mode. SWIG will now generate a list of all datatypes that were used but undefined (useful for tracking down weird bugs). This is enabled with the -v option (which is now officially known as "overly verbose" mode) or the -stat option. 3/25/97 : Slight change to the parser to make include guards work correctly. For example : #ifndef INTERFACE_I #define INTERFACE_I %module foobar.i ... declarations ... #endif 3/24/97 : %checkout directive added. This allows an interface file to extract files from the SWIG library and place them in the current directory. This can be used to extract scripts and other helper code that might be associated with library files. For example : %checkout array.tcl Will look for a file "array.tcl" in the library and copy it to the current directory. If the file already exists in the directory, this directive does nothing (it will not overwrite an existing file). This only an experimental feature for now. 3/24/97 : SWIG will now look in the SWIG Library for a file if it can't find it in the current directory. As a result, it is easy to make modules from SWIG library files. For example, if you want to make a Python module from the SWIG timers library, just type this in any directory : swig -python timers.i You will get the files timers_wrap.c and timers_wrap.doc in the current directory that you can now compile. The file remains in the SWIG library (although you can check it out using the -co option). *** New Feature *** 3/24/97 : -co option added to SWIG to allow easy access to the SWIG library. When used, this instructs SWIG to check out a library file and place it in the current directory. For example : unix > swig -co array.i array.i checked out from the SWIG library unix > Once in your directory you can customize the file to suit your particular purposes. The checkout option makes it easy to grab library files without knowing anything about the SWIG installation, but it also makes it possible to start including scripts, C code, and other miscellaneous files in the library. For example, you could put a cool script in the library and check it out whenever you wanted to use it. *** New Feature *** 3/24/97 : #pragma export directives added to Tcl output for compiling shared libraries on the Mac. 3/24/97 : Minor changes to wish.i and tclsh.i library files to provide support for the Macintosh. 3/19/97 : SWIG's policy towards NULL pointers has been relaxed. The policy of requiring a special compiler directive -DALLOW_NULL to use NULL pointers is no longer supported. While this may seem "unsafe", it turns out that you can use a "check" typemap to achieve some safety. For example : %typemap(perl5,check) Node * { if (!$target) croak("NULL Pointers not allowed."); } This prevents any NULL value of a "Node *" pointer to be passed to a function. (I think this is much cleaner than the old -DALLOW_NULL hack anyways). 3/19/97 : Fixed pointer handling errors in Perl5 module. Modules no longer core dump when a Perl reference is inadvertently passed in as a C pointer. 3/18/97 : Added a "check" typemap. This can be used to check the validity of function input values. For example : %typemap(perl5,check) int posint { if ($target < 0) croak("Argument is not a positive integer"); } 3/18/97 : Added an $arg variable to Tcl typemaps. This makes it easier to return argument values by "reference". 3/18/97 : Fixed a code generation bug when using C++ references and the %addmethods directive. 3/18/97 : Fixed a few glitches in the typemap module with respect to chaining. For example : %typemap(tcl,in) int { $in // Inserts prexisting typemap printf("Received a %d\n", $target); } This has been allowed for quite some time, but didn't work if no existing typemap was defined. Now, it still doesn't work if no existing typemap is defined, but it issues a warning message. There is some support using default typemaps, but none of the language modules take advantage of it. This should be considered experimental at this time. Version 1.1b5 Patch 1 (March 16, 1997) ====================================== 3/16/97 : Fixed references bug with C++ code generation. 3/16/97 : Fixed initialization bug in the documentation system that was causing weird problems. 3/16/97 : Fixed fatal bug with -c option in the Python module. 3/13/97 : Fixed bug in the documentation system involving the %text directive and sorting. In the old system, %text entries would float to the top of a section because they were "nameless". Now they are attached to the previous declaration and will stay in the proper location relative to the previous entry. Version 1.1b5 (March 12, 1997) ============================== 3/11/97 : Fixed compilation problems introduced by Tcl/Tk 8.0a2. *** INCOMPATIBILITY *** SWIG no longer works with Tcl/Tk 8.0a1. 3/10/97 : Fixed bug with ignored arguments and C++ member functions in the Python module. 3/9/97 : Parsing bugs with nested class definitions and privately declared nested class definitions fixed. 3/9/97 : Fixed a few minor code generation bugs with C++ classes and constructors. In some cases, the resulting wrapper code would not compile properly. SWIG now attempts to use the default copy constructor instead. 3/8/97 : Added a -l option to SWIG that allows additional SWIG library files to be grabbed without having them specified in the interface file. This makes it easier to keep the interface file clean and move certain options into a Makefile. For example : swig -tcl example.i # Build a normal Tcl extension swig -tcl -lwish.i example.i # Build it as a wish extension # by including the 'wish.i' file. swig -python example.i # Build a dynamically loaded extension swig -python -lembed.i example.i # Build a static extension These kinds of options could previously be accomplished with conditional compilation such as : %module example ... #ifdef STATIC %include embed.i #endif 3/8/97 : Incorporated changes to Guile module to use the new gh interface in FSF Guile 1.0. The older gscm interface used in Cygnus Guile releases is no longer supported by SWIG. 3/8/97 : Cleaned up the Tcl Netscape plugin example. It should work with version 1.1 of the plugin now. 3/8/97 : Added better array support to the typemap module. The keyword ANY can now be used to match any array dimension. For example : %typemap(tcl,in) double [ANY] { ... get an array ... } This will match any single-dimensional double array. The array dimension is passed in the variables $dim0, $dim1, ... $dim9. For example : %typemap(tcl,in) double [ANY][ANY][ANY] { printf("Received a double[%d][%d][%d]\n",$dim0,$dim1,$dim2); } Any typemap involving a specific array dimension will override any specified with the ANY tag. Thus, a %typemap(tcl,in) double [5][4][ANY] {} would override a double [ANY][ANY][ANY]. However, overuse of the ANY tag in arrays of high-dimensions may not work as you expect due to the pattern matching rule used. For example, which of the following typemaps has precedence? %typemap(in) double [ANY][5] {} // Avoid this! %typemap(in) double [5][ANY] {} 3/7/97 : Fixed a number of bugs related to multi-dimensional array handling. Typedefs involving multi-dimensional arrays now works correctly. For example : typedef double MATRIX[4][4]; ... extern double foo(MATRIX a); Typecasting of pointers into multi-dimensional arrays is now implemented properly when making C/C++ function calls. 3/6/97 : Fixed potentially dangerous bug in the Tcl Object-oriented interface. Well, actually, didn't fix it but issued a Tcl error instead. The bug would manifest itself as follows: % set l [List] # Create an object ... % set m [List -this $l] # Make $m into an object assuming $l # contains a pointer. # Since $m == $l, $l gets destroyed # (since its the same command name) % $m insert Foo Segmentation fault # Note : the list no longer exists! Now, an error will be generated instead of redefining the command. As in : % set l [List] ... % set m [List -this $l] Object name already exists! Use catch{} to ignore the error. 3/3/97 : Better support for enums added. Datatypes of 'enum MyEnum' and typedefs such as 'typedef enum MyEnum Foo;' now work. 3/3/97 : Parser modified to ignore constructor initializers such as : class Foo : public Bar { int a,b; public: Foo(int i) : a(0), b(i), Bar(i,0) { }; }; 3/3/97 : Modified parser to ignore C++ exception specifications such as : int foo(double) throw(X,Y); 3/3/97 : Added %import directive. This works exactly like %extern except it tells the language module that the declarations are coming from a separate module. This is usually only needed when working with shadow classes. 3/2/97 : Changed pointer type-checker to be significantly more efficient when working with derived datatypes. This has been accomplished by storing type-mappings in sorted order, using binary search schemes, and caching recently used datatypes. For SWIG generated C++ modules that make a large number of C function calls with derived types, this could result in speedups of between 100 and 50000 percent. However, due to the required sorting operation, module loading time may increased slightly when there are lots of datatypes. 3/2/97 : Fixed some C++ compilation problems with Python embed.i library files. 2/27/97 : Slight change to C++ code generation to use copy constructors when returning complex data type by value. 2/26/97 : Fixed bug in Python module with -c option. 2/26/97 : Slight tweak of parser to allow trailing comma in enumerations such as enum Value (ALE, STOUT, LAGER, }; 2/25/97 : Fixed code generation bug in Tcl module when using the %name() directive on a classname. 2/25/97 : Finished code-size optimization of C++ code generation with inheritance of attributes. Inherited attributes now only generate one set of wrapper functions that are re-used in any derived classes. This could provide big code size improvements in some scripting language interfaces. 2/25/97 : Perl5 module modified to support both the Unix and Windows versions. The windows version has been tested with the Activeware port of Perl 5.003 running under Windows 95. The C source generated by SWIG should compile without modification under both versions of Perl, but is now even more hideous than before. 2/25/97 : Modified parser to allow scope resolution operation to appear in expressions and default arguments as in : void foo(int a = Bar::defvalue); 2/25/97 : Fixed bug when resolving symbols inside C++ classes. For example : class Foo { public: enum Value {ALE, STOUT, LAGER}; ... void defarg(Value v = STOUT); }; 2/24/97 : Fixed bug with member functions returning void *. 2/23/97 : Modified Python module to be better behaved under Windows - Module initialization function is now properly exported. It should not be neccessary to explicitly export this function yourself. - Bizarre compilation problems when compiling the SWIG wrapper code as ANSI C under Visual C++ 4.x fixed. - Tested with both the stock Python-1.4 distribution and Pythonwin running under Win95. 2/19/97 : Fixed typedef handling bug in Perl5 shadow classes. 2/19/97 : Added exception support. To use it, do the following : %except(lang) { ... try part of the exception ... $function ... catch part of exception ... } $function is a SWIG variable that will be replaced by the actual C/C++ function call in a wrapper function. Thus, a real exception specification might look like this : %except(perl5) { try { $function } catch (char *& sz) { ... process an exception ... } catch(...) { croak("Unknown exception. Bailing out..."); } } 2/19/97 : Added support for managing generic code fragments (needed for exceptions). 2/19/97 : Fixed some really obscure typemap scoping bugs in the C++ handler. 2/18/97 : Cleaned up perlmain.i file by removing some problematic, but seemingly unnecessary declarations. 2/18/97 : Optimized handling of member functions under inheritance. SWIG can now use wrapper functions generated for a base class instead of regenerating wrappers for the same functions in a derived class. This could make a drastic reduction in wrapper code size for C++ applications with deep inheritance hierarchies and lots of functions. 2/18/97 : Additional methods specified with %addmethods can now be inherited along with normal C++ member functions. 2/18/97 : Minor internal fixes to make SWIG's string handling a little safer. 2/16/97 : Moved some code generation of Tcl shadow classes to library files. 2/16/97 : Fixed documentation error of '-configure' method in Tcl modules. 2/16/97 : Modified Perl5 module slightly to allow typemaps to use Perl references. 2/12/97 : Fixed argument checking bug that was introduced by default arguments (function calls with too many arguments would still be executed). Functions now must have the same number of arguments as C version (with possibility of default/optional arguments still supported). 2/12/97 : Fixed default argument bug in Perl5 module when generating wrapper functions involving default arguments of complex datatypes. 2/12/97 : Fixed typemap scoping problems. For example : %typemap(tcl,in) double { .. get a double .. } class Foo { public: double bar(double); } %typemap(tcl,in) double { .. new get double .. } Would apply the second typemap to all functions in Foo due to delayed generation of C++ wrapper code (clearly this is not the desired effect). Problem has been fixed by assigning unique numerical identifiers to every datatype in an interface file and recording the "range of effect" of each typemap. 2/11/97 : Added support for "ignore" and "default" typemaps. Only use if you absolutely know what you're doing. 2/9/97 : Added automatic creation of constructors and destructors for C structs and C++ classes that do not specify any sort of constructor or destructor. This feature can be enabled by running SWIG with the '-make_default' option or by inserting the following pragma into an interface file : %pragma make_default The following pragma disables automatic constructor generation %pragma no_default 2/9/97 : Added -make_default option for producing default constructors and destructors for classes without them. 2/9/97 : Changed the syntax of the SWIG %pragma directive to %pragma option=value or %pragma(lang) option=value. This change makes the syntax a little more consistent between general pragmas and language-specific pragmas. The old syntax still works, but will probably be phased out (a warning message is currently printed). 2/9/97 : Improved Tcl support of global variables that are of structures, classes, and unions. 2/9/97 : Fixed C++ compilation problem in Python 'embed.i' library file. 2/9/97 : Fixed missing return value in perlmain.i library file. 2/9/97 : Fixed Python shadow classes to return an AttributeError when undefined attributes are accessed (older versions returned a NameError). 2/9/97 : Fixed bug when %addmethods is used after a class definition whose last section is protected or private. 2/8/97 : Made slight changes in include file processing to support the Macintosh. 2/8/97 : Extended swigmain.cxx to provide a rudimentary Macintosh interface. It's a really bad interface, but works until something better is written. 1/29/97 : Fixed type-casting bug introduced by 1.1b4 when setting/getting the value of global variables involving complex data types. 1/29/97 : Removed erroneous white space before an #endif in the code generated by the Python module (was causing errors on DEC Alpha compilers). 1/26/97 : Fixed errors when using default/optional arguments in Python shadow shadow classes. 1/23/97 : Fixed bug with nested %extern declarations. 1/21/97 : Fixed problem with typedef involving const datatypes. 1/21/97 : Somewhat obscure, but serious bug with having multiple levels of typedefs fixed. For example : typedef char *String; typedef String Name; Version 1.1 Beta4 (January 16, 1997) ==================================== Note : SWIG 1.1b3 crashed and burned shortly after take off due to a few major run-time problems that surfaced after release. This release should fix most, if not all, of those problems. 1/16/97 : Fixed major memory management bug on Linux 1/14/97 : Fixed bug in functions returning constant C++ references. 1/14/97 : Modified C++ module to handle datatypes better. 1/14/97 : Modified parser to allow a *single* scope resolution operator in datatypes. Ie : Foo::bar. SWIG doesn't yet handle nested classes, so this should be sufficient for now. 1/14/97 : Modified parser to allow typedef inside a C++ class. 1/14/97 : Fixed some problems related to datatypes defined inside a C++ class. SWIG was not generating correct code, but a new scoping mechanism and method for handling datatypes inside a C++ class have been added. 1/14/97 : Changed enumerations to use the value name instead of any values that might have appeared in the interface file. This makes the code a little more friendly to C++ compilers. 1/14/97 : Removed typedef bug that made all enumerations equivalent to each other in the type checker (since it generated alot of unnecessary code). Version 1.1 Beta3 (January 9, 1997) ==================================== Note : A *huge* number of changes related to ongoing modifications. 1. Support for C++ multiple inheritance added. 2. Typemaps added. 3. Some support for nested structure definitions added. 4. Default argument handling added. 5. -c option added for building bare wrapper code modules. 6. Rewrote Pointer type-checking to support multiple inheritance correctly. 7. Tcl 8.0 module added. 8. Perl4 and Guile modules resurrected from the dead (well, they at least work again). 9. New Object Oriented Tcl interface added. 10. Bug fixes to Perl5 shadow classes. 11. Cleaned up many of the internal modules of the parser. 12. Tons of examples and testing modules added. 13. Fixed bugs related to use of "const" return values. 14. Fixed bug with C++ member functions returning void *. 15. Changed SWIG configuration script. Version 1.1 Beta2 (December 3, 1996) ==================================== 1. Completely rewrote the SWIG documentation system. The changes involved are too numerous to mention. Basically, take everything you knew about the old system, throw them out, and read the file Doc/doc.ps. 2. Limited support for #if defined() added. 3. Type casts are now allowed in constant expressions. ie #define A (int) 3 4. Added support for typedef lists. For example : typedef struct { double x,y,z; } Vector, *VectorPtr; 5. New SWIG directives (related to documentation system) %style %localstyle %subsection %subsubsection 6. Reorganized the C++ handling and made it a little easier to work with internally. 7. Fixed problem with inheriting data members in Python shadow classes. 8. Fixed symbol table problems with shadow classes in both Python and Perl. 9. Fixed annoying segmentation fault bug in wrapper code generated for Perl5. 10. Fixed bug with %addmethods directive. Now it can be placed anywhere in a class. 11. More test cases added to the SWIG self-test. Documentation tests are now performed along with other things. 12. Reorganized the SWIG library a little bit and set it up to self-document itself using SWIG. 13. Lots and lots of minor bug fixes (mostly obscure, but bugs nonetheless). Version 1.1 Beta1 (October 30, 1996) ==================================== 1. Added new %extern directive for handling multiple files 2. Perl5 shadow classes added 3. Rewrote conditional compilation to work better 4. Added 'bool' datatype 5. %{,%} block is now optional. 6. Fixed some bugs in the Python shadow class module 7. Rewrote all of the SWIG tests to be more informative (and less scary). 8. Rewrote parameter list handling to be more memory efficient and flexible. 9. Changed parser to ignore 'static' declarations. 10. Initializers are now ignored. For example : struct FooBar a = {3,4,5}; 11. Somewhat better parsing of arrays (although it's usually just a better error message now). 12. Lot's of minor bug fixes. Version 1.0 Final (August 31, 1996) =================================== 1. Fixed minor bug in C++ module 2. Fixed minor bug in pointer type-checker when using -DALLOW_NULL. 3. Fixed configure script to work with Python 1.4beta3 4. Changed configure script to allow compilation without yacc or bison. Version 1.0 Final (August 28, 1996) =================================== 1. Changed parser to support more C/C++ datatypes (well, more variants). Types like "unsigned", "short int", "long int", etc... now work. 2. "unions" added to parser. 3. Use of "typedef" as in : typedef struct { double x,y,z; } Vector; Now works correctly. The name of the typedef is used as the structure name. 4. Conditional compilation with #ifdef, #else, #endif, etc... added. 5. New %disabledoc, %enabledoc directives allow documentation to selectively be disabled for certain parts of a wrapper file. 6. New Python module supports better variable linking, constants, and shadow classes. 7. Perl5 module improved with better compatibility with XS and xsubpp. SWIG pointers and now created so that they are compatible with xsubpp pointers. 8. Support for [incr Tcl] namespaces added to Tcl module. 9. %pragma directive added. 10. %addmethods directive added. 11. %native directive added to allow pre-existing wrapper functions to be used. 12. Wrote configure script for SWIG installation. 13. Function pointers now allowed with typedef statements. 14. %typedef modified to insert a corresponding C typedef into the output file. 15. Fixed some problems related to C++ references. 16. New String and WrapperFunction classes add to make generating wrapper code easier. 17. Fixed command line option processing to eliminate core dumps and to allow help messages. 18. Lot's of minor bug fixes to almost all code modules Version 1.0 Beta 3 (Patch 1) July 17, 1996 ========================================== 1.0 Final is not quite ready yet, but this release fixes a number of immediate problems : 1. Compiler errors when using -strict 1 type checking have been fixed. 2. Pointer type checker now recognizes pointers of the form _0_Type correctly. 3. A few minor fixes were made in the Makefile Version 1.0 Beta 3 (June 14, 1996) =================================== There are lots of changes in this release : 1. SWIG is now invoked using the "swig" command instead of "wrap". Hey, swig sounds cooler. 2. The SWIG_LIB environment variable can be set to change the location where SWIG looks for library files. 3. C++ support has been added. You should use the -c++ option to enable it. 4. The %init directive has been replaced by the %module directive. %module constructs a valid name for the initialization function for whatever target language you're using (actually this makes SWIG files a little cleaner). The old %init directive still works. 5. The syntax of the %name directive has been changed. Use of the old one should generate a warning message, but may still work. 6. To support Tcl/Tk on non-unix platforms, SWIG imports a file called swigtcl.cfg from the $(SWIG_LIB)/tcl directory. I don't have access to an NT machine, but this file is supposedly allows SWIG to produce wrapper code that compiles on both UNIX and non UNIX machines. If this doesn't work, you'll have to edit the file swigtcl.cfg. Please let me know if this doesn't work so I can update the file as necessary. 7. The SWIG run-time typechecker has been improved. You can also now redefine how it works by supplying a file called "swigptr.cfg" in the same directory as your SWIG interface files. By default, SWIG reads this file from $(SWIG_LIB)/config. 8. The documentation system has been changed to support the following : - Documentation order is printed in interface file order by default. This can be overridden by putting an %alpha directive in the beginning of the interface file. - You can supply additional documentation text using %text %{ put your text here %} - A few minor bugs were fixed. 9. A few improvements have been made to the handling of command line options (but it's still not finished). 10. Lots of minor bug fixes in most of the language modules have been made. 11. Filenames have been changed to 8.3 for compatibility with a SWIG port to non-unix platforms (work in progress). 12. C++ file suffix is now .cxx (for same reason). 13. The documentation has been upgraded significantly and is now around 100 pages. I added new examples and a section on C++. The documentation now includes a Table of Contents. 14. The SWIG Examples directory is still woefully sparse, but is getting better. Special notice about C++ ------------------------ This is the first version of SWIG to support C++ parsing. Currently the C++ is far from complete, but seems to work for simple cases. No work has been done to add special C++ processing to any of the target languages. See the user manual for details about how C++ is handled. If you find problems with the C++ implementation, please let me know. Expect major improvements in this area. Note : I have only successfully used SWIG and C++ with Tcl and Python. Notice about Version 1.0Final ----------------------------- Version 1.0B3 is the last Beta release before version 1.0 Final is released. I have frozen the list of features supported in version 1.0 and will only fix bugs as they show up. Work on SWIG version 2.0 is already in progress, but is going to result in rather significant changes to SWIG's internal structure (hopefully for the better). No anticipated date for version 2.0 is set, but if you've got an idea, let me know. Version 1.0 Beta 2 (April 26, 1996) =================================== This release is identical to Beta1 except a few minor bugs are fixed and the SWIG library has been updated to work with Tcl 7.5/Tk 4.1. A tcl7.5 examples directory is now included. - Fixed a bug in the Makefile that didn't install the libraries correctly. - SWIG Library files are now updated to work with Tcl 7.5 and Tk 4.1. - Minor bug fixes in other modules. Version 1.0 Beta 1 (April 10, 1996). ===================================== This is the first "semi-official" release of SWIG. It has a number of substantial improvements over the Alpha release. These notes are in no particular order--hope I remembered everything.... 1. Tcl/Tk SWIG is known to work with Tcl7.3, Tk3.6 and later versions. I've also tested SWIG with expect-5.19. Normally SWIG expects to use the header files "tcl.h" and "tk.h". Newer versions of Tcl/Tk use version numbers. You can specify these in SWIG as follows : % wrap -htcl tcl7.4.h -htk tk4.0.h example.i Of course, I prefer to simply set up symbolic links between "tcl.h" and the most recent stable version on the machine. 2. Perl4 This implementation has been based on Perl-4.035. SWIG's interface to Perl4 is based on the documentation provided in the "Programming Perl" book by Larry Wall, and files located in the "usub" directory of the Perl4 distribution. In order to compile with Perl4, you'll need to link with the uperl.o file found in the Perl4 source directory. You may want to move this file to a more convenient location. 3. Perl5 This is a somewhat experimental implementation, but is alot less buggy than the alpha release. SWIG operates independently of the XS language and xsubpp supplied with Perl5. Currently SWIG produces the necessary C code and .pm file needed to dynamically load a module into Perl5. To support Perl5's notion of modules and packages (as with xsubpp), you can use the following command line options : % wrap -perl5 -module MyModule -package MyPackage example.i Note : In order for dynamic loading to be effective, you need to be careful about naming. For a module named "MyModule", you'll need to create a shared object file called "MyModule.so" using something like % ld -shared my_obj.o -o MyModule.so The use of the %init directive must match the module name since Perl5 calls a function "boot_ModuleName" in order to initialize things. See the Examples directory for some examples of how to get things to work. 4. Python1.3 This is the first release supporting Python. The Python port is experimental and may be rewritten. Variable linkage is done through functions which is sort of a kludge. I also think it would be nice to import SWIG pointers into Python as a new object (instead of strings). Of course, this needs a little more work. 5. Guile3 If you really want to live on the edge, pick up a copy of Guile-iii and play around with this. This is highly experimental---especially since I'm not sure what the official state of Guile is these days. This implementation may change at any time should I suddenly figure out better ways to do things. 6. Extending SWIG SWIG is written in C++ although I tend to think of the code as mostly being ANSI C with a little inheritance thrown in. Each target language is implemented as a C++ class that can be plugged into the system. If you want to add your own modifications, see Appendix C of the user manual. Then take a look at the "user" directory which contains some code for building your own extenions. 7. The SWIG library The SWIG library is still incomplete. Some of the files mentioned in the user manual are unavailable. These files will be made available when they are ready. Subscribe to the SWIG mailing list for announcements and updates. 8. SWIG Documentation I have sometimes experienced problems viewing the SWIG documentation in some postscript viewers. However, the documentation seems to print normally. I'm working on making much of the documentation online, but this takes time. Version 0.1 Alpha (February 9, 1996) ==================================== 1. Run-time type-checking of SWIG pointers. Pointers are now represented as strings with both numeric and encoded type information. This makes it a little harder to shoot yourself in the foot (and it eliminates some segmentation faults and other oddities). 2. Python 1.3 now supported. 3. #define and enum can be used to install constants. 4. Completely rewrote the %include directive and made it alot more powerful. 5. Restructured the SWIG library to make it work better. 6. Various bug fixes to Tcl, Perl4, Perl5, and Guile implementations. 7. Better implementation of %typedef directive. 8. Made some changes to SWIG's class structure to make it easier to expand. SWIG is now built into a library file that you can use to make your own extenions. 9. Made extensive changes to the documentation. 10. Minor changes to the SWIG parser to make it use less memory. Also took out some extraneous rules that were undocumented and didn't work in the first place. 11. The SWIG library files "tclsh", "wish", "expect", etc... in the first release have been restructured and renamed to "tclsh.i", "wish.i", and so on. cableswig-0.1.0+git20150808.orig/SWIG/LICENSE0000644000175000000620000000606412561312227016611 0ustar stevestaffSWIG is distributed under the following terms: I. This software includes contributions that are Copyright (c) 1998-2002 University of Chicago. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. Neither the name of the University of Chicago nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY OF CHICAGO AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OF CHICAGO OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. II. Copyright (c) 1995-1998 The University of Utah and the Regents of the University of California All Rights Reserved Permission is hereby granted, without written agreement and without license or royalty fees, to use, copy, modify, and distribute this software and its documentation for any purpose, provided that (1) The above copyright notice and the following two paragraphs appear in all copies of the source code and (2) redistributions including binaries reproduces these notices in the supporting documentation. Substantial modifications to this software may be copyrighted by their authors and need not follow the licensing terms described here, provided that the new terms are clearly indicated in all files where they apply. IN NO EVENT SHALL THE AUTHOR, THE UNIVERSITY OF CALIFORNIA, THE UNIVERSITY OF UTAH OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHOR, THE UNIVERSITY OF CALIFORNIA, AND THE UNIVERSITY OF UTAH SPECIFICALLY DISCLAIM ANY WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. cableswig-0.1.0+git20150808.orig/SWIG/vms/0002755000175000000620000000000012561312227016405 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/vms/build_swig.com0000755000175000000620000000004412561312227021234 0ustar stevestaff$ @swig_root:[vms.scripts]build_all cableswig-0.1.0+git20150808.orig/SWIG/vms/logicals.com0000755000175000000620000000077212561312227020711 0ustar stevestaff$! $! $! $ proc = f$environment("PROCEDURE") $ proc = f$parse(proc,"sys$disk:[]",,,"NO_CONCEAL") $ cur_dev = f$parse(proc,,,"DEVICE","SYNTAX_ONLY") $ cur_dir = f$parse(proc,,,"DIRECTORY","SYNTAX_ONLY") $ cur_dir = f$extract(1,f$length(cur_dir)-2,cur_dir) $ cur_dir = cur_dir - "[" $ cur_dir = cur_dir - "]" $ cur_dir = cur_dir - "<" $ cur_dir = cur_dir - ">" $ $! remove trealing .VMS $ root_dir = f$extract(0,f$length(cur_dir)-4,cur_dir) $ $ define 'p1' /trans=concealed swig_root 'cur_dev'['root_dir'.] cableswig-0.1.0+git20150808.orig/SWIG/vms/build_init.com0000755000175000000620000000053212561312227021230 0ustar stevestaff$ set def swig_root:[vms] $ $ swiglib = "swig_root:[vms.o_alpha]swig.olb $ $ if (f$search("swig_root:[vms]o_alpha.dir") .eqs. "") then $ - create/dir swig_root:[vms.o_alpha] $ $ copy swigconfig.h [-.source.include] $ copy swigver.h [-.source.include] $ $ if (f$search("''swiglib'") .eqs. "") then $ - library/create/object 'swiglib' $ cableswig-0.1.0+git20150808.orig/SWIG/vms/swigconfig.h0000644000175000000620000000012712561312227020713 0ustar stevestaff /* Note that this file has changed. TODO Get the latest from the original version. */ cableswig-0.1.0+git20150808.orig/SWIG/vms/genbuild.py0000644000175000000620000000772412561312227020560 0ustar stevestaffimport os.path, string, posix, pyvms # # IDIR = ['swig_root:[source.swig]', 'swig_root:[source.doh.include]', 'swig_root:[source.include]', 'swig_root:[source.preprocessor]'] def new_file(fg, dirname): global IDIR fn = 'swig_root:[vms.scripts]compil_' + os.path.basename(dirname) + '.com' print >> fg, '$ @' + fn f = open(fn, 'w') print >> f, '$!' print >> f, '$! Generated by genbuild.py' print >> f, '$!' print >> f, '$ libname = "swig_root:[vms.o_alpha]swig.olb"' print >> f, '$' print >> f, '$ set default', pyvms.crtl_to_vms(dirname)[0][0] print >> f, '$' print >> f, "$ idir := ", IDIR[0] for i in range(1, len(IDIR)): print >> f, '$ idir = idir + ",' + IDIR[i] + '"' print >> f, '$' print >> f, "$ iflags = \"/include=(''idir', sys$disk:[])\"" print >> f, '$ oflags = \"/object=swig_root:[vms.o_alpha]' print >> f, "$ cflags = \"''oflags'''iflags'''dflags'\"" print >> f, "$ cxxflags = \"''oflags'''iflags'''dflags'\"" print >> f, '$' return f def end_file(f): print >>f,"""$ exit $! $! $MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES $ V = 'F$Verify(0) $! P1 = What we are trying to make $! P2 = Command to make it $! P3 = Source file $! P4 - P8 What it depends on $ $ modname = f$parse(p3,,,"name") $ set noon $ set message/nofacility/noident/noseverity/notext $ libr/lis=swig_root:[vms]swiglib.tmp/full/width=132/only='modname' 'libname' $ set message/facility/ident/severity/text $ on error then exit $ open/read swigtmp swig_root:[vms]swiglib.tmp $! skip header $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $! $ $ read/end=module_not_found swigtmp r $ modfound = 1 $ Time = f$cvtime(f$extract(49, 20, r)) $ goto end_search_module $ module_not_found: $ modfound = 0 $ $ end_search_module: $ close swigtmp $ delete swig_root:[vms]swiglib.tmp;* $ $ if modfound .eq. 0 then $ goto Makeit $ $! Time = F$CvTime(F$File(P1,"RDT")) $arg=3 $Loop: $ Argument = P'arg $ If Argument .Eqs. "" Then Goto Exit $ El=0 $Loop2: $ File = F$Element(El," ",Argument) $ If File .Eqs. " " Then Goto Endl $ AFile = "" $Loop3: $ OFile = AFile $ AFile = F$Search(File) $ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl $ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit $ Goto Loop3 $NextEL: $ El = El + 1 $ Goto Loop2 $EndL: $ arg=arg+1 $ If arg .Le. 8 Then Goto Loop $ Goto Exit $ $Makeit: $ VV=F$VERIFY(1) $ 'P2' 'P3' $ VV='F$Verify(VV) $Exit: $ If V Then Set Verify $ENDSUBROUTINE""" def listRep(args, dirname, filenames): fg = args[0] first = 1 for fn in filenames: if fn[-2:] == '.c': if first: first = 0 fc = new_file(fg, dirname) cstr = "\"cc ''cflags'\" " line = "$ call make swig_root:[vms.o_alpha]" line += fn[:-1] + 'obj -' print >> fc, line line = "\t" + cstr + fn print >> fc, line elif fn[-4:] == '.cxx': if first: first = 0 fc = new_file(fg, dirname) cstr = "\"cxx ''cxxflags'\" " line = "$ call make swig_root:[vms.o_alpha]" line += fn[:-3] + 'obj -' print >> fc, line line = "\t" + cstr + fn print >> fc, line if first == 0: end_file(fc) fc.close() # def genbuild(f, dir): os.path.walk(dir, listRep, (f,)) cmd = 'set default swig_root:[vms]' # f = open('swig_root:[vms.scripts]build_all.com','w') print >> f, '$!' print >> f, '$! Generated by genbuild.py' print >> f, '$!' print >> f, '$ set default swig_root:[vms]' print >> f, '$' print >> f, '$ @swig_root:[vms]build_init' # genbuild(f, '/swig_root/source') print >> f, '$' print >> f, '$ set default swig_root:[vms]' print >> f, '$' print >> f, '$ @swig_root:[vms]build_end' f.close cableswig-0.1.0+git20150808.orig/SWIG/vms/build_end.com0000755000175000000620000000112412561312227021031 0ustar stevestaff$ set def swig_root:[vms] $ $ file = f$search("swig_root:[vms.o_alpha]*.obj") $ newobj = 0 $ if file .nes. "" $ then $ v = f$verify(1) $ library/replace swig_root:[vms.o_alpha]swig.olb swig_root:[vms.o_alpha]*.obj $ delete swig_root:[vms.o_alpha]*.obj;* $ v = f$verify(v) $ newobj = 1 $ endif $ file = f$search("swig_root:[vms]swig.exe") $ if file .eqs. "" .or. newobj $ then $ v = f$verify(1) $ cxxlink/exe=swig_root:[vms]swig.exe - /repo=swig_root:[source.modules1_1.cxx_repository] - swig_root:[vms.o_alpha]swig.olb/include=swigmain $ v = f$verify(v) $ endif cableswig-0.1.0+git20150808.orig/SWIG/vms/scripts/0002755000175000000620000000000012561312227020074 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/vms/scripts/compil_cparse.com0000755000175000000620000000451112561312227023416 0ustar stevestaff$! $! Generated by genbuild.py $! $ libname = "swig_root:[vms.o_alpha]swig.olb" $ $ set default SWIG_ROOT:[SOURCE.CPARSE] $ $ idir := swig_root:[source.swig] $ idir = idir + ",swig_root:[source.doh.include]" $ idir = idir + ",swig_root:[source.include]" $ idir = idir + ",swig_root:[source.preprocessor]" $ $ iflags = "/include=(''idir', sys$disk:[])" $ oflags = "/object=swig_root:[vms.o_alpha] $ cflags = "''oflags'''iflags'''dflags'" $ cxxflags = "''oflags'''iflags'''dflags'" $ $ call make swig_root:[vms.o_alpha]cscanner.obj - "cc ''cflags'" cscanner.c $ call make swig_root:[vms.o_alpha]parser.obj - "cc ''cflags'" parser.c $ call make swig_root:[vms.o_alpha]templ.obj - "cc ''cflags'" templ.c $ call make swig_root:[vms.o_alpha]util.obj - "cc ''cflags'" util.c $ exit $! $! $MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES $ V = 'F$Verify(0) $! P1 = What we are trying to make $! P2 = Command to make it $! P3 = Source file $! P4 - P8 What it depends on $ $ modname = f$parse(p3,,,"name") $ set noon $ set message/nofacility/noident/noseverity/notext $ libr/lis=swig_root:[vms]swiglib.tmp/full/width=132/only='modname' 'libname' $ set message/facility/ident/severity/text $ on error then exit $ open/read swigtmp swig_root:[vms]swiglib.tmp $! skip header $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $! $ $ read/end=module_not_found swigtmp r $ modfound = 1 $ Time = f$cvtime(f$extract(49, 20, r)) $ goto end_search_module $ module_not_found: $ modfound = 0 $ $ end_search_module: $ close swigtmp $ delete swig_root:[vms]swiglib.tmp;* $ $ if modfound .eq. 0 then $ goto Makeit $ $! Time = F$CvTime(F$File(P1,"RDT")) $arg=3 $Loop: $ Argument = P'arg $ If Argument .Eqs. "" Then Goto Exit $ El=0 $Loop2: $ File = F$Element(El," ",Argument) $ If File .Eqs. " " Then Goto Endl $ AFile = "" $Loop3: $ OFile = AFile $ AFile = F$Search(File) $ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl $ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit $ Goto Loop3 $NextEL: $ El = El + 1 $ Goto Loop2 $EndL: $ arg=arg+1 $ If arg .Le. 8 Then Goto Loop $ Goto Exit $ $Makeit: $ VV=F$VERIFY(1) $ 'P2' 'P3' $ VV='F$Verify(VV) $Exit: $ If V Then Set Verify $ENDSUBROUTINE cableswig-0.1.0+git20150808.orig/SWIG/vms/scripts/build_all.com0000755000175000000620000000057612561312227022534 0ustar stevestaff$! $! Generated by genbuild.py $! $ set default swig_root:[vms] $ $ @swig_root:[vms]build_init $ @swig_root:[vms.scripts]compil_cparse.com $ @swig_root:[vms.scripts]compil_doh.com $ @swig_root:[vms.scripts]compil_modules1_1.com $ @swig_root:[vms.scripts]compil_preprocessor.com $ @swig_root:[vms.scripts]compil_swig.com $ $ set default swig_root:[vms] $ $ @swig_root:[vms]build_end cableswig-0.1.0+git20150808.orig/SWIG/vms/scripts/compil_doh.com0000755000175000000620000000512612561312227022716 0ustar stevestaff$! $! Generated by genbuild.py $! $ libname = "swig_root:[vms.o_alpha]swig.olb" $ $ set default SWIG_ROOT:[SOURCE.DOH.DOH] $ $ idir := swig_root:[source.swig] $ idir = idir + ",swig_root:[source.doh.include]" $ idir = idir + ",swig_root:[source.include]" $ idir = idir + ",swig_root:[source.preprocessor]" $ $ iflags = "/include=(''idir', sys$disk:[])" $ oflags = "/object=swig_root:[vms.o_alpha] $ cflags = "''oflags'''iflags'''dflags'" $ cxxflags = "''oflags'''iflags'''dflags'" $ $ call make swig_root:[vms.o_alpha]base.obj - "cc ''cflags'" base.c $ call make swig_root:[vms.o_alpha]file.obj - "cc ''cflags'" file.c $ call make swig_root:[vms.o_alpha]fio.obj - "cc ''cflags'" fio.c $ call make swig_root:[vms.o_alpha]hash.obj - "cc ''cflags'" hash.c $ call make swig_root:[vms.o_alpha]list.obj - "cc ''cflags'" list.c $ call make swig_root:[vms.o_alpha]memory.obj - "cc ''cflags'" memory.c $ call make swig_root:[vms.o_alpha]string.obj - "cc ''cflags'" string.c $ call make swig_root:[vms.o_alpha]void.obj - "cc ''cflags'" void.c $ exit $! $! $MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES $ V = 'F$Verify(0) $! P1 = What we are trying to make $! P2 = Command to make it $! P3 = Source file $! P4 - P8 What it depends on $ $ modname = f$parse(p3,,,"name") $ set noon $ set message/nofacility/noident/noseverity/notext $ libr/lis=swig_root:[vms]swiglib.tmp/full/width=132/only='modname' 'libname' $ set message/facility/ident/severity/text $ on error then exit $ open/read swigtmp swig_root:[vms]swiglib.tmp $! skip header $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $! $ $ read/end=module_not_found swigtmp r $ modfound = 1 $ Time = f$cvtime(f$extract(49, 20, r)) $ goto end_search_module $ module_not_found: $ modfound = 0 $ $ end_search_module: $ close swigtmp $ delete swig_root:[vms]swiglib.tmp;* $ $ if modfound .eq. 0 then $ goto Makeit $ $! Time = F$CvTime(F$File(P1,"RDT")) $arg=3 $Loop: $ Argument = P'arg $ If Argument .Eqs. "" Then Goto Exit $ El=0 $Loop2: $ File = F$Element(El," ",Argument) $ If File .Eqs. " " Then Goto Endl $ AFile = "" $Loop3: $ OFile = AFile $ AFile = F$Search(File) $ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl $ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit $ Goto Loop3 $NextEL: $ El = El + 1 $ Goto Loop2 $EndL: $ arg=arg+1 $ If arg .Le. 8 Then Goto Loop $ Goto Exit $ $Makeit: $ VV=F$VERIFY(1) $ 'P2' 'P3' $ VV='F$Verify(VV) $Exit: $ If V Then Set Verify $ENDSUBROUTINE cableswig-0.1.0+git20150808.orig/SWIG/vms/scripts/compil_modules1_1.com0000755000175000000620000000717712561312227024125 0ustar stevestaff$! $! Generated by genbuild.py $! $ libname = "swig_root:[vms.o_alpha]swig.olb" $ $ set default SWIG_ROOT:[SOURCE.MODULES1_1] $ $ idir := swig_root:[source.swig] $ idir = idir + ",swig_root:[source.doh.include]" $ idir = idir + ",swig_root:[source.include]" $ idir = idir + ",swig_root:[source.preprocessor]" $ $ iflags = "/include=(''idir', sys$disk:[])" $ oflags = "/object=swig_root:[vms.o_alpha] $ cflags = "''oflags'''iflags'''dflags'" $ cxxflags = "''oflags'''iflags'''dflags'" $ $ call make swig_root:[vms.o_alpha]allocate.obj - "cxx ''cxxflags'" allocate.cxx $ call make swig_root:[vms.o_alpha]browser.obj - "cxx ''cxxflags'" browser.cxx $ call make swig_root:[vms.o_alpha]contract.obj - "cxx ''cxxflags'" contract.cxx $ call make swig_root:[vms.o_alpha]emit.obj - "cxx ''cxxflags'" emit.cxx $ call make swig_root:[vms.o_alpha]guile.obj - "cxx ''cxxflags'" guile.cxx $ call make swig_root:[vms.o_alpha]java.obj - "cxx ''cxxflags'" java.cxx $ call make swig_root:[vms.o_alpha]lang.obj - "cxx ''cxxflags'" lang.cxx $ call make swig_root:[vms.o_alpha]main.obj - "cxx ''cxxflags'" main.cxx $ call make swig_root:[vms.o_alpha]module.obj - "cxx ''cxxflags'" module.cxx $ call make swig_root:[vms.o_alpha]mzscheme.obj - "cxx ''cxxflags'" mzscheme.cxx $ call make swig_root:[vms.o_alpha]ocaml.obj - "cxx ''cxxflags'" ocaml.cxx $ call make swig_root:[vms.o_alpha]overload.obj - "cxx ''cxxflags'" overload.cxx $ call make swig_root:[vms.o_alpha]perl5.obj - "cxx ''cxxflags'" perl5.cxx $ call make swig_root:[vms.o_alpha]php4.obj - "cxx ''cxxflags'" php4.cxx $ call make swig_root:[vms.o_alpha]pike.obj - "cxx ''cxxflags'" pike.cxx $ call make swig_root:[vms.o_alpha]python.obj - "cxx ''cxxflags'" python.cxx $ call make swig_root:[vms.o_alpha]ruby.obj - "cxx ''cxxflags'" ruby.cxx $ call make swig_root:[vms.o_alpha]swigmain.obj - "cxx ''cxxflags'" swigmain.cxx $ call make swig_root:[vms.o_alpha]tcl8.obj - "cxx ''cxxflags'" tcl8.cxx $ call make swig_root:[vms.o_alpha]typepass.obj - "cxx ''cxxflags'" typepass.cxx $ call make swig_root:[vms.o_alpha]xml.obj - "cxx ''cxxflags'" xml.cxx $ exit $! $! $MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES $ V = 'F$Verify(0) $! P1 = What we are trying to make $! P2 = Command to make it $! P3 = Source file $! P4 - P8 What it depends on $ $ modname = f$parse(p3,,,"name") $ set noon $ set message/nofacility/noident/noseverity/notext $ libr/lis=swig_root:[vms]swiglib.tmp/full/width=132/only='modname' 'libname' $ set message/facility/ident/severity/text $ on error then exit $ open/read swigtmp swig_root:[vms]swiglib.tmp $! skip header $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $! $ $ read/end=module_not_found swigtmp r $ modfound = 1 $ Time = f$cvtime(f$extract(49, 20, r)) $ goto end_search_module $ module_not_found: $ modfound = 0 $ $ end_search_module: $ close swigtmp $ delete swig_root:[vms]swiglib.tmp;* $ $ if modfound .eq. 0 then $ goto Makeit $ $! Time = F$CvTime(F$File(P1,"RDT")) $arg=3 $Loop: $ Argument = P'arg $ If Argument .Eqs. "" Then Goto Exit $ El=0 $Loop2: $ File = F$Element(El," ",Argument) $ If File .Eqs. " " Then Goto Endl $ AFile = "" $Loop3: $ OFile = AFile $ AFile = F$Search(File) $ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl $ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit $ Goto Loop3 $NextEL: $ El = El + 1 $ Goto Loop2 $EndL: $ arg=arg+1 $ If arg .Le. 8 Then Goto Loop $ Goto Exit $ $Makeit: $ VV=F$VERIFY(1) $ 'P2' 'P3' $ VV='F$Verify(VV) $Exit: $ If V Then Set Verify $ENDSUBROUTINE cableswig-0.1.0+git20150808.orig/SWIG/vms/scripts/compil_preprocessor.com0000755000175000000620000000426512561312227024675 0ustar stevestaff$! $! Generated by genbuild.py $! $ libname = "swig_root:[vms.o_alpha]swig.olb" $ $ set default SWIG_ROOT:[SOURCE.PREPROCESSOR] $ $ idir := swig_root:[source.swig] $ idir = idir + ",swig_root:[source.doh.include]" $ idir = idir + ",swig_root:[source.include]" $ idir = idir + ",swig_root:[source.preprocessor]" $ $ iflags = "/include=(''idir', sys$disk:[])" $ oflags = "/object=swig_root:[vms.o_alpha] $ cflags = "''oflags'''iflags'''dflags'" $ cxxflags = "''oflags'''iflags'''dflags'" $ $ call make swig_root:[vms.o_alpha]cpp.obj - "cc ''cflags'" cpp.c $ call make swig_root:[vms.o_alpha]expr.obj - "cc ''cflags'" expr.c $ exit $! $! $MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES $ V = 'F$Verify(0) $! P1 = What we are trying to make $! P2 = Command to make it $! P3 = Source file $! P4 - P8 What it depends on $ $ modname = f$parse(p3,,,"name") $ set noon $ set message/nofacility/noident/noseverity/notext $ libr/lis=swig_root:[vms]swiglib.tmp/full/width=132/only='modname' 'libname' $ set message/facility/ident/severity/text $ on error then exit $ open/read swigtmp swig_root:[vms]swiglib.tmp $! skip header $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $! $ $ read/end=module_not_found swigtmp r $ modfound = 1 $ Time = f$cvtime(f$extract(49, 20, r)) $ goto end_search_module $ module_not_found: $ modfound = 0 $ $ end_search_module: $ close swigtmp $ delete swig_root:[vms]swiglib.tmp;* $ $ if modfound .eq. 0 then $ goto Makeit $ $! Time = F$CvTime(F$File(P1,"RDT")) $arg=3 $Loop: $ Argument = P'arg $ If Argument .Eqs. "" Then Goto Exit $ El=0 $Loop2: $ File = F$Element(El," ",Argument) $ If File .Eqs. " " Then Goto Endl $ AFile = "" $Loop3: $ OFile = AFile $ AFile = F$Search(File) $ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl $ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit $ Goto Loop3 $NextEL: $ El = El + 1 $ Goto Loop2 $EndL: $ arg=arg+1 $ If arg .Le. 8 Then Goto Loop $ Goto Exit $ $Makeit: $ VV=F$VERIFY(1) $ 'P2' 'P3' $ VV='F$Verify(VV) $Exit: $ If V Then Set Verify $ENDSUBROUTINE cableswig-0.1.0+git20150808.orig/SWIG/vms/scripts/compil_swig.com0000755000175000000620000000626112561312227023116 0ustar stevestaff$! $! Generated by genbuild.py $! $ libname = "swig_root:[vms.o_alpha]swig.olb" $ $ set default SWIG_ROOT:[SOURCE.SWIG] $ $ idir := swig_root:[source.swig] $ idir = idir + ",swig_root:[source.doh.include]" $ idir = idir + ",swig_root:[source.include]" $ idir = idir + ",swig_root:[source.preprocessor]" $ $ iflags = "/include=(''idir', sys$disk:[])" $ oflags = "/object=swig_root:[vms.o_alpha] $ cflags = "''oflags'''iflags'''dflags'" $ cxxflags = "''oflags'''iflags'''dflags'" $ $ call make swig_root:[vms.o_alpha]cwrap.obj - "cc ''cflags'" cwrap.c $ call make swig_root:[vms.o_alpha]error.obj - "cc ''cflags'" error.c $ call make swig_root:[vms.o_alpha]fragment.obj - "cc ''cflags'" fragment.c $ call make swig_root:[vms.o_alpha]getopt.obj - "cc ''cflags'" getopt.c $ call make swig_root:[vms.o_alpha]include.obj - "cc ''cflags'" include.c $ call make swig_root:[vms.o_alpha]misc.obj - "cc ''cflags'" misc.c $ call make swig_root:[vms.o_alpha]naming.obj - "cc ''cflags'" naming.c $ call make swig_root:[vms.o_alpha]parms.obj - "cc ''cflags'" parms.c $ call make swig_root:[vms.o_alpha]scanner.obj - "cc ''cflags'" scanner.c $ call make swig_root:[vms.o_alpha]stype.obj - "cc ''cflags'" stype.c $ call make swig_root:[vms.o_alpha]symbol.obj - "cc ''cflags'" symbol.c $ call make swig_root:[vms.o_alpha]tree.obj - "cc ''cflags'" tree.c $ call make swig_root:[vms.o_alpha]typemap.obj - "cc ''cflags'" typemap.c $ call make swig_root:[vms.o_alpha]typesys.obj - "cc ''cflags'" typesys.c $ call make swig_root:[vms.o_alpha]warn.obj - "cc ''cflags'" warn.c $ call make swig_root:[vms.o_alpha]wrapfunc.obj - "cc ''cflags'" wrapfunc.c $ exit $! $! $MAKE: SUBROUTINE !SUBROUTINE TO CHECK DEPENDENCIES $ V = 'F$Verify(0) $! P1 = What we are trying to make $! P2 = Command to make it $! P3 = Source file $! P4 - P8 What it depends on $ $ modname = f$parse(p3,,,"name") $ set noon $ set message/nofacility/noident/noseverity/notext $ libr/lis=swig_root:[vms]swiglib.tmp/full/width=132/only='modname' 'libname' $ set message/facility/ident/severity/text $ on error then exit $ open/read swigtmp swig_root:[vms]swiglib.tmp $! skip header $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $ read swigtmp r $! $ $ read/end=module_not_found swigtmp r $ modfound = 1 $ Time = f$cvtime(f$extract(49, 20, r)) $ goto end_search_module $ module_not_found: $ modfound = 0 $ $ end_search_module: $ close swigtmp $ delete swig_root:[vms]swiglib.tmp;* $ $ if modfound .eq. 0 then $ goto Makeit $ $! Time = F$CvTime(F$File(P1,"RDT")) $arg=3 $Loop: $ Argument = P'arg $ If Argument .Eqs. "" Then Goto Exit $ El=0 $Loop2: $ File = F$Element(El," ",Argument) $ If File .Eqs. " " Then Goto Endl $ AFile = "" $Loop3: $ OFile = AFile $ AFile = F$Search(File) $ If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl $ If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit $ Goto Loop3 $NextEL: $ El = El + 1 $ Goto Loop2 $EndL: $ arg=arg+1 $ If arg .Le. 8 Then Goto Loop $ Goto Exit $ $Makeit: $ VV=F$VERIFY(1) $ 'P2' 'P3' $ VV='F$Verify(VV) $Exit: $ If V Then Set Verify $ENDSUBROUTINE cableswig-0.1.0+git20150808.orig/SWIG/vms/aaareadme.txt0000644000175000000620000000064212561312227021046 0ustar stevestaffPort on OpenVMS 7.3 using CC 6.5 and CXX 6.5 Building procedure: $ @logicals $ @build_all the logicals swig_root is defined by the procedure logicals.com. The logicals.com procedure can be invoke with an optional argument for the define command, for example: $ @logicals "/system/exec" genbuild.py is the python program use to generate all the procedures in the [vms.scripts] directory. jf.pieronne@laposte.net cableswig-0.1.0+git20150808.orig/SWIG/Lib/0002755000175000000620000000000012561312227016306 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Lib/python/0002755000175000000620000000000012561312227017627 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Lib/python/pythonkw.swg0000644000175000000620000000366312561312227022242 0ustar stevestaff/* Warnings for Python keywords, built-in names and bad names. */ #define PYTHONKW(x) %namewarn("314:" #x " is a python keyword") #x #define PYTHONBN(x) %namewarn("321:" #x " conflicts with a built-in name in python") "::"#x /* Warnings for Python keywords http://www.fnorb.org/docs/1.2/Fnorb-Guide/node62.html */ PYTHONKW(and); PYTHONKW(assert); PYTHONKW(break); PYTHONKW(class); PYTHONKW(continue); PYTHONKW(def); PYTHONKW(del); PYTHONKW(elif); PYTHONKW(else); PYTHONKW(except); PYTHONKW(exec); PYTHONKW(finally); PYTHONKW(for); PYTHONKW(from); PYTHONKW(global); PYTHONKW(if); PYTHONKW(import); PYTHONKW(in); PYTHONKW(is); PYTHONKW(lambda); PYTHONKW(not); PYTHONKW(or); PYTHONKW(pass); PYTHONKW(print); PYTHONKW(raise); PYTHONKW(return); PYTHONKW(try); PYTHONKW(while); PYTHONKW(yield); /* built-in functions http://www.zvon.org/other/python/doc21/lib/built-in-funcs.html */ PYTHONBN(abs); PYTHONBN(apply); PYTHONBN(buffer); PYTHONBN(callable); PYTHONBN(chr); PYTHONBN(cmp); PYTHONBN(coerce); PYTHONBN(compile); PYTHONBN(complex); PYTHONBN(delattr); PYTHONBN(dir); PYTHONBN(divmod); PYTHONBN(eval); PYTHONBN(execfile); PYTHONBN(filter); PYTHONBN(float); PYTHONBN(getattr); PYTHONBN(globals); PYTHONBN(hasattr); PYTHONBN(hash); PYTHONBN(hex); PYTHONBN(id); PYTHONBN(input); PYTHONBN(int); PYTHONBN(intern); PYTHONBN(isinstance); PYTHONBN(issubclass); PYTHONBN(len); PYTHONBN(list); PYTHONBN(locals); PYTHONBN(long); PYTHONBN(map); PYTHONBN(max); PYTHONBN(min); PYTHONBN(oct); PYTHONBN(open); PYTHONBN(ord); PYTHONBN(pow); PYTHONBN(range); PYTHONBN(raw_input); PYTHONBN(reduce); PYTHONBN(reload); PYTHONBN(repr); PYTHONBN(round); PYTHONBN(setattr); PYTHONBN(slice); PYTHONBN(str); PYTHONBN(tuple); PYTHONBN(type); PYTHONBN(vars); PYTHONBN(xrange); PYTHONBN(zip); /* built-in names boolean type and None */ PYTHONBN(True); PYTHONBN(False); PYTHONBN(None); /* 'self' is also a bad Name */ PYTHONBN(self); #undef PYTHONBN #undef PYTHONKW cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/pyopers.swg0000644000175000000620000000347212561312227022056 0ustar stevestaff/* ------------------------------------------------------------ * Overloaded operator support * ------------------------------------------------------------ */ #ifdef __cplusplus %rename(__add__) *::operator+; %rename(__pos__) *::operator+(); %rename(__pos__) *::operator+() const; %rename(__sub__) *::operator-; %rename(__neg__) *::operator-(); %rename(__neg__) *::operator-() const; %rename(__mul__) *::operator*; %rename(__div__) *::operator/; %rename(__mod__) *::operator%; %rename(__lshift__) *::operator<<; %rename(__rshift__) *::operator>>; %rename(__and__) *::operator&; %rename(__or__) *::operator|; %rename(__xor__) *::operator^; %rename(__invert__) *::operator~; %rename(__iadd__) *::operator+=; %rename(__isub__) *::operator-=; %rename(__imul__) *::operator*=; %rename(__idiv__) *::operator/=; %rename(__imod__) *::operator%=; %rename(__ilshift__) *::operator<<=; %rename(__irshift__) *::operator>>=; %rename(__iand__) *::operator&=; %rename(__ior__) *::operator|=; %rename(__ixor__) *::operator^=; %rename(__lt__) *::operator<; %rename(__le__) *::operator<=; %rename(__gt__) *::operator>; %rename(__ge__) *::operator>=; %rename(__eq__) *::operator==; %rename(__ne__) *::operator!=; /* Special cases */ %rename(__call__) *::operator(); /* Ignored operators */ %ignorewarn("362:operator= ignored") operator=; %ignorewarn("383:operator++ ignored") operator++; %ignorewarn("384:operator-- ignored") operator--; %ignorewarn("361:operator! ignored") operator!; %ignorewarn("381:operator&& ignored") operator&&; %ignorewarn("382:operator|| ignored") operator||; %ignorewarn("386:operator->* ignored") operator->*; %ignorewarn("389:operator[] ignored (consider using %extend)") operator[]; #endif cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/std_list.i0000644000175000000620000001160012561312227021622 0ustar stevestaff// // SWIG typemaps for std::list types // Jing Cao // Aug 1st, 2002 // // Python implementation %module std_list %{ #include #include %} %include "exception.i" %exception std::list::__getitem__ { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::list::__setitem__ { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::list::__delitem__ { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } namespace std{ template class list { public: typedef T &reference; typedef const T& const_reference; typedef T &iterator; typedef const T& const_iterator; list(); list(unsigned int size, const T& value = T()); list(const list &); ~list(); void assign(unsigned int n, const T& value); void swap(list &x); const_reference front(); const_reference back(); const_iterator begin(); const_iterator end(); void resize(unsigned int n, T c = T()); bool empty() const; void push_front(const T& x); void push_back(const T& x); void pop_front(); void pop_back(); void clear(); unsigned int size() const; unsigned int max_size() const; void resize(unsigned int n, const T& value); void remove(const T& value); void unique(); void reverse(); void sort(); %extend { const_reference __getitem__(int i) { std::list::iterator first = self->begin(); int size = int(self->size()); if (i<0) i += size; if (i>=0 && i::iterator first = self->begin(); int size = int(self->size()); if (i<0) i += size; if (i>=0 && i::iterator first = self->begin(); int size = int(self->size()); if (i<0) i += size; if (i>=0 && ierase(first); } else throw std::out_of_range("list index out of range"); } std::list __getslice__(int i,int j) { std::list::iterator first = self->begin(); std::list::iterator end = self->end(); int size = int(self->size()); if (i<0) i += size; if (j<0) j += size; if (i<0) i = 0; if (j>size) j = size; if (i>=j) i=j; if (i>=0 && i=0) { for (int k=0;k tmp(j-i); if (j>i) std::copy(first,end,tmp.begin()); return tmp; } else throw std::out_of_range("list index out of range"); } void __delslice__(int i,int j) { std::list::iterator first = self->begin(); std::list::iterator end = self->end(); int size = int(self->size()); if (i<0) i += size; if (j<0) j += size; if (i<0) i = 0; if (j>size) j = size; for (int k=0;kerase(first,end); } void __setslice__(int i,int j, const std::list& v) { std::list::iterator first = self->begin(); std::list::iterator end = self->end(); int size = int(self->size()); if (i<0) i += size; if (j<0) j += size; if (i<0) i = 0; if (j>size) j = size; for (int k=0;kerase(first,end); if (i+1 <= int(self->size())) { first = self->begin(); for (int k=0;kinsert(first,v.begin(),v.end()); } else self->insert(self->end(),v.begin(),v.end()); } } unsigned int __len__() { return self->size(); } bool __nonzero__() { return !(self->empty()); } void append(const T& x) { self->push_back(x); } void pop() { self->pop_back(); } }; }; } cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/std_string.i0000644000175000000620000000336712561312227022170 0ustar stevestaff// // SWIG typemaps for std::string // Luigi Ballabio // Apr 8, 2002 // // Python implementation // ------------------------------------------------------------------------ // std::string is typemapped by value // This can prevent exporting methods which return a string // in order for the user to modify it. // However, I think I'll wait until someone asks for it... // ------------------------------------------------------------------------ %{ #include %} /* defining the std::string as/from/check methods */ %fragment("SWIG_TryStdString","header", fragment="SWIG_AsCharPtrAndSize") %{ SWIGSTATICINLINE(int) SWIG_TryStdString(PyObject* obj, char*& buf, size_t& size) { SWIG_AsCharPtrAndSize(obj, &buf, &size); if (PyErr_Occurred() || !buf) { if (PyErr_Occurred()) PyErr_Clear(); return 0; } return 1; } %} %fragment("SWIG_CheckStdString","header", fragment="SWIG_TryStdString") %{ SWIGSTATICINLINE(int) SWIG_CheckStdString(PyObject* obj) { char* buf = 0 ; size_t size = 0; return SWIG_TryStdString(obj, buf, size); } SWIGSTATICINLINE(std::string) SWIG_AsStdString(PyObject* obj) { char* buf = 0 ; size_t size = 0; if (SWIG_TryStdString(obj, buf, size)) { return std::string(buf, size); } else { PyErr_SetString(PyExc_TypeError,"a string is expected"); return std::string(); } } %} %fragment("SWIG_AsStdString","header", fragment="SWIG_TryStdString") %{ %} %fragment("SWIG_FromStdString","header", fragment="SWIG_FromCharArray") %{ SWIGSTATICINLINE(PyObject*) SWIG_FromStdString(const std::string& s) { return SWIG_FromCharArray(s.data(), s.size()); } %} /* declaring the typemaps */ %typemap_asfromcheck(std::string, STRING, SWIG_AsStdString, SWIG_FromStdString, SWIG_CheckStdString); cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/pymisctypes.swg0000644000175000000620000000077712561312227022753 0ustar stevestaff /* ------------------------------------------------------------ * --- ANSI/Posix C/C++ types --- * ------------------------------------------------------------ */ %apply unsigned long { size_t }; %apply const unsigned long& { const size_t& }; %apply long { ptrdiff_t }; %apply const long& { const ptrdiff_t& }; #ifdef __cplusplus %apply unsigned long { std::size_t }; %apply const unsigned long& { const std::size_t& }; %apply long { std::ptrdiff_t }; %apply const long& { const std::ptrdiff_t& }; #endif cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/pystrings.swg0000644000175000000620000002343312561312227022416 0ustar stevestaff /* ------------------------------------------------------------ * utility methods for strings handling * ------------------------------------------------------------ */ %types(char *); %fragment("SWIG_AsCharPtrAndSize","header") %{ /* returns '1' if the input is a raw char*, '0' if is a PyString */ SWIGSTATIC(int) SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* size) { static swig_type_info* pchar_info = 0; #if defined(PY_SSIZE_T_MAX) Py_ssize_t psize = 0; #else int psize = 0; #endif if (!pchar_info) pchar_info = SWIG_TypeQuery("char *"); if (SWIG_ConvertPtr(obj, swig_reinterpret_cast(void **,cptr), pchar_info, 0) == -1) { PyErr_Clear(); PyString_AsStringAndSize(obj, cptr, &psize); if (PyErr_Occurred()) { PyErr_Clear(); PyErr_SetString(PyExc_TypeError,"a string is expected"); } if (size) *size = psize; return 0; } else { if (size) *size = (*cptr) ? (strlen(*cptr) + 1) : 0; return 1; } } %} %fragment("SWIG_AsCharPtr","header", fragment="SWIG_AsCharPtrAndSize") %{ SWIGSTATICINLINE(char* ) SWIG_AsCharPtr(PyObject *obj) { char* cptr; SWIG_AsCharPtrAndSize(obj, &cptr, 0); if (PyErr_Occurred()) { PyErr_Clear(); PyErr_SetString(PyExc_TypeError, "a char* is expected"); } return cptr; } %} %fragment("SWIG_FromCharPtr","header") %{ SWIGSTATICINLINE(PyObject *) SWIG_FromCharPtr(const char* cptr) { size_t size = cptr ? strlen(cptr) : 0; if (cptr) { if (size > INT_MAX) { return SWIG_NewPointerObj(swig_const_cast(char*,cptr), SWIG_TypeQuery("char *"), 0); } else { return PyString_FromStringAndSize(cptr, swig_numeric_cast(int,size)); } } else { Py_INCREF(Py_None); return Py_None; } } %} %fragment("SWIG_AsNewCharPtr","header", fragment="SWIG_AsCharPtrAndSize") %{ SWIGSTATIC(char*) SWIG_AsNewCharPtr(PyObject *obj) { char *res = 0; char* cptr; size_t csize; int is_raw_pchar = SWIG_AsCharPtrAndSize(obj, &cptr, &csize); if (PyErr_Occurred()) { PyErr_Clear(); PyErr_SetString(PyExc_TypeError, "a char* is expected"); } else if (cptr) { /* we add the '0' terminator if needed */ size_t size = (!is_raw_pchar && csize && !(cptr[csize - 1])) ? csize : csize + 1; if (size) { res = swig_new_array(char, size); if (csize) memcpy(res, cptr, csize); if (csize < size) res[csize] = 0; } } return res; } %} %fragment("SWIG_AsCharArray","header", fragment="SWIG_AsCharPtrAndSize") %{ SWIGSTATIC(void) SWIG_AsCharArray(PyObject *obj, char* carray, size_t size) { char* cptr; size_t csize; SWIG_AsCharPtrAndSize(obj, &cptr, &csize); if (PyErr_Occurred()) { PyErr_Clear(); PyObject *err = PyString_FromFormat("a char array of size %d is expected", size); PyErr_SetObject(PyExc_TypeError, err); Py_DECREF(err); } else { /* in C (but not in C++) you can do: char x[5] = "hello"; ie, assing the array using an extra '0' char. */ #ifndef __cplusplus if ((csize == size + 1) && !(cptr[csize-1])) --csize; #endif if (csize > size) { PyObject *err = PyString_FromFormat("a char array of maximum size %d is expected", size); PyErr_SetObject(PyExc_TypeError, err); Py_DECREF(err); } else { if (csize) memcpy(carray, cptr, csize); if (csize < size) memset(carray + csize, 0, size - csize); } } } %} %fragment("SWIG_FromCharArray","header") %{ SWIGSTATICINLINE(PyObject *) SWIG_FromCharArray(const char* carray, size_t size) { if (size > INT_MAX) { SWIG_NewPointerObj(swig_const_cast(char*,carray), SWIG_TypeQuery("char *"), 0); return Py_None; } else { return PyString_FromStringAndSize(carray, swig_numeric_cast(int,size)); } } %} /* ------------------------------------------------------------ * The plain char * handling * ------------------------------------------------------------ */ /* in */ %typemap(in,fragment="SWIG_AsCharPtr") char *, char const*, char *const, char const *const "$1 = SWIG_AsCharPtr($input); if (PyErr_Occurred()) SWIG_fail;"; %typemap(in,fragment="SWIG_AsCharPtr") char const*&, char *const&, char const *const & { $*ltype temp = SWIG_AsCharPtr($input); if (PyErr_Occurred()) SWIG_fail; $1 = &temp; } /* out */ %typemap(out,fragment="SWIG_FromCharPtr") char *, char const*, char *const, char const *const "$result = SWIG_FromCharPtr($1);"; %typemap(out,fragment="SWIG_FromCharPtr") char *const &, char const* &, char const *const & "$result = SWIG_FromCharPtr(*$1);"; /* varin */ %typemap(varin,fragment="SWIG_AsNewCharPtr") char * { char *cptr = SWIG_AsNewCharPtr($input); if (PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); return 1; } if ($1) swig_delete_array($1); $1 = cptr; } %typemap(varin,fragment="SWIG_AsNewCharPtr", warning="451:Setting const char * variable may leak memory") const char * { char *cptr = SWIG_AsNewCharPtr($input); if (PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); return 1; } $1 = cptr; } /* varout */ %typemap(varout,fragment="SWIG_FromCharPtr") char*, char const*, char *const, char const *const "$result = SWIG_FromCharPtr($1);"; /* constant */ %typemap(constcode,fragment="SWIG_FromCharPtr") char *, char const*, char * const, char const* const "PyDict_SetItemString(d,\"$symname\", SWIG_FromCharPtr($value));"; /* directorin */ %typemap(directorin,fragment="SWIG_FromCharPtr") char *, char const*, char *const, char const *const, char const *&, char *const &, char const *const & "$input = SWIG_NewPointerObj(swig_const_cast(char*,$1_name), $descriptor(char *), 0);" /* "$input = SWIG_FromCharPtr($1_name);"; */ /* directorout */ %typemap(directorout,fragment="SWIG_AsCharPtr") char *, char const*, char *const, char const* const "$result = SWIG_AsCharPtr($input); if (PyErr_Occurred()) { Swig::DirectorTypeMismatchException(\"Error converting Python object into char*\"); }"; %typemap(directorout,fragment="SWIG_AsCharPtr") char const *&, char *const &, char const *const & { char* temp = SWIG_AsCharPtr($input); if (PyErr_Occurred()) { Swig::DirectorTypeMismatchException("Error converting Python object into char*"); } $result = ($1_ltype) &temp; } /* typecheck */ %typemap(typecheck,precedence=SWIG_TYPECHECK_STRING, fragment="SWIG_AsCharPtr") char *, char const*, char *const, char const *const, char const*&, char *const&, char const *const & "SWIG_AsCharPtr($input); if (PyErr_Occurred()) { $1 = 0; PyErr_Clear(); } else { $1 = 1; }"; /* throws */ %typemap(throws,fragment="SWIG_FromCharPtr") char *, char const*, char * const, char const* const { PyErr_SetObject(PyExc_RuntimeError, SWIG_FromCharPtr($1)); SWIG_fail; } /* ------------------------------------------------------------ * Fix size character array char[ANY] handling * ------------------------------------------------------------ */ /* memberin and globalin typemaps */ %typemap(memberin) char [ANY] { if ($input) memcpy($1,$input,$1_dim0); else memset($1,0,$1_dim0); } %typemap(globalin) char [ANY] { if ($input) memcpy($1,$input,$1_dim0); else memset($1,0,$1_dim0); } /* in */ %typemap(in,fragment="SWIG_AsCharArray") char [ANY], const char [ANY] { char temp[$1_dim0]; SWIG_AsCharArray($input, temp, $1_dim0); if (PyErr_Occurred()) SWIG_fail; $1 = temp; } /* out */ %typemap(out,fragment="SWIG_FromCharArray") char [ANY], const char [ANY] "$result = SWIG_FromCharArray($1, $1_dim0);"; /* varin */ %typemap(varin,fragment="SWIG_AsCharArray") char [ANY] { SWIG_AsCharArray($input, $1, $1_dim0); if (PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); return 1; } } /* varout */ %typemap(varout,fragment="SWIG_FromCharArray") char [ANY], const char [ANY] "$result = SWIG_FromCharArray($1, $1_dim0);"; /* constants */ %typemap(constcode,fragment="SWIG_FromCharArray") char [ANY], const char [ANY] "PyDict_SetItemString(d,\"$symname\", SWIG_FromCharArray($value, $value_dim0));"; /* directorin */ %typemap(directorin,fragment="SWIG_FromCharArray") char [ANY], const char [ANY] "$input = SWIG_FromCharArray($1_name, $1_dim0);"; /* directorout */ %typemap(directorout,fragment="SWIG_AsCharArray") char [ANY], const char [ANY] (char temp[$result_dim0]) { SWIG_AsCharArray($input, temp, $result_dim0); if (PyErr_Occurred()) { Swig::DirectorTypeMismatchException("Error converting Python object into char[$result_dim0]"); } $result = temp; } /* typecheck */ %typemap(typecheck,precedence=SWIG_TYPECHECK_STRING, fragment="SWIG_AsCharArray") char [ANY], const char[ANY] { char* carray = 0; size_t size = 0; SWIG_AsCharArray($input, &carray, &size); if (PyErr_Occurred()) { $1 = 0; PyErr_Clear(); } else { $1 = ((carray != 0) && (size <= $input_dim0)); } } /* throw */ %typemap(throws,fragment="SWIG_FromCharArray") char[ANY], const char[ANY] { PyErr_SetObject(PyExc_RuntimeError, SWIG_FromCharArray($1,$1_dim0)); SWIG_fail; } /* ------------------------------------------------------------ * --- String & length --- * ------------------------------------------------------------ */ /* Here len doesn't include the '0' terminator */ %typemap(in, fragment="SWIG_AsCharPtrAndSize") (char *STRING, int LENGTH) (char *buf, size_t size) { int is_raw_pchar = SWIG_AsCharPtrAndSize($input, &buf, &size); if (PyErr_Occurred()) SWIG_fail; $1 = ($1_ltype) buf; $2 = ($2_ltype) (is_raw_pchar && size) ? size - 1 : size; } /* Here size includes the '0' terminator */ %typemap(in,fragment="SWIG_AsCharPtrAndSize") (char *STRING, int SIZE) (char *buf, size_t size) { SWIG_AsCharPtrAndSize($input, &buf, &size); if (PyErr_Occurred()) SWIG_fail; $1 = ($1_ltype) buf; $2 = ($2_ltype) size; } cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/std_map.i0000644000175000000620000021266612561312227021443 0ustar stevestaff// // SWIG typemaps for std::map // Luigi Ballabio // Jan. 2003 // // Python implementation %include std_common.i %include exception.i %exception std::map::__getitem__ { try { $action } catch (std::out_of_range& e) { PyErr_SetString(PyExc_KeyError,const_cast(e.what())); SWIG_fail; } } %exception std::map::__delitem__ { try { $action } catch (std::out_of_range& e) { PyErr_SetString(PyExc_KeyError,const_cast(e.what())); SWIG_fail; } } %exception std::map::__iter__ { try { $action } catch (std::runtime_error& e) { PyErr_SetString(PyExc_RuntimeError,const_cast(e.what())); SWIG_fail; } } // ------------------------------------------------------------------------ // std::map // // The aim of all that follows would be to integrate std::map with // Python as much as possible, namely, to allow the user to pass and // be returned Python dictionaries. // const declarations are used to guess the intent of the function being // exported; therefore, the following rationale is applied: // // -- f(std::map), f(const std::map&), f(const std::map*): // the parameter being read-only, either a Python dictionary or a // previously wrapped std::map can be passed. // -- f(std::map&), f(std::map*): // the parameter must be modified; therefore, only a wrapped std::map // can be passed. // -- std::map f(): // the map is returned by copy; therefore, a Python dictionary // is returned which is most easily used in other Python functions // -- std::map& f(), std::map* f(), const std::map& f(), // const std::map* f(): // the map is returned by reference; therefore, a wrapped std::map // is returned // ------------------------------------------------------------------------ %{ #include #include #include %} // exported class namespace std { template class map { %typemap(in) map (std::map* m) { if (PyDict_Check($input)) { $1 = std::map(); PyObject* items = PyMapping_Items($input); unsigned int size = PyList_Size(items); for (unsigned int i=0; i expected"); SWIG_fail; } } Py_DECREF(items); } else if (SWIG_ConvertPtr($input,(void **) &m, $&1_descriptor,0) != -1) { $1 = *m; } else { PyErr_SetString(PyExc_TypeError, "map<" #K "," #T "> expected"); SWIG_fail; } } %typemap(in) const map& (std::map temp, std::map* m), const map* (std::map temp, std::map* m) { if (PyDict_Check($input)) { PyObject* items = PyMapping_Items($input); unsigned int size = PyList_Size(items); temp = std::map(); $1 = &temp; for (unsigned int i=0; i expected"); SWIG_fail; } } Py_DECREF(items); } else if (SWIG_ConvertPtr($input,(void **) &m, $1_descriptor,0) != -1) { $1 = m; } else { PyErr_SetString(PyExc_TypeError, "map<" #K "," #T "> expected"); SWIG_fail; } } %typemap(out) map { $result = PyDict_New(); for (std::map::iterator i=$1.begin(); i!=$1.end(); ++i) { K* key = new K(i->first); T* obj = new T(i->second); PyDict_SetItem($result, SWIG_NewPointerObj((void *) key, $descriptor(K *), 1), SWIG_NewPointerObj((void *) obj, $descriptor(T *), 1)); } } %typecheck(SWIG_TYPECHECK_MAP) map { /* native sequence? */ if (PyDict_Check($input)) { PyObject* items = PyMapping_Items($input); unsigned int size = PyList_Size(items); if (size == 0) { /* an empty dictionary can be of any type */ $1 = 1; } else { /* check the first element only */ K* k; T* x; PyObject* pair = PySequence_GetItem(items,0); PyObject* key = PySequence_GetItem(pair,0); PyObject* o = PySequence_GetItem(pair,1); if (SWIG_ConvertPtr(key,(void **) &k, $descriptor(K *),0) != -1 && SWIG_ConvertPtr(o,(void **) &x, $descriptor(T *),0) != -1) $1 = 1; else $1 = 0; Py_DECREF(key); Py_DECREF(o); Py_DECREF(pair); } Py_DECREF(items); } else { /* wrapped map? */ std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $&1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_MAP) const map&, const map* { /* native sequence? */ if (PyDict_Check($input)) { PyObject* items = PyMapping_Items($input); unsigned int size = PyList_Size(items); if (size == 0) { /* an empty dictionary can be of any type */ $1 = 1; } else { /* check the first element only */ K* k; T* x; PyObject* pair = PySequence_GetItem(items,0); PyObject* key = PySequence_GetItem(pair,0); PyObject* o = PySequence_GetItem(pair,1); if (SWIG_ConvertPtr(key,(void **) &k, $descriptor(K *),0) != -1 && SWIG_ConvertPtr(o,(void **) &x, $descriptor(T *),0) != -1) $1 = 1; else $1 = 0; Py_DECREF(key); Py_DECREF(o); Py_DECREF(pair); } Py_DECREF(items); } else { /* wrapped map? */ std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } public: map(); map(const map &); %rename(__len__) size; unsigned int size() const; void clear(); %extend { bool __nonzero__() { return !(self->empty()); } T& __getitem__(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void __setitem__(const K& key, const T& x) { (*self)[key] = x; } void __delitem__(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(const K& key) { std::map::iterator i = self->find(key); return i != self->end(); } PyObject* keys() { PyObject* keyList = PyList_New(self->size()); std::map::iterator i; unsigned int j; for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { K* ptr = new K(i->first); PyList_SetItem(keyList,j, SWIG_NewPointerObj((void *) ptr, $descriptor(K *),1)); } return keyList; } PyObject* values() { PyObject* valueList = PyList_New(self->size()); std::map::iterator i; unsigned int j; for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { T* ptr = new T(i->second); PyList_SetItem(valueList,j, SWIG_NewPointerObj((void *) ptr, $descriptor(T *),1)); } return valueList; } PyObject* items() { PyObject* itemList = PyList_New(self->size()); std::map::iterator i; unsigned int j; for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { K* k_ptr = new K(i->first); T* t_ptr = new T(i->second); PyObject* item = PyTuple_New(2); PyTuple_SetItem(item,0, SWIG_NewPointerObj((void *) k_ptr, $descriptor(K *),1)); PyTuple_SetItem(item,1, SWIG_NewPointerObj((void *) t_ptr, $descriptor(T *),1)); PyList_SetItem(itemList,j,item); } return itemList; } // Python 2.2 methods bool __contains__(const K& key) { std::map::iterator i = self->find(key); return i != self->end(); } PyObject* __iter__() { %#if PY_VERSION_HEX >= 0x02020000 PyObject* keyList = PyList_New(self->size()); std::map::iterator i; unsigned int j; for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { K* ptr = new K(i->first); PyList_SetItem(keyList,j, SWIG_NewPointerObj((void *) ptr, $descriptor(K *),1)); } PyObject* iter = PyObject_GetIter(keyList); Py_DECREF(keyList); return iter; %#else throw std::runtime_error("Python 2.2 or later is needed" " for iterator support"); %#endif } } }; // specializations for built-ins %define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO) template class map { %typemap(in) map (std::map* m) { if (PyDict_Check($input)) { $1 = std::map(); PyObject* items = PyMapping_Items($input); unsigned int size = PyList_Size(items); for (unsigned int i=0; i expected"); SWIG_fail; } } Py_DECREF(items); } else if (SWIG_ConvertPtr($input,(void **) &m, $&1_descriptor,0) != -1) { $1 = *m; } else { PyErr_SetString(PyExc_TypeError, "map<" #K "," #T "> expected"); SWIG_fail; } } %typemap(in) const map& (std::map temp, std::map* m), const map* (std::map temp, std::map* m) { if (PyDict_Check($input)) { PyObject* items = PyMapping_Items($input); unsigned int size = PyList_Size(items); temp = std::map(); $1 = &temp; for (unsigned int i=0; i expected"); SWIG_fail; } } Py_DECREF(items); } else if (SWIG_ConvertPtr($input,(void **) &m, $1_descriptor,0) != -1) { $1 = m; } else { PyErr_SetString(PyExc_TypeError, "map<" #K "," #T "> expected"); SWIG_fail; } } %typemap(out) map { $result = PyDict_New(); for (std::map::iterator i=$1.begin(); i!=$1.end(); ++i) { T* obj = new T(i->second); PyDict_SetItem($result, CONVERT_TO(i->first), SWIG_NewPointerObj((void *) obj, $descriptor(T *), 1)); } } %typecheck(SWIG_TYPECHECK_MAP) map { /* native sequence? */ if (PyDict_Check($input)) { PyObject* items = PyMapping_Items($input); unsigned int size = PyList_Size(items); if (size == 0) { /* an empty dictionary can be of any type */ $1 = 1; } else { /* check the first element only */ T* x; PyObject* pair = PySequence_GetItem(items,0); PyObject* key = PySequence_GetItem(pair,0); PyObject* o = PySequence_GetItem(pair,1); if (CHECK(key) && SWIG_ConvertPtr(o,(void **) &x, $descriptor(T *),0) != -1) $1 = 1; else $1 = 0; Py_DECREF(key); Py_DECREF(o); Py_DECREF(pair); } Py_DECREF(items); } else { /* wrapped map? */ std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $&1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_MAP) const map&, const map* { /* native sequence? */ if (PyDict_Check($input)) { PyObject* items = PyMapping_Items($input); unsigned int size = PyList_Size(items); if (size == 0) { /* an empty dictionary can be of any type */ $1 = 1; } else { /* check the first element only */ T* x; PyObject* pair = PySequence_GetItem(items,0); PyObject* key = PySequence_GetItem(pair,0); PyObject* o = PySequence_GetItem(pair,1); if (CHECK(key) && SWIG_ConvertPtr(o,(void **) &x, $descriptor(T *),0) != -1) $1 = 1; else $1 = 0; Py_DECREF(key); Py_DECREF(o); Py_DECREF(pair); } Py_DECREF(items); } else { /* wrapped map? */ std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } public: map(); map(const map &); %rename(__len__) size; unsigned int size() const; void clear(); %extend { bool __nonzero__() { return !(self->empty()); } T& __getitem__(K key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void __setitem__(K key, const T& x) { (*self)[key] = x; } void __delitem__(K key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(K key) { std::map::iterator i = self->find(key); return i != self->end(); } PyObject* keys() { PyObject* keyList = PyList_New(self->size()); std::map::iterator i; unsigned int j; for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { PyList_SetItem(keyList,j, CONVERT_TO(i->first)); } return keyList; } PyObject* values() { PyObject* valueList = PyList_New(self->size()); std::map::iterator i; unsigned int j; for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { T* ptr = new T(i->second); PyList_SetItem(valueList,j, SWIG_NewPointerObj((void *) ptr, $descriptor(T *),1)); } return valueList; } PyObject* items() { PyObject* itemList = PyList_New(self->size()); std::map::iterator i; unsigned int j; for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { T* t_ptr = new T(i->second); PyObject* item = PyTuple_New(2); PyTuple_SetItem(item,0, CONVERT_TO(i->first)); PyTuple_SetItem(item,1, SWIG_NewPointerObj((void *) t_ptr, $descriptor(T *),1)); PyList_SetItem(itemList,j,item); } return itemList; } // Python 2.2 methods bool __contains__(K key) { std::map::iterator i = self->find(key); return i != self->end(); } PyObject* __iter__() { %#if PY_VERSION_HEX >= 0x02020000 PyObject* keyList = PyList_New(self->size()); std::map::iterator i; unsigned int j; for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { PyList_SetItem(keyList,j, CONVERT_TO(i->first)); } PyObject* iter = PyObject_GetIter(keyList); Py_DECREF(keyList); return iter; %#else throw std::runtime_error("Python 2.2 or later is needed" " for iterator support"); %#endif } } }; %enddef %define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO) template class map { %typemap(in) map (std::map* m) { if (PyDict_Check($input)) { $1 = std::map(); PyObject* items = PyMapping_Items($input); unsigned int size = PyList_Size(items); for (unsigned int i=0; i expected"); SWIG_fail; } } Py_DECREF(items); } else if (SWIG_ConvertPtr($input,(void **) &m, $&1_descriptor,0) != -1) { $1 = *m; } else { PyErr_SetString(PyExc_TypeError, "map<" #K "," #T "> expected"); SWIG_fail; } } %typemap(in) const map& (std::map temp, std::map* m), const map* (std::map temp, std::map* m) { if (PyDict_Check($input)) { PyObject* items = PyMapping_Items($input); unsigned int size = PyList_Size(items); temp = std::map(); $1 = &temp; for (unsigned int i=0; i expected"); SWIG_fail; } } Py_DECREF(items); } else if (SWIG_ConvertPtr($input,(void **) &m, $1_descriptor,0) != -1) { $1 = m; } else { PyErr_SetString(PyExc_TypeError, "map<" #K "," #T "> expected"); SWIG_fail; } } %typemap(out) map { $result = PyDict_New(); for (std::map::iterator i=$1.begin(); i!=$1.end(); ++i) { K* key = new K(i->first); PyDict_SetItem($result, SWIG_NewPointerObj((void *) key, $descriptor(K *), 1), CONVERT_TO(i->second)); } } %typecheck(SWIG_TYPECHECK_MAP) map { /* native sequence? */ if (PyDict_Check($input)) { PyObject* items = PyMapping_Items($input); unsigned int size = PyList_Size(items); if (size == 0) { /* an empty dictionary can be of any type */ $1 = 1; } else { /* check the first element only */ K* k; PyObject* pair = PySequence_GetItem(items,0); PyObject* key = PySequence_GetItem(pair,0); PyObject* o = PySequence_GetItem(pair,1); if (SWIG_ConvertPtr(key,(void **) &k, $descriptor(K *),0) != -1 && CHECK(o)) $1 = 1; else $1 = 0; Py_DECREF(key); Py_DECREF(o); Py_DECREF(pair); } Py_DECREF(items); } else { /* wrapped map? */ std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $&1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_MAP) const map&, const map* { /* native sequence? */ if (PyDict_Check($input)) { PyObject* items = PyMapping_Items($input); unsigned int size = PyList_Size(items); if (size == 0) { /* an empty dictionary can be of any type */ $1 = 1; } else { /* check the first element only */ K* k; PyObject* pair = PySequence_GetItem(items,0); PyObject* key = PySequence_GetItem(pair,0); PyObject* o = PySequence_GetItem(pair,1); if (SWIG_ConvertPtr(key,(void **) &k, $descriptor(K *),0) != -1 && CHECK(o)) $1 = 1; else $1 = 0; Py_DECREF(key); Py_DECREF(o); Py_DECREF(pair); } Py_DECREF(items); } else { /* wrapped map? */ std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } public: map(); map(const map &); %rename(__len__) size; unsigned int size() const; void clear(); %extend { bool __nonzero__() { return !(self->empty()); } T __getitem__(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void __setitem__(const K& key, T x) { (*self)[key] = x; } void __delitem__(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(const K& key) { std::map::iterator i = self->find(key); return i != self->end(); } PyObject* keys() { PyObject* keyList = PyList_New(self->size()); std::map::iterator i; unsigned int j; for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { K* ptr = new K(i->first); PyList_SetItem(keyList,j, SWIG_NewPointerObj((void *) ptr, $descriptor(K *),1)); } return keyList; } PyObject* values() { PyObject* valueList = PyList_New(self->size()); std::map::iterator i; unsigned int j; for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { PyList_SetItem(valueList,j, CONVERT_TO(i->second)); } return valueList; } PyObject* items() { PyObject* itemList = PyList_New(self->size()); std::map::iterator i; unsigned int j; for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { K* k_ptr = new K(i->first); PyObject* item = PyTuple_New(2); PyTuple_SetItem(item,0, SWIG_NewPointerObj((void *) k_ptr, $descriptor(K *),1)); PyTuple_SetItem(item,1, CONVERT_TO(i->second)); PyList_SetItem(itemList,j,item); } return itemList; } // Python 2.2 methods bool __contains__(const K& key) { std::map::iterator i = self->find(key); return i != self->end(); } PyObject* __iter__() { %#if PY_VERSION_HEX >= 0x02020000 PyObject* keyList = PyList_New(self->size()); std::map::iterator i; unsigned int j; for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { K* ptr = new K(i->first); PyList_SetItem(keyList,j, SWIG_NewPointerObj((void *) ptr, $descriptor(K *),1)); } PyObject* iter = PyObject_GetIter(keyList); Py_DECREF(keyList); return iter; %#else throw std::runtime_error("Python 2.2 or later is needed" " for iterator support"); %#endif } } }; %enddef %define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO) template<> class map { %typemap(in) map (std::map* m) { if (PyDict_Check($input)) { $1 = std::map(); PyObject* items = PyMapping_Items($input); unsigned int size = PyList_Size(items); for (unsigned int i=0; i expected"); SWIG_fail; } } Py_DECREF(items); } else if (SWIG_ConvertPtr($input,(void **) &m, $&1_descriptor,0) != -1) { $1 = *m; } else { PyErr_SetString(PyExc_TypeError, "map<" #K "," #T "> expected"); SWIG_fail; } } %typemap(in) const map& (std::map temp, std::map* m), const map* (std::map temp, std::map* m) { if (PyDict_Check($input)) { PyObject* items = PyMapping_Items($input); unsigned int size = PyList_Size(items); temp = std::map(); $1 = &temp; for (unsigned int i=0; i expected"); SWIG_fail; } } Py_DECREF(items); } else if (SWIG_ConvertPtr($input,(void **) &m, $1_descriptor,0) != -1) { $1 = m; } else { PyErr_SetString(PyExc_TypeError, "map<" #K "," #T "> expected"); SWIG_fail; } } %typemap(out) map { $result = PyDict_New(); for (std::map::iterator i=$1.begin(); i!=$1.end(); ++i) { PyDict_SetItem($result, CONVERT_K_TO(i->first), CONVERT_T_TO(i->second)); } } %typecheck(SWIG_TYPECHECK_MAP) map { /* native sequence? */ if (PyDict_Check($input)) { PyObject* items = PyMapping_Items($input); unsigned int size = PyList_Size(items); if (size == 0) { /* an empty dictionary can be of any type */ $1 = 1; } else { /* check the first element only */ PyObject* pair = PySequence_GetItem(items,0); PyObject* key = PySequence_GetItem(pair,0); PyObject* o = PySequence_GetItem(pair,1); if (CHECK_K(key) && CHECK_T(o)) $1 = 1; else $1 = 0; Py_DECREF(key); Py_DECREF(o); Py_DECREF(pair); } Py_DECREF(items); } else { /* wrapped map? */ std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $&1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_MAP) const map&, const map* { /* native sequence? */ if (PyDict_Check($input)) { PyObject* items = PyMapping_Items($input); unsigned int size = PyList_Size(items); if (size == 0) { /* an empty dictionary can be of any type */ $1 = 1; } else { /* check the first element only */ PyObject* pair = PySequence_GetItem(items,0); PyObject* key = PySequence_GetItem(pair,0); PyObject* o = PySequence_GetItem(pair,1); if (CHECK_K(key) && CHECK_T(o)) $1 = 1; else $1 = 0; Py_DECREF(key); Py_DECREF(o); Py_DECREF(pair); } Py_DECREF(items); } else { /* wrapped map? */ std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } public: map(); map(const map &); %rename(__len__) size; unsigned int size() const; void clear(); %extend { bool __nonzero__() { return !(self->empty()); } T __getitem__(K key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void __setitem__(K key, T x) { (*self)[key] = x; } void __delitem__(K key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(K key) { std::map::iterator i = self->find(key); return i != self->end(); } PyObject* keys() { PyObject* keyList = PyList_New(self->size()); std::map::iterator i; unsigned int j; for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { PyList_SetItem(keyList,j, CONVERT_K_TO(i->first)); } return keyList; } PyObject* values() { PyObject* valueList = PyList_New(self->size()); std::map::iterator i; unsigned int j; for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { PyList_SetItem(valueList,j, CONVERT_T_TO(i->second)); } return valueList; } PyObject* items() { PyObject* itemList = PyList_New(self->size()); std::map::iterator i; unsigned int j; for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { PyObject* item = PyTuple_New(2); PyTuple_SetItem(item,0, CONVERT_K_TO(i->first)); PyTuple_SetItem(item,1, CONVERT_T_TO(i->second)); PyList_SetItem(itemList,j,item); } return itemList; } // Python 2.2 methods bool __contains__(K key) { std::map::iterator i = self->find(key); return i != self->end(); } PyObject* __iter__() { %#if PY_VERSION_HEX >= 0x02020000 PyObject* keyList = PyList_New(self->size()); std::map::iterator i; unsigned int j; for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { PyList_SetItem(keyList,j, CONVERT_K_TO(i->first)); } PyObject* iter = PyObject_GetIter(keyList); Py_DECREF(keyList); return iter; %#else throw std::runtime_error("Python 2.2 or later is needed" " for iterator support"); %#endif } } }; %enddef specialize_std_map_on_key(bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool); specialize_std_map_on_key(int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_key(short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_key(long,PyLong_Check, PyLong_AsLong,PyLong_FromLong); specialize_std_map_on_key(unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_key(unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_key(unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); specialize_std_map_on_key(double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_map_on_key(float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_map_on_key(std::string,PyString_Check, SwigString_AsString,SwigString_FromString); specialize_std_map_on_value(bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool); specialize_std_map_on_value(int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_value(short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_value(long,PyLong_Check, PyLong_AsLong,PyLong_FromLong); specialize_std_map_on_value(unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_value(unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_value(unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); specialize_std_map_on_value(double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_map_on_value(float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_map_on_value(std::string,PyString_Check, SwigString_AsString,SwigString_FromString); specialize_std_map_on_both(bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool, bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool); specialize_std_map_on_both(bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool, int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool, short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool, long,PyLong_Check, PyLong_AsLong,PyLong_FromLong); specialize_std_map_on_both(bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool, unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool, unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool, unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); specialize_std_map_on_both(bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool, double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_map_on_both(bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool, float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_map_on_both(bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool, std::string,PyString_Check, SwigString_AsString,SwigString_FromString); specialize_std_map_on_both(int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool); specialize_std_map_on_both(int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, long,PyLong_Check, PyLong_AsLong,PyLong_FromLong); specialize_std_map_on_both(int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); specialize_std_map_on_both(int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_map_on_both(int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_map_on_both(int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, std::string,PyString_Check, SwigString_AsString,SwigString_FromString); specialize_std_map_on_both(short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool); specialize_std_map_on_both(short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, long,PyLong_Check, PyLong_AsLong,PyLong_FromLong); specialize_std_map_on_both(short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); specialize_std_map_on_both(short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_map_on_both(short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_map_on_both(short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, std::string,PyString_Check, SwigString_AsString,SwigString_FromString); specialize_std_map_on_both(long,PyLong_Check, PyLong_AsLong,PyLong_FromLong, bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool); specialize_std_map_on_both(long,PyLong_Check, PyLong_AsLong,PyLong_FromLong, int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(long,PyLong_Check, PyLong_AsLong,PyLong_FromLong, short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(long,PyLong_Check, PyLong_AsLong,PyLong_FromLong, long,PyLong_Check, PyLong_AsLong,PyLong_FromLong); specialize_std_map_on_both(long,PyLong_Check, PyLong_AsLong,PyLong_FromLong, unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(long,PyLong_Check, PyLong_AsLong,PyLong_FromLong, unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(long,PyLong_Check, PyLong_AsLong,PyLong_FromLong, unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); specialize_std_map_on_both(long,PyLong_Check, PyLong_AsLong,PyLong_FromLong, double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_map_on_both(long,PyLong_Check, PyLong_AsLong,PyLong_FromLong, float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_map_on_both(long,PyLong_Check, PyLong_AsLong,PyLong_FromLong, std::string,PyString_Check, SwigString_AsString,SwigString_FromString); specialize_std_map_on_both(unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool); specialize_std_map_on_both(unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, long,PyLong_Check, PyLong_AsLong,PyLong_FromLong); specialize_std_map_on_both(unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); specialize_std_map_on_both(unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_map_on_both(unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_map_on_both(unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, std::string,PyString_Check, SwigString_AsString,SwigString_FromString); specialize_std_map_on_both(unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool); specialize_std_map_on_both(unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, long,PyLong_Check, PyLong_AsLong,PyLong_FromLong); specialize_std_map_on_both(unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); specialize_std_map_on_both(unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_map_on_both(unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_map_on_both(unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, std::string,PyString_Check, SwigString_AsString,SwigString_FromString); specialize_std_map_on_both(unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool); specialize_std_map_on_both(unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, long,PyLong_Check, PyLong_AsLong,PyLong_FromLong); specialize_std_map_on_both(unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); specialize_std_map_on_both(unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_map_on_both(unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_map_on_both(unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, std::string,PyString_Check, SwigString_AsString,SwigString_FromString); specialize_std_map_on_both(double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool); specialize_std_map_on_both(double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, long,PyLong_Check, PyLong_AsLong,PyLong_FromLong); specialize_std_map_on_both(double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); specialize_std_map_on_both(double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_map_on_both(double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_map_on_both(double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, std::string,PyString_Check, SwigString_AsString,SwigString_FromString); specialize_std_map_on_both(float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool); specialize_std_map_on_both(float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, long,PyLong_Check, PyLong_AsLong,PyLong_FromLong); specialize_std_map_on_both(float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); specialize_std_map_on_both(float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_map_on_both(float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_map_on_both(float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, std::string,PyString_Check, SwigString_AsString,SwigString_FromString); specialize_std_map_on_both(std::string,PyString_Check, SwigString_AsString,SwigString_FromString, bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool); specialize_std_map_on_both(std::string,PyString_Check, SwigString_AsString,SwigString_FromString, int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(std::string,PyString_Check, SwigString_AsString,SwigString_FromString, short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(std::string,PyString_Check, SwigString_AsString,SwigString_FromString, long,PyLong_Check, PyLong_AsLong,PyLong_FromLong); specialize_std_map_on_both(std::string,PyString_Check, SwigString_AsString,SwigString_FromString, unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(std::string,PyString_Check, SwigString_AsString,SwigString_FromString, unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_map_on_both(std::string,PyString_Check, SwigString_AsString,SwigString_FromString, unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); specialize_std_map_on_both(std::string,PyString_Check, SwigString_AsString,SwigString_FromString, double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_map_on_both(std::string,PyString_Check, SwigString_AsString,SwigString_FromString, float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_map_on_both(std::string,PyString_Check, SwigString_AsString,SwigString_FromString, std::string,PyString_Check, SwigString_AsString,SwigString_FromString); } cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/argcargv.i0000644000175000000620000000341212561312227021573 0ustar stevestaff/* ------------------------------------------------------------ * --- Argc & Argv --- * ------------------------------------------------------------ */ %fragment("SWIG_AsArgcArgv","header") %{ SWIGSTATIC(char**) SWIG_AsArgcArgv(PyObject* input, swig_type_info* ppchar_info, swig_type_info* pchar_info, size_t* argc, int* owner) { char **argv = 0; size_t i = 0; if (SWIG_ConvertPtr(input, (void **)&argv, ppchar_info, 0) == -1) { PyErr_Clear(); int list = PyList_Check(input); if (list || PyTuple_Check(input)) { *argc = list ? PyList_Size(input) : PyTuple_Size(input); argv = swig_new_array(char*, *argc + 1); *owner = 1; for (; i < *argc; ++i) { PyObject *obj = list ? PyList_GetItem(input,i) : PyTuple_GetItem(input,i); argv[i] = SWIG_AsCharPtr(obj, pchar_info); if (PyErr_Occurred()) { PyErr_Clear(); PyErr_SetString(PyExc_TypeError,"list or tuple must contain strings only"); } } argv[i] = 0; return argv; } else { *argc = 0; PyErr_SetString(PyExc_TypeError,"a list or tuple is expected"); return 0; } } else { /* seems dangerous, but the user asked for it... */ while (argv[i] != 0) ++i; *argc = i; owner = 0; return argv; } } %} /* This typemap works with either a char**, a python list or a python tuple */ %typemap(in,fragment="SWIG_AsArgcArgv") (int ARGC, char **ARGV) (int owner) { size_t argc = 0; char **argv = SWIG_AsArgcArgv($input, $descriptor(char**), $descriptor(char*), &argc, &owner); if (PyErr_Occurred()) { $1 = 0; $2 = 0; SWIG_fail; } else { $1 = ($1_ltype) argc; $2 = ($2_ltype) argv; } } %typemap(freearg) (int ARGC, char **ARGV) (owner) { if (owner) swig_delete_array($2); } cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/CMakeLists.txt0000644000175000000620000000036112561312227022365 0ustar stevestaffFILE(GLOB __files1 "${CMAKE_CURRENT_SOURCE_DIR}/*.i") FILE(GLOB __files2 "${CMAKE_CURRENT_SOURCE_DIR}/*.swg") INSTALL(FILES ${__files1} ${__files2} DESTINATION ${CableSwig_INSTALL_ROOT}lib/CableSwig/SWIGLib/python COMPONENT Development) cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/python.swg0000644000175000000620000000664612561312227021704 0ustar stevestaff/* ----------------------------------------------------------------------------- * python.swg * * Python configuration module. * ----------------------------------------------------------------------------- */ /* Python.h has to appear first */ %insert(runtime) %{ #include "Python.h" %} %insert(runtime) "precommon.swg"; %insert(runtime) "common.swg"; /* Common type-checking code */ %insert(runtime) "pyrun.swg"; /* Python run-time code */ /* Special directive for shadow code */ #define %shadow %insert("shadow") #define %pythoncode %insert("python") %{ /* Auxiliar swig macros */ #ifdef __cplusplus #define SWIGSTATICINLINE(a) static inline a #define SWIGSTATIC(a) static a #define swig_new_array(type, size) (new type[(size)]) #define swig_delete_array(cptr) delete[] cptr #define swig_const_cast(type,a) const_cast(a) #define swig_static_cast(type,a) static_cast(a) #define swig_reinterpret_cast(type,a) reinterpret_cast(a) #ifdef HAVE_NUMERIC_CAST #define swig_numeric_cast(type,a) numeric_cast(a) #else #define swig_numeric_cast(type,a) static_cast(a) #endif #else /* C case */ #define SWIGSTATICINLINE(a) static a #define SWIGSTATIC(a) static a #define swig_new_array(type, size) ((type*) malloc((size)*sizeof(type))) #define swig_delete_array(cptr) free((char*)cptr) #define swig_const_cast(type,a) (type)(a) #define swig_static_cast(type,a) (type)(a) #define swig_reinterpret_cast(type,a) (type)(a) #define swig_numeric_cast(type,a) (type)(a) #endif /* __cplusplus */ %} /* ----------------------------------------------------------------------------- * SWIGTYPE typemaps * ----------------------------------------------------------------------------- */ %include "pyswigtype.swg" /* ----------------------------------------------------------------------------- * Typemap specializations * ----------------------------------------------------------------------------- */ %include "pyvoid.swg" %include "pyobject.swg" %include "pystrings.swg" %include "pyvaltypes.swg" %include "pyprimtypes.swg" %include "pymisctypes.swg" /* ------------------------------------------------------------ * Enums * ------------------------------------------------------------ */ %apply int { enum SWIGTYPE }; /* this doesn't work now, you need to redefined it for each enum. */ %apply const int& { const enum SWIGTYPE& }; /* ------------------------------------------------------------ * Overloaded operator support * ------------------------------------------------------------ */ %include "pyopers.swg" /* ------------------------------------------------------------ * Warnings for Python keywords * ------------------------------------------------------------ */ %include "pythonkw.swg" /* ------------------------------------------------------------ * The start of the Python initialization function * ------------------------------------------------------------ */ %init %{ #ifdef __cplusplus extern "C" #endif SWIGEXPORT(void) SWIG_init(void) { static PyObject *SWIG_globals = 0; static int typeinit = 0; PyObject *m, *d; int i; if (!SWIG_globals) SWIG_globals = SWIG_newvarlink(); m = Py_InitModule((char *) SWIG_name, SwigMethods); d = PyModule_GetDict(m); if (!typeinit) { for (i = 0; swig_types_initial[i]; i++) { swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]); } typeinit = 1; } SWIG_InstallConstants(d,swig_const_table); %} cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/Makefile.in0000644000175000000620000000751012561312227021675 0ustar stevestaff# --------------------------------------------------------------- # /cvsroot/SWIG/Lib/python/Makefile.in,v 1.3 2002/11/30 22:10:08 beazley Exp # SWIG Python Makefile # # This file can be used to build various Python extensions with SWIG. # By default this file is set up for dynamic loading, but it can # be easily customized for static extensions by modifying various # portions of the file. # # SRCS = C source files # CXXSRCS = C++ source files # OBJCSRCS = Objective-C source files # OBJS = Additional .o files (compiled previously) # INTERFACE = SWIG interface file # TARGET = Name of target module or executable # # Many portions of this file were created by the SWIG configure # script and should already reflect your machine. #---------------------------------------------------------------- SRCS = CXXSRCS = OBJCSRCS = OBJS = INTERFACE = WRAPFILE = $(INTERFACE:.i=_wrap.c) WRAPOBJ = $(INTERFACE:.i=_wrap.o) TARGET = module@SO@ # Use this kind of target for dynamic loading #TARGET = mypython # Use this target for static linking prefix = @prefix@ exec_prefix = @exec_prefix@ CC = @CC@ CXX = @CXX@ OBJC = @CC@ -Wno-import # -Wno-import needed for gcc CFLAGS = INCLUDES = LIBS = # SWIG Options # SWIG = location of the SWIG executable # SWIGOPT = SWIG compiler options # SWIGCC = Compiler used to compile the wrapper file SWIG = $(exec_prefix)/bin/swig SWIGOPT = -python SWIGCC = $(CC) # SWIG Library files. Uncomment if rebuilding the Python interpreter #SWIGLIB = -lembed.i # Rules for creating .o files from source. COBJS = $(SRCS:.c=.o) CXXOBJS = $(CXXSRCS:.cxx=.o) OBJCOBJS = $(OBJCSRCS:.m=.o) ALLOBJS = $(COBJS) $(CXXOBJS) $(OBJCOBJS) $(OBJS) # Command that will be used to build the final extension. BUILD = $(SWIGCC) # Uncomment the following if you are using dynamic loading CCSHARED = @CCSHARED@ BUILD = @LDSHARED@ # Uncomment the following if you are using dynamic loading with C++ and # need to provide additional link libraries (this is not always required). #DLL_LIBS = -L/usr/local/lib/gcc-lib/sparc-sun-solaris2.5.1/2.7.2 \ -L/usr/local/lib -lg++ -lstdc++ -lgcc # X11 installation (needed if rebuilding Python + tkinter) XLIB = @XLIBSW@ XINCLUDE = @XINCLUDES@ # Python installation PY_INCLUDE = -DHAVE_CONFIG_H @PYINCLUDE@ PY_LIB = @PYLIB@ # Tcl installation. Needed if rebuilding Python with tkinter. TCL_INCLUDE = @TCLINCLUDE@ TCL_LIB = @TCLLIB@ # Build libraries (needed for static builds) LIBM = @LIBM@ LIBC = @LIBC@ SYSLIBS = $(LIBM) $(LIBC) @LIBS@ # Build options (uncomment only one these) #TKINTER = $(TCL_LIB) -ltk -ltcl $(XLIB) BUILD_LIBS = $(LIBS) # Dynamic loading #BUILD_LIBS = $(PY_LIB) @PYLINK@ $(TKINTER) $(LIBS) $(SYSLIBS) # Compilation rules for non-SWIG components .SUFFIXES: .c .cxx .m .c.o: $(CC) $(CCSHARED) $(CFLAGS) $(INCLUDES) -c $< .cxx.o: $(CXX) $(CCSHARED) $(CXXFLAGS) $(INCLUDES) -c $< .m.o: $(OBJC) $(CCSHARED) $(CFLAGS) $(INCLUDES) -c $< # ---------------------------------------------------------------------- # Rules for building the extension # ---------------------------------------------------------------------- all: $(TARGET) # Convert the wrapper file into an object file $(WRAPOBJ) : $(WRAPFILE) $(SWIGCC) -c $(CCSHARED) $(CFLAGS) $(WRAPFILE) $(INCLUDES) $(PY_INCLUDE) $(WRAPFILE) : $(INTERFACE) $(SWIG) $(SWIGOPT) -o $(WRAPFILE) $(SWIGLIB) $(INTERFACE) $(TARGET): $(WRAPOBJ) $(ALLOBJS) $(BUILD) $(WRAPOBJ) $(ALLOBJS) $(BUILD_LIBS) -o $(TARGET) clean: rm -f $(COBJS) $(CXXOBJS) $(OBJCOBJS) $(WRAPOBJ) $(WRAPFILE) $(TARGET) cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/complex_common.i0000644000175000000620000000336612561312227023026 0ustar stevestaff#ifndef __python_complex_common_i__ #define __python_complex_common_i__ /* Defines the As/From conversors for double/float complex, you need to provide complex Type, the Name you want to use in the conversors, the complex Constructor method, and the Real and Imag complex accesor methods. See the std_complex.i and ccomplex.i for concret examples. */ /* the common from conversor */ %define %swig_fromcplx_conv(Type, Name, Real, Imag) %fragment("SWIG_From"#Name,"header") %{ SWIGSTATIC(PyObject*) SWIG_From##Name(Type c) { return PyComplex_FromDoubles(Real(c), Imag(c)); } %} %enddef /* the double case */ %define %swig_cplxdbl_conv(Type, Name, Constructor, Real, Imag) %fragment("SWIG_As"#Name,"header", fragment="SWIG_AsDouble") %{ SWIGSTATIC(Type) SWIG_As##Name(PyObject *o) { Type c = PyComplex_Check(o) ? Constructor(PyComplex_RealAsDouble(o), PyComplex_ImagAsDouble(o)) : Constructor(SWIG_AsDouble(o), 0); if (PyErr_Occurred()){ PyErr_Clear(); PyErr_SetString(PyExc_TypeError, "a Type is expected"); } return c; } %} %swig_fromcplx_conv(Type, Name, Real, Imag); %enddef /* the float case */ %define %swig_cplxflt_conv(Type, Name, Constructor, Real, Imag) %fragment("SWIG_As"#Name,"header", fragment="SWIG_CheckFloat", fragment="SWIG_AsDouble") %{ SWIGSTATIC(Type) SWIG_As##Name(PyObject *o) { Type c = PyComplex_Check(o) ? Constructor(SWIG_CheckFloat(PyComplex_RealAsDouble(o)), SWIG_CheckFloat(PyComplex_RealAsDouble(o))) : Constructor(SWIG_CheckFloat(SWIG_AsDouble(o)),0); if (PyErr_Occurred()) { PyErr_Clear(); PyErr_SetString(PyExc_TypeError, "a Type is expected"); } return c; } %} %swig_fromcplx_conv(Type, Name, Real, Imag); %enddef #endif //__python_complex_common_i__ cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/std_common.i0000644000175000000620000000137612561312227022150 0ustar stevestaff// // SWIG typemaps for STL - common utilities // Luigi Ballabio // Aug 3, 2002 // // Python implementation %apply size_t { std::size_t }; %{ #include PyObject* SwigInt_FromBool(bool b) { return PyInt_FromLong(b ? 1L : 0L); } int SwigNumber_Check(PyObject* o) { return PyFloat_Check(o) || PyInt_Check(o) || PyLong_Check(o); } double SwigNumber_AsDouble(PyObject* o) { return PyFloat_Check(o) ? PyFloat_AsDouble(o) : (PyInt_Check(o) ? double(PyInt_AsLong(o)) : double(PyLong_AsLong(o))); } PyObject* SwigString_FromString(const std::string& s) { return PyString_FromStringAndSize(s.data(),s.size()); } std::string SwigString_AsString(PyObject* o) { return std::string(PyString_AsString(o)); } %} cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/pyrun.swg0000644000175000000620000003210612561312227021526 0ustar stevestaff/*********************************************************************** * 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) /* Python-specific SWIG API */ #define SWIG_newvarlink() \ SWIG_Python_newvarlink() #define SWIG_addvarlink(p, name, get_attr, set_attr) \ SWIG_Python_addvarlink(p, name, get_attr, set_attr) #define SWIG_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) #define SWIG_InstallConstants(d, constants) \ SWIG_Python_InstallConstants(d, constants) 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); SWIGIMPORT(PyObject *) SWIG_Python_newvarlink(void); SWIGIMPORT(void) SWIG_Python_addvarlink(PyObject *, char *, PyObject *(*)(void), int (*)(PyObject *)); SWIGIMPORT(int) SWIG_Python_ConvertPacked(PyObject *, void *, int sz, swig_type_info *, int); SWIGIMPORT(PyObject *) SWIG_Python_NewPackedObj(void *, int sz, swig_type_info *); SWIGIMPORT(void) SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]); #else /* ----------------------------------------------------------------------------- * global variable support code. * ----------------------------------------------------------------------------- */ typedef struct swig_globalvar { char *name; /* Name of global variable */ PyObject *(*get_attr)(void); /* Return the current value */ int (*set_attr)(PyObject *); /* Set the value */ struct swig_globalvar *next; } swig_globalvar; typedef struct swig_varlinkobject { PyObject_HEAD swig_globalvar *vars; } swig_varlinkobject; static PyObject * swig_varlink_repr(swig_varlinkobject *v) { v = v; return PyString_FromString(""); } static int swig_varlink_print(swig_varlinkobject *v, FILE *fp, int flags) { swig_globalvar *var; flags = flags; fprintf(fp,"Global variables { "); for (var = v->vars; var; var=var->next) { fprintf(fp,"%s", var->name); if (var->next) fprintf(fp,", "); } fprintf(fp," }\n"); return 0; } static PyObject * swig_varlink_getattr(swig_varlinkobject *v, char *n) { swig_globalvar *var = v->vars; while (var) { if (strcmp(var->name,n) == 0) { return (*var->get_attr)(); } var = var->next; } PyErr_SetString(PyExc_NameError,"Unknown C global variable"); return NULL; } static int swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) { swig_globalvar *var = v->vars; while (var) { if (strcmp(var->name,n) == 0) { return (*var->set_attr)(p); } var = var->next; } PyErr_SetString(PyExc_NameError,"Unknown C global variable"); return 1; } statichere PyTypeObject varlinktype = { PyObject_HEAD_INIT(0) 0, /* Number of items in variable part (ob_size) */ (char *)"swigvarlink", /* Type name (tp_name) */ sizeof(swig_varlinkobject), /* Basic size (tp_basicsize) */ 0, /* Itemsize (tp_itemsize) */ 0, /* Deallocator (tp_dealloc) */ (printfunc) swig_varlink_print, /* Print (tp_print) */ (getattrfunc) swig_varlink_getattr, /* get attr (tp_getattr) */ (setattrfunc) swig_varlink_setattr, /* Set attr (tp_setattr) */ 0, /* tp_compare */ (reprfunc) swig_varlink_repr, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ 0, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ 0, /* tp_flags */ 0, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ 0, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ 0, /* tp_methods */ 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ 0, /* tp_descr_set */ 0, /* tp_dictoffset */ 0, /* tp_init */ 0, /* tp_alloc */ 0, /* tp_new */ 0, /* tp_free */ 0, /* tp_is_gc */ 0, /* tp_bases */ 0, /* tp_mro */ 0, /* tp_cache */ 0, /* tp_subclasses */ 0, /* tp_weaklist */ }; /* Create a variable linking object for use later */ SWIGRUNTIME(PyObject *) SWIG_Python_newvarlink(void) { swig_varlinkobject *result = 0; result = PyMem_NEW(swig_varlinkobject,1); varlinktype.ob_type = &PyType_Type; /* Patch varlinktype into a PyType */ result->ob_type = &varlinktype; result->vars = 0; result->ob_refcnt = 0; Py_XINCREF((PyObject *) result); return ((PyObject*) result); } SWIGRUNTIME(void) SWIG_Python_addvarlink(PyObject *p, char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) { swig_varlinkobject *v; swig_globalvar *gv; v= (swig_varlinkobject *) p; gv = (swig_globalvar *) malloc(sizeof(swig_globalvar)); gv->name = (char *) malloc(strlen(name)+1); strcpy(gv->name,name); gv->get_attr = get_attr; gv->set_attr = set_attr; gv->next = v->vars; v->vars = gv; } /* 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: if (flags & SWIG_POINTER_EXCEPTION) { if (ty && c) { PyObject *err = PyString_FromFormat("Type error. Got %s, expected %s",c,ty->name); PyErr_SetObject(PyExc_TypeError, err); Py_DECREF(err); } 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; (void)argnum; SWIG_Python_ConvertPtr(obj, &result, ty, flags | SWIG_POINTER_EXCEPTION); return result; } /* Convert a packed value value */ SWIGRUNTIME(int) SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, int sz, swig_type_info *ty, int flags) { swig_type_info *tc; char *c = 0; if ((!obj) || (!PyString_Check(obj))) goto type_error; c = PyString_AsString(obj); /* Pointer values must start with leading underscore */ if (*c != '_') goto type_error; c++; c = SWIG_UnpackData(c,ptr,sz); if (ty) { tc = SWIG_TypeCheck(c,ty); if (!tc) goto type_error; } return 0; type_error: if (flags) { if (ty && c) { PyObject *err = PyString_FromFormat("Type error. Got %s, expected %s",c,ty->name); PyErr_SetObject(PyExc_TypeError, err); Py_DECREF(err); } else { PyErr_SetString(PyExc_TypeError,"Expected a pointer"); } } return -1; } /* 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; } SWIGRUNTIME(PyObject *) SWIG_Python_NewPackedObj(void *ptr, int sz, swig_type_info *type) { char result[1024]; char *r = result; if ((2*sz + 1 + strlen(type->name)) > 1000) return 0; *(r++) = '_'; r = SWIG_PackData(r,ptr,sz); strcpy(r,type->name); return PyString_FromString(result); } /* Install Constants */ SWIGRUNTIME(void) SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) { int i; PyObject *obj; for (i = 0; constants[i].type; i++) { switch(constants[i].type) { case SWIG_PY_INT: obj = PyInt_FromLong(constants[i].lvalue); break; case SWIG_PY_FLOAT: obj = PyFloat_FromDouble(constants[i].dvalue); break; case SWIG_PY_STRING: if (constants[i].pvalue) { obj = PyString_FromString((char *) constants[i].pvalue); } else { Py_INCREF(Py_None); obj = Py_None; } break; case SWIG_PY_POINTER: obj = SWIG_NewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0); break; case SWIG_PY_BINARY: obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype)); break; default: obj = 0; break; } if (obj) { PyDict_SetItemString(d,constants[i].name,obj); Py_DECREF(obj); } } } #endif /* Contract support */ #define SWIG_contract_assert(expr, msg) if (!(expr)) { PyErr_SetString(PyExc_RuntimeError, (char *) msg ); goto fail; } else #ifdef __cplusplus } #endif cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/typemaps.i0000644000175000000620000002543612561312227021653 0ustar stevestaff// // SWIG Typemap library // Dave Beazley // May 5, 1997 // // Python implementation // // This library provides standard typemaps for modifying SWIG's behavior. // With enough entries in this file, I hope that very few people actually // ever need to write a typemap. // // Disclaimer : Unless you really understand how typemaps work, this file // probably isn't going to make much sense. // // ------------------------------------------------------------------------ // Pointer handling // // These mappings provide support for input/output arguments and common // uses for C/C++ pointers. // ------------------------------------------------------------------------ // INPUT typemaps. // These remap a C pointer to be an "INPUT" value which is passed by value // instead of reference. /* The following methods can be applied to turn a pointer into a simple "input" value. That is, instead of passing a pointer to an object, you would use a real value instead. int *INPUT short *INPUT long *INPUT long long *INPUT unsigned int *INPUT unsigned short *INPUT unsigned long *INPUT unsigned long long *INPUT unsigned char *INPUT bool *INPUT float *INPUT double *INPUT To use these, suppose you had a C function like this : double fadd(double *a, double *b) { return *a+*b; } You could wrap it with SWIG as follows : %include typemaps.i double fadd(double *INPUT, double *INPUT); or you can use the %apply directive : %include typemaps.i %apply double *INPUT { double *a, double *b }; double fadd(double *a, double *b); */ %define INPUT_TYPEMAP(type, converter) %typemap(in) type *INPUT($*1_ltype temp), type &INPUT($*1_ltype temp) { temp = converter($input); if (PyErr_Occurred()) SWIG_fail; $1 = &temp; } %typemap(typecheck) type *INPUT = type; %typemap(typecheck) type &INPUT = type; %enddef INPUT_TYPEMAP(float, PyFloat_AsDouble); INPUT_TYPEMAP(double, PyFloat_AsDouble); INPUT_TYPEMAP(int, PyInt_AsLong); INPUT_TYPEMAP(short, PyInt_AsLong); INPUT_TYPEMAP(long, PyInt_AsLong); INPUT_TYPEMAP(long long, PyLong_AsLongLong); INPUT_TYPEMAP(unsigned int, PyInt_AsLong); INPUT_TYPEMAP(unsigned short, PyInt_AsLong); INPUT_TYPEMAP(unsigned long, PyInt_AsLong); INPUT_TYPEMAP(unsigned long long, PyLong_AsUnsignedLongLong); INPUT_TYPEMAP(unsigned char, PyInt_AsLong); INPUT_TYPEMAP(signed char, PyInt_AsLong); #undef INPUT_TYPEMAP %typemap(in) bool *INPUT(bool temp), bool &INPUT(bool temp) { temp = PyInt_AsLong($input) ? true : false; if (PyErr_Occurred()) SWIG_fail; $1 = &temp; } %typemap(typecheck) bool *INPUT = bool; %typemap(typecheck) bool &INPUT = bool; // OUTPUT typemaps. These typemaps are used for parameters that // are output only. The output value is appended to the result as // a list element. /* The following methods can be applied to turn a pointer into an "output" value. When calling a function, no input value would be given for a parameter, but an output value would be returned. In the case of multiple output values, they are returned in the form of a Python tuple. int *OUTPUT short *OUTPUT long *OUTPUT long long *OUTPUT unsigned int *OUTPUT unsigned short *OUTPUT unsigned long *OUTPUT unsigned long long *OUTPUT unsigned char *OUTPUT bool *OUTPUT float *OUTPUT double *OUTPUT For example, suppose you were trying to wrap the modf() function in the C math library which splits x into integral and fractional parts (and returns the integer part in one of its parameters).K: double modf(double x, double *ip); You could wrap it with SWIG as follows : %include typemaps.i double modf(double x, double *OUTPUT); or you can use the %apply directive : %include typemaps.i %apply double *OUTPUT { double *ip }; double modf(double x, double *ip); The Python output of the function would be a tuple containing both output values. */ // These typemaps contributed by Robin Dunn //---------------------------------------------------------------------- // // T_OUTPUT typemap (and helper function) to return multiple argouts as // a tuple instead of a list. // // Author: Robin Dunn //---------------------------------------------------------------------- %include "fragments.i" %define OUTPUT_TYPEMAP(type, converter, convtype) %typemap(in,numinputs=0) type *OUTPUT($*1_ltype temp), type &OUTPUT($*1_ltype temp) "$1 = &temp;"; %typemap(argout,fragment="t_output_helper") type *OUTPUT, type &OUTPUT { PyObject *o = converter(convtype (*$1)); $result = t_output_helper($result,o); } %enddef OUTPUT_TYPEMAP(int, PyInt_FromLong, (long)); OUTPUT_TYPEMAP(short, PyInt_FromLong, (long)); OUTPUT_TYPEMAP(long, PyInt_FromLong, (long)); OUTPUT_TYPEMAP(long long, PyLong_FromLongLong, ($*1_ltype)); OUTPUT_TYPEMAP(unsigned int, PyInt_FromLong, (long)); OUTPUT_TYPEMAP(unsigned short, PyInt_FromLong, (long)); OUTPUT_TYPEMAP(unsigned long, PyInt_FromLong, (long)); OUTPUT_TYPEMAP(unsigned long long, PyLong_FromUnsignedLongLong, ($*1_ltype)); OUTPUT_TYPEMAP(unsigned char, PyInt_FromLong, (long)); OUTPUT_TYPEMAP(signed char, PyInt_FromLong, (long)); OUTPUT_TYPEMAP(bool, PyInt_FromLong, (long)); OUTPUT_TYPEMAP(float, PyFloat_FromDouble, (double)); OUTPUT_TYPEMAP(double, PyFloat_FromDouble, (double)); #undef OUTPUT_TYPEMAP // INOUT // Mappings for an argument that is both an input and output // parameter /* The following methods can be applied to make a function parameter both an input and output value. This combines the behavior of both the "INPUT" and "OUTPUT" methods described earlier. Output values are returned in the form of a Python tuple. int *INOUT short *INOUT long *INOUT long long *INOUT unsigned int *INOUT unsigned short *INOUT unsigned long *INOUT unsigned long long *INOUT unsigned char *INOUT bool *INOUT float *INOUT double *INOUT For example, suppose you were trying to wrap the following function : void neg(double *x) { *x = -(*x); } You could wrap it with SWIG as follows : %include typemaps.i void neg(double *INOUT); or you can use the %apply directive : %include typemaps.i %apply double *INOUT { double *x }; void neg(double *x); Unlike C, this mapping does not directly modify the input value (since this makes no sense in Python). Rather, the modified input value shows up as the return value of the function. Thus, to apply this function to a Python variable you might do this : x = neg(x) Note : previous versions of SWIG used the symbol 'BOTH' to mark input/output arguments. This is still supported, but will be slowly phased out in future releases. */ %typemap(in) int *INOUT = int *INPUT; %typemap(in) short *INOUT = short *INPUT; %typemap(in) long *INOUT = long *INPUT; %typemap(in) long long *INOUT = long long *INPUT; %typemap(in) unsigned *INOUT = unsigned *INPUT; %typemap(in) unsigned short *INOUT = unsigned short *INPUT; %typemap(in) unsigned long *INOUT = unsigned long *INPUT; %typemap(in) unsigned long long *INOUT = unsigned long long *INPUT; %typemap(in) unsigned char *INOUT = unsigned char *INPUT; %typemap(in) bool *INOUT = bool *INPUT; %typemap(in) float *INOUT = float *INPUT; %typemap(in) double *INOUT = double *INPUT; %typemap(in) int &INOUT = int &INPUT; %typemap(in) short &INOUT = short &INPUT; %typemap(in) long &INOUT = long &INPUT; %typemap(in) long long &INOUT = long long &INPUT; %typemap(in) unsigned &INOUT = unsigned &INPUT; %typemap(in) unsigned short &INOUT = unsigned short &INPUT; %typemap(in) unsigned long &INOUT = unsigned long &INPUT; %typemap(in) unsigned long long &INOUT = unsigned long long &INPUT; %typemap(in) unsigned char &INOUT = unsigned char &INPUT; %typemap(in) bool &INOUT = bool &INPUT; %typemap(in) float &INOUT = float &INPUT; %typemap(in) double &INOUT = double &INPUT; %typemap(argout) int *INOUT = int *OUTPUT; %typemap(argout) short *INOUT = short *OUTPUT; %typemap(argout) long *INOUT = long *OUTPUT; %typemap(argout) long long *INOUT = long long *OUTPUT; %typemap(argout) unsigned *INOUT = unsigned *OUTPUT; %typemap(argout) unsigned short *INOUT = unsigned short *OUTPUT; %typemap(argout) unsigned long *INOUT = unsigned long *OUTPUT; %typemap(argout) unsigned long long *INOUT = unsigned long long *OUTPUT; %typemap(argout) unsigned char *INOUT = unsigned char *OUTPUT; %typemap(argout) bool *INOUT = bool *OUTPUT; %typemap(argout) float *INOUT = float *OUTPUT; %typemap(argout) double *INOUT = double *OUTPUT; %typemap(argout) int &INOUT = int &OUTPUT; %typemap(argout) short &INOUT = short &OUTPUT; %typemap(argout) long &INOUT = long &OUTPUT; %typemap(argout) long long &INOUT = long long &OUTPUT; %typemap(argout) unsigned &INOUT = unsigned &OUTPUT; %typemap(argout) unsigned short &INOUT = unsigned short &OUTPUT; %typemap(argout) unsigned long &INOUT = unsigned long &OUTPUT; %typemap(argout) unsigned long long &INOUT = unsigned long long &OUTPUT; %typemap(argout) unsigned char &INOUT = unsigned char &OUTPUT; %typemap(argout) bool &INOUT = bool &OUTPUT; %typemap(argout) float &INOUT = float &OUTPUT; %typemap(argout) double &INOUT = double &OUTPUT; /* Overloading information */ %typemap(typecheck) double *INOUT = double; %typemap(typecheck) bool *INOUT = bool; %typemap(typecheck) signed char *INOUT = signed char; %typemap(typecheck) unsigned char *INOUT = unsigned char; %typemap(typecheck) unsigned long *INOUT = unsigned long; %typemap(typecheck) unsigned long long *INOUT = unsigned long long; %typemap(typecheck) unsigned short *INOUT = unsigned short; %typemap(typecheck) unsigned int *INOUT = unsigned int; %typemap(typecheck) long *INOUT = long; %typemap(typecheck) long long *INOUT = long long; %typemap(typecheck) short *INOUT = short; %typemap(typecheck) int *INOUT = int; %typemap(typecheck) float *INOUT = float; %typemap(typecheck) double &INOUT = double; %typemap(typecheck) bool &INOUT = bool; %typemap(typecheck) signed char &INOUT = signed char; %typemap(typecheck) unsigned char &INOUT = unsigned char; %typemap(typecheck) unsigned long &INOUT = unsigned long; %typemap(typecheck) unsigned long long &INOUT = unsigned long long; %typemap(typecheck) unsigned short &INOUT = unsigned short; %typemap(typecheck) unsigned int &INOUT = unsigned int; %typemap(typecheck) long &INOUT = long; %typemap(typecheck) long long &INOUT = long long; %typemap(typecheck) short &INOUT = short; %typemap(typecheck) int &INOUT = int; %typemap(typecheck) float &INOUT = float; cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/std_pair.i0000644000175000000620000014050312561312227021607 0ustar stevestaff// // SWIG typemaps for std::pair // Luigi Ballabio // July 2003 // // Python implementation %include std_common.i %include exception.i // ------------------------------------------------------------------------ // std::pair // // See std_vector.i for the rationale of typemap application // ------------------------------------------------------------------------ %{ #include %} // exported class namespace std { template struct pair { %typemap(in) pair (std::pair* p) { if (PyTuple_Check($input)) { if (PyTuple_Size($input) != 2) { SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); } T* x; U* y; PyObject* first = PySequence_GetItem($input,0); PyObject* second = PySequence_GetItem($input,1); if (SWIG_ConvertPtr(first,(void **) &x, $descriptor(T *),0) != -1 && SWIG_ConvertPtr(second,(void **) &y, $descriptor(U *),0) != -1) { $1 = std::make_pair(x,y); Py_DECREF(first); Py_DECREF(second); } else { Py_DECREF(first); Py_DECREF(second); SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); } } else if (SWIG_ConvertPtr($input,(void **) &p, $&1_descriptor,0) != -1) { $1 = *p; } else { SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); } } %typemap(in) const pair& (std::pair temp, std::pair* p), const pair* (std::pair temp, std::pair* p) { if (PyTuple_Check($input)) { if (PyTuple_Size($input) != 2) { SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); } T* x; U* y; PyObject* first = PySequence_GetItem($input,0); PyObject* second = PySequence_GetItem($input,1); if (SWIG_ConvertPtr(first,(void **) &x, $descriptor(T *),0) != -1 && SWIG_ConvertPtr(second,(void **) &y, $descriptor(U *),0) != -1) { temp = std::make_pair(x,y); $1 = &temp; Py_DECREF(first); Py_DECREF(second); } else { Py_DECREF(first); Py_DECREF(second); SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); } } else if (SWIG_ConvertPtr($input,(void **) &p, $1_descriptor,0) != -1) { $1 = p; } else { SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); } } %typemap(out) pair { $result = PyTuple_New(2); T* x = new T($1.first); U* y = new U($1.second); PyTuple_SetItem($result,0, SWIG_NewPointerObj((void *) x, $descriptor(T *), 1)); PyTuple_SetItem($result,1, SWIG_NewPointerObj((void *) y, $descriptor(U *), 1)); } %typecheck(SWIG_TYPECHECK_PAIR) pair { /* native sequence? */ if (PyTuple_Check($input)) { if (PyTuple_Size($input) != 2) { /* not a pair anyway */ $1 = 0; } else { T* x; U* y; PyObject* first = PySequence_GetItem($input,0); PyObject* second = PySequence_GetItem($input,1); if (SWIG_ConvertPtr(first,(void **) &x, $descriptor(T *),0) != -1 && SWIG_ConvertPtr(second,(void **) &y, $descriptor(U *),0) != -1) { $1 = 1; } else { $1 = 0; } } } else { /* wrapped pair? */ std::pair* p; if (SWIG_ConvertPtr($input,(void **) &p, $&1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_PAIR) const pair&, const pair* { /* native sequence? */ if (PyTuple_Check($input)) { if (PyTuple_Size($input) != 2) { /* not a pair anyway */ $1 = 0; } else { T* x; U* y; PyObject* first = PySequence_GetItem($input,0); PyObject* second = PySequence_GetItem($input,1); if (SWIG_ConvertPtr(first,(void **) &x, $descriptor(T *),0) != -1 && SWIG_ConvertPtr(second,(void **) &y, $descriptor(U *),0) != -1) { $1 = 1; } else { $1 = 0; } } } else { /* wrapped pair? */ std::pair* p; if (SWIG_ConvertPtr($input,(void **) &p, $1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } T first; U second; }; // specializations for built-ins %define specialize_std_pair_on_first(T,CHECK,CONVERT_FROM,CONVERT_TO) template struct pair { %typemap(in) pair (std::pair* p) { if (PyTuple_Check($input)) { if (PyTuple_Size($input) != 2) { SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); } U* y; PyObject* first = PySequence_GetItem($input,0); PyObject* second = PySequence_GetItem($input,1); if (CHECK(first) && SWIG_ConvertPtr(second,(void **) &y, $descriptor(U *),0) != -1) { $1 = std::make_pair(CONVERT_FROM(first),y); Py_DECREF(first); Py_DECREF(second); } else { Py_DECREF(first); Py_DECREF(second); SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); } } else if (SWIG_ConvertPtr($input,(void **) &p, $&1_descriptor,0) != -1) { $1 = *p; } else { SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); } } %typemap(in) const pair& (std::pair temp, std::pair* p), const pair* (std::pair temp, std::pair* p) { if (PyTuple_Check($input)) { if (PyTuple_Size($input) != 2) { SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); } U* y; PyObject* first = PySequence_GetItem($input,0); PyObject* second = PySequence_GetItem($input,1); if (CHECK(first) && SWIG_ConvertPtr(second,(void **) &y, $descriptor(U *),0) != -1) { temp = std::make_pair(CONVERT_FROM(first),y); $1 = &temp; Py_DECREF(first); Py_DECREF(second); } else { Py_DECREF(first); Py_DECREF(second); SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); } } else if (SWIG_ConvertPtr($input,(void **) &p, $1_descriptor,0) != -1) { $1 = p; } else { SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); } } %typemap(out) pair { $result = PyTuple_New(2); U* y = new U($1.second); PyTuple_SetItem($result,0,CONVERT_TO($1.first)); PyTuple_SetItem($result,1, SWIG_NewPointerObj((void *) y, $descriptor(U *), 1)); } %typecheck(SWIG_TYPECHECK_PAIR) pair { /* native sequence? */ if (PyTuple_Check($input)) { if (PyTuple_Size($input) != 2) { /* not a pair anyway */ $1 = 0; } else { U* y; PyObject* first = PySequence_GetItem($input,0); PyObject* second = PySequence_GetItem($input,1); if (CHECK(first) && SWIG_ConvertPtr(second,(void **) &y, $descriptor(U *),0) != -1) { $1 = 1; } else { $1 = 0; } } } else { /* wrapped pair? */ std::pair* p; if (SWIG_ConvertPtr($input,(void **) &p, $&1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_PAIR) const pair&, const pair* { /* native sequence? */ if (PyTuple_Check($input)) { if (PyTuple_Size($input) != 2) { /* not a pair anyway */ $1 = 0; } else { U* y; PyObject* first = PySequence_GetItem($input,0); PyObject* second = PySequence_GetItem($input,1); if (CHECK(first) && SWIG_ConvertPtr(second,(void **) &y, $descriptor(U *),0) != -1) { $1 = 1; } else { $1 = 0; } } } else { /* wrapped pair? */ std::pair* p; if (SWIG_ConvertPtr($input,(void **) &p, $1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } T first; U second; }; %enddef %define specialize_std_pair_on_second(U,CHECK,CONVERT_FROM,CONVERT_TO) template struct pair { %typemap(in) pair (std::pair* p) { if (PyTuple_Check($input)) { if (PyTuple_Size($input) != 2) { SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); } T* x; PyObject* first = PySequence_GetItem($input,0); PyObject* second = PySequence_GetItem($input,1); if (SWIG_ConvertPtr(first,(void **) &x, $descriptor(T *),0) != -1 && CHECK(second)) { $1 = std::make_pair(x,CONVERT_FROM(second)); Py_DECREF(first); Py_DECREF(second); } else { Py_DECREF(first); Py_DECREF(second); SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); } } else if (SWIG_ConvertPtr($input,(void **) &p, $&1_descriptor,0) != -1) { $1 = *p; } else { SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); } } %typemap(in) const pair& (std::pair temp, std::pair* p), const pair* (std::pair temp, std::pair* p) { if (PyTuple_Check($input)) { if (PyTuple_Size($input) != 2) { SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); } T* x; PyObject* first = PySequence_GetItem($input,0); PyObject* second = PySequence_GetItem($input,1); if (SWIG_ConvertPtr(first,(void **) &x, $descriptor(T *),0) != -1 && CHECK(second)) { temp = std::make_pair(x,CONVERT_FROM(second)); $1 = &temp; Py_DECREF(first); Py_DECREF(second); } else { Py_DECREF(first); Py_DECREF(second); SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); } } else if (SWIG_ConvertPtr($input,(void **) &p, $1_descriptor,0) != -1) { $1 = p; } else { SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); } } %typemap(out) pair { $result = PyTuple_New(2); T* x = new T($1.first); PyTuple_SetItem($result,0, SWIG_NewPointerObj((void *) x, $descriptor(T *), 1)); PyTuple_SetItem($result,1,CONVERT_TO($1.second)); } %typecheck(SWIG_TYPECHECK_PAIR) pair { /* native sequence? */ if (PyTuple_Check($input)) { if (PyTuple_Size($input) != 2) { /* not a pair anyway */ $1 = 0; } else { T* x; PyObject* first = PySequence_GetItem($input,0); PyObject* second = PySequence_GetItem($input,1); if (SWIG_ConvertPtr(first,(void **) &x, $descriptor(T *),0) != -1 && CHECK(second)) { $1 = 1; } else { $1 = 0; } } } else { /* wrapped pair? */ std::pair* p; if (SWIG_ConvertPtr($input,(void **) &p, $&1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_PAIR) const pair&, const pair* { /* native sequence? */ if (PyTuple_Check($input)) { if (PyTuple_Size($input) != 2) { /* not a pair anyway */ $1 = 0; } else { T* x; PyObject* first = PySequence_GetItem($input,0); PyObject* second = PySequence_GetItem($input,1); if (SWIG_ConvertPtr(first,(void **) &x, $descriptor(T *),0) != -1 && CHECK(second)) { $1 = 1; } else { $1 = 0; } } } else { /* wrapped pair? */ std::pair* p; if (SWIG_ConvertPtr($input,(void **) &p, $1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } T first; U second; }; %enddef %define specialize_std_pair_on_both(T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO, U,CHECK_U,CONVERT_U_FROM,CONVERT_U_TO) template<> struct pair { %typemap(in) pair (std::pair* p) { if (PyTuple_Check($input)) { if (PyTuple_Size($input) != 2) { SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); } PyObject* first = PySequence_GetItem($input,0); PyObject* second = PySequence_GetItem($input,1); if (CHECK_T(first) && CHECK_U(second)) { $1 = std::make_pair(CONVERT_T_FROM(first), CONVERT_U_FROM(second)); Py_DECREF(first); Py_DECREF(second); } else { Py_DECREF(first); Py_DECREF(second); SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); } } else if (SWIG_ConvertPtr($input,(void **) &p, $&1_descriptor,0) != -1) { $1 = *p; } else { SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); } } %typemap(in) const pair& (std::pair temp, std::pair* p), const pair* (std::pair temp, std::pair* p) { if (PyTuple_Check($input)) { if (PyTuple_Size($input) != 2) { SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); } PyObject* first = PySequence_GetItem($input,0); PyObject* second = PySequence_GetItem($input,1); if (CHECK_T(first) && CHECK_U(second)) { temp = std::make_pair(CONVERT_T_FROM(first), CONVERT_U_FROM(second)); $1 = &temp; Py_DECREF(first); Py_DECREF(second); } else { Py_DECREF(first); Py_DECREF(second); SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); } } else if (SWIG_ConvertPtr($input,(void **) &p, $1_descriptor,0) != -1) { $1 = p; } else { SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); } } %typemap(out) pair { $result = PyTuple_New(2); PyTuple_SetItem($result,0,CONVERT_T_TO($1.first)); PyTuple_SetItem($result,1,CONVERT_U_TO($1.second)); } %typecheck(SWIG_TYPECHECK_PAIR) pair { /* native sequence? */ if (PyTuple_Check($input)) { if (PyTuple_Size($input) != 2) { /* not a pair anyway */ $1 = 0; } else { PyObject* first = PySequence_GetItem($input,0); PyObject* second = PySequence_GetItem($input,1); if (CHECK_T(first) && CHECK_U(second)) { $1 = 1; } else { $1 = 0; } } } else { /* wrapped pair? */ std::pair* p; if (SWIG_ConvertPtr($input,(void **) &p, $&1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_PAIR) const pair&, const pair* { /* native sequence? */ if (PyTuple_Check($input)) { if (PyTuple_Size($input) != 2) { /* not a pair anyway */ $1 = 0; } else { PyObject* first = PySequence_GetItem($input,0); PyObject* second = PySequence_GetItem($input,1); if (CHECK_T(first) && CHECK_U(second)) { $1 = 1; } else { $1 = 0; } } } else { /* wrapped pair? */ std::pair* p; if (SWIG_ConvertPtr($input,(void **) &p, $1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } T first; U second; }; %enddef specialize_std_pair_on_first(bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool); specialize_std_pair_on_first(int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_first(short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_first(long,PyLong_Check, PyLong_AsLong,PyLong_FromLong); specialize_std_pair_on_first(unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_first(unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_first(unsigned long,PyLong_Check, PyLong_AsUnsignedLong, PyLong_FromUnsignedLong); specialize_std_pair_on_first(double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_pair_on_first(float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_pair_on_first(std::string,PyString_Check, SwigString_AsString,SwigString_FromString); specialize_std_pair_on_second(bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool); specialize_std_pair_on_second(int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_second(short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_second(long,PyLong_Check, PyLong_AsLong,PyLong_FromLong); specialize_std_pair_on_second(unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_second(unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_second(unsigned long,PyLong_Check, PyLong_AsUnsignedLong, PyLong_FromUnsignedLong); specialize_std_pair_on_second(double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_pair_on_second(float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_pair_on_second(std::string,PyString_Check, SwigString_AsString,SwigString_FromString); specialize_std_pair_on_both(bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool, bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool); specialize_std_pair_on_both(bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool, int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool, short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool, long,PyLong_Check, PyLong_AsLong,PyLong_FromLong); specialize_std_pair_on_both(bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool, unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool, unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool, unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); specialize_std_pair_on_both(bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool, double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_pair_on_both(bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool, float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_pair_on_both(bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool, std::string,PyString_Check, SwigString_AsString,SwigString_FromString); specialize_std_pair_on_both(int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool); specialize_std_pair_on_both(int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, long,PyLong_Check, PyLong_AsLong,PyLong_FromLong); specialize_std_pair_on_both(int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); specialize_std_pair_on_both(int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_pair_on_both(int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_pair_on_both(int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, std::string,PyString_Check, SwigString_AsString,SwigString_FromString); specialize_std_pair_on_both(short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool); specialize_std_pair_on_both(short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, long,PyLong_Check, PyLong_AsLong,PyLong_FromLong); specialize_std_pair_on_both(short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); specialize_std_pair_on_both(short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_pair_on_both(short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_pair_on_both(short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, std::string,PyString_Check, SwigString_AsString,SwigString_FromString); specialize_std_pair_on_both(long,PyLong_Check, PyLong_AsLong,PyLong_FromLong, bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool); specialize_std_pair_on_both(long,PyLong_Check, PyLong_AsLong,PyLong_FromLong, int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(long,PyLong_Check, PyLong_AsLong,PyLong_FromLong, short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(long,PyLong_Check, PyLong_AsLong,PyLong_FromLong, long,PyLong_Check, PyLong_AsLong,PyLong_FromLong); specialize_std_pair_on_both(long,PyLong_Check, PyLong_AsLong,PyLong_FromLong, unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(long,PyLong_Check, PyLong_AsLong,PyLong_FromLong, unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(long,PyLong_Check, PyLong_AsLong,PyLong_FromLong, unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); specialize_std_pair_on_both(long,PyLong_Check, PyLong_AsLong,PyLong_FromLong, double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_pair_on_both(long,PyLong_Check, PyLong_AsLong,PyLong_FromLong, float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_pair_on_both(long,PyLong_Check, PyLong_AsLong,PyLong_FromLong, std::string,PyString_Check, SwigString_AsString,SwigString_FromString); specialize_std_pair_on_both(unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool); specialize_std_pair_on_both(unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, long,PyLong_Check, PyLong_AsLong,PyLong_FromLong); specialize_std_pair_on_both(unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); specialize_std_pair_on_both(unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_pair_on_both(unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_pair_on_both(unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong, std::string,PyString_Check, SwigString_AsString,SwigString_FromString); specialize_std_pair_on_both(unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool); specialize_std_pair_on_both(unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, long,PyLong_Check, PyLong_AsLong,PyLong_FromLong); specialize_std_pair_on_both(unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); specialize_std_pair_on_both(unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_pair_on_both(unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_pair_on_both(unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong, std::string,PyString_Check, SwigString_AsString,SwigString_FromString); specialize_std_pair_on_both(unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool); specialize_std_pair_on_both(unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, long,PyLong_Check, PyLong_AsLong,PyLong_FromLong); specialize_std_pair_on_both(unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); specialize_std_pair_on_both(unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_pair_on_both(unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_pair_on_both(unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong, std::string,PyString_Check, SwigString_AsString,SwigString_FromString); specialize_std_pair_on_both(double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool); specialize_std_pair_on_both(double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, long,PyLong_Check, PyLong_AsLong,PyLong_FromLong); specialize_std_pair_on_both(double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); specialize_std_pair_on_both(double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_pair_on_both(double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_pair_on_both(double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, std::string,PyString_Check, SwigString_AsString,SwigString_FromString); specialize_std_pair_on_both(float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool); specialize_std_pair_on_both(float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, long,PyLong_Check, PyLong_AsLong,PyLong_FromLong); specialize_std_pair_on_both(float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); specialize_std_pair_on_both(float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_pair_on_both(float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_pair_on_both(float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble, std::string,PyString_Check, SwigString_AsString,SwigString_FromString); specialize_std_pair_on_both(std::string,PyString_Check, SwigString_AsString,SwigString_FromString, bool,PyInt_Check, PyInt_AsLong,SwigInt_FromBool); specialize_std_pair_on_both(std::string,PyString_Check, SwigString_AsString,SwigString_FromString, int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(std::string,PyString_Check, SwigString_AsString,SwigString_FromString, short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(std::string,PyString_Check, SwigString_AsString,SwigString_FromString, long,PyLong_Check, PyLong_AsLong,PyLong_FromLong); specialize_std_pair_on_both(std::string,PyString_Check, SwigString_AsString,SwigString_FromString, unsigned int,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(std::string,PyString_Check, SwigString_AsString,SwigString_FromString, unsigned short,PyInt_Check, PyInt_AsLong,PyInt_FromLong); specialize_std_pair_on_both(std::string,PyString_Check, SwigString_AsString,SwigString_FromString, unsigned long,PyLong_Check, PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); specialize_std_pair_on_both(std::string,PyString_Check, SwigString_AsString,SwigString_FromString, double,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_pair_on_both(std::string,PyString_Check, SwigString_AsString,SwigString_FromString, float,SwigNumber_Check, SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_pair_on_both(std::string,PyString_Check, SwigString_AsString,SwigString_FromString, std::string,PyString_Check, SwigString_AsString,SwigString_FromString); } cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/embed.i0000644000175000000620000000522212561312227021054 0ustar stevestaff// // embed15.i // SWIG file embedding the Python interpreter in something else. // This file is based on Python-1.5. It will not work with // earlier versions. // // This file makes it possible to extend Python and all of its // built-in functions without having to hack it's setup script. // #ifdef AUTODOC %subsection "embed.i" %text %{ This module provides support for building a new version of the Python executable. This will be necessary on systems that do not support shared libraries and may be necessary with C++ extensions. This file contains everything you need to build a new version of Python from include files and libraries normally installed with the Python language. This module will automatically grab all of the Python modules present in your current Python executable (including any special purpose modules you have enabled such as Tkinter). Thus, you may need to provide additional link libraries when compiling. This library file only works with Python 1.5. A version compatible with Python 1.4 is available as embed14.i and a Python1.3 version is available as embed13.i. As far as I know, this module is C++ safe. %} #else %echo "embed.i : Using Python 1.5" #endif %wrapper %{ #include #ifdef __cplusplus extern "C" #endif void SWIG_init(); /* Forward reference */ #define _PyImport_Inittab swig_inittab /* Grab Python's inittab[] structure */ #ifdef __cplusplus extern "C" { #endif #include #undef _PyImport_Inittab /* Now define our own version of it. Hopefully someone does not have more than 1000 built-in modules */ struct _inittab SWIG_Import_Inittab[1000]; static int swig_num_modules = 0; /* Function for adding modules to Python */ static void swig_add_module(char *name, void (*initfunc)()) { SWIG_Import_Inittab[swig_num_modules].name = name; SWIG_Import_Inittab[swig_num_modules].initfunc = initfunc; swig_num_modules++; SWIG_Import_Inittab[swig_num_modules].name = (char *) 0; SWIG_Import_Inittab[swig_num_modules].initfunc = 0; } /* Function to add all of Python's build in modules to our interpreter */ static void swig_add_builtin() { int i = 0; while (swig_inittab[i].name) { swig_add_module(swig_inittab[i].name, swig_inittab[i].initfunc); i++; } #ifdef SWIGMODINIT SWIGMODINIT #endif /* Add SWIG builtin function */ swig_add_module(SWIG_name, SWIG_init); } #ifdef __cplusplus } #endif #ifdef __cplusplus extern "C" { #endif extern int Py_Main(int, char **); #ifdef __cplusplus } #endif extern struct _inittab *PyImport_Inittab; int main(int argc, char **argv) { swig_add_builtin(); PyImport_Inittab = SWIG_Import_Inittab; return Py_Main(argc,argv); } %} cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/pyswigtype.swg0000644000175000000620000001673712561312227022611 0ustar stevestaff/* ----------------------------------------------------------------------------- * --- Input arguments --- * ----------------------------------------------------------------------------- */ /* Pointers, references, and arrays */ %typemap(in) SWIGTYPE *, SWIGTYPE [] "if ((SWIG_ConvertPtr($input,(void **)(&$1),$1_descriptor, SWIG_POINTER_EXCEPTION | $disown)) == -1) SWIG_fail;"; %typemap(in) SWIGTYPE *DISOWN "if ((SWIG_ConvertPtr($input,(void **)(&$1),$1_descriptor, SWIG_POINTER_EXCEPTION | SWIG_POINTER_DISOWN)) == -1) SWIG_fail;"; /* Additional check for null references */ %typemap(in) SWIGTYPE & "if ((SWIG_ConvertPtr($input,(void **)(&$1),$1_descriptor, SWIG_POINTER_EXCEPTION | $disown)) == -1) SWIG_fail; if ($1 == NULL) { PyErr_SetString(PyExc_TypeError,\"null reference\"); SWIG_fail; }"; /* Object passed by value. Convert to a pointer */ %typemap(in) SWIGTYPE ($&1_ltype argp) "if ((SWIG_ConvertPtr($input,(void **)(&argp),$&1_descriptor, SWIG_POINTER_EXCEPTION) == -1)) SWIG_fail; $1 = *argp;"; /* Pointer to a class member */ %typemap(in) SWIGTYPE (CLASS::*) "if ((SWIG_ConvertPacked($input,(void *)(&$1),sizeof($1_type), $1_descriptor,SWIG_POINTER_EXCEPTION)) == -1) SWIG_fail;"; /* ----------------------------------------------------------------------------- * --- Outnput arguments --- * ----------------------------------------------------------------------------- */ /* Pointers, references, and arrays */ %typemap(out) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] "$result = SWIG_NewPointerObj((void*)($1), $1_descriptor, $owner);"; /* Dynamic casts */ %typemap(out) SWIGTYPE *DYNAMIC, SWIGTYPE &DYNAMIC { swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor, (void **) &$1); $result = SWIG_NewPointerObj((void *) $1, ty, $owner); } /* Member pointer */ %typemap(out) SWIGTYPE (CLASS::*) "$result = SWIG_NewPackedObj((void*)(&$1), sizeof($1_type), $1_descriptor);"; /* Primitive types--return by value */ #ifdef __cplusplus %typemap(out) SWIGTYPE { $&1_ltype resultptr; resultptr = new $1_ltype(($1_ltype &) $1); $result = SWIG_NewPointerObj((void *)(resultptr), $&1_descriptor, 1); } #else %typemap(out /* warning="452:Default return typemap could be unsafe" */) SWIGTYPE { $&1_ltype resultptr; resultptr = ($&1_ltype) malloc(sizeof($1_type)); memmove(resultptr, &$1, sizeof($1_type)); $result = SWIG_NewPointerObj((void *)(resultptr), $&1_descriptor, 1); } #endif /* ----------------------------------------------------------------------------- * --- Variable input --- * ----------------------------------------------------------------------------- */ /* Pointers, references, and arrays */ %typemap(varin) SWIGTYPE [ANY] { void *temp; int ii; $1_basetype *b = 0; if ((SWIG_ConvertPtr($input, &temp, $1_descriptor, SWIG_POINTER_EXCEPTION)) == -1) { PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); return 1; } b = ($1_basetype *) $1; for (ii = 0; ii < $1_size; ii++) b[ii] = *(($1_basetype *) temp + ii); } %typemap(varin) SWIGTYPE * { void *temp; if ((SWIG_ConvertPtr($input, &temp, $1_descriptor, SWIG_POINTER_EXCEPTION | SWIG_POINTER_DISOWN)) == -1) { PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); return 1; } $1 = ($1_ltype) temp; } %typemap(varin) SWIGTYPE & { void *temp; if ((SWIG_ConvertPtr($input, &temp, $1_descriptor, SWIG_POINTER_EXCEPTION)) == -1 || temp == NULL) { PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); return 1; } $1 = *($1_ltype) temp; } %typemap(varin) SWIGTYPE (CLASS::*) { char temp[sizeof($1_type)]; if ((SWIG_ConvertPacked($input,(void *) temp, sizeof($1_type), $1_descriptor, SWIG_POINTER_EXCEPTION)) == -1) { PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); return 1; } memmove((void *) &$1,temp,sizeof($1_type)); } %typemap(varin) SWIGTYPE { $&1_ltype temp; if ((SWIG_ConvertPtr($input, (void **)(&temp), $&1_descriptor, SWIG_POINTER_EXCEPTION)) == -1) { PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); return 1; } $1 = *(($&1_type) temp); } /* ----------------------------------------------------------------------------- * --- Variable output --- * ----------------------------------------------------------------------------- */ /* Pointers and arrays */ %typemap(varout) SWIGTYPE *, SWIGTYPE [] "$result = SWIG_NewPointerObj((void *)($1), $1_descriptor, 0);"; /* References */ %typemap(varout) SWIGTYPE & "$result = SWIG_NewPointerObj((void *)(&$1), $1_descriptor, 0);"; /* Member pointer */ %typemap(varout) SWIGTYPE (CLASS::*) "$result = SWIG_NewPackedObj((void *)(&$1), sizeof($1_type), $1_descriptor);"; %typemap(varout) SWIGTYPE "$result = SWIG_NewPointerObj((void *)(&$1), $&1_descriptor, 0);"; /* ----------------------------------------------------------------------------- * --- Constants --- * * ----------------------------------------------------------------------------- */ /* Pointers, arrays, objects */ %typemap(consttab) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { SWIG_PY_POINTER, (char*)"$symname", 0, 0, (void *)$value, &$1_descriptor} %typemap(consttab) SWIGTYPE (CLASS::*) { SWIG_PY_BINARY, (char *)"$symname", sizeof($type), 0, (void *)&$value, &$1_descriptor} /* ----------------------------------------------------------------------------- * --- Director typemaps --- * * ----------------------------------------------------------------------------- */ /* director in not needed, see python.cxx */ /* directorout */ %typemap(directorout) SWIGTYPE ($<ype argp) "if ((SWIG_ConvertPtr($input, (void **)(&argp), $&descriptor, SWIG_POINTER_EXCEPTION | $disown)) == -1) throw Swig::DirectorTypeMismatchException(\"Pointer conversion failed.\"); $result = *argp;"; %typemap(directorout) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] "if ((SWIG_ConvertPtr($input,(void **)(&$result), $descriptor,SWIG_POINTER_EXCEPTION | $disown )) == -1) throw Swig::DirectorTypeMismatchException(\"Pointer conversion failed.\");"; /* ------------------------------------------------------------ * --- Typechecking rules --- * ------------------------------------------------------------ */ %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { void *ptr; if (SWIG_ConvertPtr($input, &ptr, $1_descriptor, 0) == -1) { $1 = 0; PyErr_Clear(); } else { $1 = 1; } } %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE { void *ptr; if (SWIG_ConvertPtr($input, &ptr, $&1_descriptor, 0) == -1) { $1 = 0; PyErr_Clear(); } else { $1 = 1; } } /* ------------------------------------------------------------ * --- Exception handling --- * ------------------------------------------------------------ */ %typemap(throws) SWIGTYPE { $&1_ltype temp = new $1_ltype($1); if ($&1_descriptor->clientdata) { PyErr_SetObject((PyObject *) ($&1_descriptor->clientdata), SWIG_NewPointerObj(temp,$&1_descriptor,1)); } else { PyErr_SetString(PyExc_RuntimeError,"$1_type"); /* PyErr_SetObject(PyExc_RuntimeError, SWIG_NewPointerObj(temp,$&1_descriptor,1)); */ } SWIG_fail; } /* This doesn't work, and not sure if it is needed... */ #if 0 %typecheck(throws) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { if ($1_descriptor->clientdata) { PyErr_SetObject((PyObject *) ($1_descriptor->clientdata), SWIG_NewPointerObj($1,$1_descriptor,1)); } else { PyErr_SetString(PyExc_RuntimeError,"$1_type"); } SWIG_fail; } #endif cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/complex.i0000644000175000000620000000025112561312227021444 0ustar stevestaff#ifndef __python_complex_i__ #define __python_complex_i__ #ifdef __cplusplus %include #else %include #endif #endif //__python_complex_i__ cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/fragments.i0000644000175000000620000000140312561312227021763 0ustar stevestaff/* Helper function to return tuples */ %fragment("t_output_helper","header") %{ static PyObject* t_output_helper(PyObject* target, PyObject* o) { PyObject* o2; PyObject* o3; if (!target) { target = o; } else if (target == Py_None) { Py_DECREF(Py_None); target = o; } else { if (!PyTuple_Check(target)) { o2 = target; target = PyTuple_New(1); PyTuple_SetItem(target, 0, o2); } o3 = PyTuple_New(1); PyTuple_SetItem(o3, 0, o); o2 = target; target = PySequence_Concat(o2, o3); Py_DECREF(o2); Py_DECREF(o3); } return target; } %} cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/std_deque.i0000644000175000000620000000103112561312227021747 0ustar stevestaff/* Default std_deque wrapper */ %module std_deque %rename(__getitem__) std::deque::getitem; %rename(__setitem__) std::deque::setitem; %rename(__delitem__) std::deque::delitem; %rename(__getslice__) std::deque::getslice; %rename(__setslice__) std::deque::setslice; %rename(__delslice__) std::deque::delslice; %extend std::deque { int __len__() { return (int) self->size(); } int __nonzero__() { return ! self->empty(); } void append(const T &x) { self->push_back(x); } }; %include "_std_deque.i" cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/pyvaltypes.swg0000644000175000000620000000724412561312227022576 0ustar stevestaff/* in */ %define PY_IN_TYPEMAP(type, pyobj_as) %typemap(in,fragment=#pyobj_as) type "$1 = ($1_type) pyobj_as($input); if (PyErr_Occurred()) SWIG_fail;" %typemap(in) const type& ($basetype temp) "temp = ($basetype) pyobj_as($input); if (PyErr_Occurred()) SWIG_fail; $1 = &temp;"; %enddef /* out */ %define PY_OUT_TYPEMAP(type, pyobj_from) %typemap(out,fragment=#pyobj_from) type "$result = pyobj_from((type)$1);"; %typemap(out,fragment=#pyobj_from) const type& "$result = pyobj_from((type)*($1));"; %enddef /* varin */ %define PY_VARIN_TYPEMAP(type, pyobj_as) %typemap(varin,fragment=#pyobj_as) type { $1_type temp = ($1_type) pyobj_as($input); if (PyErr_Occurred()) { PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); return 1; } $1 = temp; } %enddef /* varout */ %define PY_VAROUT_TYPEMAP(type, pyobj_from) %typemap(varout,fragment=#pyobj_from) type, const type& "$result = pyobj_from((type)$1);"; %enddef /* Primitive types */ %define PY_CONSTCODE_TYPEMAP(type, pyobj_from) %typemap(constcode,fragment=#pyobj_from) type "PyDict_SetItemString(d,\"$symname\", pyobj_from((type)$value));"; %enddef /* directorin */ %define PY_DIRECTORIN_TYPEMAP(type, pyobj_from) %typemap(directorin,fragment=#pyobj_from) type *DIRECTORIN "$input = pyobj_from((type)*$1_name);"; %typemap(directorin,fragment=#pyobj_from) type, const type& "$input = pyobj_from((type)$1_name);"; %enddef /* directorout */ %define PY_DIRECTOROUT_TYPEMAP(Type, pyobj_as) %typemap(directorargout,fragment=#pyobj_as) Type *DIRECTOROUT "*$result = ($basetype) pyobj_as($input); if (PyErr_Occurred()) throw Swig::DirectorTypeMismatchException(\"Error converting Python object using pyobj_as\");"; %typemap(directorout,fragment=#pyobj_as) Type "$result = ($basetype) pyobj_as($input); if (PyErr_Occurred()) throw Swig::DirectorTypeMismatchException(\"Error converting Python object using pyobj_as\");"; %typemap(directorout,fragment=#pyobj_as) const Type& "$basetype temp = ($basetype) pyobj_as($input); $result = &temp; if (PyErr_Occurred()) throw Swig::DirectorTypeMismatchException(\"Error converting Python object using pyobj_as\");"; %typemap(directorout,fragment=#pyobj_as) Type &DIRECTOROUT = Type %enddef /* throws */ %define PY_THROWS_TYPEMAP(type, pyobj_from) %typemap(throws,fragment=#pyobj_from) type { PyErr_SetObject(PyExc_RuntimeError, pyobj_from((type)$1)); SWIG_fail; } %enddef /* typecheck */ %define PY_TYPECHECK_TYPEMAP(check, type, pyobj_check) %typemap(typecheck,precedence=SWIG_TYPECHECK_##check, fragment=#pyobj_check) type, const type& "$1 = pyobj_check($input);"; %enddef /* typemap definition for types with As/From/Check methods */ %define %typemap_asfromcheck(Type, CheckCode, AsType, FromType, CheckType) PY_IN_TYPEMAP(Type, AsType); PY_OUT_TYPEMAP(Type, FromType); PY_VARIN_TYPEMAP(Type, AsType); PY_VAROUT_TYPEMAP(Type, FromType); PY_CONSTCODE_TYPEMAP(Type, FromType); PY_DIRECTORIN_TYPEMAP(Type, FromType); PY_DIRECTOROUT_TYPEMAP(Type, AsType); PY_THROWS_TYPEMAP(Type, FromType); PY_TYPECHECK_TYPEMAP(CheckCode, Type, CheckType); %enddef /* typemap for simple swig types with only As/From conversor methods named as SWIG_As##Name/SWIG_From##Name. */ %define %typemap_stype(Type, CheckCode, Name) %fragment("SWIG_Check"#Name,"header", fragment="SWIG_As"#Name) %{ SWIGSTATICINLINE(int) SWIG_Check##Name(PyObject* obj) { SWIG_As##Name(obj); if (PyErr_Occurred()) { PyErr_Clear(); return 0; } else { return 1; } } %} %typemap_asfromcheck(Type, CheckCode, SWIG_As##Name, SWIG_From##Name, SWIG_Check##Name) %enddef cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/std_complex.i0000644000175000000620000000104012561312227022313 0ustar stevestaff#ifndef SWIG_STD_COMPLEX_I_ #define SWIG_STD_COMPLEX_I_ %include "complex_common.i" %{ #include %} /* defining the complex as/from converters */ %swig_cplxdbl_conv(std::complex, StdCplxDbl, std::complex, std::real, std::imag) %swig_cplxflt_conv(std::complex, StdCplxFlt, std::complex, std::real, std::imag) /* declaring the typemaps */ %typemap_stype(std::complex, CPLXDBL, StdCplxDbl); %typemap_stype(std::complex, CPLXFLT, StdCplxFlt); #endif //SWIG_STD_COMPLEX_I_ cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/pyvoid.swg0000644000175000000620000000217712561312227021670 0ustar stevestaff/* ------------------------------------------------------------ * Void * - Accepts any kind of pointer * ------------------------------------------------------------ */ /* in */ %typemap(in) void * "if ((SWIG_ConvertPtr($input,&$1,0,SWIG_POINTER_EXCEPTION | $disown)) == -1) SWIG_fail;"; /* out */ %typemap(out) void "Py_INCREF(Py_None); $result = Py_None;"; /* varin */ %typemap(varin) void * { void * temp; if ((SWIG_ConvertPtr($input, &temp, 0, SWIG_POINTER_EXCEPTION | SWIG_POINTER_DISOWN)) == -1) { PyErr_SetString(PyExc_TypeError, "C variable '$name ($1_ltype)'"); return 1; } $1 = ($1_ltype) temp; } /* varout */ %typemap(varout) void "Py_INCREF(Py_None); $result = Py_None;"; /* directorout */ %typemap(directorout) void * "if ((SWIG_ConvertPtr($input,(void **)(&$result), 0, SWIG_POINTER_EXCEPTION | $disown )) == -1) throw Swig::DirectorTypeMismatchException(\"Pointer conversion failed.\");"; /* typecheck */ %typecheck(SWIG_TYPECHECK_VOIDPTR) void * { void *ptr; if (SWIG_ConvertPtr($input, &ptr, 0, 0) == -1) { $1 = 0; PyErr_Clear(); } else { $1 = 1; } } cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/director.swg0000644000175000000620000001240412561312227022163 0ustar stevestaff/*********************************************************************** * director.swg * * This file contains support for director classes that proxy * method calls from C++ to Python extensions. * * Author : Mark Rose (mrose@stm.lbl.gov) ************************************************************************/ #ifdef __cplusplus #include namespace Swig { /* base class for director exceptions */ class DirectorException { protected: std::string swig_msg; public: DirectorException(const char* msg="") { } const char *getMessage() const { return swig_msg.c_str(); } virtual ~DirectorException() {} }; /* type mismatch in the return value from a python method call */ class DirectorTypeMismatchException : public Swig::DirectorException { public: DirectorTypeMismatchException(const char* msg="") { swig_msg = "Swig director type mismatch: "; swig_msg += msg; PyErr_SetString(PyExc_TypeError, msg); } }; /* any python exception that occurs during a director method call */ class DirectorMethodException : public Swig::DirectorException {}; /* attempt to call a pure virtual method via a director method */ class DirectorPureVirtualException : public Swig::DirectorException {}; /* simple thread abstraction for pthreads on win32 */ #ifdef __THREAD__ #define __PTHREAD__ #if defined(_WIN32) || defined(__WIN32__) #define pthread_mutex_lock EnterCriticalSection #define pthread_mutex_unlock LeaveCriticalSection #define pthread_mutex_t CRITICAL_SECTION #define MUTEX_INIT(var) CRITICAL_SECTION var #else #include #define MUTEX_INIT(var) pthread_mutex_t var = PTHREAD_MUTEX_INITIALIZER #endif #endif /* director base class */ class Director { private: /* pointer to the wrapped python object */ PyObject* swig_self; /* flag indicating whether the object is owned by python or c++ */ mutable bool swig_disown_flag; /* shared flag for breaking recursive director calls */ static bool swig_up; #ifdef __PTHREAD__ /* locks for sharing the swig_up flag in a threaded environment */ static pthread_mutex_t swig_mutex_up; static bool swig_mutex_active; static pthread_t swig_mutex_thread; #endif /* decrement the reference count of the wrapped python object */ void swig_decref() const { if (swig_disown_flag) { Py_DECREF(swig_self); } } /* reset the swig_up flag once the routing direction has been determined */ #ifdef __PTHREAD__ void swig_clear_up() const { Swig::Director::swig_up = false; Swig::Director::swig_mutex_active = false; pthread_mutex_unlock(&swig_mutex_up); } #else void swig_clear_up() const { Swig::Director::swig_up = false; } #endif public: /* wrap a python object, optionally taking ownership */ Director(PyObject* self, bool disown) : swig_self(self), swig_disown_flag(disown) { swig_incref(); } /* discard our reference at destruction */ virtual ~Director() { swig_decref(); } /* return a pointer to the wrapped python object */ PyObject *swig_get_self() const { return swig_self; } /* get the swig_up flag to determine if the method call should be routed * to the c++ base class or through the wrapped python object */ #ifdef __PTHREAD__ bool swig_get_up() const { if (Swig::Director::swig_mutex_active) { if (pthread_equal(Swig::Director::swig_mutex_thread, pthread_self())) { bool up = swig_up; swig_clear_up(); return up; } } return 0; } #else bool swig_get_up() const { bool up = swig_up; swig_up = false; return up; } #endif /* set the swig_up flag if the next method call should be directed to * the c++ base class rather than the wrapped python object */ #ifdef __PTHREAD__ void swig_set_up() const { pthread_mutex_lock(&Swig::Director::swig_mutex_up); Swig::Director::swig_mutex_thread = pthread_self(); Swig::Director::swig_mutex_active = true; Swig::Director::swig_up = true; } #else void swig_set_up() const { Swig::Director::swig_up = true; } #endif /* acquire ownership of the wrapped python object (the sense of "disown" * is from python) */ void swig_disown() const { if (!swig_disown_flag) { swig_disown_flag=true; swig_incref(); } } /* increase the reference count of the wrapped python object */ void swig_incref() const { if (swig_disown_flag) { Py_INCREF(swig_self); } } /* methods to implement pseudo protected director members */ virtual bool swig_get_inner(const char* name) const { return true; } virtual void swig_set_inner(const char* name, bool val) const { } }; bool Swig::Director::swig_up = false; #ifdef __PTHREAD__ MUTEX_INIT(Swig::Director::swig_mutex_up); pthread_t Swig::Director::swig_mutex_thread; bool Swig::Director::swig_mutex_active = false; #endif } #endif /* __cplusplus */ cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/std_vector.i0000644000175000000620000011204712561312227022160 0ustar stevestaff// // SWIG typemaps for std::vector types // Luigi Ballabio // Apr 8, 2002 // // Python implementation %include std_common.i %include exception.i // __getitem__ is required to raise an IndexError for for-loops to work // other methods which can raise are made to throw an IndexError as well %exception std::vector::__getitem__ { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::vector::__setitem__ { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::vector::__delitem__ { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::vector::pop { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } // ------------------------------------------------------------------------ // std::vector // // The aim of all that follows would be to integrate std::vector with // Python as much as possible, namely, to allow the user to pass and // be returned Python tuples or lists. // const declarations are used to guess the intent of the function being // exported; therefore, the following rationale is applied: // // -- f(std::vector), f(const std::vector&), f(const std::vector*): // the parameter being read-only, either a Python sequence or a // previously wrapped std::vector can be passed. // -- f(std::vector&), f(std::vector*): // the parameter must be modified; therefore, only a wrapped std::vector // can be passed. // -- std::vector f(): // the vector is returned by copy; therefore, a Python sequence of T:s // is returned which is most easily used in other Python functions // -- std::vector& f(), std::vector* f(), const std::vector& f(), // const std::vector* f(): // the vector is returned by reference; therefore, a wrapped std::vector // is returned // ------------------------------------------------------------------------ %{ #include #include #include %} // exported class namespace std { template class vector { %typemap(in) vector (std::vector* v) { if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); $1.reserve(size); for (unsigned int i=0; i expected"); SWIG_fail; } } } else if (SWIG_ConvertPtr($input,(void **) &v, $&1_descriptor,0) != -1) { $1 = *v; } else { PyErr_SetString(PyExc_TypeError,"vector<" #T "> expected"); SWIG_fail; } } %typemap(directorout) vector (std::vector* v) { if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); $result.reserve(size); for (unsigned int i=0; i expected"); } } } else if (SWIG_ConvertPtr($input,(void **) &v, $&descriptor,1) != -1){ $result = *v; } else { throw Swig::DirectorTypeMismatchException("vector<" #T "> expected"); } } %typemap(in) const vector& (std::vector temp, std::vector* v), const vector* (std::vector temp, std::vector* v) { if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); temp.reserve(size); $1 = &temp; for (unsigned int i=0; i expected"); SWIG_fail; } } } else if (SWIG_ConvertPtr($input,(void **) &v, $1_descriptor,0) != -1) { $1 = v; } else { PyErr_SetString(PyExc_TypeError,"vector<" #T "> expected"); SWIG_fail; } } %typemap(directorout) const vector& (std::vector temp, std::vector* v), const vector* (std::vector temp, std::vector* v) { if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); temp.reserve(size); $result = &temp; for (unsigned int i=0; i expected"); } } } else if (SWIG_ConvertPtr($input,(void **) &v, $descriptor,1) != -1){ $result = v; } else { throw Swig::DirectorTypeMismatchException("vector<" #T "> expected"); } } %typemap(out) vector { $result = PyTuple_New($1.size()); for (unsigned int i=0; i<$1.size(); i++) { T* ptr = new T((($1_type &)$1)[i]); PyTuple_SetItem($result,i, SWIG_NewPointerObj((void *) ptr, $descriptor(T *), 1)); } } %typemap(directorin) vector { $input = PyTuple_New($1_name.size()); for (unsigned int i=0; i<$1_name.size(); i++) { T* ptr = new T((($1_type &)$1_name)[i]); PyTuple_SetItem($input,i, SWIG_NewPointerObj((void *) ptr, $descriptor(T *), 1)); } } %typecheck(SWIG_TYPECHECK_VECTOR) vector { /* native sequence? */ if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); if (size == 0) { /* an empty sequence can be of any type */ $1 = 1; } else { /* check the first element only */ T* x; PyObject* o = PySequence_GetItem($input,0); if ((SWIG_ConvertPtr(o,(void **) &x, $descriptor(T *),0)) != -1) $1 = 1; else $1 = 0; Py_DECREF(o); } } else { /* wrapped vector? */ std::vector* v; if (SWIG_ConvertPtr($input,(void **) &v, $&1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_VECTOR) const vector&, const vector* { /* native sequence? */ if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); if (size == 0) { /* an empty sequence can be of any type */ $1 = 1; } else { /* check the first element only */ T* x; PyObject* o = PySequence_GetItem($input,0); if ((SWIG_ConvertPtr(o,(void **) &x, $descriptor(T *),0)) != -1) $1 = 1; else $1 = 0; Py_DECREF(o); } } else { /* wrapped vector? */ std::vector* v; if (SWIG_ConvertPtr($input,(void **) &v, $1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } public: vector(unsigned int size = 0); vector(unsigned int size, const T& value); vector(const vector &); %rename(__len__) size; unsigned int size() const; void clear(); %rename(append) push_back; void push_back(const T& x); %extend { bool __nonzero__() { return !(self->empty()); } T pop() { if (self->size() == 0) throw std::out_of_range("pop from empty vector"); T x = self->back(); self->pop_back(); return x; } T& __getitem__(int i) { int size = int(self->size()); if (i<0) i += size; if (i>=0 && i __getslice__(int i, int j) { int size = int(self->size()); if (i<0) i = size+i; if (j<0) j = size+j; if (i<0) i = 0; if (j>size) j = size; std::vector tmp; tmp.reserve(j-i); tmp.insert(tmp.begin(),self->begin()+i,self->begin()+j); return tmp; } void __setitem__(int i, const T& x) { int size = int(self->size()); if (i<0) i+= size; if (i>=0 && i& v) { int size = int(self->size()); if (i<0) i = size+i; if (j<0) j = size+j; if (i<0) i = 0; if (j>size) j = size; if (int(v.size()) == j-i) { std::copy(v.begin(),v.end(),self->begin()+i); } else { self->erase(self->begin()+i,self->begin()+j); if (i+1 <= int(self->size())) { self->insert(self->begin()+i,v.begin(),v.end()); } else { self->insert(self->end(),v.begin(),v.end()); } } } void __delitem__(int i) { int size = int(self->size()); if (i<0) i+= size; if (i>=0 && ierase(self->begin()+i); else throw std::out_of_range("vector index out of range"); } void __delslice__(int i, int j) { int size = int(self->size()); if (i<0) i = size+i; if (j<0) j = size+j; if (i<0) i = 0; if (j>size) j = size; self->erase(self->begin()+i,self->begin()+j); } } }; // Partial specialization for vectors of pointers. [ beazley ] template class vector { %typemap(in) vector (std::vector* v) { if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); $1 = std::vector(size); for (unsigned int i=0; i expected"); SWIG_fail; } } } else if (SWIG_ConvertPtr($input,(void **) &v, $&1_descriptor,0) != -1) { $1 = *v; } else { PyErr_SetString(PyExc_TypeError,"vector<" #T "*> expected"); SWIG_fail; } } %typemap(directorout) vector (std::vector* v) { if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); $result = std::vector(size); for (unsigned int i=0; i expected"); } } } else if (SWIG_ConvertPtr($input,(void **) &v, $&descriptor,1) != -1){ $result = *v; } else { throw Swig::DirectorTypeMismatchException("vector<" #T "*> expected"); } } %typemap(in) const vector& (std::vector temp, std::vector* v), const vector* (std::vector temp, std::vector* v) { if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); temp = std::vector(size); $1 = &temp; for (unsigned int i=0; i expected"); SWIG_fail; } } } else if (SWIG_ConvertPtr($input,(void **) &v, $1_descriptor,0) != -1) { $1 = v; } else { PyErr_SetString(PyExc_TypeError,"vector<" #T "*> expected"); SWIG_fail; } } %typemap(directorout) const vector& (std::vector temp, std::vector* v), const vector* (std::vector temp, std::vector* v) { if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); temp = std::vector(size); $result = &temp; for (unsigned int i=0; i expected"); } } } else if (SWIG_ConvertPtr($input,(void **) &v, $descriptor,1) != -1){ $result = v; } else { throw Swig::DirectorTypeMismatchException("vector<" #T "*> expected"); } } %typemap(out) vector { $result = PyTuple_New($1.size()); for (unsigned int i=0; i<$1.size(); i++) { T *ptr = (($1_type &)$1)[i]; PyTuple_SetItem($result,i, SWIG_NewPointerObj((void *) ptr, $descriptor(T*), 0)); } } %typemap(directorin) vector { $input = PyTuple_New($1_name.size()); for (unsigned int i=0; i<$1_name.size(); i++) { T *ptr = (($1_type &)$1_name)[i]; PyTuple_SetItem($input,i, SWIG_NewPointerObj((void *) ptr, $descriptor(T*), 0)); } } %typecheck(SWIG_TYPECHECK_VECTOR) vector { /* native sequence? */ if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); if (size == 0) { /* an empty sequence can be of any type */ $1 = 1; } else { /* check the first element only */ T *x; PyObject* o = PySequence_GetItem($input,0); if ((SWIG_ConvertPtr(o,(void **) &x, $descriptor(T*),0)) != -1) $1 = 1; else $1 = 0; Py_DECREF(o); } } else { /* wrapped vector? */ std::vector* v; if (SWIG_ConvertPtr($input,(void **) &v, $&1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_VECTOR) const vector&, const vector* { /* native sequence? */ if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); if (size == 0) { /* an empty sequence can be of any type */ $1 = 1; } else { /* check the first element only */ T *x; PyObject* o = PySequence_GetItem($input,0); if ((SWIG_ConvertPtr(o,(void **) &x, $descriptor(T*),0)) != -1) $1 = 1; else $1 = 0; Py_DECREF(o); } } else { /* wrapped vector? */ std::vector* v; if (SWIG_ConvertPtr($input,(void **) &v, $1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } public: vector(unsigned int size = 0); vector(unsigned int size, T * &value); vector(const vector &); %rename(__len__) size; unsigned int size() const; void clear(); %rename(append) push_back; void push_back(T * x); %extend { bool __nonzero__() { return !(self->empty()); } T *pop() { if (self->size() == 0) throw std::out_of_range("pop from empty vector"); T *x = self->back(); self->pop_back(); return x; } T * __getitem__(int i) { int size = int(self->size()); if (i<0) i += size; if (i>=0 && i __getslice__(int i, int j) { int size = int(self->size()); if (i<0) i = size+i; if (j<0) j = size+j; if (i<0) i = 0; if (j>size) j = size; std::vector tmp(j-i); std::copy(self->begin()+i,self->begin()+j,tmp.begin()); return tmp; } void __setitem__(int i, T *x) { int size = int(self->size()); if (i<0) i+= size; if (i>=0 && i& v) { int size = int(self->size()); if (i<0) i = size+i; if (j<0) j = size+j; if (i<0) i = 0; if (j>size) j = size; if (int(v.size()) == j-i) { std::copy(v.begin(),v.end(),self->begin()+i); } else { self->erase(self->begin()+i,self->begin()+j); if (i+1 <= int(self->size())) self->insert(self->begin()+i,v.begin(),v.end()); else self->insert(self->end(),v.begin(),v.end()); } } void __delitem__(int i) { int size = int(self->size()); if (i<0) i+= size; if (i>=0 && ierase(self->begin()+i); else throw std::out_of_range("vector index out of range"); } void __delslice__(int i, int j) { int size = int(self->size()); if (i<0) i = size+i; if (j<0) j = size+j; if (i<0) i = 0; if (j>size) j = size; self->erase(self->begin()+i,self->begin()+j); } } }; // specializations for built-ins %define specialize_std_vector(T,CHECK,CONVERT_FROM,CONVERT_TO) template<> class vector { %typemap(in) vector (std::vector* v) { if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); $1 = std::vector(size); for (unsigned int i=0; i expected"); SWIG_fail; } } } else if (SWIG_ConvertPtr($input,(void **) &v, $&1_descriptor,1) != -1){ $1 = *v; } else { PyErr_SetString(PyExc_TypeError,"vector<" #T "> expected"); SWIG_fail; } } %typemap(directorout) vector (std::vector* v) { if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); $result = std::vector(size); for (unsigned int i=0; i expected"); } } } else if (SWIG_ConvertPtr($input,(void **) &v, $&descriptor,1) != -1){ $result = *v; } else { throw Swig::DirectorTypeMismatchException("vector<" #T "> expected"); } } %typemap(in) const vector& (std::vector temp, std::vector* v), const vector* (std::vector temp, std::vector* v) { if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); temp = std::vector(size); $1 = &temp; for (unsigned int i=0; i expected"); SWIG_fail; } } } else if (SWIG_ConvertPtr($input,(void **) &v, $1_descriptor,1) != -1){ $1 = v; } else { PyErr_SetString(PyExc_TypeError,"vector<" #T "> expected"); SWIG_fail; } } %typemap(directorout) const vector& (std::vector temp, std::vector* v), const vector* (std::vector temp, std::vector* v) { if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); temp = std::vector(size); $result = &temp; for (unsigned int i=0; i expected"); } } } else if (SWIG_ConvertPtr($input,(void **) &v, $descriptor,1) != -1){ $result = v; } else { throw Swig::DirectorTypeMismatchException("vector<" #T "> expected"); } } %typemap(out) vector { $result = PyTuple_New($1.size()); for (unsigned int i=0; i<$1.size(); i++) PyTuple_SetItem($result,i, CONVERT_TO((($1_type &)$1)[i])); } %typemap(directorin) vector { $input = PyTuple_New($1_name.size()); for (unsigned int i=0; i<$1_name.size(); i++) PyTuple_SetItem($input,i, CONVERT_TO((($1_type &)$1_name)[i])); } %typecheck(SWIG_TYPECHECK_VECTOR) vector { /* native sequence? */ if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); if (size == 0) { /* an empty sequence can be of any type */ $1 = 1; } else { /* check the first element only */ PyObject* o = PySequence_GetItem($input,0); if (CHECK(o)) $1 = 1; else $1 = 0; Py_DECREF(o); } } else { /* wrapped vector? */ std::vector* v; if (SWIG_ConvertPtr($input,(void **) &v, $&1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_VECTOR) const vector&, const vector* { /* native sequence? */ if (PyTuple_Check($input) || PyList_Check($input)) { unsigned int size = (PyTuple_Check($input) ? PyTuple_Size($input) : PyList_Size($input)); if (size == 0) { /* an empty sequence can be of any type */ $1 = 1; } else { /* check the first element only */ PyObject* o = PySequence_GetItem($input,0); if (CHECK(o)) $1 = 1; else $1 = 0; Py_DECREF(o); } } else { /* wrapped vector? */ std::vector* v; if (SWIG_ConvertPtr($input,(void **) &v, $1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } public: vector(unsigned int size = 0); vector(unsigned int size, const T& value); vector(const vector &); %rename(__len__) size; unsigned int size() const; %rename(__nonzero__) empty; bool empty() const; void clear(); %rename(append) push_back; void push_back(T x); %extend { T pop() { if (self->size() == 0) throw std::out_of_range("pop from empty vector"); T x = self->back(); self->pop_back(); return x; } T __getitem__(int i) { int size = int(self->size()); if (i<0) i += size; if (i>=0 && i __getslice__(int i, int j) { int size = int(self->size()); if (i<0) i = size+i; if (j<0) j = size+j; if (i<0) i = 0; if (j>size) j = size; std::vector tmp(j-i); std::copy(self->begin()+i,self->begin()+j,tmp.begin()); return tmp; } void __setitem__(int i, T x) { int size = int(self->size()); if (i<0) i+= size; if (i>=0 && i& v) { int size = int(self->size()); if (i<0) i = size+i; if (j<0) j = size+j; if (i<0) i = 0; if (j>size) j = size; if (int(v.size()) == j-i) { std::copy(v.begin(),v.end(),self->begin()+i); } else { self->erase(self->begin()+i,self->begin()+j); if (i+1 <= int(self->size())) self->insert(self->begin()+i,v.begin(),v.end()); else self->insert(self->end(),v.begin(),v.end()); } } void __delitem__(int i) { int size = int(self->size()); if (i<0) i+= size; if (i>=0 && ierase(self->begin()+i); else throw std::out_of_range("vector index out of range"); } void __delslice__(int i, int j) { int size = int(self->size()); if (i<0) i = size+i; if (j<0) j = size+j; if (i<0) i = 0; if (j>size) j = size; self->erase(self->begin()+i,self->begin()+j); } } }; %enddef specialize_std_vector(bool,PyInt_Check,PyInt_AsLong,SwigInt_FromBool); specialize_std_vector(char,PyInt_Check,PyInt_AsLong,PyInt_FromLong); specialize_std_vector(int,PyInt_Check,PyInt_AsLong,PyInt_FromLong); specialize_std_vector(short,PyInt_Check,PyInt_AsLong,PyInt_FromLong); specialize_std_vector(long,PyLong_Check,PyLong_AsLong,PyLong_FromLong); specialize_std_vector(unsigned char,PyInt_Check,\ PyInt_AsLong,PyInt_FromLong); specialize_std_vector(unsigned int,PyInt_Check,\ PyInt_AsLong,PyInt_FromLong); specialize_std_vector(unsigned short,PyInt_Check,\ PyInt_AsLong,PyInt_FromLong); specialize_std_vector(unsigned long,PyLong_Check,\ PyLong_AsUnsignedLong,PyLong_FromUnsignedLong); specialize_std_vector(double,SwigNumber_Check,\ SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_vector(float,SwigNumber_Check,\ SwigNumber_AsDouble,PyFloat_FromDouble); specialize_std_vector(std::string,PyString_Check,\ SwigString_AsString,SwigString_FromString); } cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/ccomplex.i0000644000175000000620000000150112561312227021606 0ustar stevestaff#ifndef __python_ccomplex_i__ #define __python_ccomplex_i__ %include "complex_common.i" /* * C complex wrap * ISO C99: 7.3 Complex arithmetic */ %{ #include %} /* *** swig workaround *** the %{}% around these typedefs must be removed once swig parser supports 'float complex'... */ %{ typedef float complex float_complex; typedef double complex double_complex; %} /* C complex constructor */ #define CCplxConst(r, i) ((r) + I*(i)) %swig_cplxflt_conv(float_complex, CCplxFlt, CCplxConst, creal, cimag); %swig_cplxdbl_conv(double_complex, CCplxDbl, CCplxConst, creal, cimag); /* declaring the typemaps */ %typemap_stype(float_complex, CPLXFLT, CCplxFlt); %typemap_stype(double_complex, CPLXDBL, CCplxDbl); %apply double_complex { complex }; #endif //__python_ccomplex_i__ cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/defarg.swg0000644000175000000620000000210012561312227021570 0ustar stevestaff/* This file defines an internal function for processing default arguments with shadow classes. There seems to be no straightforward way to write a shadow functions involving default arguments. For example : def foo(arg1,arg2,*args): shadowc.foo(arg1,arg2,args) This fails because args is now a tuple and SWIG doesn't know what to do with it. This file allows a different approach : def foo(arg1,arg2,*args): shadowc.__call_defarg(shadowc.foo,(arg1,arg2,)+args) Basically, we form a new tuple from the object, call this special __call_defarg method and it passes control to the real wrapper function. An ugly hack, but it works. */ static PyObject *swig_call_defargs(PyObject *self, PyObject *args) { PyObject *func; PyObject *parms; if (!PyArg_ParseTuple(args,"OO",&func,&parms)) return NULL; if (!PyCallable_Check(func)) { PyErr_SetString(PyExc_TypeError, "__call_defarg : Need a callable object!"); return NULL; } return PyEval_CallObject(func,parms); } cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/cstring.i0000644000175000000620000001461212561312227021454 0ustar stevestaff/* * cstring.i * /cvsroot/SWIG/Lib/python/cstring.i,v 1.4 2003/02/07 22:13:11 beazley Exp * * Author(s): David Beazley (beazley@cs.uchicago.edu) * * This file provides typemaps and macros for dealing with various forms * of C character string handling. The primary use of this module * is in returning character data that has been allocated or changed in * some way. */ %include "fragments.i" /* %cstring_input_binary(TYPEMAP, SIZE) * * Macro makes a function accept binary string data along with * a size. */ %define %cstring_input_binary(TYPEMAP, SIZE) %apply (char *STRING, int LENGTH) { (TYPEMAP, SIZE) }; %enddef /* * %cstring_bounded_output(TYPEMAP, MAX) * * This macro is used to return a NULL-terminated output string of * some maximum length. For example: * * %cstring_bounded_output(char *outx, 512); * void foo(char *outx) { * sprintf(outx,"blah blah\n"); * } * */ %define %cstring_bounded_output(TYPEMAP,MAX) %typemap(ignore) TYPEMAP(char temp[MAX+1]) { $1 = ($1_ltype) temp; } %typemap(argout,fragment="t_output_helper") TYPEMAP { PyObject *o; $1[MAX] = 0; o = PyString_FromString($1); $result = t_output_helper($result,o); } %enddef /* * %cstring_chunk_output(TYPEMAP, SIZE) * * This macro is used to return a chunk of binary string data. * Embedded NULLs are okay. For example: * * %cstring_chunk_output(char *outx, 512); * void foo(char *outx) { * memmove(outx, somedata, 512); * } * */ %define %cstring_chunk_output(TYPEMAP,SIZE) %typemap(ignore) TYPEMAP(char temp[SIZE]) { $1 = ($1_ltype) temp; } %typemap(argout,fragment="t_output_helper") TYPEMAP { PyObject *o = PyString_FromStringAndSize($1,SIZE); $result = t_output_helper($result,o); } %enddef /* * %cstring_bounded_mutable(TYPEMAP, SIZE) * * This macro is used to wrap a string that's going to mutate. * * %cstring_bounded_mutable(char *in, 512); * void foo(in *x) { * while (*x) { * *x = toupper(*x); * x++; * } * } * */ %define %cstring_bounded_mutable(TYPEMAP,MAX) %typemap(in) TYPEMAP(char temp[MAX+1]) { char *t = PyString_AsString($input); if (PyErr_Occurred()) SWIG_fail; strncpy(temp,t,MAX); $1 = ($1_ltype) temp; } %typemap(argout,fragment="t_output_helper") TYPEMAP { PyObject *o; $1[MAX] = 0; o = PyString_FromString($1); $result = t_output_helper($result,o); } %enddef /* * %cstring_mutable(TYPEMAP [, expansion]) * * This macro is used to wrap a string that will mutate in place. * It may change size up to a user-defined expansion. * * %cstring_mutable(char *in); * void foo(in *x) { * while (*x) { * *x = toupper(*x); * x++; * } * } * */ %define %cstring_mutable(TYPEMAP,...) %typemap(in) TYPEMAP { char *t = PyString_AsString($input); int n = PyString_Size($input); if (PyErr_Occurred()) SWIG_fail; $1 = ($1_ltype) t; #if #__VA_ARGS__ == "" #if __cplusplus $1 = ($1_ltype) new char[n+1]; #else $1 = ($1_ltype) malloc(n+1); #endif #else #if __cplusplus $1 = ($1_ltype) new char[n+1+__VA_ARGS__]; #else $1 = ($1_ltype) malloc(n+1+__VA_ARGS__); #endif #endif memmove($1,t,n); $1[n] = 0; } %typemap(argout,fragment="t_output_helper") TYPEMAP { PyObject *o; o = PyString_FromString($1); $result = t_output_helper($result,o); #if __cplusplus delete[] $1; #else free($1); #endif } %enddef /* * %cstring_output_maxsize(TYPEMAP, SIZE) * * This macro returns data in a string of some user-defined size. * * %cstring_output_maxsize(char *outx, int max) { * void foo(char *outx, int max) { * sprintf(outx,"blah blah\n"); * } */ %define %cstring_output_maxsize(TYPEMAP, SIZE) %typemap(in) (TYPEMAP, SIZE) { $2 = PyInt_AsLong($input); if (PyErr_Occurred()) SWIG_fail; #ifdef __cplusplus $1 = ($1_ltype) new char[$2+1]; #else $1 = ($1_ltype) malloc($2+1); #endif } %typemap(argout,fragment="t_output_helper") (TYPEMAP,SIZE) { PyObject *o; o = PyString_FromString($1); $result = t_output_helper($result,o); #ifdef __cplusplus delete [] $1; #else free($1); #endif } %enddef /* * %cstring_output_withsize(TYPEMAP, SIZE) * * This macro is used to return character data along with a size * parameter. * * %cstring_output_maxsize(char *outx, int *max) { * void foo(char *outx, int *max) { * sprintf(outx,"blah blah\n"); * *max = strlen(outx); * } */ %define %cstring_output_withsize(TYPEMAP, SIZE) %typemap(in) (TYPEMAP, SIZE) { int n = PyInt_AsLong($input); if (PyErr_Occurred()) SWIG_fail; #ifdef __cplusplus $1 = ($1_ltype) new char[n+1]; $2 = ($2_ltype) new $*2_ltype; #else $1 = ($1_ltype) malloc(n+1); $2 = ($2_ltype) malloc(sizeof($*2_ltype)); #endif *$2 = n; } %typemap(argout,fragment="t_output_helper") (TYPEMAP,SIZE) { PyObject *o; o = PyString_FromStringAndSize($1,*$2); $result = t_output_helper($result,o); #ifdef __cplusplus delete [] $1; delete $2; #else free($1); free($2); #endif } %enddef /* * %cstring_output_allocate(TYPEMAP, RELEASE) * * This macro is used to return character data that was * allocated with new or malloc. * * %cstring_output_allocated(char **outx, free($1)); * void foo(char **outx) { * *outx = (char *) malloc(512); * sprintf(outx,"blah blah\n"); * } */ %define %cstring_output_allocate(TYPEMAP, RELEASE) %typemap(ignore) TYPEMAP($*1_ltype temp = 0) { $1 = &temp; } %typemap(argout,fragment="t_output_helper") TYPEMAP { if (*$1) { PyObject *o = PyString_FromString(*$1); RELEASE; $result = t_output_helper($result,o); } } %enddef /* * %cstring_output_allocate_size(TYPEMAP, SIZE, RELEASE) * * This macro is used to return character data that was * allocated with new or malloc. * * %cstring_output_allocated(char **outx, int *sz, free($1)); * void foo(char **outx, int *sz) { * *outx = (char *) malloc(512); * sprintf(outx,"blah blah\n"); * *sz = strlen(outx); * } */ %define %cstring_output_allocate_size(TYPEMAP, SIZE, RELEASE) %typemap(ignore) (TYPEMAP, SIZE) ($*1_ltype temp = 0, $*2_ltype tempn) { $1 = &temp; $2 = &tempn; } %typemap(argout,fragment="t_output_helper")(TYPEMAP,SIZE) { if (*$1) { PyObject *o = PyString_FromStringAndSize(*$1,*$2); RELEASE; $result = t_output_helper($result,o); } } %enddef cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/pyprimtypes.swg0000644000175000000620000002223412561312227022757 0ustar stevestaff/* ------------------------------------------------------------ * Primitive Types * ------------------------------------------------------------ */ /* Define the SWIGAs/From methods for the basic types. In many cases, these method are just aliases of the original python As/From methods. In the other cases, some extra work is needed. */ /* no wrapped found needed here... yet, and we define the names SWIG for consistency */ %{ #define SWIG_FromSignedChar PyInt_FromLong #define SWIG_FromUnsignedChar PyInt_FromLong #define SWIG_FromShort PyInt_FromLong #define SWIG_FromUnsignedShort PyInt_FromLong #define SWIG_FromInt PyInt_FromLong #define SWIG_FromLong PyInt_FromLong #define SWIG_FromFloat PyFloat_FromDouble #define SWIG_FromDouble PyFloat_FromDouble #define SWIG_FromFloat PyFloat_FromDouble #define SWIG_FromDouble PyFloat_FromDouble %} %fragment("","header") %{ #include %} %fragment("SWIG_AsUnsignedLong","header") %{ SWIGSTATICINLINE(unsigned long) SWIG_AsUnsignedLong(PyObject * obj) { if (PyLong_Check(obj)) { return PyLong_AsUnsignedLong(obj); } else { long i = PyInt_AsLong(obj); if ( !PyErr_Occurred() && (i < 0)) { PyErr_SetString(PyExc_TypeError, "negative value for unsigned type"); } return i; } } %} %fragment("SWIG_CheckLongInRange","header", fragment="") %{ SWIGSTATICINLINE(long) SWIG_CheckLongInRange(long value, const char* type, long min_value, long max_value) { if (!PyErr_Occurred()) { if (value < min_value) { PyObject *err = PyString_FromFormat("value %ld is less than '%s' minimum %ld", value, type, min_value); PyErr_SetObject(PyExc_OverflowError, err); Py_DECREF(err); } else if (value > max_value) { PyObject *err = PyString_FromFormat("value %ld is greater than '%s' maximum %ld", value, type, max_value); PyErr_SetObject(PyExc_OverflowError, err); Py_DECREF(err); } } return value; } %} %fragment("SWIG_CheckUnsignedLongInRange","header", fragment="") %{ SWIGSTATICINLINE(unsigned long) SWIG_CheckUnsignedLongInRange(unsigned long value, const char* type, unsigned long max_value) { if (!PyErr_Occurred()) { if (value > max_value) { PyObject *err = PyString_FromFormat("value %ld is greater than '%s' minimum %ld", value, type, max_value); PyErr_SetObject(PyExc_OverflowError, err); Py_DECREF(err); } } return value; } %} %fragment("SWIG_AsDouble","header") %{ SWIGSTATICINLINE(double) SWIG_AsDouble(PyObject *obj) { double val = (PyFloat_Check(obj)) ? PyFloat_AsDouble(obj) : #if HAVE_LONG_LONG ((PyInt_Check(obj)) ? PyInt_AsLong(obj) : PyLong_AsLongLong(obj)); #else ((PyInt_Check(obj)) ? PyInt_AsLong(obj) : PyLong_AsLong(obj)); #endif if (PyErr_Occurred()) { PyErr_Clear(); PyErr_SetString(PyExc_TypeError, "a double is expected"); } return val; } %} %fragment("SWIG_AsLong","header") %{ SWIGSTATICINLINE(long) SWIG_AsLong(PyObject * obj) { return PyInt_Check(obj) ? PyInt_AsLong(obj) : PyLong_AsLong(obj); } %} %fragment("SWIG_FromLongLong","header", fragment="") %{ SWIGSTATICINLINE(PyObject* ) SWIG_FromLongLong(long long value) { return (value > LONG_MAX) ? PyLong_FromLongLong(value) : PyInt_FromLong(swig_numeric_cast(long,value)); } %} %fragment("SWIG_FromUnsignedLongLong","header", fragment="") %{ SWIGSTATICINLINE(PyObject* ) SWIG_FromUnsignedLongLong(unsigned long long value) { return (value > LONG_MAX) ? PyLong_FromUnsignedLongLong(value) : PyInt_FromLong(swig_numeric_cast(long, value)); } %} %fragment("SWIG_AsLongLong","header") %{ SWIGSTATICINLINE(long long) SWIG_AsLongLong(PyObject *obj) { return PyInt_Check(obj) ? PyInt_AsLong(obj) : PyLong_AsLongLong(obj); } %} %fragment("SWIG_AsUnsignedLongLong","header", fragment="SWIG_AsUnsignedLong") %{ SWIGSTATICINLINE(unsigned long long) SWIG_AsUnsignedLongLong(PyObject *obj) { return PyLong_Check(obj) ? PyLong_AsUnsignedLongLong(obj) : SWIG_AsUnsignedLong(obj); } %} %fragment("SWIG_FromUnsignedLong","header") %{ SWIGSTATICINLINE(PyObject* ) SWIG_FromUnsignedLong(unsigned long value) { return (value > LONG_MAX) ? PyLong_FromUnsignedLong(value) : PyInt_FromLong(swig_numeric_cast(long,value)); } %} %fragment("SWIG_AsSignedChar","header", fragment="SWIG_CheckLongInRange", fragment="SWIG_AsLong") %{ SWIGSTATICINLINE(signed char) SWIG_AsSignedChar(PyObject *obj) { return swig_numeric_cast(signed char, SWIG_CheckLongInRange(SWIG_AsLong(obj), "signed char", SCHAR_MIN, SCHAR_MAX)); } %} %fragment("SWIG_AsShort","header", fragment="SWIG_CheckLongInRange", fragment="SWIG_AsLong") %{ SWIGSTATICINLINE(short) SWIG_AsShort(PyObject *obj) { return swig_numeric_cast(short, SWIG_CheckLongInRange(SWIG_AsLong(obj), "short", SHRT_MIN, SHRT_MAX)); } %} /* need range checks */ %fragment("SWIG_AsInt","header", fragment="SWIG_CheckLongInRange", fragment="SWIG_AsLong") %{ #if INT_MAX != LONG_MAX SWIGSTATICINLINE(int) SWIG_AsInt(PyObject *obj) { return swig_numeric_cast(int, SWIG_CheckLongInRange(SWIG_AsLong(obj), "int", INT_MIN, INT_MAX)); } #else #define SWIG_AsInt SWIG_AsLong #endif %} %fragment("SWIG_AsUnsignedInt","header", fragment="SWIG_CheckUnsignedLongInRange", fragment="SWIG_AsUnsignedLong") %{ #if UINT_MAX != ULONG_MAX SWIGSTATICINLINE(unsigned int) SWIG_AsUnsignedInt(PyObject *obj) { return swig_numeric_cast(unsigned int, SWIG_CheckUnsignedLongInRange(SWIG_AsUnsignedLong(obj), "unsigned int", UINT_MAX)); } #else #define SWIG_AsUnsignedInt SWIG_AsUnsignedLong #endif %} %fragment("SWIG_FromUnsignedInt","header", fragment="SWIG_FromUnsignedLong") %{ #if UINT_MAX < LONG_MAX #define SWIG_FromUnsignedInt SWIG_FromLong #else #define SWIG_FromUnsignedInt SWIG_FromUnsignedLong #endif %} %fragment("SWIG_AsUnsignedChar","header", fragment="SWIG_CheckUnsignedLongInRange", fragment="SWIG_AsUnsignedLong") %{ SWIGSTATICINLINE(unsigned char) SWIG_AsUnsignedChar(PyObject *obj) { return swig_numeric_cast(unsigned char, SWIG_CheckUnsignedLongInRange(SWIG_AsUnsignedLong(obj), "unsigned char", UCHAR_MAX)); } %} %fragment("SWIG_AsUnsignedShort","header", fragment="SWIG_CheckUnsignedLongInRange", fragment="SWIG_AsUnsignedLong") %{ SWIGSTATICINLINE(unsigned short ) SWIG_AsUnsignedShort(PyObject *obj) { return swig_numeric_cast(unsigned short, SWIG_CheckUnsignedLongInRange(SWIG_AsUnsignedLong(obj), "unsigned short", USHRT_MAX)); } %} %fragment("SWIG_FloatCast","header") %{ #include SWIGSTATIC(float) SWIG_FloatCast(double value) { float f = 0; if (!PyErr_Occurred()) { if (value < -FLT_MAX) { PyObject *err = PyString_FromFormat("value %g is less than most negative float %g", value, -FLT_MAX); PyErr_SetObject(PyExc_OverflowError, err); Py_DECREF(err); } else if (value > FLT_MAX) { PyObject *err = PyString_FromFormat("value %g is greater than float maximum %g", value, FLT_MAX); PyErr_SetObject(PyExc_OverflowError, err); Py_DECREF(err); } else { f = swig_numeric_cast(float, value); } } return f; } %} %fragment("SWIG_AsFloat","header", fragment="SWIG_FloatCast", fragment="SWIG_AsDouble") %{ SWIGSTATICINLINE(float) SWIG_AsFloat(PyObject *obj) { return SWIG_FloatCast(SWIG_AsDouble(obj)); } %} %fragment("SWIG_FromChar","header") %{ SWIGSTATICINLINE(PyObject*) SWIG_FromChar(char c) { return PyString_FromStringAndSize(&c,1); } %} %fragment("SWIG_FromBool","header") %{ SWIGSTATICINLINE(PyObject*) SWIG_FromBool(bool value) { PyObject *obj = value ? Py_True : Py_False; Py_INCREF(obj); return obj; } %} %fragment("SWIG_AsBool","header") %{ SWIGSTATICINLINE(bool) SWIG_AsBool(PyObject *obj) { return PyObject_IsTrue(obj) ? true : false; } %} %fragment("SWIG_AsChar","header", fragment="SWIG_AsCharArray", fragment="SWIG_CheckLongInRange", fragment="SWIG_AsLong") %{ SWIGSTATICINLINE(char) SWIG_AsChar(PyObject *obj) { char c = 0; if (PyInt_Check(obj) || PyLong_Check(obj)) { c = swig_numeric_cast(char, SWIG_CheckLongInRange(SWIG_AsLong(obj), "char", CHAR_MIN, CHAR_MAX)); } else { SWIG_AsCharArray(obj, &c, 1); if (PyErr_Occurred()) { PyErr_Clear(); PyErr_SetString(PyExc_TypeError, "a char is expected"); } } return c; } %} %typemap_stype(bool, BOOL, Bool); %typemap_stype(signed char, INT8, SignedChar); %typemap_stype(unsigned char, UINT8, UnsignedChar); %typemap_stype(short, INT16, Short); %typemap_stype(unsigned short, UINT16, UnsignedShort); %typemap_stype(int, INT32, Int); %typemap_stype(unsigned int, UINT32, UnsignedInt); %typemap_stype(long, INT64, Long); %typemap_stype(unsigned long, UINT64, UnsignedLong); %typemap_stype(long long, INT128, LongLong); %typemap_stype(unsigned long long, UINT128, UnsignedLongLong); %typemap_stype(float, FLOAT, Float); %typemap_stype(double, DOUBLE, Double); %typemap_stype(char, CHAR, Char); cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/precommon.swg0000644000175000000620000000140012561312227022341 0ustar stevestaff/*************************************************************** -*- c -*- * python/precommon.swg * * Rename all exported symbols from common.swg, to avoid symbol * clashes if multiple interpreters are included * ************************************************************************/ #define SWIG_TypeRegister SWIG_Python_TypeRegister #define SWIG_TypeCheck SWIG_Python_TypeCheck #define SWIG_TypeCast SWIG_Python_TypeCast #define SWIG_TypeDynamicCast SWIG_Python_TypeDynamicCast #define SWIG_TypeName SWIG_Python_TypeName #define SWIG_TypeQuery SWIG_Python_TypeQuery #define SWIG_TypeClientData SWIG_Python_TypeClientData #define SWIG_PackData SWIG_Python_PackData #define SWIG_UnpackData SWIG_Python_UnpackData cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/pyobject.swg0000644000175000000620000000114612561312227022170 0ustar stevestaff/* ------------------------------------------------------------ * PyObject * - Just pass straight through unmodified * ------------------------------------------------------------ */ %typemap(in) PyObject * "$1 = $input;"; %typemap(out) PyObject * "$result = $1;"; %typemap(constcode) PyObject * "PyDict_SetItemString(d,\"$symname\", $value);"; %typemap(directorin, parse="O") PyObject * ""; %typemap(directorout) PyObject * "$result = $input;"; %typecheck(SWIG_TYPECHECK_POINTER) PyObject * "$1 = ($input != 0);"; %typemap(throws) PyObject * "PyErr_SetObject(PyExc_RuntimeError, $1); SWIG_fail;"; cableswig-0.1.0+git20150808.orig/SWIG/Lib/python/embed15.i0000644000175000000620000000522212561312227021222 0ustar stevestaff// // embed15.i // SWIG file embedding the Python interpreter in something else. // This file is based on Python-1.5. It will not work with // earlier versions. // // This file makes it possible to extend Python and all of its // built-in functions without having to hack it's setup script. // #ifdef AUTODOC %subsection "embed.i" %text %{ This module provides support for building a new version of the Python executable. This will be necessary on systems that do not support shared libraries and may be necessary with C++ extensions. This file contains everything you need to build a new version of Python from include files and libraries normally installed with the Python language. This module will automatically grab all of the Python modules present in your current Python executable (including any special purpose modules you have enabled such as Tkinter). Thus, you may need to provide additional link libraries when compiling. This library file only works with Python 1.5. A version compatible with Python 1.4 is available as embed14.i and a Python1.3 version is available as embed13.i. As far as I know, this module is C++ safe. %} #else %echo "embed.i : Using Python 1.5" #endif %wrapper %{ #include #ifdef __cplusplus extern "C" #endif void SWIG_init(); /* Forward reference */ #define _PyImport_Inittab swig_inittab /* Grab Python's inittab[] structure */ #ifdef __cplusplus extern "C" { #endif #include #undef _PyImport_Inittab /* Now define our own version of it. Hopefully someone does not have more than 1000 built-in modules */ struct _inittab SWIG_Import_Inittab[1000]; static int swig_num_modules = 0; /* Function for adding modules to Python */ static void swig_add_module(char *name, void (*initfunc)()) { SWIG_Import_Inittab[swig_num_modules].name = name; SWIG_Import_Inittab[swig_num_modules].initfunc = initfunc; swig_num_modules++; SWIG_Import_Inittab[swig_num_modules].name = (char *) 0; SWIG_Import_Inittab[swig_num_modules].initfunc = 0; } /* Function to add all of Python's build in modules to our interpreter */ static void swig_add_builtin() { int i = 0; while (swig_inittab[i].name) { swig_add_module(swig_inittab[i].name, swig_inittab[i].initfunc); i++; } #ifdef SWIGMODINIT SWIGMODINIT #endif /* Add SWIG builtin function */ swig_add_module(SWIG_name, SWIG_init); } #ifdef __cplusplus } #endif #ifdef __cplusplus extern "C" { #endif extern int Py_Main(int, char **); #ifdef __cplusplus } #endif extern struct _inittab *PyImport_Inittab; int main(int argc, char **argv) { swig_add_builtin(); PyImport_Inittab = SWIG_Import_Inittab; return Py_Main(argc,argv); } %} cableswig-0.1.0+git20150808.orig/SWIG/Lib/allkw.swg0000644000175000000620000000122312561312227020136 0ustar stevestaff#ifndef __Lib_allkw_swg__ #define __Lib_allkw_swg__ /* Include all the known keyword warnings. Very useful for adding test files to the test-suite, or check if your own library is ok for all the swig supported languages. Use as swig -Wallkw ... If you add a new language, remember to create a separete languagekw.swg file, and add it here. */ %include "chicken/chickenkw.swg" %include "csharp/csharpkw.swg" %include "java/javakw.swg" %include "php4/php4kw.swg" %include "pike/pikekw.swg" %include "python/pythonkw.swg" %include "ocaml/ocamlkw.swg" %include "ruby/rubykw.swg" %include "tcl/tcl8kw.swg" #endif //__Lib_allkw_swg__ cableswig-0.1.0+git20150808.orig/SWIG/Lib/CMakeLists.txt0000644000175000000620000000040412561312227021042 0ustar stevestaffFILE(GLOB __files1 "${CMAKE_CURRENT_SOURCE_DIR}/*.i") FILE(GLOB __files2 "${CMAKE_CURRENT_SOURCE_DIR}/*.swg") INSTALL(FILES ${__files1} ${__files2} DESTINATION ${CableSwig_INSTALL_ROOT}lib/CableSwig/SWIGLib COMPONENT Development) SUBDIRS(tcl python java) cableswig-0.1.0+git20150808.orig/SWIG/Lib/_std_deque.i0000644000175000000620000001014312561312227020571 0ustar stevestaff/* This file contains a generic definition of std::deque along with * some helper functions. Specific language modules should include * this file to generate wrappers. */ %{ #include #include %} %include "exception.i" %exception std::deque::getitem { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::deque::setitem { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::deque::delitem { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } /* This macro defines all of the standard methods for a deque. This is defined as a macro to simplify the task of specialization. For example, template<> class deque { public: %std_deque_methods(int); }; */ %define %std_deque_methods(T) typedef T &reference; typedef const T& const_reference; deque(); deque(unsigned int size, const T& value=T()); deque(const deque &); ~deque(); void assign(unsigned int n, const T& value); void swap(deque &x); unsigned int size() const; unsigned int max_size() const; void resize(unsigned int n, T c = T()); bool empty() const; const_reference front(); const_reference back(); void push_front(const T& x); void push_back(const T& x); void pop_front(); void pop_back(); void clear(); /* Some useful extensions */ %extend { const_reference getitem(int i) { int size = int(self->size()); if (i<0) i += size; if (i>=0 && isize()); if (i<0) i+= size; if (i>=0 && isize()); if (i<0) i+= size; if (i>=0 && ierase(self->begin()+i); } else { throw std::out_of_range("deque index out of range"); } } std::deque getslice(int i, int j) { int size = int(self->size()); if (i<0) i = size+i; if (j<0) j = size+j; if (i<0) i = 0; if (j>size) j = size; std::deque tmp(j-i); std::copy(self->begin()+i,self->begin()+j,tmp.begin()); return tmp; } void setslice(int i, int j, const std::deque& v) { int size = int(self->size()); if (i<0) i = size+i; if (j<0) j = size+j; if (i<0) i = 0; if (j>size) j = size; if (int(v.size()) == j-i) { std::copy(v.begin(),v.end(),self->begin()+i); } else { self->erase(self->begin()+i,self->begin()+j); if (i+1 <= size) self->insert(self->begin()+i+1,v.begin(),v.end()); else self->insert(self->end(),v.begin(),v.end()); } } void delslice(int i, int j) { int size = int(self->size()); if (i<0) i = size+i; if (j<0) j = size+j; if (i<0) i = 0; if (j>size) j = size; self->erase(self->begin()+i,self->begin()+j); } }; %enddef namespace std { template class deque { public: %std_deque_methods(T); }; } cableswig-0.1.0+git20150808.orig/SWIG/Lib/tcl/0002755000175000000620000000000012561312227017070 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Lib/tcl/tcl8.swg0000644000175000000620000004635312561312227020475 0ustar stevestaff/* ----------------------------------------------------------------------------- * tcl8.swg * * Tcl8 configuration module. * ----------------------------------------------------------------------------- */ %runtime "precommon.swg" %runtime "common.swg" %runtime "swigtcl8.swg" /* ----------------------------------------------------------------------------- * --- standard typemaps --- * ----------------------------------------------------------------------------- */ /* Input arguments */ /* For primitive types, the Tcl module uses a special function SWIG_GetArgs(Tcl_Interp *, int objc, Tcl_Obj *CONST objv[], const char *fmt, ...) The fmt field contains special conversion characters i,h,l,b,f,d,c,p, and o that are used to marshal different types. The parse codes below correspond to these special codes */ %typemap(in,parse="i") int, unsigned int ""; %typemap(in,parse="h") short, unsigned short ""; %typemap(in,parse="l") long, unsigned long ""; %typemap(in,parse="b") signed char, unsigned char ""; %typemap(in,parse="f") float ""; %typemap(in,parse="d") double ""; %typemap(in,parse="c") char ""; %typemap(in,parse="s") char *, char [ANY] ""; /* Pointers */ %typemap(in) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] "if ((SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor,SWIG_POINTER_EXCEPTION | $disown) != TCL_OK)) SWIG_fail;"; %typemap(in) void * "if ((SWIG_ConvertPtr($input, (void **) &$1, 0,SWIG_POINTER_EXCEPTION | $disown) != TCL_OK)) SWIG_fail;"; /* For bools, we first convert to an integer and then to a bool. There is no guarantee that a bool is the same size as an int so we have to do this */ %typemap(in) bool (int tempb) "if (Tcl_GetIntFromObj(interp,$input,&tempb) == TCL_ERROR) SWIG_fail; $1 = tempb ? true : false;"; /* These will pass an integer as an unsigned long. However, the implementation is crippled due to limited precision in Tcl */ %typemap(in) long long "$1 = ($1_ltype) strtoll(Tcl_GetStringFromObj($input,NULL),0,0);"; %typemap(in) unsigned long long "$1 = ($1_ltype) strtoull(Tcl_GetStringFromObj($input,NULL), 0, 0);"; /* Enum parsing. Note: internally SWIG converts enums to/from integers so it's okay to use the "i" parse code here */ %typemap(in,parse="i") enum SWIGTYPE ""; /* Unknown type. We convert from a pointer */ %typemap(in) SWIGTYPE ($&1_ltype argp) "if ((SWIG_ConvertPtr($input, (void **) &argp, $&1_descriptor,SWIG_POINTER_EXCEPTION ) != TCL_OK)) SWIG_fail; $1 = *argp; "; /* Member pointer */ %typemap(in) SWIGTYPE (CLASS::*) "if ((SWIG_ConvertPacked($input, (void *) &$1, sizeof($1_type), $1_descriptor, SWIG_POINTER_EXCEPTION)) != TCL_OK) SWIG_fail;"; /* Special constant variations. These typemaps can be used to parse objects that are both constants or values. A Hash table lookup will occur. */ %typemap(in,parse="I") int CONSTANT, unsigned int CONSTANT ""; %typemap(in,parse="H") short CONSTANT, unsigned short CONSTANT ""; %typemap(in,parse="L") long CONSTANT, unsigned long CONSTANT ""; %typemap(in,parse="B") signed char CONSTANT, unsigned char CONSTANT ""; %typemap(in,parse="F") float CONSTANT ""; %typemap(in,parse="D") double CONSTANT ""; %typemap(in,parse="C") char CONSTANT ""; %typemap(in,parse="S") char * CONSTANT ""; %typemap(in,parse="P") SWIGTYPE *CONSTANT, SWIGTYPE &CONSTANT, SWIGTYPE CONSTANT [] ""; %typemap(in,parse="I") enum SWIGTYPE CONSTANT ""; /* Constant references. Passed by value */ /* Const primitive references. Passed by value */ %typemap(in) const int & (int temp), const short & (short temp), const long & (long temp), const unsigned int & (unsigned int temp), const unsigned short & (unsigned short temp), const unsigned long & (unsigned long temp), const signed char & (signed char temp), const unsigned char & (unsigned char temp) { long ltemp; if (Tcl_GetLongFromObj(interp, $input, <emp) != TCL_OK) { SWIG_fail; } temp = ($*1_ltype) ltemp; $1 = &temp; } %typemap(in) const bool & (bool temp) { long ltemp; if (Tcl_GetLongFromObj(interp, $input, <emp) != TCL_OK) { SWIG_fail; } temp = ltemp ? true : false; $1 = &temp; } %typemap(in) const float & (float temp), const double & (double temp) { double dtemp; if (Tcl_GetDoubleFromObj(interp, $input, &dtemp) != TCL_OK) { SWIG_fail; } temp = ($*1_ltype) dtemp; $1 = &temp; } %typemap(in) const long long & ($*1_ltype temp) "temp = ($*1_ltype) strtoll(Tcl_GetStringFromObj($input,NULL),0,0); $1 = &temp;"; %typemap(in) const unsigned long long & ($*1_ltype temp) "temp = ($*1_ltype) strtoull(Tcl_GetStringFromObj($input,NULL),0,0); $1 = &temp;"; %typemap(in) const char &(char temp) { char *stemp = Tcl_GetStringFromObj($input,NULL); temp = *stemp; $1 = &temp; } /* Output values */ %typemap(out) bool, int, unsigned int, short, unsigned short, long, unsigned long, signed char, unsigned char, enum SWIGTYPE "Tcl_SetObjResult(interp,Tcl_NewIntObj((long) $1));"; %typemap(out) long long { char temp[256]; sprintf(temp,"%lld", $1); Tcl_SetObjResult(interp,Tcl_NewStringObj(temp,-1)); } %typemap(out) unsigned long long { char temp[256]; sprintf(temp,"%llu", $1); Tcl_SetObjResult(interp,Tcl_NewStringObj(temp,-1)); } %typemap(out) char "Tcl_SetObjResult(interp,Tcl_NewStringObj(&$1,1));"; %typemap(out) float, double "Tcl_SetObjResult(interp,Tcl_NewDoubleObj((double) $1));"; %typemap(out) char * "Tcl_SetObjResult(interp,Tcl_NewStringObj($1,-1));"; %typemap(out) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] "Tcl_SetObjResult(interp,SWIG_NewPointerObj((void *) $1, $1_descriptor,0));"; %typemap(out) SWIGTYPE *DYNAMIC, SWIGTYPE &DYNAMIC { swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor,(void **) &$1); Tcl_SetObjResult(interp,SWIG_NewPointerObj((void *) $1, ty,0)); } %typemap(out) SWIGTYPE *INSTANCE, SWIGTYPE &INSTANCE, SWIGTYPE INSTANCE[] "Tcl_SetObjResult(interp,SWIG_NewInstanceObj((void *) $1, $1_descriptor,0));"; %typemap(out) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] "Tcl_SetObjResult(interp,SWIG_NewInstanceObj((void *) $1, $1_descriptor,0));"; %typemap(out) SWIGTYPE *DYNAMIC, SWIGTYPE &DYNAMIC { swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor,(void **) &$1); Tcl_SetObjResult(interp,SWIG_NewInstanceObj((void *) $1, ty,0)); } %typemap(out) SWIGTYPE (CLASS::*) "Tcl_SetObjResult(interp, SWIG_NewPackedObj((void *) &$1, sizeof($1_type), $1_descriptor, 0));"; %typemap(out) void ""; /* Primitive types--return by value */ %typemap(out) SWIGTYPE NOINSTANCE #ifdef __cplusplus { $&1_ltype resultptr; resultptr = new $1_ltype(($1_ltype &) $1); Tcl_SetObjResult(interp,SWIG_NewPointerObj((void*) resultptr, $&1_descriptor,0)); } #else { $&1_ltype resultptr; resultptr = ($&1_ltype) malloc(sizeof($1_type)); memmove(resultptr, &$1, sizeof($1_type)); Tcl_SetObjResult(interp,SWIG_NewPointerObj((void*) resultptr, $&1_descriptor,0)); } #endif /* Primitive types--return by value */ %typemap(out) SWIGTYPE INSTANCE #ifdef __cplusplus { $&1_ltype resultptr; resultptr = new $1_ltype(($1_ltype &) $1); Tcl_SetObjResult(interp,SWIG_NewInstanceObj((void*) resultptr, $&1_descriptor,1)); } #else { $&1_ltype resultptr; resultptr = ($&1_ltype) malloc(sizeof($1_type)); memmove(resultptr, &$1, sizeof($1_type)); Tcl_SetObjResult(interp,SWIG_NewInstanceObj((void*) resultptr, $&1_descriptor,1)); } #endif %typemap(out) SWIGTYPE = SWIGTYPE INSTANCE; /* Special typemap for character array returns */ %typemap(out) char [ANY] "Tcl_SetObjResult(interp,Tcl_NewStringObj($1,-1));" /* Primitive references */ %typemap(out) const int &, const unsigned int &, const short &, const unsigned short &, const long &, const unsigned long &, const signed char &, const unsigned char &, const bool & "Tcl_SetObjResult(interp,Tcl_NewIntObj((long) *($1)));"; %typemap(out) const float &, const double & "Tcl_SetObjResult(interp,Tcl_NewDoubleObj((double) *($1)));"; %typemap(out) const long long & { char temp[256]; sprintf(temp,"%lld", *($1)); Tcl_SetObjResult(interp,Tcl_NewStringObj(temp,-1)); } %typemap(out) const unsigned long long & { char temp[256]; sprintf(temp,"%llu", *($1)); Tcl_SetObjResult(interp,Tcl_NewStringObj(temp,-1)); } %typemap(out) const char & "Tcl_SetObjResult(interp,Tcl_NewStringObj($1,1));"; /* --- Variable output --- */ %typemap(varout) int, unsigned int, short, unsigned short, long, unsigned long, signed char, unsigned char, bool, enum SWIGTYPE "$result = Tcl_NewIntObj((long) $1);"; %typemap(varout) long long { char temp[256]; sprintf(temp,"%lld", $1); $result = Tcl_NewStringObj(temp,-1); } %typemap(varout) unsigned long long { char temp[256]; sprintf(temp,"%llu", $1); $result = Tcl_NewStringObj(temp,-1); } %typemap(varout) double,float "$result = Tcl_NewDoubleObj((double) $1);"; %typemap(varout) char * "$result = Tcl_NewStringObj( $1,-1);"; %typemap(varout) char [ANY] "$result = Tcl_NewStringObj( $1,-1);"; %typemap(varout) char "$result = Tcl_NewStringObj(&$1,1);"; %typemap(varout) SWIGTYPE *, SWIGTYPE [] "$result = SWIG_NewPointerObj((void *) $1, $1_descriptor,0);"; %typemap(varout) SWIGTYPE & "$result = SWIG_NewPointerObj((void *) &$1, $1_descriptor,0);"; %typemap(varout) SWIGTYPE *INSTANCE, SWIGTYPE INSTANCE[] "$result = SWIG_NewInstanceObj((void *) $1, $1_descriptor,0);"; %typemap(varout) SWIGTYPE &INSTANCE "$result = SWIG_NewInstanceObj((void *) &$1, $1_descriptor,0);"; %typemap(varout) SWIGTYPE INSTANCE "$result = SWIG_NewInstanceObj((void *) &$1, $&1_descriptor,0);"; %typemap(varout) SWIGTYPE "$result = SWIG_NewInstanceObj((void *) &$1, $&1_descriptor,0);"; %typemap(varout) SWIGTYPE (CLASS::*) "$result = SWIG_NewPackedObj((void *) &$1, sizeof($1_type), $1_descriptor, 0);"; /* -- Variable input --- */ %typemap(varin) int, unsigned int, short, unsigned short, long, unsigned long, signed char, unsigned char, enum SWIGTYPE { long temp; if (Tcl_GetLongFromObj(interp, $input, &temp) != TCL_OK) { return "Type error. expected an integer"; } $1 = ($1_type) temp; } %typemap(varin) bool { long temp; if (Tcl_GetLongFromObj(interp, $input, &temp) != TCL_OK) { return "Type error. expected an integer"; } $1 = temp ? true : false; } %typemap(varin) long long "$1 = ($1_ltype) strtoll(Tcl_GetStringFromObj($input,NULL),0,0);"; %typemap(varin) unsigned long long "$1 = ($1_ltype) strtoull(Tcl_GetStringFromObj($input,NULL),0,0);"; %typemap(varin) double, float { double temp; if (Tcl_GetDoubleFromObj(interp, $input, &temp) != TCL_OK) { return "Type error. expected a double."; } $1 = ($1_type) temp; } %typemap(varin) char * #ifdef __cplusplus { char *temp = Tcl_GetStringFromObj($input,NULL); if ($1) delete [] $1; $1 = ($1_type) new char[strlen(temp)+1]; strcpy($1,temp); } #else { char *temp = Tcl_GetStringFromObj($input,NULL); if ($1) free($1); $1 = ($1_type) malloc(strlen(temp)+1); strcpy($1,temp); } #endif %typemap(varin,warning="451:Setting const char * variable may leak memory") const char * #ifdef __cplusplus { char *temp = Tcl_GetStringFromObj($input,NULL); $1 = ($1_type) new char[strlen(temp)+1]; strcpy($1,temp); } #else { char *temp = Tcl_GetStringFromObj($input,NULL); $1 = ($1_type) malloc(strlen(temp)+1); strcpy($1,temp); } #endif %typemap(varin) char [ANY] { char *temp = Tcl_GetStringFromObj($input,NULL); strncpy($1,temp,$1_dim0); } %typemap(varin) char { char *temp = Tcl_GetStringFromObj($input,NULL); $1 = *temp; } %typemap(varin) SWIGTYPE * { void *temp; if (SWIG_ConvertPtr($input,&temp,$1_descriptor, SWIG_POINTER_EXCEPTION | SWIG_POINTER_DISOWN) != TCL_OK) { return "Type error. Expected $1_ltype"; } $1 = ($1_type) temp; } %typemap(varin) void * { void *temp; if (SWIG_ConvertPtr($input,&temp,0, SWIG_POINTER_EXCEPTION | SWIG_POINTER_DISOWN) != TCL_OK) { return (void*)"Type error. Expected $1_ltype"; } $1 = ($1_type) temp; } %typemap(varin) SWIGTYPE & { void *temp; if (SWIG_ConvertPtr($input,&temp,$1_descriptor, SWIG_POINTER_EXCEPTION) != TCL_OK) { return "Type error. Expected $1_ltype"; } $1 = *($1_ltype) temp; } %typemap(varin) SWIGTYPE { void *temp; if (SWIG_ConvertPtr($input,&temp,$&1_descriptor, SWIG_POINTER_EXCEPTION) != TCL_OK) { return "Type error. Expected $&1_ltype"; } $1 = *(($&1_type) temp); } %typemap(varin) SWIGTYPE [ANY] { void *temp; if (SWIG_ConvertPtr($input,&temp,$1_descriptor, SWIG_POINTER_EXCEPTION) != TCL_OK) { return "Type error. Expected $1_ltype"; } memmove((void *) $1,temp,$1_size*sizeof($1_basetype)); } %typemap(varin) SWIGTYPE (CLASS::*) { char temp[sizeof($1_type)]; if (SWIG_ConvertPacked($input, temp, sizeof($1_type), $1_descriptor, SWIG_POINTER_EXCEPTION) != TCL_OK) { return "Type error. Expected $1_ltype"; } memmove((void *) &$1, temp, sizeof($1_type)); } /* --- Constants --- */ %typemap(consttab) int, unsigned int, short, unsigned short, long, unsigned long, unsigned char, signed char, bool, enum SWIGTYPE { SWIG_TCL_INT, "$symname", (long) $value, 0, 0, 0} %typemap(consttab) float, double { SWIG_TCL_FLOAT, "$symname", 0, (double) $value, 0, 0} %typemap(consttab) char, char * { SWIG_TCL_STRING, "$symname", 0, 0, (void *)"$value", 0} %typemap(consttab) long long, unsigned long long { SWIG_TCL_STRING, "$symname", 0, 0, (void *)"$value", 0} %typemap(consttab) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { SWIG_TCL_POINTER, "$symname", 0, 0, (void *)$value, &$1_descriptor} %typemap(consttab) SWIGTYPE (CLASS::*) { SWIG_TCL_BINARY, "$symname", sizeof($type), 0, (void *)&$value, &$1_descriptor} /* ------------------------------------------------------------ * String & length * ------------------------------------------------------------ */ %typemap(in) (char *STRING, int LENGTH) { int temp; $1 = ($1_ltype) Tcl_GetStringFromObj($input,&temp); $2 = ($2_ltype) temp; } /* ------------------------------------------------------------ * ANSI C typemaps * ------------------------------------------------------------ */ %typemap(in) size_t (int temp) "if (Tcl_GetIntFromObj(interp,$input,&temp) == TCL_ERROR) return TCL_ERROR; $1 = (size_t) temp;"; %typemap(out) size_t = long; %typemap(varin) size_t = long; %typemap(varout) size_t = long; %typemap(consttab) size_t = long; /* ------------------------------------------------------------ * Typechecking rules * ------------------------------------------------------------ */ %typecheck(SWIG_TYPECHECK_INTEGER) int, short, long, unsigned int, unsigned short, unsigned long, signed char, unsigned char, long long, unsigned long long, const int &, const short &, const long &, const unsigned int &, const unsigned short &, const unsigned long &, const long long &, const unsigned long long &, enum SWIGTYPE, bool, const bool & { long tmp; if (Tcl_GetLongFromObj(NULL,$input,&tmp) == TCL_ERROR) $1 = 0; else $1 = 1; } %typecheck(SWIG_TYPECHECK_DOUBLE) float, double, const float &, const double & { double tmp; if (Tcl_GetDoubleFromObj(NULL,$input,&tmp) == TCL_ERROR) $1 = 0; else $1 = 1; } %typecheck(SWIG_TYPECHECK_CHAR) char { char *tmp; int len; tmp = Tcl_GetStringFromObj($input,&len); $1 = (len == 1) ? 1 : 0; } %typecheck(SWIG_TYPECHECK_STRING) char * { $1 = 1; } %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { void *ptr; if (SWIG_ConvertPtr($input, (void **) &ptr, $1_descriptor, 0) == TCL_ERROR) { $1 = 0; } else { $1 = 1; } } %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE { void *ptr; if (SWIG_ConvertPtr($input, (void **) &ptr, $&1_descriptor, 0) == TCL_ERROR) { $1 = 0; } else { $1 = 1; } } %typecheck(SWIG_TYPECHECK_VOIDPTR) void * { void *ptr; if (SWIG_ConvertPtr($input, (void **) &ptr, 0, 0) == TCL_ERROR) { $1 = 0; } else { $1 = 1; } } /* ------------------------------------------------------------ * Exception handling * ------------------------------------------------------------ */ %typemap(throws) int, long, short, unsigned int, unsigned long, unsigned short { Tcl_SetObjResult(interp, Tcl_NewIntObj((long) $1)); SWIG_fail; } %typemap(throws) SWIGTYPE CLASS { $&1_ltype temp = new $1_ltype($1); Tcl_SetObjResult(interp, SWIG_NewInstanceObj((void *) temp, $&1_descriptor, 1)); SWIG_fail; } %typemap(throws) SWIGTYPE { (void)($1); Tcl_SetObjResult(interp, Tcl_NewStringObj("$1_type", -1)); SWIG_fail; } %typemap(throws) char * { Tcl_SetObjResult(interp, Tcl_NewStringObj( $1, -1)); SWIG_fail; } // Some special reserved words in classes %include "tcl8kw.swg" /* C++ overloaded operators. These declarations define how SWIG is going to rename C++ overloaded operators in Tcl. Since Tcl allows identifiers to be essentially any valid string, we'll just use the normal operator names */ #ifdef __cplusplus %rename("+") *::operator+; //%rename("u+") *::operator+(); // Unary + //%rename("u+") *::operator+() const; // Unary + %rename("-") *::operator-; //%rename("u-") *::operator-(); // Unary - //%rename("u-") *::operator-() const; // Unary - %rename("*") *::operator*; %rename("/") *::operator/; %rename("<<") *::operator<<; %rename(">>") *::operator>>; %rename("&") *::operator&; %rename("|") *::operator|; %rename("^") *::operator^; %rename("%") *::operator%; %rename("=") *::operator=; #endif /* This initialization code exports the module initialization function */ %header %{ #ifdef __cplusplus extern "C" { #endif #ifdef MAC_TCL #pragma export on #endif SWIGEXPORT(int) SWIG_init(Tcl_Interp *); #ifdef MAC_TCL #pragma export off #endif #ifdef __cplusplus } #endif %} /* Start the initialization function */ %init %{ SWIGEXPORT(int) SWIG_init(Tcl_Interp *interp) { int i; static int _init = 0; if (interp == 0) return TCL_ERROR; #ifdef USE_TCL_STUBS if (Tcl_InitStubs(interp, "8.1", 0) == NULL) { return TCL_ERROR; } #endif Tcl_PkgProvide(interp, SWIG_name, SWIG_version); #ifdef SWIG_namespace Tcl_Eval(interp, "namespace eval " SWIG_namespace " { }"); #endif if (!_init) { for (i = 0; swig_types_initial[i]; i++) { swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]); } _init = 1; } for (i = 0; swig_commands[i].name; i++) { Tcl_CreateObjCommand(interp, swig_commands[i].name, (swig_wrapper_func) swig_commands[i].wrapper, swig_commands[i].clientdata, NULL); } for (i = 0; swig_variables[i].name; i++) { Tcl_SetVar(interp, swig_variables[i].name, "", TCL_GLOBAL_ONLY); Tcl_TraceVar(interp, swig_variables[i].name, TCL_TRACE_READS | TCL_GLOBAL_ONLY, (Tcl_VarTraceProc *) swig_variables[i].get, (ClientData) swig_variables[i].addr); Tcl_TraceVar(interp, swig_variables[i].name, TCL_TRACE_WRITES | TCL_GLOBAL_ONLY, (Tcl_VarTraceProc *) swig_variables[i].set, (ClientData) swig_variables[i].addr); } SWIG_InstallConstants(interp, swig_constants); %} /* Note: the initialization function is closed after all code is generated */ cableswig-0.1.0+git20150808.orig/SWIG/Lib/tcl/std_string.i0000644000175000000620000000212412561312227021417 0ustar stevestaff// // SWIG typemaps for std::string // Luigi Ballabio and Manu ??? // Apr 26, 2002 // // Tcl implementation // ------------------------------------------------------------------------ // std::string is typemapped by value // This can prevent exporting methods which return a string // in order for the user to modify it. // However, I think I'll wait until someone asks for it... // ------------------------------------------------------------------------ %include exception.i %{ #include %} namespace std { class string; /* Overloading check */ %typemap(typecheck) string = char *; %typemap(typecheck) const string & = char *; %typemap(in) string { $1 = std::string(Tcl_GetStringFromObj($input,NULL)); } %typemap(in) const string & (std::string temp) { temp = std::string(Tcl_GetStringFromObj($input,NULL)); $1 = &temp; } %typemap(out) string { Tcl_SetStringObj($result,(char*)$1.c_str(),$1.length()); } %typemap(out) const string & { Tcl_SetStringObj($result,(char*)$1->c_str(),$1->length()); } } cableswig-0.1.0+git20150808.orig/SWIG/Lib/tcl/std_map.i0000644000175000000620000001224712561312227020675 0ustar stevestaff// // SWIG typemaps for std::map // Luigi Ballabio // Jan. 2003 // // Common implementation %include std_common.i %include exception.i %exception std::map::get { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::map::del { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } // ------------------------------------------------------------------------ // std::map // ------------------------------------------------------------------------ %{ #include #include #include %} // exported class namespace std { template class map { // add typemaps here public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T& get(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void set(const K& key, const T& x) { (*self)[key] = x; } void del(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(const K& key) { std::map::iterator i = self->find(key); return i != self->end(); } } }; // specializations for built-ins %define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO) template class map { // add typemaps here public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T& get(K key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void set(K key, const T& x) { (*self)[key] = x; } void del(K key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(K key) { std::map::iterator i = self->find(key); return i != self->end(); } } }; %enddef %define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO) template class map { // add typemaps here public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T get(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void set(const K& key, T x) { (*self)[key] = x; } void del(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(const K& key) { std::map::iterator i = self->find(key); return i != self->end(); } } }; %enddef %define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO) template<> class map { // add typemaps here public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T get(K key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void set(K key, T x) { (*self)[key] = x; } void del(K key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(K key) { std::map::iterator i = self->find(key); return i != self->end(); } } }; %enddef // add specializations here } cableswig-0.1.0+git20150808.orig/SWIG/Lib/tcl/CMakeLists.txt0000644000175000000620000000035612561312227021632 0ustar stevestaffFILE(GLOB __files1 "${CMAKE_CURRENT_SOURCE_DIR}/*.i") FILE(GLOB __files2 "${CMAKE_CURRENT_SOURCE_DIR}/*.swg") INSTALL(FILES ${__files1} ${__files2} DESTINATION ${CableSwig_INSTALL_ROOT}lib/CableSwig/SWIGLib/tcl COMPONENT Development) cableswig-0.1.0+git20150808.orig/SWIG/Lib/tcl/Makefile.in0000644000175000000620000000756212561312227021145 0ustar stevestaff# --------------------------------------------------------------- # /cvsroot/SWIG/Lib/tcl/Makefile.in,v 1.3 2002/11/30 22:10:09 beazley Exp # SWIG Tcl/Tk Makefile # # This file can be used to build various Tcl extensions with SWIG. # By default this file is set up for dynamic loading, but it can # be easily customized for static extensions by modifying various # portions of the file. # # SRCS = C source files # CXXSRCS = C++ source files # OBJCSRCS = Objective-C source files # OBJS = Additional .o files (compiled previously) # INTERFACE = SWIG interface file # TARGET = Name of target module or executable # # Many portions of this file were created by the SWIG configure # script and should already reflect your machine. However, you # may need to modify the Makefile to reflect your specific # application. #---------------------------------------------------------------- SRCS = CXXSRCS = OBJCSRCS = OBJS = INTERFACE = WRAPFILE = $(INTERFACE:.i=_wrap.c) WRAPOBJ = $(INTERFACE:.i=_wrap.o) TARGET = module@SO@ # Use this kind of target for dynamic loading #TARGET = my_tclsh # Use this target for static linking prefix = @prefix@ exec_prefix = @exec_prefix@ CC = @CC@ CXX = @CXX@ OBJC = @CC@ -Wno-import # -Wno-import needed for gcc CFLAGS = INCLUDES = LIBS = # SWIG Options # SWIG = location of the SWIG executable # SWIGOPT = SWIG compiler options # SWIGCC = Compiler used to compile the wrapper file SWIG = $(exec_prefix)/bin/swig SWIGOPT = -tcl # use -tcl8 for Tcl 8.0 SWIGCC = $(CC) # SWIG Library files. Uncomment one of these for rebuilding tclsh or wish #SWIGLIB = -ltclsh.i #SWIGLIB = -lwish.i # Rules for creating .o files from source. COBJS = $(SRCS:.c=.o) CXXOBJS = $(CXXSRCS:.cxx=.o) OBJCOBJS = $(OBJCSRCS:.m=.o) ALLOBJS = $(COBJS) $(CXXOBJS) $(OBJCOBJS) $(OBJS) # Command that will be used to build the final extension. BUILD = $(SWIGCC) # Uncomment the following if you are using dynamic loading CCSHARED = @CCSHARED@ BUILD = @LDSHARED@ # Uncomment the following if you are using dynamic loading with C++ and # need to provide additional link libraries (this is not always required). #DLL_LIBS = -L/usr/local/lib/gcc-lib/sparc-sun-solaris2.5.1/2.7.2 \ -L/usr/local/lib -lg++ -lstdc++ -lgcc # X11 installation (needed to rebuild Tk extensions) XLIB = @XLIBSW@ XINCLUDE = @XINCLUDES@ # Tcl installation (where is Tcl/Tk located) TCL_INCLUDE = @TCLINCLUDE@ TCL_LIB = @TCLLIB@ # Build libraries (needed for static builds) LIBM = @LIBM@ LIBC = @LIBC@ SYSLIBS = $(LIBM) $(LIBC) @LIBS@ # Build options (uncomment only one these) BUILD_LIBS = $(LIBS) # Dynamic loading #BUILD_LIBS = $(TCL_LIB) -ltcl $(LIBS) $(SYSLIBS) # tclsh #BUILD_LIBS = $(TCL_LIB) -ltk -ltcl $(XLIB) $(LIBS) $(SYSLIBS) # wish # Compilation rules for non-SWIG components .SUFFIXES: .c .cxx .m .c.o: $(CC) $(CCSHARED) $(CFLAGS) $(INCLUDES) -c $< .cxx.o: $(CXX) $(CCSHARED) $(CXXFLAGS) $(INCLUDES) -c $< .m.o: $(OBJC) $(CCSHARED) $(CFLAGS) $(INCLUDES) -c $< # ---------------------------------------------------------------------- # Rules for building the extension # ---------------------------------------------------------------------- all: $(TARGET) # Convert the wrapper file into an object file $(WRAPOBJ) : $(WRAPFILE) $(SWIGCC) -c $(CCSHARED) $(CFLAGS) $(WRAPFILE) $(INCLUDES) $(TCL_INCLUDE) $(WRAPFILE) : $(INTERFACE) $(SWIG) $(SWIGOPT) -o $(WRAPFILE) $(SWIGLIB) $(INTERFACE) $(TARGET): $(WRAPOBJ) $(ALLOBJS) $(BUILD) $(WRAPOBJ) $(ALLOBJS) $(BUILD_LIBS) -o $(TARGET) clean: rm -f $(COBJS) $(CXXOBJS) $(OBJCOBJS) $(WRAPOBJ) $(WRAPFILE) $(TARGET) cableswig-0.1.0+git20150808.orig/SWIG/Lib/tcl/mactclinit.c0000644000175000000620000000403212561312227021360 0ustar stevestaff/* * tclMacAppInit.c -- * * Provides a version of the Tcl_AppInit procedure for the example shell. * * Copyright (c) 1993-1994 Lockheed Missle & Space Company, AI Center * Copyright (c) 1995-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tclMacAppInit.c 1.17 97/01/21 18:13:34 */ #include "tcl.h" #include "tclInt.h" #include "tclMacInt.h" #if defined(THINK_C) # include #elif defined(__MWERKS__) # include short InstallConsole _ANSI_ARGS_((short fd)); #endif /* *---------------------------------------------------------------------- * * MacintoshInit -- * * This procedure calls initalization routines to set up a simple * console on a Macintosh. This is necessary as the Mac doesn't * have a stdout & stderr by default. * * Results: * Returns TCL_OK if everything went fine. If it didn't the * application should probably fail. * * Side effects: * Inits the appropiate console package. * *---------------------------------------------------------------------- */ #ifdef __cplusplus extern "C" #endif extern int MacintoshInit() { #if defined(THINK_C) /* Set options for Think C console package */ /* The console package calls the Mac init calls */ console_options.pause_atexit = 0; console_options.title = "\pTcl Interpreter"; #elif defined(__MWERKS__) /* Set options for CodeWarrior SIOUX package */ SIOUXSettings.autocloseonquit = true; SIOUXSettings.showstatusline = true; SIOUXSettings.asktosaveonclose = false; InstallConsole(0); SIOUXSetTitle("\pTcl Interpreter"); #elif defined(applec) /* Init packages used by MPW SIOW package */ InitGraf((Ptr)&qd.thePort); InitFonts(); InitWindows(); InitMenus(); TEInit(); InitDialogs(nil); InitCursor(); #endif TclMacSetEventProc((TclMacConvertEventPtr) SIOUXHandleOneEvent); /* No problems with initialization */ return TCL_OK; } cableswig-0.1.0+git20150808.orig/SWIG/Lib/tcl/std_common.i0000644000175000000620000000021312561312227021376 0ustar stevestaff// // SWIG typemaps for STL - common utilities // Luigi Ballabio // Aug 17, 2003 // // Tcl implementation %apply size_t { std::size_t }; cableswig-0.1.0+git20150808.orig/SWIG/Lib/tcl/typemaps.i0000644000175000000620000004130512561312227021105 0ustar stevestaff/* ----------------------------------------------------------------------------- * typemaps.i * * Swig typemap library for Tcl8. This file contains various sorts * of typemaps for modifying Swig's code generation. * * Author: David Beazley (beazley@cs.uchicago.edu) * * ----------------------------------------------------------------------------- */ /* The SWIG typemap library provides a language independent mechanism for supporting output arguments, input values, and other C function calling mechanisms. The primary use of the library is to provide a better interface to certain C function--especially those involving pointers. */ // INPUT typemaps. // These remap a C pointer to be an "INPUT" value which is passed by value // instead of reference. /* The following methods can be applied to turn a pointer into a simple "input" value. That is, instead of passing a pointer to an object, you would use a real value instead. int *INPUT short *INPUT long *INPUT long long *INPUT unsigned int *INPUT unsigned short *INPUT unsigned long *INPUT unsigned long long *INPUT unsigned char *INPUT bool *INPUT float *INPUT double *INPUT To use these, suppose you had a C function like this : double fadd(double *a, double *b) { return *a+*b; } You could wrap it with SWIG as follows : %include typemaps.i double fadd(double *INPUT, double *INPUT); or you can use the %apply directive : %include typemaps.i %apply double *INPUT { double *a, double *b }; double fadd(double *a, double *b); */ %typemap(in) double *INPUT(double temp), double &INPUT(double temp) { if (Tcl_GetDoubleFromObj(interp,$input,&temp) == TCL_ERROR) { SWIG_fail; } $1 = &temp; } %typemap(in) float *INPUT(double dvalue, float temp), float &INPUT(double dvalue, float temp) { if (Tcl_GetDoubleFromObj(interp,$input,&dvalue) == TCL_ERROR) { SWIG_fail; } temp = (float) dvalue; $1 = &temp; } %typemap(in) int *INPUT(int temp), int &INPUT(int temp) { if (Tcl_GetIntFromObj(interp,$input,&temp) == TCL_ERROR) { SWIG_fail; } $1 = &temp; } %typemap(in) short *INPUT(int ivalue, short temp), short &INPUT(int ivalue, short temp) { if (Tcl_GetIntFromObj(interp,$input,&ivalue) == TCL_ERROR) { SWIG_fail; } temp = (short) ivalue; $1 = &temp; } %typemap(in) long *INPUT(int ivalue, long temp), long &INPUT(int ivalue, long temp) { if (Tcl_GetIntFromObj(interp,$input,&ivalue) == TCL_ERROR) { SWIG_fail; } temp = (long) ivalue; $1 = &temp; } %typemap(in) unsigned int *INPUT(int ivalue, unsigned int temp), unsigned int &INPUT(int ivalue, unsigned int temp) { if (Tcl_GetIntFromObj(interp,$input,&ivalue) == TCL_ERROR) { SWIG_fail; } temp = (unsigned int) ivalue; $1 = &temp; } %typemap(in) unsigned short *INPUT(int ivalue, unsigned short temp), unsigned short &INPUT(int ivalue, unsigned short temp) { if (Tcl_GetIntFromObj(interp,$input,&ivalue) == TCL_ERROR) { SWIG_fail; } temp = (unsigned short) ivalue; $1 = &temp; } %typemap(in) unsigned long *INPUT(int ivalue, unsigned long temp), unsigned long &INPUT(int ivalue, unsigned long temp) { if (Tcl_GetIntFromObj(interp,$input,&ivalue) == TCL_ERROR) { SWIG_fail; } temp = (unsigned long) ivalue; $1 = &temp; } %typemap(in) unsigned char *INPUT(int ivalue, unsigned char temp), unsigned char &INPUT(int ivalue, unsigned char temp) { if (Tcl_GetIntFromObj(interp,$input,&ivalue) == TCL_ERROR) { SWIG_fail; } temp = (unsigned char) ivalue; $1 = &temp; } %typemap(in) signed char *INPUT(int ivalue, signed char temp), signed char &INPUT(int ivalue, signed char temp) { if (Tcl_GetIntFromObj(interp,$input,&ivalue) == TCL_ERROR) { SWIG_fail; } temp = (signed char) ivalue; $1 = &temp; } %typemap(in) bool *INPUT(int ivalue, bool temp), bool &INPUT(int ivalue, bool temp) { if (Tcl_GetIntFromObj(interp,$input,&ivalue) == TCL_ERROR) { SWIG_fail; } temp = ivalue ? true : false; $1 = &temp; } %typemap(in) long long *INPUT($*1_ltype temp), long long &INPUT($*1_ltype temp) { temp = ($*1_ltype) strtoll(Tcl_GetStringFromObj($input,NULL),0,0); $1 = &temp; } %typemap(in) unsigned long long *INPUT($*1_ltype temp), unsigned long long &INPUT($*1_ltype temp) { temp = ($*1_ltype) strtoull(Tcl_GetStringFromObj($input,NULL),0,0); $1 = &temp; } // OUTPUT typemaps. These typemaps are used for parameters that // are output only. The output value is appended to the result as // a list element. /* The following methods can be applied to turn a pointer into an "output" value. When calling a function, no input value would be given for a parameter, but an output value would be returned. In the case of multiple output values, they are returned in the form of a Tcl list. int *OUTPUT short *OUTPUT long *OUTPUT long long *OUTPUT unsigned int *OUTPUT unsigned short *OUTPUT unsigned long *OUTPUT unsigned long long *OUTPUT unsigned char *OUTPUT bool *OUTPUT float *OUTPUT double *OUTPUT For example, suppose you were trying to wrap the modf() function in the C math library which splits x into integral and fractional parts (and returns the integer part in one of its parameters).K: double modf(double x, double *ip); You could wrap it with SWIG as follows : %include typemaps.i double modf(double x, double *OUTPUT); or you can use the %apply directive : %include typemaps.i %apply double *OUTPUT { double *ip }; double modf(double x, double *ip); The Tcl output of the function would be a list containing both output values. */ %typemap(in,numinputs=0) int *OUTPUT(int temp), short *OUTPUT(short temp), long *OUTPUT(long temp), unsigned int *OUTPUT(unsigned int temp), unsigned short *OUTPUT(unsigned short temp), unsigned long *OUTPUT(unsigned long temp), unsigned char *OUTPUT(unsigned char temp), signed char *OUTPUT(signed char temp), bool *OUTPUT(bool temp), float *OUTPUT(float temp), double *OUTPUT(double temp), long long *OUTPUT($*1_ltype temp), unsigned long long *OUTPUT($*1_ltype temp), int &OUTPUT(int temp), short &OUTPUT(short temp), long &OUTPUT(long temp), unsigned int &OUTPUT(unsigned int temp), unsigned short &OUTPUT(unsigned short temp), unsigned long &OUTPUT(unsigned long temp), signed char &OUTPUT(signed char temp), bool &OUTPUT(bool temp), unsigned char &OUTPUT(unsigned char temp), float &OUTPUT(float temp), double &OUTPUT(double temp), long long &OUTPUT($*1_ltype temp), unsigned long long &OUTPUT($*1_ltype temp) "$1 = &temp;"; %typemap(argout) int *OUTPUT, int &OUTPUT, short *OUTPUT, short &OUTPUT, long *OUTPUT, long &OUTPUT, unsigned int *OUTPUT, unsigned int &OUTPUT, unsigned short *OUTPUT, unsigned short &OUTPUT, unsigned long *OUTPUT, unsigned long &OUTPUT, unsigned char *OUTPUT, unsigned char &OUTPUT, signed char *OUTPUT, signed char &OUTPUT, bool *OUTPUT, bool &OUTPUT { Tcl_Obj *o; o = Tcl_NewIntObj((int) *($1)); Tcl_ListObjAppendElement(interp,Tcl_GetObjResult(interp),o); } %typemap(argout) float *OUTPUT, float &OUTPUT, double *OUTPUT, double &OUTPUT { Tcl_Obj *o; o = Tcl_NewDoubleObj((double) *($1)); Tcl_ListObjAppendElement(interp,Tcl_GetObjResult(interp),o); } %typemap(argout) long long *OUTPUT, long long &OUTPUT { char temp[256]; Tcl_Obj *o; sprintf(temp,"%lld",*($1)); o = Tcl_NewStringObj(temp,-1); Tcl_ListObjAppendElement(interp,Tcl_GetObjResult(interp),o); } %typemap(argout) unsigned long long *OUTPUT, unsigned long long &OUTPUT { char temp[256]; Tcl_Obj *o; sprintf(temp,"%llu",*($1)); o = Tcl_NewStringObj(temp,-1); Tcl_ListObjAppendElement(interp,Tcl_GetObjResult(interp),o); } // INOUT // Mappings for an argument that is both an input and output // parameter /* The following methods can be applied to make a function parameter both an input and output value. This combines the behavior of both the "INPUT" and "OUTPUT" methods described earlier. Output values are returned in the form of a Tcl list. int *INOUT short *INOUT long *INOUT long long *INOUT unsigned int *INOUT unsigned short *INOUT unsigned long *INOUT unsigned long long *INOUT unsigned char *INOUT bool *INOUT float *INOUT double *INOUT For example, suppose you were trying to wrap the following function : void neg(double *x) { *x = -(*x); } You could wrap it with SWIG as follows : %include typemaps.i void neg(double *INOUT); or you can use the %apply directive : %include typemaps.i %apply double *INOUT { double *x }; void neg(double *x); Unlike C, this mapping does not directly modify the input value (since this makes no sense in Tcl). Rather, the modified input value shows up as the return value of the function. Thus, to apply this function to a Tcl variable you might do this : set x [neg $x] */ %typemap(in) int *INOUT = int *INPUT; %typemap(in) short *INOUT = short *INPUT; %typemap(in) long *INOUT = long *INPUT; %typemap(in) unsigned int *INOUT = unsigned int *INPUT; %typemap(in) unsigned short *INOUT = unsigned short *INPUT; %typemap(in) unsigned long *INOUT = unsigned long *INPUT; %typemap(in) unsigned char *INOUT = unsigned char *INPUT; %typemap(in) signed char *INOUT = signed char *INPUT; %typemap(in) bool *INOUT = bool *INPUT; %typemap(in) float *INOUT = float *INPUT; %typemap(in) double *INOUT = double *INPUT; %typemap(in) long long *INOUT = long long *INPUT; %typemap(in) unsigned long long *INOUT = unsigned long long *INPUT; %typemap(in) int &INOUT = int &INPUT; %typemap(in) short &INOUT = short &INPUT; %typemap(in) long &INOUT = long &INPUT; %typemap(in) unsigned int &INOUT = unsigned int &INPUT; %typemap(in) unsigned short &INOUT = unsigned short &INPUT; %typemap(in) unsigned long &INOUT = unsigned long &INPUT; %typemap(in) unsigned char &INOUT = unsigned char &INPUT; %typemap(in) signed char &INOUT = signed char &INPUT; %typemap(in) bool &INOUT = bool &INPUT; %typemap(in) float &INOUT = float &INPUT; %typemap(in) double &INOUT = double &INPUT; %typemap(in) long long &INOUT = long long &INPUT; %typemap(in) unsigned long long &INOUT = unsigned long long &INPUT; %typemap(argout) int *INOUT = int *OUTPUT; %typemap(argout) short *INOUT = short *OUTPUT; %typemap(argout) long *INOUT = long *OUTPUT; %typemap(argout) unsigned int *INOUT = unsigned int *OUTPUT; %typemap(argout) unsigned short *INOUT = unsigned short *OUTPUT; %typemap(argout) unsigned long *INOUT = unsigned long *OUTPUT; %typemap(argout) unsigned char *INOUT = unsigned char *OUTPUT; %typemap(argout) signed char *INOUT = signed char *OUTPUT; %typemap(argout) bool *INOUT = bool *OUTPUT; %typemap(argout) float *INOUT = float *OUTPUT; %typemap(argout) double *INOUT = double *OUTPUT; %typemap(argout) long long *INOUT = long long *OUTPUT; %typemap(argout) unsigned long long *INOUT = unsigned long long *OUTPUT; %typemap(argout) int &INOUT = int &OUTPUT; %typemap(argout) short &INOUT = short &OUTPUT; %typemap(argout) long &INOUT = long &OUTPUT; %typemap(argout) unsigned int &INOUT = unsigned int &OUTPUT; %typemap(argout) unsigned short &INOUT = unsigned short &OUTPUT; %typemap(argout) unsigned long &INOUT = unsigned long &OUTPUT; %typemap(argout) unsigned char &INOUT = unsigned char &OUTPUT; %typemap(argout) signed char &INOUT = signed char &OUTPUT; %typemap(argout) bool &INOUT = bool &OUTPUT; %typemap(argout) float &INOUT = float &OUTPUT; %typemap(argout) double &INOUT = double &OUTPUT; %typemap(argout) long long &INOUT = long long &OUTPUT; %typemap(argout) unsigned long long &INOUT = unsigned long long &OUTPUT; // -------------------------------------------------------------------- // Special types // -------------------------------------------------------------------- // If interp * appears as a function argument, we ignore it and get // it from the wrapper function. /* The typemaps.i library also provides the following mappings : Tcl_Interp *interp Passes the current Tcl_Interp value directly to a C function. This can be used to work with existing wrapper functions or if you just need the interp value for some reason. When used, the 'interp' parameter becomes hidden in the Tcl interface--that is, you don't specify it explicitly. SWIG fills in its value automatically. int Tcl_Result Makes the integer return code of a function the return value of a SWIG generated wrapper function. For example : int foo() { ... do stuff ... return TCL_OK; } could be wrapped as follows : %include typemaps.i %apply int Tcl_Result { int foo }; int foo(); */ %typemap(in,numinputs=0) Tcl_Interp *interp { $1 = interp; } // If return code is a Tcl_Result, simply pass it on %typemap(out) int Tcl_Result { return $1; } /* Overloading information */ %typemap(typecheck) double *INPUT = double; %typemap(typecheck) bool *INPUT = bool; %typemap(typecheck) signed char *INPUT = signed char; %typemap(typecheck) unsigned char *INPUT = unsigned char; %typemap(typecheck) unsigned long *INPUT = unsigned long; %typemap(typecheck) unsigned short *INPUT = unsigned short; %typemap(typecheck) unsigned int *INPUT = unsigned int; %typemap(typecheck) long *INPUT = long; %typemap(typecheck) short *INPUT = short; %typemap(typecheck) int *INPUT = int; %typemap(typecheck) float *INPUT = float; %typemap(typecheck) long long *INPUT = long long; %typemap(typecheck) unsigned long long *INPUT = unsigned long long; %typemap(typecheck) double &INPUT = double; %typemap(typecheck) bool &INPUT = bool; %typemap(typecheck) signed char &INPUT = signed char; %typemap(typecheck) unsigned char &INPUT = unsigned char; %typemap(typecheck) unsigned long &INPUT = unsigned long; %typemap(typecheck) unsigned short &INPUT = unsigned short; %typemap(typecheck) unsigned int &INPUT = unsigned int; %typemap(typecheck) long &INPUT = long; %typemap(typecheck) short &INPUT = short; %typemap(typecheck) int &INPUT = int; %typemap(typecheck) float &INPUT = float; %typemap(typecheck) long long &INPUT = long long; %typemap(typecheck) unsigned long long &INPUT = unsigned long long; %typemap(typecheck) double *INOUT = double; %typemap(typecheck) bool *INOUT = bool; %typemap(typecheck) signed char *INOUT = signed char; %typemap(typecheck) unsigned char *INOUT = unsigned char; %typemap(typecheck) unsigned long *INOUT = unsigned long; %typemap(typecheck) unsigned short *INOUT = unsigned short; %typemap(typecheck) unsigned int *INOUT = unsigned int; %typemap(typecheck) long *INOUT = long; %typemap(typecheck) short *INOUT = short; %typemap(typecheck) int *INOUT = int; %typemap(typecheck) float *INOUT = float; %typemap(typecheck) long long *INOUT = long long; %typemap(typecheck) unsigned long long *INOUT = unsigned long long; %typemap(typecheck) double &INOUT = double; %typemap(typecheck) bool &INOUT = bool; %typemap(typecheck) signed char &INOUT = signed char; %typemap(typecheck) unsigned char &INOUT = unsigned char; %typemap(typecheck) unsigned long &INOUT = unsigned long; %typemap(typecheck) unsigned short &INOUT = unsigned short; %typemap(typecheck) unsigned int &INOUT = unsigned int; %typemap(typecheck) long &INOUT = long; %typemap(typecheck) short &INOUT = short; %typemap(typecheck) int &INOUT = int; %typemap(typecheck) float &INOUT = float; %typemap(typecheck) long long &INOUT = long long; %typemap(typecheck) unsigned long long &INOUT = unsigned long long; cableswig-0.1.0+git20150808.orig/SWIG/Lib/tcl/swigtcl8.swg0000644000175000000620000006066412561312227021370 0ustar stevestaff/* * /cvsroot/SWIG/Lib/tcl/swigtcl8.swg,v 1.19 2003/12/09 12:44:49 beazley Exp * * swigtcl8.swg */ #include #include #include #include #ifdef __cplusplus extern "C" { #endif #if (TCL_MAJOR_VERSION >= 8) && (TCL_MINOR_VERSION >=4) //If using TCL version 84, then add some more const. #define SWIG_TCL_CONST84 const #define SWIG_TCL_CONST83 const //#error "Found that version is 8.4" #else #define SWIG_TCL_CONST84 #define SWIG_TCL_CONST83 const //#error "Found that version is not 8.4" #endif /* Constant table */ #define SWIG_TCL_INT 1 #define SWIG_TCL_FLOAT 2 #define SWIG_TCL_STRING 3 #define SWIG_TCL_POINTER 4 #define SWIG_TCL_BINARY 5 /* Flags for pointer conversion */ #define SWIG_POINTER_EXCEPTION 0x1 #define SWIG_POINTER_DISOWN 0x2 /* Swig fail macro */ #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; typedef int (*swig_wrapper)(ClientData, Tcl_Interp *, int, Tcl_Obj *const []); typedef int (*swig_wrapper_func)(ClientData, Tcl_Interp *, int, Tcl_Obj *const []); typedef char *(*swig_variable_func)(ClientData, Tcl_Interp *, char *, char *, int); typedef void (*swig_delete_func)(ClientData); typedef struct swig_method { SWIG_TCL_CONST84 char *name; swig_wrapper method; } swig_method; typedef struct swig_attribute { SWIG_TCL_CONST84 char *name; swig_wrapper getmethod; swig_wrapper setmethod; } swig_attribute; typedef struct swig_class { SWIG_TCL_CONST84 char *name; swig_type_info **type; swig_wrapper constructor; void (*destructor)(void *); swig_method *methods; swig_attribute *attributes; const char **bases; } swig_class; typedef struct swig_instance { Tcl_Obj *thisptr; void *thisvalue; swig_class *classptr; int destroy; Tcl_Command cmdtok; } swig_instance; #define SWIG_NewPointerObj(ptr, type, flags) \ SWIG_Tcl_NewPointerObj(ptr, type, flags) #define SWIG_ConvertPtr(oc, ptr, ty, flags) \ SWIG_Tcl_ConvertPtr(interp, oc, ptr, ty, flags) #define SWIG_ConvertPtrFromString(c, ptr, ty, flags) \ SWIG_Tcl_ConvertPtrFromString(interp, c, ptr, ty, flags) #define SWIG_ConvertPacked(obj, ptr, sz, ty, flags) \ SWIG_Tcl_ConvertPacked(interp, obj, ptr, sz, ty, flags) #define SWIG_MakePtr(c, ptr, ty, flags) \ SWIG_Tcl_MakePtr(c, ptr, ty, flags) #define SWIG_NewPackedObj(ptr, sz, type, flags) \ SWIG_Tcl_NewPackedObj(ptr, sz, type, flags) #define SWIG_GetArgs SWIG_Tcl_GetArgs #define SWIG_PointerTypeFromString(c) \ SWIG_Tcl_PointerTypeFromString(c) #define SWIG_Acquire(ptr) \ SWIG_Tcl_Acquire(ptr) #define SWIG_Disown(ptr) \ SWIG_Tcl_Disown(ptr) #define SWIG_Thisown(ptr) \ SWIG_Tcl_Thisown(ptr) #define SWIG_InstallConstants(interp, constants) \ SWIG_Tcl_InstallConstants(interp, constants) #define SWIG_GetConstant(key) \ SWIG_Tcl_GetConstant(key) #define SWIG_NewInstanceObj(thisvalue, type, flags) \ SWIG_Tcl_NewInstanceObj(interp, thisvalue, type, flags) #define SWIG_ObjectConstructor SWIG_Tcl_ObjectConstructor #define SWIG_MethodCommand SWIG_Tcl_MethodCommand #define SWIG_ObjectDelete SWIG_Tcl_ObjectDelete #ifdef SWIG_NOINCLUDE SWIGIMPORT(int) SWIG_Tcl_ConvertPtrFromString(Tcl_Interp *, char *, void **, swig_type_info *,int flags); SWIGIMPORT(int) SWIG_Tcl_ConvertPtr(Tcl_Interp *, Tcl_Obj *, void **, swig_type_info *, int flags); SWIGIMPORT(int) SWIG_Tcl_ConvertPacked(Tcl_Interp *, Tcl_Obj *, void *, int sz, swig_type_info *, int flags); SWIGIMPORT(void) SWIG_Tcl_MakePtr(char *, void *, swig_type_info *, int flags); SWIGIMPORT(Tcl_Obj *) SWIG_Tcl_NewPointerObj(void *, swig_type_info *, int flags); SWIGIMPORT(Tcl_Obj *) SWIG_Tcl_NewPackedObj(void *, int sz, swig_type_info *, int flags); SWIGIMPORT(int) SWIG_Tcl_GetArgs(Tcl_Interp *, int, Tcl_Obj *const [], const char *, ...); SWIGIMPORT(char *) SWIG_Tcl_PointerTypeFromString(char *c); SWIGIMPORT(void) SWIG_Tcl_Acquire(SWIG_TCL_CONST84 void * const ptr); SWIGIMPORT(int) SWIG_Tcl_Disown(SWIG_TCL_CONST84 void * const ptr); SWIGIMPORT(int) SWIG_Tcl_Thisown(SWIG_TCL_CONST84 void * const ptr); SWIGIMPORT(void) SWIG_Tcl_InstallConstants(Tcl_Interp *interp, struct swig_const_info constants[]); SWIGIMPORT(Tcl_Obj *) SWIG_Tcl_GetConstant(const char *key); SWIGIMPORT(Tcl_Obj *) SWIG_Tcl_NewInstanceObj(Tcl_Interp *interp, void *, swig_type_info *, int flags); SWIGIMPORT(int) SWIG_Tcl_ObjectConstructor(ClientData, Tcl_Interp *, int, Tcl_Obj *const objv[]); SWIGIMPORT(int) SWIG_Tcl_MethodCommand(ClientData, Tcl_Interp *, int, Tcl_Obj *objv[]); SWIGIMPORT(void) SWIG_Tcl_ObjectDelete(ClientData); #else /* Object support */ static Tcl_HashTable swigobjectTable; static int swigobjectTableinit = 0; /* Acquire ownership of a pointer */ SWIGRUNTIME(void) SWIG_Tcl_Acquire(SWIG_TCL_CONST84 void * const ptr) { //Not UsedTcl_HashEntry *entryPtr; int newobj; if (!swigobjectTableinit) { Tcl_InitHashTable(&swigobjectTable, TCL_ONE_WORD_KEYS); swigobjectTableinit = 1; } //Not Used entryPtr = Tcl_CreateHashEntry(&swigobjectTable, (SWIG_TCL_CONST84 char *) ptr, &newobj); } /* Disown a pointer. Returns 1 if we owned it to begin with */ SWIGRUNTIME(int) SWIG_Tcl_Disown(SWIG_TCL_CONST84 void * const ptr) { Tcl_HashEntry *entryPtr; if (!swigobjectTableinit) return 0; entryPtr = Tcl_FindHashEntry(&swigobjectTable, (SWIG_TCL_CONST84 char *) ptr); if (entryPtr) { Tcl_DeleteHashEntry(entryPtr); return 1; } return 0; } SWIGRUNTIME(int) SWIG_Tcl_Thisown(SWIG_TCL_CONST84 void * const ptr) { if (!swigobjectTableinit) return 0; if (Tcl_FindHashEntry(&swigobjectTable, (SWIG_TCL_CONST84 char *) ptr)) { return 1; } return 0; } /************************/ /*NOTE: All this carring on is due to the fact that tcl is not */ /* cost correct, and requires that non-cost char strings are passed. */ SWIGRUNTIME(void) SWIG_Tcl_SetResultFromConstString(Tcl_Interp * interp, char const * const str, Tcl_FreeProc * freeProc) { const size_t NullTerminatedStringLength=strlen(str)+1; char * Msg= (char *) malloc(NullTerminatedStringLength); strncpy(Msg,str,NullTerminatedStringLength); Tcl_SetResult(interp, Msg, TCL_VOLATILE); free(Msg); return; } /* Convert a pointer value */ SWIGRUNTIME(int) SWIG_Tcl_ConvertPtrFromString(Tcl_Interp *interp, char *c, void **ptr, swig_type_info *ty, int flags) { swig_type_info *tc; /* Pointer values must start with leading underscore */ while (*c != '_') { *ptr = (void *) 0; if (strcmp(c,"NULL") == 0) return TCL_OK; /* Hmmm. It could be an object name. */ { char TempGetCmd[17]=" cget -this";/* This is to avoid compiler warnings because TCL is not const correct! */ if (Tcl_VarEval(interp,c,TempGetCmd, (char *) NULL) == TCL_OK) { Tcl_Obj *result = Tcl_GetObjResult(interp); c = Tcl_GetStringFromObj(result, NULL); continue; } } Tcl_ResetResult(interp); if (flags & SWIG_POINTER_EXCEPTION) SWIG_Tcl_SetResultFromConstString(interp, "Type error. Expected a pointer", TCL_STATIC); return TCL_ERROR; } c++; c = SWIG_UnpackData(c,ptr,sizeof(void *)); if (ty) { tc = SWIG_TypeCheck(c,ty); if ((!tc) && (flags & SWIG_POINTER_EXCEPTION)) { SWIG_Tcl_SetResultFromConstString(interp, "Type error. Expected ", TCL_STATIC); Tcl_AppendElement(interp, ty->name); return TCL_ERROR; } else if (!tc) { Tcl_ResetResult(interp); return TCL_ERROR; } if (flags & SWIG_POINTER_DISOWN) { SWIG_Disown((void *) *ptr); } *ptr = SWIG_TypeCast(tc,(void *) *ptr); } return TCL_OK; } /* Convert a pointer value */ SWIGRUNTIME(int) SWIG_Tcl_ConvertPtr(Tcl_Interp *interp, Tcl_Obj *oc, void **ptr, swig_type_info *ty, int flags) { return SWIG_Tcl_ConvertPtrFromString(interp, Tcl_GetStringFromObj(oc,NULL), ptr, ty, flags); } /* Convert a pointer value */ SWIGRUNTIME(char *) SWIG_Tcl_PointerTypeFromString(char *c) { char d; /* Pointer values must start with leading underscore. NULL has no type */ if (*c != '_') { return 0; } c++; /* Extract hex value from pointer */ while ((d = *c)) { if (!(((d >= '0') && (d <= '9')) || ((d >= 'a') && (d <= 'f')))) break; c++; } return c; } /* Convert a packed value value */ SWIGRUNTIME(int) SWIG_Tcl_ConvertPacked(Tcl_Interp *interp, Tcl_Obj *obj, void *ptr, int sz, swig_type_info *ty, int flags) { swig_type_info *tc; char *c; if (!obj) goto type_error; c = Tcl_GetStringFromObj(obj,NULL); /* Pointer values must start with leading underscore */ if (*c != '_') goto type_error; c++; c = SWIG_UnpackData(c,ptr,sz); if (ty) { tc = SWIG_TypeCheck(c,ty); if (!tc) goto type_error; } return TCL_OK; type_error: if (flags) { if (ty) { SWIG_Tcl_SetResultFromConstString(interp, "Type error. Expected ", TCL_STATIC); Tcl_AppendElement(interp, ty->name); return TCL_ERROR; } else { SWIG_Tcl_SetResultFromConstString(interp, "Expected packed data.", TCL_STATIC); return TCL_ERROR; } } return TCL_ERROR; } /* Take a pointer and convert it to a string */ SWIGRUNTIME(void) SWIG_Tcl_MakePtr(char *c, void *ptr, swig_type_info *ty, int flags) { if (ptr) { *(c++) = '_'; c = SWIG_PackData(c,&ptr,sizeof(void *)); strcpy(c,ty->name); } else { strcpy(c,"NULL"); } flags = 0; } /* Create a new pointer object */ SWIGRUNTIME(Tcl_Obj *) SWIG_Tcl_NewPointerObj(void *ptr, swig_type_info *type, int flags) { Tcl_Obj *robj; char result[512]; SWIG_MakePtr(result,ptr,type,flags); robj = Tcl_NewStringObj((SWIG_TCL_CONST84 char *)result,-1); return robj; } SWIGRUNTIME(Tcl_Obj *) SWIG_Tcl_NewPackedObj(void *ptr, int sz, swig_type_info *type, int flags) { char result[1024]; char *r = result; if ((2*sz + 1 + strlen(type->name)) > 1000) return 0; *(r++) = '_'; r = SWIG_PackData(r,ptr,sz); strcpy(r,type->name); flags = 0; return Tcl_NewStringObj((SWIG_TCL_CONST84 char *)result,-1); } static Tcl_HashTable swigconstTable; static int swigconstTableinit = 0; /* Install Constants */ SWIGRUNTIME(void) SWIG_Tcl_InstallConstants(Tcl_Interp *interp, swig_const_info constants[]) { int i; Tcl_Obj *obj; Tcl_HashEntry *entryPtr; int newobj; if (!swigconstTableinit) { Tcl_InitHashTable(&swigconstTable, TCL_STRING_KEYS); swigconstTableinit = 1; } for (i = 0; constants[i].type; i++) { switch(constants[i].type) { case SWIG_TCL_INT: obj = Tcl_NewIntObj(constants[i].lvalue); break; case SWIG_TCL_FLOAT: obj = Tcl_NewDoubleObj(constants[i].dvalue); break; case SWIG_TCL_STRING: obj = Tcl_NewStringObj((SWIG_TCL_CONST84 char *) constants[i].pvalue,-1); break; case SWIG_TCL_POINTER: obj = SWIG_NewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0); break; case SWIG_TCL_BINARY: obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype),0); break; default: obj = 0; break; } if (obj) { Tcl_ObjSetVar2(interp,Tcl_NewStringObj((SWIG_TCL_CONST84 char *)constants[i].name,-1), NULL, obj, TCL_GLOBAL_ONLY); entryPtr = Tcl_CreateHashEntry(&swigconstTable, (SWIG_TCL_CONST84 char *)constants[i].name, &newobj); Tcl_SetHashValue(entryPtr, (ClientData) obj); } } } SWIGRUNTIME(Tcl_Obj *) SWIG_Tcl_GetConstant(SWIG_TCL_CONST84 char *key) { Tcl_HashEntry *entryPtr; if (!swigconstTableinit) return 0; entryPtr = Tcl_FindHashEntry(&swigconstTable, (SWIG_TCL_CONST84 char *)key); if (entryPtr) { return (Tcl_Obj *) Tcl_GetHashValue(entryPtr); } printf("Searching %s\n", key); return 0; } /* Get arguments */ SWIGRUNTIME(int) SWIG_Tcl_GetArgs(Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], const char *fmt, ...) { int argno = 0, opt = 0; long tempi; double tempd; const char *c; va_list ap; void *vptr; Tcl_Obj *obj = 0; swig_type_info *ty; va_start(ap,fmt); for (c = fmt; (*c && (*c != ':') && (*c != ';')); c++,argno++) { if (*c == '|') { opt = 1; c++; } if (argno >= (objc-1)) { if (!opt) { SWIG_Tcl_SetResultFromConstString(interp, "Wrong # args. ", TCL_STATIC); goto argerror; } else { va_end(ap); return TCL_OK; } } vptr = va_arg(ap,void *); if (vptr) { if (isupper(*c)) { obj = SWIG_GetConstant(Tcl_GetStringFromObj(objv[argno+1],0)); if (!obj) obj = objv[argno+1]; } else { obj = objv[argno+1]; } switch(*c) { case 'i': case 'I': case 'l': case 'L': case 'h': case 'H': case 'b': case 'B': if (Tcl_GetLongFromObj(interp,obj,&tempi) != TCL_OK) goto argerror; if ((*c == 'i') || (*c == 'I')) *((int *)vptr) = (int)tempi; else if ((*c == 'l') || (*c == 'L')) *((long *)vptr) = (long)tempi; else if ((*c == 'h') || (*c == 'H')) *((short*)vptr) = (short)tempi; else if ((*c == 'b') || (*c == 'B')) *((unsigned char *)vptr) = (unsigned char)tempi; break; case 'f': case 'F': case 'd': case 'D': if (Tcl_GetDoubleFromObj(interp,obj,&tempd) != TCL_OK) goto argerror; if ((*c == 'f') || (*c == 'F')) *((float *) vptr) = (float)tempd; else if ((*c == 'd') || (*c == 'D')) *((double*) vptr) = tempd; break; case 's': case 'S': if (*(c+1) == '#') { int *vlptr = (int *) va_arg(ap, void *); *((char **) vptr) = Tcl_GetStringFromObj(obj, vlptr); c++; } else { *((char **)vptr) = Tcl_GetStringFromObj(obj,NULL); } break; case 'c': case 'C': *((char *)vptr) = *(Tcl_GetStringFromObj(obj,NULL)); break; case 'p': case 'P': ty = (swig_type_info *) va_arg(ap, void *); if (SWIG_Tcl_ConvertPtr(interp, obj, (void **) vptr, ty, SWIG_POINTER_EXCEPTION) == TCL_ERROR) goto argerror; break; case 'o': case 'O': *((Tcl_Obj **)vptr) = objv[argno+1]; break; default: break; } } } if ((*c != ';') && ((objc-1) > argno)) { SWIG_Tcl_SetResultFromConstString(interp, "Wrong # args.", TCL_STATIC); goto argerror; } va_end(ap); return TCL_OK; argerror: { char temp[32]; sprintf(temp,"%d", argno+1); c = strchr(fmt,':'); if (!c) c = strchr(fmt,';'); if (!c) c = ""; Tcl_AppendResult(interp,c," argument ", temp, NULL); va_end(ap); return TCL_ERROR; } } SWIGRUNTIME(void) SWIG_Tcl_ObjectDelete(ClientData clientData) { swig_instance *si = (swig_instance *) clientData; if ((si) && (si->destroy) && (SWIG_Disown(si->thisvalue))) { if (si->classptr->destructor) { (si->classptr->destructor)(si->thisvalue); } } Tcl_DecrRefCount(si->thisptr); free(si); } /* Function to invoke object methods given an instance */ SWIGRUNTIME(int) SWIG_Tcl_MethodCommand(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj * _objv[]) { char *method, *attrname; swig_instance *inst = (swig_instance *) clientData; swig_method *meth; swig_attribute *attr; Tcl_Obj *oldarg; int rcode; swig_class *cls; swig_class *cls_stack[64]; int cls_stack_bi[64]; int cls_stack_top = 0; int numconf = 2; int bi; const char* base_name; Tcl_Obj **objv = (Tcl_Obj **) _objv; if (objc < 2) { SWIG_Tcl_SetResultFromConstString(interp, "wrong # args.", TCL_STATIC); return TCL_ERROR; } method = Tcl_GetStringFromObj(objv[1],NULL); if (strcmp(method,"-acquire") == 0) { inst->destroy = 1; SWIG_Acquire(inst->thisvalue); return TCL_OK; } if (strcmp(method,"-disown") == 0) { if (inst->destroy) { SWIG_Disown(inst->thisvalue); } inst->destroy = 0; return TCL_OK; } if (strcmp(method,"-delete") == 0) { Tcl_DeleteCommandFromToken(interp,inst->cmdtok); return TCL_OK; } cls_stack[cls_stack_top] = inst->classptr; cls_stack_bi[cls_stack_top] = -1; cls = inst->classptr; while (1) { bi = cls_stack_bi[cls_stack_top]; cls = cls_stack[cls_stack_top]; if (bi != -1) { if(cls->bases) base_name = cls->bases[bi]; else base_name = 0; if(base_name) cls = (swig_class *) SWIG_TypeQuery(base_name)->clientdata; else cls = 0; if (cls) { cls_stack_bi[cls_stack_top]++; cls_stack_top++; cls_stack[cls_stack_top] = cls; cls_stack_bi[cls_stack_top] = -1; continue; } } if (!cls) { cls_stack_top--; if (cls_stack_top < 0) break; else continue; } cls_stack_bi[cls_stack_top]++; meth = cls->methods; /* Check for methods */ while (meth && meth->name) { if (strcmp(meth->name,method) == 0) { oldarg = objv[1]; objv[1] = inst->thisptr; Tcl_IncrRefCount(inst->thisptr); rcode = (*meth->method)(clientData,interp,objc,objv); objv[1] = oldarg; Tcl_DecrRefCount(inst->thisptr); return rcode; } meth++; } /* Check class methods for a match */ if (strcmp(method,"cget") == 0) { if (objc < 3) { SWIG_Tcl_SetResultFromConstString(interp, "wrong # args.", TCL_STATIC); return TCL_ERROR; } attrname = Tcl_GetStringFromObj(objv[2],NULL); attr = cls->attributes; while (attr && attr->name) { if ((strcmp(attr->name, attrname) == 0) && (attr->getmethod)) { oldarg = objv[1]; objv[1] = inst->thisptr; Tcl_IncrRefCount(inst->thisptr); rcode = (*attr->getmethod)(clientData,interp,2, objv); objv[1] = oldarg; Tcl_DecrRefCount(inst->thisptr); return rcode; } attr++; } if (strcmp(attrname, "-this") == 0) { Tcl_SetObjResult(interp, Tcl_DuplicateObj(inst->thisptr)); return TCL_OK; } if (strcmp(attrname, "-thisown") == 0) { if (SWIG_Thisown(inst->thisvalue)) { SWIG_Tcl_SetResultFromConstString(interp,"1",TCL_STATIC); } else { SWIG_Tcl_SetResultFromConstString(interp,"0",TCL_STATIC); } return TCL_OK; } } else if (strcmp(method, "configure") == 0) { int i; if (objc < 4) { SWIG_Tcl_SetResultFromConstString(interp, "wrong # args.", TCL_STATIC); return TCL_ERROR; } i = 2; while (i < objc) { attrname = Tcl_GetStringFromObj(objv[i],NULL); attr = cls->attributes; while (attr && attr->name) { if ((strcmp(attr->name, attrname) == 0) && (attr->setmethod)) { oldarg = objv[i]; objv[i] = inst->thisptr; Tcl_IncrRefCount(inst->thisptr); rcode = (*attr->setmethod)(clientData,interp,3, &objv[i-1]); objv[i] = oldarg; Tcl_DecrRefCount(inst->thisptr); if (rcode != TCL_OK) return rcode; numconf += 2; } attr++; } i+=2; } } } if (strcmp(method,"configure") == 0) { if (numconf >= objc) { return TCL_OK; } else { SWIG_Tcl_SetResultFromConstString(interp,"Invalid attribute name.", TCL_STATIC); return TCL_ERROR; } } if (strcmp(method,"cget") == 0) { SWIG_Tcl_SetResultFromConstString(interp, "Invalid attribute name.", TCL_STATIC); return TCL_ERROR; } SWIG_Tcl_SetResultFromConstString(interp, "Invalid method. Must be one of: configure cget -acquire -disown -delete", TCL_STATIC); cls = inst->classptr; bi = 0; while (cls) { meth = cls->methods; while (meth && meth->name) { SWIG_TCL_CONST84 char *cr = (SWIG_TCL_CONST84 char *) Tcl_GetStringResult(interp); if (!strstr(strchr(cr,':'), meth->name)) Tcl_AppendElement(interp, meth->name); meth++; } if(inst->classptr->bases) { base_name = inst->classptr->bases[bi++]; } else { base_name = 0; bi++; } if(base_name) cls = (swig_class *) SWIG_TypeQuery(base_name)->clientdata; else cls = 0; } return TCL_ERROR; } /* Function to create objects */ SWIGRUNTIME(int) SWIG_Tcl_ObjectConstructor(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Tcl_Obj *newObj = 0; void *thisvalue = 0; swig_instance *newinst = 0; swig_class *classptr = (swig_class *) clientData; swig_wrapper cons = 0; char *name = 0; int firstarg = 0; int thisarg = 0; int destroy = 1; if (!classptr) { SWIG_Tcl_SetResultFromConstString(interp, "swig: internal runtime error. No class object defined.", TCL_STATIC); return TCL_ERROR; } cons = classptr->constructor; if (objc > 1) { char *s = Tcl_GetStringFromObj(objv[1],NULL); if (strcmp(s,"-this") == 0) { thisarg = 2; cons = 0; } else if (strcmp(s,"-args") == 0) { firstarg = 1; } else if (objc == 2) { firstarg = 1; name = s; } else if (objc >= 3) { char *s1; name = s; s1 = Tcl_GetStringFromObj(objv[2],NULL); if (strcmp(s1,"-this") == 0) { thisarg = 3; cons = 0; } else { firstarg = 1; } } } if (cons) { int result; result = (*cons)(0, interp, objc-firstarg, &objv[firstarg]); if (result != TCL_OK) { return result; } newObj = Tcl_DuplicateObj(Tcl_GetObjResult(interp)); if (!name) name = Tcl_GetStringFromObj(newObj,NULL); } else if (thisarg > 0) { if (thisarg < objc) { destroy = 0; newObj = Tcl_DuplicateObj(objv[thisarg]); if (!name) name = Tcl_GetStringFromObj(newObj,NULL); } else { SWIG_Tcl_SetResultFromConstString(interp, "wrong # args.", TCL_STATIC); return TCL_ERROR; } } else { SWIG_Tcl_SetResultFromConstString(interp, "No constructor available.", TCL_STATIC); return TCL_ERROR; } if (SWIG_Tcl_ConvertPtr(interp,newObj, (void **) &thisvalue, *(classptr->type), SWIG_POINTER_EXCEPTION) == TCL_ERROR) { Tcl_DecrRefCount(newObj); return TCL_ERROR; } newinst = (swig_instance *) malloc(sizeof(swig_instance)); newinst->thisptr = newObj; Tcl_IncrRefCount(newObj); newinst->thisvalue = thisvalue; newinst->classptr = classptr; newinst->destroy = destroy; if (destroy) { SWIG_Acquire(thisvalue); } newinst->cmdtok = Tcl_CreateObjCommand(interp,name, (swig_wrapper) SWIG_MethodCommand, (ClientData) newinst, (swig_delete_func) SWIG_ObjectDelete); return TCL_OK; } /* This function takes the current result and turns it into an object command */ SWIGRUNTIME(Tcl_Obj *) SWIG_Tcl_NewInstanceObj(Tcl_Interp *interp, void *thisvalue, swig_type_info *type, int flags) { Tcl_Obj *robj = SWIG_NewPointerObj(thisvalue, type,0); /* Check to see if this pointer belongs to a class or not */ if ((type->clientdata) && (interp)) { Tcl_CmdInfo ci; char *name = Tcl_GetStringFromObj(robj,NULL); if (!Tcl_GetCommandInfo(interp,name, &ci) || (flags)) { swig_instance *newinst = (swig_instance *) malloc(sizeof(swig_instance)); newinst->thisptr = Tcl_DuplicateObj(robj); Tcl_IncrRefCount(newinst->thisptr); newinst->thisvalue = thisvalue; newinst->classptr = (swig_class *) type->clientdata; newinst->destroy = flags; newinst->cmdtok = Tcl_CreateObjCommand(interp, Tcl_GetStringFromObj(robj,NULL), (swig_wrapper_func) SWIG_MethodCommand, (ClientData) newinst, (swig_delete_func) SWIG_ObjectDelete); if (flags) { SWIG_Acquire(thisvalue); } } } return robj; } #endif /* Structure for command table */ typedef struct { SWIG_TCL_CONST84 char *name; int (*wrapper)(ClientData, Tcl_Interp *, int, Tcl_Obj *const []); ClientData clientdata; } swig_command_info; /* Structure for variable linking table */ typedef struct { SWIG_TCL_CONST84 char *name; void *addr; char * (*get)(ClientData, Tcl_Interp *, char *, char *, int); char * (*set)(ClientData, Tcl_Interp *, char *, char *, int); } swig_var_info; /* Contract support */ #define SWIG_contract_assert(expr, msg) if (!(expr)) { SWIG_Tcl_SetResultFromConstString(interp, msg, TCL_STATIC ); goto fail; } else #ifdef __cplusplus } #endif cableswig-0.1.0+git20150808.orig/SWIG/Lib/tcl/std_pair.i0000644000175000000620000000100612561312227021042 0ustar stevestaff// // SWIG typemaps for std::pair // Luigi Ballabio // July 2003 // // Common implementation %include std_common.i %include exception.i // ------------------------------------------------------------------------ // std::pair // ------------------------------------------------------------------------ %{ #include %} // exported class namespace std { template struct pair { // add typemaps here T first; U second; }; // add specializations here } cableswig-0.1.0+git20150808.orig/SWIG/Lib/tcl/std_vector.i0000644000175000000620000003663012561312227021424 0ustar stevestaff// // SWIG typemaps for std::vector // Luigi Ballabio and Manu ??? and Kristopher Blom // Apr 26, 2002, updated Nov 13, 2002[blom] // // Tcl implementation %include exception.i // containers // methods which can raise are caused to throw an IndexError %exception std::vector::get { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::vector::set { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::vector::pop { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } // ------------------------------------------------------------------------ // std::vector // // The aim of all that follows would be to integrate std::vector with // Tcl as much as possible, namely, to allow the user to pass and // be returned Tcl lists. // const declarations are used to guess the intent of the function being // exported; therefore, the following rationale is applied: // // -- f(std::vector), f(const std::vector&), f(const std::vector*): // the parameter being read-only, either a Tcl list or a // previously wrapped std::vector can be passed. // -- f(std::vector&), f(std::vector*): // the parameter must be modified; therefore, only a wrapped std::vector // can be passed. // -- std::vector f(): // the vector is returned by copy; therefore, a Tcl list of T:s // is returned which is most easily used in other Tcl functions procs // -- std::vector& f(), std::vector* f(), const std::vector& f(), // const std::vector* f(): // the vector is returned by reference; therefore, a wrapped std::vector // is returned // ------------------------------------------------------------------------ %{ #include #include #include #include Tcl_Obj* SwigString_FromString(std::string s) { return Tcl_NewStringObj(s.c_str(), s.length()); } int SwigString_AsString(Tcl_Interp *interp, Tcl_Obj *o, std::string *val) { int len; const char* temp = Tcl_GetStringFromObj(o, &len); (void)interp; if(temp == NULL) return TCL_ERROR; *val = temp; return TCL_OK; } // behaviour of this is such as the real Tcl_GetIntFromObj template int SwigInt_As(Tcl_Interp *interp, Tcl_Obj *o, Type *val) { int temp_val, return_val; return_val = Tcl_GetIntFromObj(interp, o, &temp_val); *val = (Type) temp_val; return return_val; } // behaviour of this is such as the real Tcl_GetDoubleFromObj template int SwigDouble_As(Tcl_Interp *interp, Tcl_Obj *o, Type *val) { int return_val; double temp_val; return_val = Tcl_GetDoubleFromObj(interp, o, &temp_val); *val = (Type) temp_val; return return_val; } %} // exported class namespace std { template class vector { %typemap(in) vector (std::vector *v) { Tcl_Obj **listobjv; int nitems; int i; T* temp; if (SWIG_ConvertPtr($input, (void **) &v, \ $&1_descriptor, 0) == 0){ $1 = *v; } else { // It isn't a vector so it should be a list of T's if(Tcl_ListObjGetElements(interp, $input, \ &nitems, &listobjv) == TCL_ERROR) return TCL_ERROR; $1 = std::vector(); for (i = 0; i < nitems; i++) { if ((SWIG_ConvertPtr(listobjv[i],(void **) &temp, $descriptor(T),0)) != 0) { char message[] = "list of type $descriptor(T) expected"; Tcl_SetResult(interp, message, TCL_VOLATILE); return TCL_ERROR; } $1.push_back(*temp); } } } %typemap(in) const vector* (std::vector *v, std::vector w), const vector& (std::vector *v, std::vector w) { Tcl_Obj **listobjv; int nitems; int i; T* temp; if(SWIG_ConvertPtr($input, (void **) &v, \ $&1_descriptor, 0) == 0) { $1 = v; } else { // It isn't a vector so it should be a list of T's if(Tcl_ListObjGetElements(interp, $input, &nitems, &listobjv) == TCL_ERROR) return TCL_ERROR; w = std::vector(); for (i = 0; i < nitems; i++) { if ((SWIG_ConvertPtr(listobjv[i],(void **) &temp, $descriptor(T),0)) != 0) { char message[] = "list of type $descriptor(T) expected"; Tcl_SetResult(interp, message, TCL_VOLATILE); return TCL_ERROR; } w.push_back(*temp); } $1 = &w; } } %typemap(out) vector { for (unsigned int i=0; i<$1.size(); i++) { T* ptr = new T((($1_type &)$1)[i]); Tcl_ListObjAppendElement(interp, $result, \ SWIG_NewPointerObj(ptr, $descriptor(T), 0)); } } %typecheck(SWIG_TYPECHECK_VECTOR) vector { Tcl_Obj **listobjv; int nitems; int i; T* temp; std::vector *v; if(SWIG_ConvertPtr($input, (void **) &v, \ $&1_descriptor, 0) == 0) { /* wrapped vector */ $1 = 1; } else { // It isn't a vector so it should be a list of T's if(Tcl_ListObjGetElements(interp, $input, &nitems, &listobjv) == TCL_ERROR) $1 = 0; else if (nitems == 0) $1 = 1; //check the first value to see if it is of correct type else if ((SWIG_ConvertPtr(listobjv[i], (void **) &temp, $descriptor(T),0)) != 0) $1 = 0; else $1 = 1; } } %typecheck(SWIG_TYPECHECK_VECTOR) const vector&, const vector* { Tcl_Obj **listobjv; int nitems; int i; T* temp; std::vector *v; if(SWIG_ConvertPtr($input, (void **) &v, \ $1_descriptor, 0) == 0){ /* wrapped vector */ $1 = 1; } else { // It isn't a vector so it should be a list of T's if(Tcl_ListObjGetElements(interp, $input, &nitems, &listobjv) == TCL_ERROR) $1 = 0; else if (nitems == 0) $1 = 1; //check the first value to see if it is of correct type else if ((SWIG_ConvertPtr(listobjv[i], (void **) &temp, $descriptor(T),0)) != 0) $1 = 0; else $1 = 1; } } public: vector(unsigned int size = 0); vector(unsigned int size, const T& value); vector(const vector &); unsigned int size() const; bool empty() const; void clear(); %rename(push) push_back; void push_back(const T& x); %extend { T pop() { if (self->size() == 0) throw std::out_of_range("pop from empty vector"); T x = self->back(); self->pop_back(); return x; } T& get(int i) { int size = int(self->size()); if (i<0) i += size; if (i>=0 && isize()); if (i<0) i+= size; if (i>=0 && i class vector { %typemap(in) vector (std::vector *v){ Tcl_Obj **listobjv; int nitems; int i; T temp; if(SWIG_ConvertPtr($input, (void **) &v, \ $&1_descriptor, 0) == 0) { $1 = *v; } else { // It isn't a vector so it should be a list of T's if(Tcl_ListObjGetElements(interp, $input, &nitems, &listobjv) == TCL_ERROR) return TCL_ERROR; $1 = std::vector(); for (i = 0; i < nitems; i++) { if (CONVERT_FROM(interp, listobjv[i], &temp) == TCL_ERROR) return TCL_ERROR; $1.push_back(temp); } } } %typemap(in) const vector& (std::vector *v,std::vector w), const vector* (std::vector *v,std::vector w) { Tcl_Obj **listobjv; int nitems; int i; T temp; if(SWIG_ConvertPtr($input, (void **) &v, \ $1_descriptor, 0) == 0) { $1 = v; } else { // It isn't a vector so it should be a list of T's if(Tcl_ListObjGetElements(interp, $input, &nitems, &listobjv) == TCL_ERROR) return TCL_ERROR; w = std::vector(); for (i = 0; i < nitems; i++) { if (CONVERT_FROM(interp, listobjv[i], &temp) == TCL_ERROR) return TCL_ERROR; w.push_back(temp); } $1 = &w; } } %typemap(out) vector { for (unsigned int i=0; i<$1.size(); i++) { Tcl_ListObjAppendElement(interp, $result, \ CONVERT_TO((($1_type &)$1)[i])); } } %typecheck(SWIG_TYPECHECK_VECTOR) vector { Tcl_Obj **listobjv; int nitems; T temp; std::vector *v; if(SWIG_ConvertPtr($input, (void **) &v, \ $&1_descriptor, 0) == 0){ /* wrapped vector */ $1 = 1; } else { // It isn't a vector so it should be a list of T's if(Tcl_ListObjGetElements(interp, $input, &nitems, &listobjv) == TCL_ERROR) $1 = 0; else if (nitems == 0) $1 = 1; //check the first value to see if it is of correct type if (CONVERT_FROM(interp, listobjv[0], &temp) == TCL_ERROR) $1 = 0; else $1 = 1; } } %typecheck(SWIG_TYPECHECK_VECTOR) const vector&, const vector*{ Tcl_Obj **listobjv; int nitems; T temp; std::vector *v; if(SWIG_ConvertPtr($input, (void **) &v, \ $1_descriptor, 0) == 0){ /* wrapped vector */ $1 = 1; } else { // It isn't a vector so it should be a list of T's if(Tcl_ListObjGetElements(interp, $input, &nitems, &listobjv) == TCL_ERROR) $1 = 0; else if (nitems == 0) $1 = 1; //check the first value to see if it is of correct type if (CONVERT_FROM(interp, listobjv[0], &temp) == TCL_ERROR) $1 = 0; else $1 = 1; } } public: vector(unsigned int size = 0); vector(unsigned int size, const T& value); vector(const vector &); unsigned int size() const; bool empty() const; void clear(); %rename(push) push_back; void push_back(T x); %extend { T pop() { if (self->size() == 0) throw std::out_of_range("pop from empty vector"); T x = self->back(); self->pop_back(); return x; } T get(int i) { int size = int(self->size()); if (i<0) i += size; if (i>=0 && isize()); if (i<0) i+= size; if (i>=0 && i, Tcl_NewIntObj); specialize_std_vector(long, SwigInt_As, Tcl_NewIntObj); specialize_std_vector(unsigned char, SwigInt_As, Tcl_NewIntObj); specialize_std_vector(unsigned int, SwigInt_As, Tcl_NewIntObj); specialize_std_vector(unsigned short, SwigInt_As, Tcl_NewIntObj); specialize_std_vector(unsigned long, SwigInt_As, Tcl_NewIntObj); specialize_std_vector(double, Tcl_GetDoubleFromObj, Tcl_NewDoubleObj); specialize_std_vector(float, SwigDouble_As, Tcl_NewDoubleObj); specialize_std_vector(std::string, SwigString_AsString, SwigString_FromString); } cableswig-0.1.0+git20150808.orig/SWIG/Lib/tcl/mactkinit.c0000644000175000000620000001210112561312227021210 0ustar stevestaff/* This is a support file needed to build a new version of Wish Normally, this capability is found in TkAppInit.c, but this creates tons of namespace problems for many applications. */ #include #include #include #include #include #include #include "tk.h" #include "tkInt.h" #include "tkMacInt.h" typedef int (*TclMacConvertEventPtr) _ANSI_ARGS_((EventRecord *eventPtr)); Tcl_Interp *gStdoutInterp = NULL; void TclMacSetEventProc _ANSI_ARGS_((TclMacConvertEventPtr procPtr)); int TkMacConvertEvent _ANSI_ARGS_((EventRecord *eventPtr)); /* * Prototypes for functions the ANSI library needs to link against. */ short InstallConsole _ANSI_ARGS_((short fd)); void RemoveConsole _ANSI_ARGS_((void)); long WriteCharsToConsole _ANSI_ARGS_((char *buff, long n)); long ReadCharsFromConsole _ANSI_ARGS_((char *buff, long n)); char * __ttyname _ANSI_ARGS_((long fildes)); short SIOUXHandleOneEvent _ANSI_ARGS_((EventRecord *event)); /* * Forward declarations for procedures defined later in this file: */ /* *---------------------------------------------------------------------- * * MacintoshInit -- * * This procedure calls Mac specific initilization calls. Most of * these calls must be made as soon as possible in the startup * process. * * Results: * Returns TCL_OK if everything went fine. If it didn't the * application should probably fail. * * Side effects: * Inits the application. * *---------------------------------------------------------------------- */ int MacintoshInit() { int i; long result, mask = 0x0700; /* mask = system 7.x */ /* * Tk needs us to set the qd pointer it uses. This is needed * so Tk doesn't have to assume the availablity of the qd global * variable. Which in turn allows Tk to be used in code resources. */ tcl_macQdPtr = &qd; InitGraf(&tcl_macQdPtr->thePort); InitFonts(); InitWindows(); InitMenus(); InitDialogs((long) NULL); InitCursor(); /* * Make sure we are running on system 7 or higher */ if ((NGetTrapAddress(_Gestalt, ToolTrap) == NGetTrapAddress(_Unimplemented, ToolTrap)) || (((Gestalt(gestaltSystemVersion, &result) != noErr) || (mask != (result & mask))))) { panic("Tcl/Tk requires System 7 or higher."); } /* * Make sure we have color quick draw * (this means we can't run on 68000 macs) */ if (((Gestalt(gestaltQuickdrawVersion, &result) != noErr) || (result < gestalt32BitQD13))) { panic("Tk requires Color QuickDraw."); } FlushEvents(everyEvent, 0); SetEventMask(everyEvent); /* * Set up stack & heap sizes */ /* TODO: stack size size = StackSpace(); SetAppLimit(GetAppLimit() - 8192); */ MaxApplZone(); for (i = 0; i < 4; i++) { (void) MoreMasters(); } TclMacSetEventProc(TkMacConvertEvent); TkConsoleCreate(); return TCL_OK; } /* *---------------------------------------------------------------------- * * SetupMainInterp -- * * This procedure calls initalization routines require a Tcl * interp as an argument. This call effectively makes the passed * iterpreter the "main" interpreter for the application. * * Results: * Returns TCL_OK if everything went fine. If it didn't the * application should probably fail. * * Side effects: * More initilization. * *---------------------------------------------------------------------- */ int SetupMainInterp( Tcl_Interp *interp) { /* * Initialize the console only if we are running as an interactive * application. */ TkMacInitAppleEvents(interp); TkMacInitMenus(interp); if (strcmp(Tcl_GetVar(interp, "tcl_interactive", TCL_GLOBAL_ONLY), "1") == 0) { if (TkConsoleInit(interp) == TCL_ERROR) { goto error; } } /* * Attach the global interpreter to tk's expected global console */ gStdoutInterp = interp; return TCL_OK; error: panic(interp->result); return TCL_ERROR; } /* *---------------------------------------------------------------------- * * InstallConsole, RemoveConsole, etc. -- * * The following functions provide the UI for the console package. * Users wishing to replace SIOUX with their own console package * need only provide the four functions below in a library. * * Results: * See SIOUX documentation for details. * * Side effects: * See SIOUX documentation for details. * *---------------------------------------------------------------------- */ short InstallConsole(short fd) { #pragma unused (fd) return 0; } void RemoveConsole(void) { } long WriteCharsToConsole(char *buffer, long n) { TkConsolePrint(gStdoutInterp, TCL_STDOUT, buffer, n); return n; } long ReadCharsFromConsole(char *buffer, long n) { return 0; } extern char * __ttyname(long fildes) { static char *devicename = "null device"; if (fildes >= 0 && fildes <= 2) { return (devicename); } return (0L); } short SIOUXHandleOneEvent(EventRecord *event) { return 0; } cableswig-0.1.0+git20150808.orig/SWIG/Lib/tcl/cstring.i0000644000175000000620000001477512561312227020727 0ustar stevestaff/* * cstring.i * /cvsroot/SWIG/Lib/tcl/cstring.i,v 1.4 2003/09/23 21:22:43 cheetah Exp * * Author(s): David Beazley (beazley@cs.uchicago.edu) * * This file provides typemaps and macros for dealing with various forms * of C character string handling. The primary use of this module * is in returning character data that has been allocated or changed in * some way. */ /* %cstring_input_binary(TYPEMAP, SIZE) * * Macro makes a function accept binary string data along with * a size. */ %define %cstring_input_binary(TYPEMAP, SIZE) %apply (char *STRING, int LENGTH) { (TYPEMAP, SIZE) }; %enddef /* * %cstring_bounded_output(TYPEMAP, MAX) * * This macro is used to return a NULL-terminated output string of * some maximum length. For example: * * %cstring_bounded_output(char *outx, 512); * void foo(char *outx) { * sprintf(outx,"blah blah\n"); * } * */ %define %cstring_bounded_output(TYPEMAP,MAX) %typemap(ignore) TYPEMAP(char temp[MAX+1]) { $1 = ($1_ltype) temp; } %typemap(argout,fragment="t_output_helper") TYPEMAP { Tcl_Obj *o; $1[MAX] = 0; o = Tcl_NewStringObj($1,-1); Tcl_ListObjAppendElement(interp,Tcl_GetObjResult(interp), o); } %enddef /* * %cstring_chunk_output(TYPEMAP, SIZE) * * This macro is used to return a chunk of binary string data. * Embedded NULLs are okay. For example: * * %cstring_chunk_output(char *outx, 512); * void foo(char *outx) { * memmove(outx, somedata, 512); * } * */ %define %cstring_chunk_output(TYPEMAP,SIZE) %typemap(ignore) TYPEMAP(char temp[SIZE]) { $1 = ($1_ltype) temp; } %typemap(argout,fragment="t_output_helper") TYPEMAP { Tcl_Obj *o = Tcl_NewStringObj($1,SIZE); Tcl_ListObjAppendElement(interp, Tcl_GetObjResult(interp),o); } %enddef /* * %cstring_bounded_mutable(TYPEMAP, SIZE) * * This macro is used to wrap a string that's going to mutate. * * %cstring_bounded_mutable(char *in, 512); * void foo(in *x) { * while (*x) { * *x = toupper(*x); * x++; * } * } * */ %define %cstring_bounded_mutable(TYPEMAP,MAX) %typemap(in) TYPEMAP(char temp[MAX+1]) { char *t = Tcl_GetStringFromObj($input,NULL); strncpy(temp,t,MAX); $1 = ($1_ltype) temp; } %typemap(argout,fragment="t_output_helper") TYPEMAP { Tcl_Obj *o; $1[MAX] = 0; o = Tcl_NewStringObj($1,-1); Tcl_ListObjAppendElement(interp, Tcl_GetObjResult(interp),o); } %enddef /* * %cstring_mutable(TYPEMAP [, expansion]) * * This macro is used to wrap a string that will mutate in place. * It may change size up to a user-defined expansion. * * %cstring_mutable(char *in); * void foo(in *x) { * while (*x) { * *x = toupper(*x); * x++; * } * } * */ %define %cstring_mutable(TYPEMAP,...) %typemap(in) TYPEMAP { int n; char *t = Tcl_GetStringFromObj($input,&n); $1 = ($1_ltype) t; #if #__VA_ARGS__ == "" #if __cplusplus $1 = ($1_ltype) new char[n+1]; #else $1 = ($1_ltype) malloc(n+1); #endif #else #if __cplusplus $1 = ($1_ltype) new char[n+1+__VA_ARGS__]; #else $1 = ($1_ltype) malloc(n+1+__VA_ARGS__); #endif #endif memmove($1,t,n); $1[n] = 0; } %typemap(argout,fragment="t_output_helper") TYPEMAP { Tcl_Obj *o; o = Tcl_NewStringObj($1,-1); Tcl_ListObjAppendElement(interp, Tcl_GetObjResult(interp), o); #if __cplusplus delete[] $1; #else free($1); #endif } %enddef /* * %cstring_output_maxsize(TYPEMAP, SIZE) * * This macro returns data in a string of some user-defined size. * * %cstring_output_maxsize(char *outx, int max) { * void foo(char *outx, int max) { * sprintf(outx,"blah blah\n"); * } */ %define %cstring_output_maxsize(TYPEMAP, SIZE) %typemap(in) (TYPEMAP, SIZE) { long temp; if (Tcl_GetLongFromObj(interp,$input,&temp) != TCL_OK) { SWIG_fail; } $2 = ($2_ltype) temp; #ifdef __cplusplus $1 = ($1_ltype) new char[$2+1]; #else $1 = ($1_ltype) malloc($2+1); #endif } %typemap(argout,fragment="t_output_helper") (TYPEMAP,SIZE) { Tcl_Obj *o; o = Tcl_NewStringObj($1,-1); Tcl_ListObjAppendElement(interp,Tcl_GetObjResult(interp),o); #ifdef __cplusplus delete [] $1; #else free($1); #endif } %enddef /* * %cstring_output_withsize(TYPEMAP, SIZE) * * This macro is used to return character data along with a size * parameter. * * %cstring_output_maxsize(char *outx, int *max) { * void foo(char *outx, int *max) { * sprintf(outx,"blah blah\n"); * *max = strlen(outx); * } */ %define %cstring_output_withsize(TYPEMAP, SIZE) %typemap(in) (TYPEMAP, SIZE) { long n; if (Tcl_GetLongFromObj(interp,$input,&n) != TCL_OK) { SWIG_fail; } #ifdef __cplusplus $1 = ($1_ltype) new char[n+1]; $2 = ($2_ltype) new $*1_ltype; #else $1 = ($1_ltype) malloc(n+1); $2 = ($2_ltype) malloc(sizeof($*1_ltype)); #endif *$2 = n; } %typemap(argout,fragment="t_output_helper") (TYPEMAP,SIZE) { Tcl_Obj *o; o = Tcl_NewStringObj($1,*$2); Tcl_ListObjAppendElement(interp,Tcl_GetObjResult(interp), o); #ifdef __cplusplus delete [] $1; delete $2; #else free($1); free($2); #endif } %enddef /* * %cstring_output_allocate(TYPEMAP, RELEASE) * * This macro is used to return character data that was * allocated with new or malloc. * * %cstring_output_allocated(char **outx, free($1)); * void foo(char **outx) { * *outx = (char *) malloc(512); * sprintf(outx,"blah blah\n"); * } */ %define %cstring_output_allocate(TYPEMAP, RELEASE) %typemap(ignore) TYPEMAP($*1_ltype temp = 0) { $1 = &temp; } %typemap(argout,fragment="t_output_helper") TYPEMAP { if (*$1) { Tcl_Obj *o = Tcl_NewStringObj(*$1,-1); RELEASE; Tcl_ListObjAppendElement(interp, Tcl_GetObjResult(interp), o); } } %enddef /* * %cstring_output_allocate_size(TYPEMAP, SIZE, RELEASE) * * This macro is used to return character data that was * allocated with new or malloc. * * %cstring_output_allocated(char **outx, int *sz, free($1)); * void foo(char **outx, int *sz) { * *outx = (char *) malloc(512); * sprintf(outx,"blah blah\n"); * *sz = strlen(outx); * } */ %define %cstring_output_allocate_size(TYPEMAP, SIZE, RELEASE) %typemap(ignore) (TYPEMAP, SIZE) ($*1_ltype temp = 0, $*2_ltype tempn) { $1 = &temp; $2 = &tempn; } %typemap(argout,fragment="t_output_helper")(TYPEMAP,SIZE) { if (*$1) { Tcl_Obj *o = Tcl_NewStringObj(*$1,*$2); RELEASE; Tcl_ListObjAppendElement(interp,Tcl_GetObjResult(interp), o); } } %enddef cableswig-0.1.0+git20150808.orig/SWIG/Lib/tcl/tcl8kw.swg0000644000175000000620000000040112561312227021017 0ustar stevestaff#ifndef __tcl_tclkw_swg__ #define __tcl_tclkw_swg__ // Some special reserved words in classes %namewarn("314:cget is a tcl reserved method name") *::cget; %namewarn("314:configure is a tcl reserved method name") *::configure; #endif //__tcl_tclkw_swg__ cableswig-0.1.0+git20150808.orig/SWIG/Lib/tcl/tclsh.i0000644000175000000620000000341112561312227020354 0ustar stevestaff// /cvsroot/SWIG/Lib/tcl/tclsh.i,v 1.3 2002/11/30 22:10:09 beazley Exp // // SWIG File for building new tclsh program // Dave Beazley // April 25, 1996 // #ifdef AUTODOC %subsection "tclsh.i" %text %{ This module provides the Tcl_AppInit() function needed to build a new version of the tclsh executable. This file should not be used when using dynamic loading. To make an interface file work with both static and dynamic loading, put something like this in your interface file : #ifdef STATIC %include tclsh.i #endif %} #endif %{ /* A TCL_AppInit() function that lets you build a new copy * of tclsh. * * The macro SWIG_init contains the name of the initialization * function in the wrapper file. */ #ifndef SWIG_RcFileName char *SWIG_RcFileName = "~/.myapprc"; #endif #ifdef MAC_TCL extern int MacintoshInit _ANSI_ARGS_((void)); #endif int Tcl_AppInit(Tcl_Interp *interp){ if (Tcl_Init(interp) == TCL_ERROR) return TCL_ERROR; /* Now initialize our functions */ if (SWIG_init(interp) == TCL_ERROR) return TCL_ERROR; #if TCL_MAJOR_VERSION > 7 || TCL_MAJOR_VERSION == 7 && TCL_MINOR_VERSION >= 5 Tcl_SetVar(interp, (char *) "tcl_rcFileName",SWIG_RcFileName,TCL_GLOBAL_ONLY); #else tcl_RcFileName = SWIG_RcFileName; #endif #ifdef SWIG_RcRsrcName Tcl_SetVar(interp, (char *) "tcl_rcRsrcName",SWIG_RcRsrcName,TCL_GLOBAL); #endif return TCL_OK; } #if TCL_MAJOR_VERSION > 7 || TCL_MAJOR_VERSION == 7 && TCL_MINOR_VERSION >= 4 int main(int argc, char **argv) { #ifdef MAC_TCL char *newArgv[2]; if (MacintoshInit() != TCL_OK) { Tcl_Exit(1); } argc = 1; newArgv[0] = "tclsh"; newArgv[1] = NULL; argv = newArgv; #endif Tcl_Main(argc, argv, Tcl_AppInit); return(0); } #else extern int main(); #endif %} cableswig-0.1.0+git20150808.orig/SWIG/Lib/tcl/precommon.swg0000644000175000000620000000134212561312227021607 0ustar stevestaff/*************************************************************** -*- c -*- * Tcl/precommon.swg * * Rename all exported symbols from common.swg, to avoid symbol * clashes if multiple interpreters are included * ************************************************************************/ #define SWIG_TypeRegister SWIG_Tcl_TypeRegister #define SWIG_TypeCheck SWIG_Tcl_TypeCheck #define SWIG_TypeCast SWIG_Tcl_TypeCast #define SWIG_TypeDynamicCast SWIG_Tcl_TypeDynamicCast #define SWIG_TypeName SWIG_Tcl_TypeName #define SWIG_TypeQuery SWIG_Tcl_TypeQuery #define SWIG_TypeClientData SWIG_Tcl_TypeClientData #define SWIG_PackData SWIG_Tcl_PackData #define SWIG_UnpackData SWIG_Tcl_UnpackData cableswig-0.1.0+git20150808.orig/SWIG/Lib/tcl/wish.i0000644000175000000620000000735412561312227020223 0ustar stevestaff// // /cvsroot/SWIG/Lib/tcl/wish.i,v 1.3 2002/11/30 22:10:09 beazley Exp // // SWIG File for making wish // Dave Beazley // April 25, 1996 // /* Revision History * wish.i,v * Revision 1.3 2002/11/30 22:10:09 beazley * *** empty log message *** * * Revision 1.1.2.1 2001/06/20 11:47:29 mkoeppe * Portability fixes * * Revision 1.1 2000/01/11 21:15:54 beazley * Added files * * Revision 1.2 1999/11/05 21:45:14 beazley * Minor Changes * * Revision 1.1.1.1 1999/02/28 02:00:56 beazley * Swig1.1 * * Revision 1.1 1996/05/22 19:47:45 beazley * Initial revision * */ #ifdef AUTODOC %subsection "wish.i" %text %{ This module provides the Tk_AppInit() function needed to build a new version of the wish executable. Like tclsh.i, this file should not be used with dynamic loading. To make an interface file work with both static and dynamic loading, put something like this in your interface file : #ifdef STATIC %include wish.i #endif A startup file may be specified by defining the symbol SWIG_RcFileName as follows (this should be included in a code-block) : #define SWIG_RcFileName "~/.mywishrc" %} #endif %{ /* Initialization code for wish */ #include #ifndef SWIG_RcFileName char *SWIG_RcFileName = "~/.wishrc"; #endif #ifdef MAC_TCL extern int MacintoshInit _ANSI_ARGS_((void)); extern int SetupMainInterp _ANSI_ARGS_((Tcl_Interp *interp)); #endif /* *---------------------------------------------------------------------- * * Tcl_AppInit -- * * This procedure performs application-specific initialization. * Most applications, especially those that incorporate additional * packages, will have their own version of this procedure. * * Results: * Returns a standard Tcl completion code, and leaves an error * message in interp->result if an error occurs. * * Side effects: * Depends on the startup script. * *---------------------------------------------------------------------- */ int Tcl_AppInit(Tcl_Interp *interp) { #ifndef MAC_TCL Tk_Window main; main = Tk_MainWindow(interp); #endif /* * Call the init procedures for included packages. Each call should * look like this: * * if (Mod_Init(interp) == TCL_ERROR) { * return TCL_ERROR; * } * * where "Mod" is the name of the module. */ if (Tcl_Init(interp) == TCL_ERROR) { return TCL_ERROR; } if (Tk_Init(interp) == TCL_ERROR) { return TCL_ERROR; } /* * Call Tcl_CreateCommand for application-specific commands, if * they weren't already created by the init procedures called above. */ if (SWIG_init(interp) == TCL_ERROR) { return TCL_ERROR; } #ifdef MAC_TCL SetupMainInterp(interp); #endif /* * Specify a user-specific startup file to invoke if the application * is run interactively. Typically the startup file is "~/.apprc" * where "app" is the name of the application. If this line is deleted * then no user-specific startup file will be run under any conditions. */ #if TCL_MAJOR_VERSION >= 8 || TCL_MAJOR_VERSION == 7 && TCL_MINOR_VERSION >= 5 Tcl_SetVar(interp, (char *) "tcl_rcFileName",SWIG_RcFileName,TCL_GLOBAL_ONLY); #else tcl_RcFileName = SWIG_RcFileName; #endif /* For Macintosh might also want this */ #ifdef MAC_TCL #ifdef SWIG_RcRsrcName Tcl_SetVar(interp, (char *) "tcl_rcRsrcName",SWIG_RcRsrcName,TCL_GLOBAL_ONLY); #endif #endif return TCL_OK; } #if TK_MAJOR_VERSION >= 4 int main(int argc, char **argv) { #ifdef MAC_TCL char *newArgv[2]; if (MacintoshInit() != TCL_OK) { Tcl_Exit(1); } argc = 1; newArgv[0] = "Wish"; newArgv[1] = NULL; argv = newArgv; #endif Tk_Main(argc, argv, Tcl_AppInit); return(0); } #else extern int main(); #endif %} cableswig-0.1.0+git20150808.orig/SWIG/Lib/swig.swg0000644000175000000620000003025612561312227020005 0ustar stevestaff/* ----------------------------------------------------------------------------- * swig.swg * * /cvsroot/SWIG/Lib/swig.swg,v 1.20 2004/01/28 01:34:32 mmatus Exp * * Common macro definitions for various SWIG directives. This file is always * included at the top of each input file. * ----------------------------------------------------------------------------- */ /* Deprecated SWIG directives */ #define %disabledoc %warn "104:%disabledoc is deprecated" #define %enabledoc %warn "105:%enabledoc is deprecated" #define %doconly %warn "106:%doconly is deprecated" #define %style %warn "107:%style is deprecated" /##/ #define %localstyle %warn "108:%localstyle is deprecated" /##/ #define %title %warn "109:%title is deprecated" /##/ #define %section %warn "110:%section is deprecated" /##/ #define %subsection %warn "111:%subsection is deprecated" /##/ #define %subsubsection %warn "112:%subsubsection is deprecated" /##/ #define %new %warn "117:%new is deprecated. Use %newobject" #define %text %insert("null") /* Code insertion directives such as %wrapper %{ ... %} */ #define %init %insert("init") #define %wrapper %insert("wrapper") #define %header %insert("header") #define %runtime %insert("runtime") /* Class extension */ #define %addmethods %warn "113:%addmethods is now %extend" %extend /* Access control directives */ #define %readonly %warn "114:%readonly is deprecated. Use %immutable; " %feature("immutable"); #define %readwrite %warn "115:%readwrite is deprecated. Use %mutable; " %feature("immutable",""); #define %immutable %feature("immutable") #define %mutable %feature("immutable","") /* Directives for callback functions */ /* Experimental */ #define %callback(x) %feature("callback") `x`; #define %nocallback %feature("callback",""); /* Directives for attribute functions */ #define %attributefunc(_x,_y) %pragma(swig) attributefunction=`_x`":"`_y`; #define %noattributefunc %pragma(swig) noattributefunction; /* %ignore directive */ #define %ignore %rename($ignore) #define %ignorewarn(x) %rename("$ignore:" x) /* Generation of default constructors/destructors */ #define %nodefault %feature("nodefault") #define %makedefault %feature("nodefault","") /* Common features */ #define %exception %feature("except") #define %noexception %feature("except","") #define %newobject %feature("new") /* Warnings */ #define %warnfilter(...) %feature("warnfilter",`__VA_ARGS__`) /* Contract support - Experimental and undocumented */ #define %contract %feature("contract") /* Default handling of certain overloaded operators */ #ifdef __cplusplus %ignorewarn("350:operator new ignored") operator new; %ignorewarn("351:operator delete ignored") operator delete; %ignorewarn("394:operator new[] ignored") operator new[]; %ignorewarn("395:operator delete[] ignored") operator delete[]; /* Smart pointer handling */ %rename(__deref__) operator->; /* Define std namespace */ namespace std { } #endif /* Set up the typemap for handling new return strings */ #ifdef __cplusplus %typemap(newfree) char * "delete [] $1;"; #else %typemap(newfree) char * "free($1);"; #endif /* Default typemap for handling char * members */ #ifdef __cplusplus %typemap(memberin) char * { if ($1) delete [] $1; if ($input) { $1 = ($1_type) (new char[strlen($input)+1]); strcpy((char *) $1,$input); } else { $1 = 0; } } %typemap(memberin,warning="451:Setting const char * member may leak memory.") const char * { if ($input) { $1 = ($1_type) (new char[strlen($input)+1]); strcpy((char *) $1,$input); } else { $1 = 0; } } %typemap(globalin) char * { if ($1) delete [] $1; if ($input) { $1 = ($1_type) (new char[strlen($input)+1]); strcpy((char *) $1,$input); } else { $1 = 0; } } %typemap(globalin,warning="451:Setting const char * variable may leak memory.") const char * { if ($input) { $1 = ($1_type) (new char[strlen($input)+1]); strcpy((char *) $1,$input); } else { $1 = 0; } } #else %typemap(memberin) char * { if ($1) free((char*)$1); if ($input) { $1 = ($1_type) malloc(strlen($input)+1); strcpy((char*)$1,$input); } else { $1 = 0; } } %typemap(memberin,warning="451:Setting const char * member may leak memory.") const char * { if ($input) { $1 = ($1_type) malloc(strlen($input)+1); strcpy((char*)$1,$input); } else { $1 = 0; } } %typemap(globalin) char * { if ($1) free((char*)$1); if ($input) { $1 = ($1_type) malloc(strlen($input)+1); strcpy((char*)$1,$input); } else { $1 = 0; } } %typemap(globalin,warning="451:Setting const char * variable may leak memory.") const char * { if ($input) { $1 = ($1_type) malloc(strlen($input)+1); strcpy((char*)$1,$input); } else { $1 = 0; } } #endif /* Character array handling */ %typemap(memberin) char [ANY] { if ($input) strncpy($1,$input,$1_dim0); else $1[0] = 0; } %typemap(globalin) char [ANY] { if ($input) strncpy($1,$input,$1_dim0); else $1[0] = 0; } /* memberin typemap for arrays. */ %typemap(memberin) SWIGTYPE [ANY] { int ii; $1_basetype *b = ($1_basetype *) $1; for (ii = 0; ii < $1_size; ii++) b[ii] = *(($1_basetype *) $input + ii); } %typemap(globalin) SWIGTYPE [ANY] { int ii; $1_basetype *b = ($1_basetype *) $1; for (ii = 0; ii < $1_size; ii++) b[ii] = *(($1_basetype *) $input + ii); } /* Typemap for variable length arguments sentinel value. Used by the %varargs directive. */ %typemap(in,numinputs=0) SWIGTYPE *VARARGS_SENTINEL, SWIGTYPE VARARGS_SENTINEL ""; /* * Function/method overloading support. This is done through typemaps, * but also involve a precedence level. */ /* Macro for overload resolution */ #define %typecheck(_x) %typemap(typecheck, precedence=_x) /* Macros for precedence levels */ %define SWIG_TYPECHECK_POINTER 0 %enddef %define SWIG_TYPECHECK_VOIDPTR 10 %enddef %define SWIG_TYPECHECK_BOOL 15 %enddef %define SWIG_TYPECHECK_UINT8 20 %enddef %define SWIG_TYPECHECK_INT8 25 %enddef %define SWIG_TYPECHECK_UINT16 30 %enddef %define SWIG_TYPECHECK_INT16 35 %enddef %define SWIG_TYPECHECK_UINT32 40 %enddef %define SWIG_TYPECHECK_INT32 45 %enddef %define SWIG_TYPECHECK_UINT64 50 %enddef %define SWIG_TYPECHECK_INT64 55 %enddef %define SWIG_TYPECHECK_UINT128 60 %enddef %define SWIG_TYPECHECK_INT128 65 %enddef %define SWIG_TYPECHECK_INTEGER 70 %enddef %define SWIG_TYPECHECK_FLOAT 80 %enddef %define SWIG_TYPECHECK_DOUBLE 90 %enddef %define SWIG_TYPECHECK_CPLXFLT 95 %enddef %define SWIG_TYPECHECK_CPLXDBL 100 %enddef %define SWIG_TYPECHECK_COMPLEX 105 %enddef %define SWIG_TYPECHECK_UNICHAR 110 %enddef %define SWIG_TYPECHECK_UNISTRING 120 %enddef %define SWIG_TYPECHECK_CHAR 130 %enddef %define SWIG_TYPECHECK_STRING 140 %enddef %define SWIG_TYPECHECK_VECTOR 150 %enddef %define SWIG_TYPECHECK_MAP 160 %enddef %define SWIG_TYPECHECK_PAIR 170 %enddef %define SWIG_TYPECHECK_BOOL_ARRAY 1015 %enddef %define SWIG_TYPECHECK_INT8_ARRAY 1025 %enddef %define SWIG_TYPECHECK_INT16_ARRAY 1035 %enddef %define SWIG_TYPECHECK_INT32_ARRAY 1045 %enddef %define SWIG_TYPECHECK_INT64_ARRAY 1055 %enddef %define SWIG_TYPECHECK_INT128_ARRAY 1065 %enddef %define SWIG_TYPECHECK_FLOAT_ARRAY 1080 %enddef %define SWIG_TYPECHECK_DOUBLE_ARRAY 1090 %enddef %define SWIG_TYPECHECK_CHAR_ARRAY 1130 %enddef %define SWIG_TYPECHECK_STRING_ARRAY 1140 %enddef %define SWIG_TYPECHECK_OBJECT_ARRAY 1150 %enddef /* Switch to enable runtime mode */ #ifndef SWIGSEXP #ifdef SWIG_RUNTIME_MODE %insert("runtime") %{ #define SWIG_GLOBAL 1 %} #endif #endif /* * This template wrapper is used to handle C++ objects that are passed or * returned by value. This is necessary to handle objects that define * no default-constructor (making it difficult for SWIG to properly declare * local variables). * * The wrapper is used as follows. First consider a function like this: * * Vector cross_product(Vector a, Vector b) * * Now, if Vector is defined as a C++ class with no default constructor, * code is generated as follows: * * Vector *wrap_cross_product(Vector *inarg1, Vector *inarg2) { * SwigValueWrapper arg1; * SwigValueWrapper arg2; * SwigValueWrapper result; * * arg1 = *inarg1; * arg2 = *inarg2; * ... * result = cross_product(arg1,arg2); * ... * return new Vector(result); * } * * In the wrappers, the template SwigValueWrapper simply provides a thin * layer around a Vector *. However, it does this in a way that allows * the object to be bound after the variable declaration (which is not possible * with the bare object when it lacks a default constructor). * * An observant reader will notice that the code after the variable declarations * is *identical* to the code used for classes that do define default constructors. * Thus, this neat trick allows us to fix this special case without having to * make massive changes to typemaps and other parts of the SWIG code generator. * * Note: this code is not included when SWIG runs in C-mode, when classes * define default constructors, or when pointers and references are used. * SWIG tries to avoid doing this except in very special circumstances. * * Note: This solution suffers from making a large number of copies * of the underlying object. However, this is needed in the interest of * safety and in order to cover all of the possible ways in which a value * might be assigned. For example: * * arg1 = *inarg1; // Assignment from a pointer * arg1 = Vector(1,2,3); // Assignment from a value * * This wrapping technique was suggested by William Fulton and is henceforth * known as the "Fulton Transform" :-). */ #ifndef SWIGSEXP #ifdef __cplusplus %insert("runtime") %{ #ifdef __cplusplus template class SwigValueWrapper { T *tt; public: SwigValueWrapper() : tt(0) { } SwigValueWrapper(const SwigValueWrapper& rhs) : tt(new T(*rhs.tt)) { } SwigValueWrapper(const T& t) : tt(new T(t)) { } ~SwigValueWrapper() { delete tt; } SwigValueWrapper& operator=(const T& t) { delete tt; tt = new T(t); return *this; } operator T&() const { return *tt; } T *operator&() { return tt; } private: SwigValueWrapper& operator=(const SwigValueWrapper& rhs); }; #endif %} #endif #endif /* Macro for setting a dynamic cast function */ %define DYNAMIC_CAST(mangle,func) %init %{ mangle->dcast = (swig_dycast_func) func; %} %enddef /* This macro performs constant aggregation. Basically the idea of constant aggregation is that you can group a collection of constants together. For example, suppose you have some code like this: #define UP 1 #define DOWN 2 #define LEFT 3 #define RIGHT 4 Now, suppose you had a function like this: int move(int direction) In this case, you might want to restrict the direction argument to one of the supplied constant names. To do this, you could write some typemap code by hand. Alternatively, you can use the %aggregate_check macro defined here to create a simple check function for you. Here is an example: %aggregate_check(int, check_direction, UP, DOWN, LEFT, RIGHT); Now, using a typemap %typemap(check) int direction { if (!check_direction($1)) SWIG_exception(SWIG_ValueError,"Bad direction."); } or a contract (better) %contract move(int x) { require: check_direction(x); } */ %define %aggregate_check(TYPE, NAME, FIRST, ...) %wrapper %{ static int NAME(TYPE x) { static TYPE values[] = { FIRST, ##__VA_ARGS__ }; static int size = sizeof(values); int i,j; for (i = 0, j = 0; i < size; i+=sizeof(TYPE),j++) { if (x == values[j]) return 1; } return 0; } %} %enddef cableswig-0.1.0+git20150808.orig/SWIG/Lib/exception.i0000644000175000000620000002112612561312227020456 0ustar stevestaff// // except.i // Dave Beazley // April 14, 1997 // // This SWIG library file provides language independent exception handling %{ #define SWIG_MemoryError 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_UnknownError 99 %} #ifdef SWIGTCL8 %{ #define SWIG_exception(a,b) { Tcl_SetResult(interp,b,TCL_VOLATILE); SWIG_fail; } %} #else #ifdef SWIGTCL %{ #define SWIG_exception(a,b) { Tcl_SetResult(interp,b,TCL_VOLATILE); return TCL_ERROR; } %} #endif #endif #ifdef SWIGPERL5 %{ #define SWIG_exception(a,b) SWIG_croak(b) %} #endif #ifdef SWIGPHP4 %{ /* We should make use of "code" if we can */ #define SWIG_exception(code, msg) { zend_error(E_ERROR, msg); } %} #endif #ifdef SWIGPYTHON %{ static void SWIG_exception_(int code, const char *msg) { switch(code) { case SWIG_MemoryError: PyErr_SetString(PyExc_MemoryError,msg); break; case SWIG_IOError: PyErr_SetString(PyExc_IOError,msg); break; case SWIG_RuntimeError: PyErr_SetString(PyExc_RuntimeError,msg); break; case SWIG_IndexError: PyErr_SetString(PyExc_IndexError,msg); break; case SWIG_TypeError: PyErr_SetString(PyExc_TypeError,msg); break; case SWIG_DivisionByZero: PyErr_SetString(PyExc_ZeroDivisionError,msg); break; case SWIG_OverflowError: PyErr_SetString(PyExc_OverflowError,msg); break; case SWIG_SyntaxError: PyErr_SetString(PyExc_SyntaxError,msg); break; case SWIG_ValueError: PyErr_SetString(PyExc_ValueError,msg); break; case SWIG_SystemError: PyErr_SetString(PyExc_SystemError,msg); break; default: PyErr_SetString(PyExc_RuntimeError,msg); break; } } #define SWIG_exception(a,b) { SWIG_exception_(a,b); SWIG_fail; } %} #endif #ifdef SWIGGUILE %{ static void SWIG_exception_ (int code, const char *msg, const char *subr) { #define ERROR(scmerr) \ scm_error(gh_symbol2scm((char *) (scmerr)), \ (char *) subr, (char *) msg, \ SCM_EOL, SCM_BOOL_F) #define MAP(swigerr, scmerr) \ case swigerr: \ ERROR(scmerr); \ break switch (code) { MAP(SWIG_MemoryError, "swig-memory-error"); MAP(SWIG_IOError, "swig-io-error"); MAP(SWIG_RuntimeError, "swig-runtime-error"); MAP(SWIG_IndexError, "swig-index-error"); MAP(SWIG_TypeError, "swig-type-error"); MAP(SWIG_DivisionByZero, "swig-division-by-zero"); MAP(SWIG_OverflowError, "swig-overflow-error"); MAP(SWIG_SyntaxError, "swig-syntax-error"); MAP(SWIG_ValueError, "swig-value-error"); MAP(SWIG_SystemError, "swig-system-error"); default: ERROR("swig-error"); } #undef ERROR #undef MAP } #define SWIG_exception(a,b) SWIG_exception_(a, b, FUNC_NAME) %} #endif #ifdef SWIGMZSCHEME %{ static void SWIG_exception_ (int code, const char *msg) { #define ERROR(errname) \ scheme_signal_error(errname " (%s)", msg); #define MAP(swigerr, errname) \ case swigerr: \ ERROR(errname); \ break switch (code) { MAP(SWIG_MemoryError, "swig-memory-error"); MAP(SWIG_IOError, "swig-io-error"); MAP(SWIG_RuntimeError, "swig-runtime-error"); MAP(SWIG_IndexError, "swig-index-error"); MAP(SWIG_TypeError, "swig-type-error"); MAP(SWIG_DivisionByZero, "swig-division-by-zero"); MAP(SWIG_OverflowError, "swig-overflow-error"); MAP(SWIG_SyntaxError, "swig-syntax-error"); MAP(SWIG_ValueError, "swig-value-error"); MAP(SWIG_SystemError, "swig-system-error"); default: ERROR("swig-error"); } #undef ERROR #undef MAP } #define SWIG_exception(a,b) SWIG_exception_(a, b) %} #endif #ifdef SWIGJAVA %{ static void SWIG_JavaException(JNIEnv *jenv, int code, const char *msg) { SWIG_JavaExceptionCodes exception_code = SWIG_JavaUnknownError; switch(code) { case SWIG_MemoryError: exception_code = SWIG_JavaOutOfMemoryError; break; case SWIG_IOError: exception_code = SWIG_JavaIOException; break; case SWIG_SystemError: case SWIG_RuntimeError: exception_code = SWIG_JavaRuntimeException; break; case SWIG_OverflowError: case SWIG_IndexError: exception_code = SWIG_JavaIndexOutOfBoundsException; break; case SWIG_DivisionByZero: exception_code = SWIG_JavaArithmeticException; break; case SWIG_SyntaxError: case SWIG_ValueError: case SWIG_TypeError: exception_code = SWIG_JavaIllegalArgumentException; break; case SWIG_UnknownError: default: exception_code = SWIG_JavaUnknownError; break; } SWIG_JavaThrowException(jenv, exception_code, msg); } #define SWIG_exception(code, msg) { SWIG_JavaException(jenv, code, msg); } %} #endif // SWIGJAVA #ifdef SWIGOCAML %{ #define OCAML_MSG_BUF_LEN 1024 static void SWIG_exception_(int code, const char *msg) { char msg_buf[OCAML_MSG_BUF_LEN]; sprintf( msg_buf, "Exception(%d): %s\n", code, msg ); failwith( msg_buf ); } #define SWIG_exception(a,b) SWIG_exception_((a),(b)) %} #endif #ifdef SWIGRUBY %{ static void SWIG_exception_(int code, const char *msg) { switch (code) { case SWIG_MemoryError: rb_raise(rb_eNoMemError, msg); break; case SWIG_IOError: rb_raise(rb_eIOError, msg); break; case SWIG_RuntimeError: rb_raise(rb_eRuntimeError, msg); break; case SWIG_IndexError: rb_raise(rb_eIndexError, msg); break; case SWIG_TypeError: rb_raise(rb_eTypeError, msg); break; case SWIG_DivisionByZero: rb_raise(rb_eZeroDivError, msg); break; case SWIG_OverflowError: rb_raise(rb_eRangeError, msg); break; case SWIG_SyntaxError: rb_raise(rb_eSyntaxError, msg); break; case SWIG_ValueError: rb_raise(rb_eArgError, msg); break; case SWIG_SystemError: rb_raise(rb_eFatal, msg); break; case SWIG_UnknownError: rb_raise(rb_eRuntimeError, msg); break; default: break; } } #define SWIG_exception(a, b) SWIG_exception_((a), (b)) %} #endif #ifdef SWIGCHICKEN %{ #define CHICKEN_MSG_BUF_LEN 1024 static void SWIG_exception_(int code, const char *msg) { char msg_buf[CHICKEN_MSG_BUF_LEN]; C_word *a; C_word scmmsg; sprintf (msg_buf, "Exception(%d): %.950s\n", code, msg); a = C_alloc (C_SIZEOF_STRING (strlen (msg_buf))); scmmsg = C_string2 (&a, msg_buf); C_halt (scmmsg); } #define SWIG_exception(a,b) SWIG_exception_((a),(b)) %} #endif #ifdef SWIGCSHARP %{ static void SWIG_exception(int code, const char *msg) { SWIG_CSharpExceptionCodes exception_code = SWIG_CSharpException; switch(code) { case SWIG_MemoryError: exception_code = SWIG_CSharpOutOfMemoryException; break; case SWIG_IndexError: exception_code = SWIG_CSharpIndexOutOfRangeException; break; case SWIG_DivisionByZero: exception_code = SWIG_CSharpDivideByZeroException; break; case SWIG_ValueError: exception_code = SWIG_CSharpArgumentOutOfRangeException; break; case SWIG_IOError: case SWIG_RuntimeError: case SWIG_TypeError: case SWIG_OverflowError: case SWIG_SyntaxError: case SWIG_SystemError: case SWIG_UnknownError: default: exception_code = SWIG_CSharpException; break; } SWIG_CSharpThrowException(exception_code, msg); } %} #endif // SWIGCSHARP #ifdef __cplusplus /* You can use the SWIG_CATCH_STDEXCEPT macro with the %exception directive as follows: %exception { try { $action } catch (my_except& e) { ... } SWIG_CATCH_STDEXCEPT // catch std::exception catch (...) { SWIG_exception(SWIG_UnknownError, "Unknown exception"); } } */ %{ #include %} %define SWIG_CATCH_STDEXCEPT /* catching std::exception */ catch (std::invalid_argument& e) { SWIG_exception(SWIG_ValueError, e.what() ); } catch (std::domain_error& e) { SWIG_exception(SWIG_ValueError, e.what() ); } catch (std::overflow_error& e) { SWIG_exception(SWIG_OverflowError, e.what() ); } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError, e.what() ); } catch (std::length_error& e) { SWIG_exception(SWIG_IndexError, e.what() ); } catch (std::runtime_error& e) { SWIG_exception(SWIG_RuntimeError, e.what() ); } catch (std::exception& e) { SWIG_exception(SWIG_SystemError, e.what() ); } %enddef #endif // __cplusplus /* exception.i ends here */ cableswig-0.1.0+git20150808.orig/SWIG/Lib/chicken/0002755000175000000620000000000012561312227017712 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Lib/chicken/chicken.swg0000644000175000000620000005273112561312227022046 0ustar stevestaff/* ----------------------------------------------------------------------------- * chicken.swg * * CHICKEN configuration module. * ----------------------------------------------------------------------------- */ /* chicken.h has to appear first. */ %insert(runtime) %{ #include "chicken.h" %} %insert(runtime) "precommon.swg" %insert(runtime) "common.swg"; // Common type-checking code %insert(runtime) "chickenrun.swg"; // CHICKEN run-time code /* ----------------------------------------------------------------------------- * standard typemaps * ----------------------------------------------------------------------------- */ /* CHICKEN: C ---------- fixnum: int, short, unsigned int, unsigned short, unsigned char, signed char char: char bool: bool flonum: float, double, long, long long, unsigned long, unsigned long long */ /* --- Primitive types --- */ %include "fragments.i" %define SIMPLE_TYPEMAP(type_, from_scheme, to_scheme, checker, convtype, storage_) %typemap(in) type_ %{ if (!checker ($input)) { swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Argument #$argnum is not of type 'type_'"); } $1 = ($1_ltype) from_scheme ($input); %} /* Const primitive references. Passed by value */ %typemap(in) const type_ & ($*1_ltype temp) %{ if (!checker ($input)) { swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Argument #$argnum is not of type 'type_'"); } temp = ($*1_ltype) from_scheme ($input); $1 = &temp; %} /* --- Variable input --- */ %typemap(varin) type_ %{ if (!checker ($input)) { swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Cannot use '$1_ltype' for variable '$name' of type 'type_'"); } $1 = ($1_ltype) from_scheme ($input); %} #if "storage_" == "0" %typemap(out, fragment="list_output_helper",chicken_words="storage_") type_ %{/*if ONE*/ $result = to_scheme (convtype ($1)); /*else*/ $result = list_output_helper (&known_space, $result, to_scheme (convtype ($1))); /*endif*/ %} /* References to primitive types. Return by value */ %typemap(out, fragment="list_output_helper",chicken_words="storage_") const type_ & %{/*if ONE*/ $result = to_scheme (convtype (*$1)); /*else*/ $result = list_output_helper (&known_space, $result, to_scheme (convtype (*$1))); /*endif*/ %} /* --- Variable output --- */ %typemap(varout, fragment="list_output_helper",chicken_words="storage_") type_ %{/*if ONE*/ $result = to_scheme (convtype ($varname)); /*else*/ $result = list_output_helper (&known_space, $result, to_scheme (convtype ($varname))); /*endif*/ %} #else %typemap(out, fragment="list_output_helper",chicken_words="storage_") type_ %{/*if ONE*/ $result = to_scheme (&known_space, convtype ($1)); /*else*/ $result = list_output_helper (&known_space, $result, to_scheme (&known_space, convtype ($1))); /*endif*/ %} /* References to primitive types. Return by value */ %typemap(out, fragment="list_output_helper",chicken_words="storage_") const type_ & %{/*if ONE*/ $result = to_scheme (convtype (*$1)); /*else*/ $result = list_output_helper (&known_space, $result, to_scheme (convtype (*$1))); /*endif*/ %} /* --- Variable output --- */ %typemap(varout, fragment="list_output_helper",chicken_words="storage_") type_ %{/*if ONE*/ $result = to_scheme (&known_space, convtype ($varname)); /*else*/ $result = list_output_helper (&known_space, $result, to_scheme (&known_space, convtype ($varname))); /*endif*/ %} #endif /* --- Constants --- */ #if ("type_" == "char") || ("type_" == "unsigned char") || ("type_" == "signed char") %typemap(constcode) type_ "static const $1_type $result = '$value';" #else %typemap(constcode) type_ "static const $1_type $result = $value;" #endif %enddef SIMPLE_TYPEMAP(int, C_unfix, C_fix, C_swig_is_fixnum, (int), 0); SIMPLE_TYPEMAP(enum SWIGTYPE, C_unfix, C_fix, C_swig_is_fixnum, (int), 0); SIMPLE_TYPEMAP(short, C_unfix, C_fix, C_swig_is_fixnum, (int), 0); SIMPLE_TYPEMAP(long, C_flonum_magnitude, C_flonum, C_swig_is_flonum, (double), WORDS_PER_FLONUM); SIMPLE_TYPEMAP(long long, C_flonum_magnitude, C_flonum, C_swig_is_flonum, (double), WORDS_PER_FLONUM); SIMPLE_TYPEMAP(unsigned int, C_unfix, C_fix, C_swig_is_fixnum, (int), 0); SIMPLE_TYPEMAP(unsigned short, C_unfix, C_fix, C_swig_is_fixnum, (int), 0); SIMPLE_TYPEMAP(unsigned long, C_flonum_magnitude, C_flonum, C_swig_is_flonum, (double), WORDS_PER_FLONUM); SIMPLE_TYPEMAP(unsigned long long, C_flonum_magnitude, C_flonum, C_swig_is_flonum, (double), WORDS_PER_FLONUM); SIMPLE_TYPEMAP(unsigned char, C_unfix, C_fix, C_swig_is_fixnum, (int), 0); SIMPLE_TYPEMAP(signed char, C_unfix, C_fix, C_swig_is_fixnum, (int), 0); SIMPLE_TYPEMAP(char, C_character_code, C_make_character, C_swig_is_char, (char), 0); SIMPLE_TYPEMAP(bool, C_truep, C_mk_bool, C_swig_is_bool, (bool), 0); SIMPLE_TYPEMAP(float, C_flonum_magnitude, C_flonum, C_swig_is_flonum, (double), WORDS_PER_FLONUM); SIMPLE_TYPEMAP(double, C_flonum_magnitude, C_flonum, C_swig_is_flonum, (double), WORDS_PER_FLONUM); /* --- Input arguments --- */ /* Strings */ %typemap(in) char * { if ($input == C_SCHEME_FALSE) { $1 = NULL; } else { if (!C_swig_is_string ($input)) { swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Argument #$argnum is not of type 'char *'"); } $1 = ($ltype) swig_make_string ($input); } } %typemap(freearg) char * "if ($1 != NULL) { free ($1); }" /* Pointers, references, and arrays */ %typemap(in) SWIGTYPE *, SWIGTYPE [] "swig_convert_ptr($input,(void **) &$1, $1_descriptor,SWIG_POINTER_EXCEPTION);" /* Additional check for null references */ %typemap(in) SWIGTYPE & "swig_convert_ptr($input,(void **) &$1, $1_descriptor,SWIG_POINTER_EXCEPTION); if ($1 == NULL) swig_barf (SWIG_BARF1_ARGUMENT_NULL, \"null reference\");" /* Void pointer. Accepts any kind of pointer */ %typemap(in) void * "swig_convert_ptr($input,(void **) &$1, 0, SWIG_POINTER_EXCEPTION);" /* Object passed by value. Convert to a pointer */ %typemap(in) SWIGTYPE ($&1_ltype argp) "swig_convert_ptr($input,(void **) &argp, $&1_descriptor,SWIG_POINTER_EXCEPTION); $1 = *argp; "; /* Pointer to a class member */ %typemap(in) SWIGTYPE (CLASS::*) "swig_convert_packed($input, (void *) &$1, sizeof($1_type), $1_descriptor,SWIG_POINTER_EXCEPTION);"; /* --- Output values --- */ /* Strings */ %typemap(out,fragment="list_output_helper",chicken_words="0") char * { char *s = (char*) $1; if ($1 == NULL) { $result = C_SCHEME_FALSE; } else { int string_len = strlen ($1); C_word *string_space = C_alloc (C_SIZEOF_STRING (string_len)); /*if ONE*/ $result = C_string (&string_space, string_len, s); /*else*/ $result = list_output_helper (&known_space, $result, C_string (&string_space, string_len, s)); /*endif*/ } } %typemap(varout,fragment="list_output_helper",chicken_words="0") char * { char *s = (char*) $varname; if ($varname == NULL) { $result = C_SCHEME_FALSE; } else { int string_len = strlen ($varname); C_word *string_space = C_alloc (C_SIZEOF_STRING (string_len)); /*if ONE*/ $result = C_string (&string_space, string_len, s); /*else*/ $result = list_output_helper (&known_space, $result, C_string (&string_space, string_len, s)); /*endif*/ } } /* Pointers, references, and arrays */ %typemap(out,chicken_words="SWIG_ALLOCSZ_POINTER($typename)") SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] "$result = swig_new_pointer_obj((void *) $1, &known_space, $1_descriptor);"; /* Dynamic casts */ %typemap(out,chicken_words="SWIG_ALLOCSZ_POINTER($typename)") SWIGTYPE *DYNAMIC, SWIGTYPE &DYNAMIC { swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor, (void **) &$1); $result = swig_new_pointer_obj((void *) $1, &known_space, ty); } /* Member pointer */ %typemap(out,chicken_words="SWIG_ALLOCSZ_PACKED_OBJ(sizeof($1_type),$typename)") SWIGTYPE (CLASS::*) "$result = swig_new_packed_obj((void *) &$1, &known_space, sizeof($1_type), $1_descriptor);"; /* Void */ %typemap(out,chicken_words="void") void %{ /*if ONE*/ $result = C_SCHEME_UNDEFINED; /*else*/ /* void return value, no need to be in $result */ /*endif*/ %} /* Special typemap for character array return values */ %typemap(out,fragment="list_output_helper",chicken_words="0") char [ANY], const char [ANY] %{ if ($1 == NULL) { $result = C_SCHEME_FALSE; } else { const int string_len = strlen ($1); C_word *string_space = C_alloc (C_SIZEOF_STRING (string_len)); /*if ONE*/ $result = C_string (&string_space, string_len, $1); /*else*/ $result = list_output_helper (&known_space, $result, C_string (&string_space, string_len, $1)); /*endif*/ } %} /* Primitive types--return by value */ %typemap(out,chicken_words="SWIG_ALLOCSZ_POINTER($typename)") SWIGTYPE #ifdef __cplusplus { $&1_ltype resultptr; resultptr = new $1_ltype(($1_ltype &) $1); $result = swig_new_pointer_obj((void *) resultptr, &known_space, $&1_descriptor); } #else { $&1_ltype resultptr; resultptr = ($&1_ltype) malloc(sizeof($1_type)); memmove(resultptr, &$1, sizeof($1_type)); $result = swig_new_pointer_obj((void *) resultptr, &known_space, $&1_descriptor); } #endif /* --- Variable input --- */ /* A string */ #ifdef __cplusplus %typemap(varin) char * { if ($input == C_SCHEME_FALSE) { $1 = NULL; } else if (!C_swig_is_string ($input)) { swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "C variable '$name ($1_ltype)'"); } else { char *temp = C_c_string ($input); int len = C_header_size ($input); if ($1) delete [] $1; $1 = ($type) new char[len+1]; strncpy((char*)$1, temp, len); ((char*)$1) [len] = 0; } } %typemap(varin,warning="451:Setting const char * variable may leak memory") const char * { if ($input == C_SCHEME_FALSE) { $1 = NULL; } else if (!C_swig_is_string ($input)) { swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "C variable '$name ($1_ltype)'"); } else { char *temp = C_c_string ($input); int len = C_header_size ($input); $1 = ($type) new char[len+1]; strncpy((char*)$1,temp,len); ((char*)$1) [len] = 0; } } #else %typemap(varin) char * { if ($input == C_SCHEME_FALSE) { $1 = NULL; } else if (!C_swig_is_string ($input)) { swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "C variable '$name ($1_ltype)'"); } else { char *temp = C_c_string ($input); int len = C_header_size ($input); if ($1) free((char*) $1); $1 = ($type) malloc(len+1); strncpy((char*)$1,temp,len); ((char*)$1) [len] = 0; } } %typemap(varin,warning="451:Setting const char * variable may leak memory") const char * { if ($input == C_SCHEME_FALSE) { $1 = NULL; } else if (!C_swig_is_string ($input)) { swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "C variable '$name ($1_ltype)'"); } else { char *temp = C_c_string ($input); int len = C_header_size ($input); $1 = ($type) malloc(len+1); strncpy((char*)$1,temp,len); ((char*)$1) [len] = 0; } } #endif /* Special case for string array variables */ %typemap(varin) char [ANY] { if ($input == C_SCHEME_FALSE) { $1 = NULL; } else if (!C_swig_is_string ($input)) { swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "C variable '$name ($1_ltype)'"); } else { char *temp = C_c_string ($input); strncpy($1,temp,$1_dim0); } } %typemap(varin) SWIGTYPE * { if ($input == C_SCHEME_FALSE) { $1 = NULL; } else { void *temp; swig_convert_ptr($input,(void **) &temp, $1_descriptor, SWIG_POINTER_EXCEPTION); $1 = ($1_ltype) temp; } } %typemap(varin) SWIGTYPE & { void *temp; swig_convert_ptr($input,(void **) &temp, $1_descriptor, SWIG_POINTER_EXCEPTION); if (temp == NULL) { swig_barf (SWIG_BARF1_ARGUMENT_NULL, "$name is a null reference"); return 1; } $1 = ($1_ltype) temp; } %typemap(varin) void * { void * temp; swig_convert_ptr($input,(void **) &temp, 0, SWIG_POINTER_EXCEPTION | SWIG_POINTER_DISOWN); $1 = ($1_ltype) temp; } %typemap(varin) SWIGTYPE (CLASS::*) { char temp[sizeof($1_type)]; swig_convert_packed($input,(void *) temp, sizeof($1_type), $1_descriptor, SWIG_POINTER_EXCEPTION); memmove((void *) &$1,temp,sizeof($1_type)); } %typemap(varin) SWIGTYPE { $&1_ltype temp; swig_convert_ptr($input, (void **) &temp, $&1_descriptor, SWIG_POINTER_EXCEPTION); $1 = *(($&1_type) temp); } /* --- Variable output --- */ /* Pointers, references, and arrays */ %typemap(varout,chicken_words="SWIG_ALLOCSZ_POINTER($typename)") SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] "$result = swig_new_pointer_obj((void *) $varname, &known_space, $1_descriptor);"; /* Member pointer */ %typemap(varout,chicken_words="SWIG_ALLOCSZ_PACKED_OBJ(sizeof($1_type),$typename)") SWIGTYPE (CLASS::*) "$result = swig_new_packed_obj((void *) &$varname, sizeof($1_type), &known_space, $1_descriptor);"; /* Void */ %typemap(varout) void "$result = C_SCHEME_UNDEFINED;"; /* Special typemap for character array return values */ %typemap(varout) char [ANY], const char [ANY] %{ if ($varname == C_SCHEME_FALSE) { $result = NULL; } else if (C_swig_is_string ($varname)) { $result = swig_make_string ($varname); } else { swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Argument #$argnum is not of type 'string'"); } %} %typemap(varout,chicken_words="SWIG_ALLOCSZ_POINTER($typename)") SWIGTYPE "$result = swig_new_pointer_obj((void *) &$varname, &known_space, $&1_descriptor);"; /* --- Constants --- */ %typemap(constcode) char * "static const char *$result = \"$value\";" %typemap(constcode) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] "static const void *$result = (void*) $value;" %typemap(constcode) SWIGTYPE (CLASS::*) "static const void *$result = (void*) &$value;" /* ------------------------------------------------------------ * String & length * ------------------------------------------------------------ */ %typemap(in) (char *STRING, int LENGTH) { if ($input == C_SCHEME_FALSE) { swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Cannot use a null/#f string for a char*, int arguments"); } else if (C_swig_is_string ($input)) { $1 = ($1_ltype) C_c_string ($input); $2 = ($2_ltype) C_header_size ($input); } else { swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Argument #$argnum is not of type 'string'"); } } /* ------------------------------------------------------------ * ANSI C typemaps * ------------------------------------------------------------ */ %typemap(in) size_t %{ if (!C_swig_is_flonum ($input)) { swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Argument #$argnum is not of type 'flonum'"); } $1 = (size_t) C_flonum_magnitude ($input); %} %typemap(out) size_t = long; %typemap(varin) size_t = long; %typemap(varout) size_t = long; %typemap(constcode) size_t = long; /* ------------------------------------------------------------ * CHICKEN types * ------------------------------------------------------------ */ %typemap(in) C_word "$1 = $input;"; %typemap(out) C_word "$result = $1;"; /* ------------------------------------------------------------ * Typechecking rules * ------------------------------------------------------------ */ %typecheck(SWIG_TYPECHECK_INTEGER) bool, const bool & { $1 = C_swig_is_bool ($input); } %typecheck(SWIG_TYPECHECK_INTEGER) int, short, unsigned int, unsigned short, signed char, unsigned char, const int &, const short &, const unsigned int &, const unsigned short &, enum SWIGTYPE { $1 = C_swig_is_fixnum ($input); } %typecheck(SWIG_TYPECHECK_INTEGER) long, unsigned long, long long, unsigned long long, const long &, const unsigned long &, const long long &, const unsigned long long & { $1 = (C_swig_is_bool ($input) || C_swig_is_fixnum ($input) || C_swig_is_flonum ($input)) ? 1 : 0; } %typecheck(SWIG_TYPECHECK_DOUBLE) float, double, const float &, const double & { $1 = C_swig_is_flonum ($input); } %typecheck(SWIG_TYPECHECK_CHAR) char { $1 = C_swig_is_string ($input); } %typecheck(SWIG_TYPECHECK_STRING) char * { $1 = C_swig_is_string ($input); } %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { void *ptr; if (swig_convert_ptr($input, (void **) &ptr, $1_descriptor, 0) == -1) { $1 = 0; } else { $1 = 1; } } %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE { void *ptr; if (swig_convert_ptr($input, (void **) &ptr, $&1_descriptor, 0) == -1) { $1 = 0; } else { $1 = 1; } } %typecheck(SWIG_TYPECHECK_VOIDPTR) void * { void *ptr; if (swig_convert_ptr($input, (void **) &ptr, 0, 0) == -1) { $1 = 0; } else { $1 = 1; } } /* ------------------------------------------------------------ * Exception handling * ------------------------------------------------------------ */ /* TODO */ /* ------------------------------------------------------------ * Overloaded operator support * ------------------------------------------------------------ */ #ifdef __cplusplus %rename(__add__) *::operator+; %rename(__pos__) *::operator+(); %rename(__pos__) *::operator+() const; %rename(__sub__) *::operator-; %rename(__neg__) *::operator-(); %rename(__neg__) *::operator-() const; %rename(__mul__) *::operator*; %rename(__div__) *::operator/; %rename(__mod__) *::operator%; %rename(__lshift__) *::operator<<; %rename(__rshift__) *::operator>>; %rename(__and__) *::operator&; %rename(__or__) *::operator|; %rename(__xor__) *::operator^; %rename(__invert__) *::operator~; %rename(__iadd__) *::operator+=; %rename(__isub__) *::operator-=; %rename(__imul__) *::operator*=; %rename(__idiv__) *::operator/=; %rename(__imod__) *::operator%=; %rename(__ilshift__) *::operator<<=; %rename(__irshift__) *::operator>>=; %rename(__iand__) *::operator&=; %rename(__ior__) *::operator|=; %rename(__ixor__) *::operator^=; %rename(__lt__) *::operator<; %rename(__le__) *::operator<=; %rename(__gt__) *::operator>; %rename(__ge__) *::operator>=; %rename(__eq__) *::operator==; %rename(__ne__) *::operator!=; /* Special cases */ %rename(__call__) *::operator(); /* Ignored operators */ %ignorewarn("362:operator= ignored") operator=; %ignorewarn("383:operator++ ignored") operator++; %ignorewarn("384:operator-- ignored") operator--; %ignorewarn("381:operator&& ignored") operator&&; %ignorewarn("382:operator|| ignored") operator||; %ignorewarn("386:operator->* ignored") operator->*; %ignorewarn("389:operator[] ignored (consider using %extend)") operator[]; #endif /* Warnings for certain CHICKEN keywords */ %include "chickenkw.swg" /* TinyCLOS <--> Low-level CHICKEN */ %typemap("clos_in") SIMPLE_CLOS_OBJECT * "(slot-ref $input (quote this))" %typemap("clos_out") SIMPLE_CLOS_OBJECT * "(make $class (quote this) $1)" /* VERBATIM CODE INSERTIONS */ %insert(header) %{ #ifdef __cplusplus extern "C" { #endif /* Chicken initialization function */ SWIGEXPORT(void) $realmodule_swig_init(int, C_word, C_word) C_noret; /* Tag functions */ SWIGEXPORT(int) $realmodule_swig_num_types (void); SWIGEXPORT(const char*) $realmodule_swig_type_name (int); SWIGEXPORT(void*) $realmodule_swig_type_ptr (int); SWIGEXPORT(const char*) $realmodule_swig_type_str (int); SWIGEXPORT(void) $realmodule_swig_type_tag (int, C_word); #ifdef __cplusplus } #endif %} %insert(init) %{ /* CHICKEN initialization function */ SWIGEXPORT(void) $realmodule_swig_init(int argc, C_word closure, C_word continuation) { static int typeinit = 0; int i; if (!typeinit) { for (i = 0; swig_types_initial[i]; i++) { swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]); } typeinit = 1; swig_init_helper (continuation); } else { C_kontinue (continuation, C_SCHEME_FALSE); } } /* Tag functions */ SWIGEXPORT(int) $realmodule_swig_num_types (void) { int i; for (i=0; swig_types_initial[i]; i++); return i; } SWIGEXPORT(const char*) $realmodule_swig_type_name (int index) { return swig_types[index]->name; } SWIGEXPORT(void*) $realmodule_swig_type_ptr (int index) { return (void*) (swig_types[index]); } SWIGEXPORT(const char*) $realmodule_swig_type_str (int index) { return swig_types[index]->str; } SWIGEXPORT(void) $realmodule_swig_type_tag (int index, C_word tag) { swig_chicken_clientdata *data = (swig_chicken_clientdata*) malloc (sizeof (swig_chicken_clientdata)); C_mutate (&(data->tag), tag); data->literal_frame = C_register_lf (&(data->tag), 1); SWIG_TypeClientData (swig_types[index], (void*) data); } %} %insert(chicken) %{ (declare (foreign-declare "C_extern int $realmodule_swig_num_types (void);") (foreign-declare "C_extern char* $realmodule_swig_type_name (int);") (foreign-declare "C_extern void* $realmodule_swig_type_ptr (int);") (foreign-declare "C_extern char* $realmodule_swig_type_str (int);") (foreign-declare "C_extern void $realmodule_swig_type_tag (int, C_word);")) (define-record swig-$module-tag class name ptr str) (define-record-printer (swig-$module-tag tag out) (fprintf out "#(~A)" (swig-$module-tag-str tag) (swig-$module-tag-ptr tag))) (define swig-$module-tag-num ((foreign-lambda int "$realmodule_swig_num_types"))) (define swig-$module-tags (make-vector swig-$module-tag-num #f)) (letrec ((gen (lambda (l i) (if (= i 0) (cons 0 l) (gen (cons i l) (- i 1)))))) (let ((indices (if (<= swig-$module-tag-num 0) (quote ()) (gen (quote ()) (- swig-$module-tag-num 1))))) (for-each (lambda (index) (let ((tag (make-swig-$module-tag 1000 ((foreign-lambda c-string "$realmodule_swig_type_name" int) index) ((foreign-lambda c-pointer "$realmodule_swig_type_ptr" int) index) ((foreign-lambda c-string "$realmodule_swig_type_str" int) index)))) (vector-set! swig-$module-tags index tag) ((foreign-lambda void "$realmodule_swig_type_tag" int scheme-object) index tag))) indices))) %} cableswig-0.1.0+git20150808.orig/SWIG/Lib/chicken/typemaps.i0000644000175000000620000003034212561312227021726 0ustar stevestaff// // SWIG Typemap library // Jonah Beckford // Nov 22, 2002 // Derived: Dave Beazley (Author); Lib/python/typemaps.i; May 5, 1997 // // CHICKEN implementation // // This library provides standard typemaps for modifying SWIG's behavior. // With enough entries in this file, I hope that very few people actually // ever need to write a typemap. // // Disclaimer : Unless you really understand how typemaps work, this file // probably isn't going to make much sense. // // ------------------------------------------------------------------------ // Pointer handling // // These mappings provide support for input/output arguments and // common uses for C/C++ pointers. INOUT mappings allow for C/C++ // pointer variables in addition to input/output arguments. // ------------------------------------------------------------------------ // INPUT typemaps. // These remap a C pointer to be an "INPUT" value which is passed by value // instead of reference. /* The following methods can be applied to turn a pointer into a simple "input" value. That is, instead of passing a pointer to an object, you would use a real value instead. int *INPUT short *INPUT long *INPUT long long *INPUT unsigned int *INPUT unsigned short *INPUT unsigned long *INPUT unsigned long long *INPUT unsigned char *INPUT char *INPUT bool *INPUT float *INPUT double *INPUT To use these, suppose you had a C function like this : double fadd(double *a, double *b) { return *a+*b; } You could wrap it with SWIG as follows : %include typemaps.i double fadd(double *INPUT, double *INPUT); or you can use the %apply directive : %include typemaps.i %apply double *INPUT { double *a, double *b }; double fadd(double *a, double *b); */ // OUTPUT typemaps. These typemaps are used for parameters that // are output only. The output value is appended to the result as // a list element. /* The following methods can be applied to turn a pointer into an "output" value. When calling a function, no input value would be given for a parameter, but an output value would be returned. In the case of multiple output values, they are returned in the form of a Scheme list. int *OUTPUT short *OUTPUT long *OUTPUT long long *OUTPUT unsigned int *OUTPUT unsigned short *OUTPUT unsigned long *OUTPUT unsigned long long *OUTPUT unsigned char *OUTPUT char *OUTPUT bool *OUTPUT float *OUTPUT double *OUTPUT For example, suppose you were trying to wrap the modf() function in the C math library which splits x into integral and fractional parts (and returns the integer part in one of its parameters).K: double modf(double x, double *ip); You could wrap it with SWIG as follows : %include typemaps.i double modf(double x, double *OUTPUT); or you can use the %apply directive : %include typemaps.i %apply double *OUTPUT { double *ip }; double modf(double x, double *ip); The CHICKEN output of the function would be a list containing both output values, in reverse order. */ // These typemaps contributed by Robin Dunn //---------------------------------------------------------------------- // // T_OUTPUT typemap (and helper function) to return multiple argouts as // a tuple instead of a list. // // Author: Robin Dunn //---------------------------------------------------------------------- %include "fragments.i" // Simple types %define INOUT_TYPEMAP(type_, from_scheme, to_scheme, checker, convtype, storage_) %typemap(in) type_ *INPUT($*1_ltype temp), type_ &INPUT($*1_ltype temp) %{ if (!checker ($input)) { swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Argument #$argnum is not of type 'type_'"); } temp = from_scheme ($input); $1 = &temp; %} %typemap(typecheck) type_ *INPUT = type_; %typemap(typecheck) type_ &INPUT = type_; %typemap(in, numinputs=0) type_ *OUTPUT($*1_ltype temp), type_ &OUTPUT($*1_ltype temp) " $1 = &temp;" #if "storage_" == "0" %typemap(argout,fragment="list_output_helper",chicken_words="storage_") type_ *OUTPUT, type_ &OUTPUT %{ if ($1 == NULL) { swig_barf (SWIG_BARF1_ARGUMENT_NULL, "Argument #$argnum must be non-null"); } /*if ONE*/ $result = to_scheme (convtype (*$1)); /*else*/ $result = list_output_helper (&known_space, $result, to_scheme (convtype (*$1))); /*endif*/ %} #else %typemap(argout,fragment="list_output_helper",chicken_words="storage_") type_ *OUTPUT, type_ &OUTPUT %{if ($1 == NULL) { swig_barf (SWIG_BARF1_ARGUMENT_NULL, "Variable '$1' must be non-null"); } /*if ONE*/ $result = to_scheme (&known_space, convtype (*$1)); /*else*/ $result = list_output_helper (&known_space, $result, to_scheme (&known_space, convtype (*$1))); /*endif*/ %} #endif %enddef INOUT_TYPEMAP(int, C_unfix, C_fix, C_swig_is_fixnum, (int), 0); INOUT_TYPEMAP(enum SWIGTYPE, C_unfix, C_fix, C_swig_is_fixnum, (int), 0); INOUT_TYPEMAP(short, C_unfix, C_fix, C_swig_is_fixnum, (int), 0); INOUT_TYPEMAP(long, C_flonum_magnitude, C_flonum, C_swig_is_flonum, (double), WORDS_PER_FLONUM); INOUT_TYPEMAP(long long, C_flonum_magnitude, C_flonum, C_swig_is_flonum, (double), WORDS_PER_FLONUM); INOUT_TYPEMAP(unsigned int, C_unfix, C_fix, C_swig_is_fixnum, (int), 0); INOUT_TYPEMAP(unsigned short, C_unfix, C_fix, C_swig_is_fixnum, (int), 0); INOUT_TYPEMAP(unsigned long, C_flonum_magnitude, C_flonum, C_swig_is_flonum, (double), WORDS_PER_FLONUM); INOUT_TYPEMAP(unsigned long long, C_flonum_magnitude, C_flonum, C_swig_is_flonum, (double), WORDS_PER_FLONUM); INOUT_TYPEMAP(unsigned char, C_unfix, C_fix, C_swig_is_fixnum, (int), 0); INOUT_TYPEMAP(signed char, C_unfix, C_fix, C_swig_is_fixnum, (int), 0); INOUT_TYPEMAP(char, C_character_code, C_make_character, C_swig_is_char, (char), 0); INOUT_TYPEMAP(bool, C_truep, C_mk_bool, C_swig_is_bool, (bool), 0); INOUT_TYPEMAP(float, C_flonum_magnitude, C_flonum, C_swig_is_flonum, (double), WORDS_PER_FLONUM); INOUT_TYPEMAP(double, C_flonum_magnitude, C_flonum, C_swig_is_flonum, (double), WORDS_PER_FLONUM); // INOUT // Mappings for an argument that is both an input and output // parameter /* The following methods can be applied to make a function parameter both an input and output value. This combines the behavior of both the "INPUT" and "OUTPUT" methods described earlier. Output values are returned in the form of a CHICKEN tuple. int *INOUT short *INOUT long *INOUT long long *INOUT unsigned int *INOUT unsigned short *INOUT unsigned long *INOUT unsigned long long *INOUT unsigned char *INOUT char *INOUT bool *INOUT float *INOUT double *INOUT For example, suppose you were trying to wrap the following function : void neg(double *x) { *x = -(*x); } You could wrap it with SWIG as follows : %include typemaps.i void neg(double *INOUT); or you can use the %apply directive : %include typemaps.i %apply double *INOUT { double *x }; void neg(double *x); As well, you can wrap variables with : %include typemaps.i %apply double *INOUT { double *y }; extern double *y; Unlike C, this mapping does not directly modify the input value (since this makes no sense in CHICKEN). Rather, the modified input value shows up as the return value of the function. Thus, to apply this function to a CHICKEN variable you might do this : x = neg(x) Note : previous versions of SWIG used the symbol 'BOTH' to mark input/output arguments. This is still supported, but will be slowly phased out in future releases. */ %typemap(in) int *INOUT = int *INPUT; %typemap(in) enum SWIGTYPE *INOUT = enum SWIGTYPE *INPUT; %typemap(in) short *INOUT = short *INPUT; %typemap(in) long *INOUT = long *INPUT; %typemap(in) long long *INOUT = long long *INPUT; %typemap(in) unsigned *INOUT = unsigned *INPUT; %typemap(in) unsigned short *INOUT = unsigned short *INPUT; %typemap(in) unsigned long *INOUT = unsigned long *INPUT; %typemap(in) unsigned long long *INOUT = unsigned long long *INPUT; %typemap(in) unsigned char *INOUT = unsigned char *INPUT; %typemap(in) char *INOUT = char *INPUT; %typemap(in) bool *INOUT = bool *INPUT; %typemap(in) float *INOUT = float *INPUT; %typemap(in) double *INOUT = double *INPUT; %typemap(in) int &INOUT = int &INPUT; %typemap(in) enum SWIGTYPE &INOUT = enum SWIGTYPE &INPUT; %typemap(in) short &INOUT = short &INPUT; %typemap(in) long &INOUT = long &INPUT; %typemap(in) long long &INOUT = long long &INPUT; %typemap(in) unsigned &INOUT = unsigned &INPUT; %typemap(in) unsigned short &INOUT = unsigned short &INPUT; %typemap(in) unsigned long &INOUT = unsigned long &INPUT; %typemap(in) unsigned long long &INOUT = unsigned long long &INPUT; %typemap(in) unsigned char &INOUT = unsigned char &INPUT; %typemap(in) char &INOUT = char &INPUT; %typemap(in) bool &INOUT = bool &INPUT; %typemap(in) float &INOUT = float &INPUT; %typemap(in) double &INOUT = double &INPUT; %typemap(argout) int *INOUT = int *OUTPUT; %typemap(argout) enum SWIGTYPE *INOUT = enum SWIGTYPE *OUTPUT; %typemap(argout) short *INOUT = short *OUTPUT; %typemap(argout) long *INOUT = long *OUTPUT; %typemap(argout) long long *INOUT = long long *OUTPUT; %typemap(argout) unsigned *INOUT = unsigned *OUTPUT; %typemap(argout) unsigned short *INOUT = unsigned short *OUTPUT; %typemap(argout) unsigned long *INOUT = unsigned long *OUTPUT; %typemap(argout) unsigned long long *INOUT = unsigned long long *OUTPUT; %typemap(argout) unsigned char *INOUT = unsigned char *OUTPUT; %typemap(argout) bool *INOUT = bool *OUTPUT; %typemap(argout) float *INOUT = float *OUTPUT; %typemap(argout) double *INOUT = double *OUTPUT; %typemap(argout) int &INOUT = int &OUTPUT; %typemap(argout) enum SWIGTYPE &INOUT = enum SWIGTYPE &OUTPUT; %typemap(argout) short &INOUT = short &OUTPUT; %typemap(argout) long &INOUT = long &OUTPUT; %typemap(argout) long long &INOUT = long long &OUTPUT; %typemap(argout) unsigned &INOUT = unsigned &OUTPUT; %typemap(argout) unsigned short &INOUT = unsigned short &OUTPUT; %typemap(argout) unsigned long &INOUT = unsigned long &OUTPUT; %typemap(argout) unsigned long long &INOUT = unsigned long long &OUTPUT; %typemap(argout) unsigned char &INOUT = unsigned char &OUTPUT; %typemap(argout) char &INOUT = char &OUTPUT; %typemap(argout) bool &INOUT = bool &OUTPUT; %typemap(argout) float &INOUT = float &OUTPUT; %typemap(argout) double &INOUT = double &OUTPUT; /* Overloading information */ %typemap(typecheck) double *INOUT = double; %typemap(typecheck) bool *INOUT = bool; %typemap(typecheck) char *INOUT = char; %typemap(typecheck) signed char *INOUT = signed char; %typemap(typecheck) unsigned char *INOUT = unsigned char; %typemap(typecheck) unsigned long *INOUT = unsigned long; %typemap(typecheck) unsigned long long *INOUT = unsigned long long; %typemap(typecheck) unsigned short *INOUT = unsigned short; %typemap(typecheck) unsigned int *INOUT = unsigned int; %typemap(typecheck) long *INOUT = long; %typemap(typecheck) long long *INOUT = long long; %typemap(typecheck) short *INOUT = short; %typemap(typecheck) int *INOUT = int; %typemap(typecheck) enum SWIGTYPE *INOUT = enum SWIGTYPE; %typemap(typecheck) float *INOUT = float; %typemap(typecheck) double &INOUT = double; %typemap(typecheck) bool &INOUT = bool; %typemap(typecheck) char &INOUT = char; %typemap(typecheck) signed char &INOUT = signed char; %typemap(typecheck) unsigned char &INOUT = unsigned char; %typemap(typecheck) unsigned long &INOUT = unsigned long; %typemap(typecheck) unsigned long long &INOUT = unsigned long long; %typemap(typecheck) unsigned short &INOUT = unsigned short; %typemap(typecheck) unsigned int &INOUT = unsigned int; %typemap(typecheck) long &INOUT = long; %typemap(typecheck) long long &INOUT = long long; %typemap(typecheck) short &INOUT = short; %typemap(typecheck) int &INOUT = int; %typemap(typecheck) enum SWIGTYPE &INOUT = enum SWIGTYPE; %typemap(typecheck) float &INOUT = float; cableswig-0.1.0+git20150808.orig/SWIG/Lib/chicken/fragments.i0000644000175000000620000000102112561312227022042 0ustar stevestaff/* Helper function to return tuples. * Jonah Beckford * * Derived from Lib/python/fragments.i; Author: Robin Dunn * * */ %fragment("list_output_helper","header") %{ static C_word list_output_helper(C_word **ptr, C_word target, C_word o) /* Prepends 'o' to list 'target'. ptr must be from C_alloc and have room for 3 C_words. */ { if (!target || C_truep (C_undefinedp (target))) { target = C_pair (ptr, o, C_SCHEME_END_OF_LIST); } else { target = C_pair (ptr, o, target); } return target; } %} cableswig-0.1.0+git20150808.orig/SWIG/Lib/chicken/chickenkw.swg0000644000175000000620000000125412561312227022402 0ustar stevestaff#ifndef __chicken_chickenkw_swg__ #define __chicken_chickenkw_swg__ /* Warnings for certain CHICKEN keywords. From Section 7.1.1 of Revised^5 Report on the Algorithmic Language Scheme */ #define CHICKENKW(x) %namewarn("314:" #x " is a R^5RS syntatic keyword") #x CHICKENKW(else); CHICKENKW(=>); CHICKENKW(define); CHICKENKW(unquote); CHICKENKW(unquote-splicing); CHICKENKW(quote); CHICKENKW(lambda); CHICKENKW(if); CHICKENKW(set!); CHICKENKW(begin); CHICKENKW(cond); CHICKENKW(and); CHICKENKW(or); CHICKENKW(case); CHICKENKW(let); CHICKENKW(let*); CHICKENKW(letrec); CHICKENKW(do); CHICKENKW(delay); CHICKENKW(quasiquote); #undef CHICKENKW #endif //__chicken_chickenkw_swg__ cableswig-0.1.0+git20150808.orig/SWIG/Lib/chicken/chickenrun.swg0000644000175000000620000002331012561312227022562 0ustar stevestaff/*********************************************************************** * chickenrun.swg * * This file contains the runtime support for CHICKEN modules * and includes code for managing global variables and pointer * type checking. * * Author : Jonah Beckford * Derived from - file : pyrun.swg * Derived from - author : David Beazley (beazley@cs.uchicago.edu) ************************************************************************/ #ifdef __cplusplus extern "C" { #endif #ifdef C_SIXTY_FOUR # define WORDS_PER_FLONUM 2 #else # define WORDS_PER_FLONUM 4 #endif /* Flags for pointer conversion */ #define SWIG_POINTER_EXCEPTION 0x1 #define C_swig_is_bool(x) C_truep (C_booleanp (x)) #define C_swig_is_char(x) C_truep (C_charp (x)) #define C_swig_is_fixnum(x) C_truep (C_fixnump (x)) #define C_swig_is_flonum(x) (C_truep (C_blockp (x)) && C_truep (C_flonump (x))) #define C_swig_is_string(x) (C_truep (C_blockp (x)) && C_truep (C_stringp (x))) #define C_swig_is_vector(x) (C_truep (C_blockp (x)) && C_truep (C_vectorp (x))) #define C_swig_is_list(x) (C_truep (C_i_listp (x))) #define C_swig_is_tagged_ptr(x) (C_truep (C_blockp (x)) && C_truep (C_taggedpointerp (x))) #define C_swig_is_tag_struct(x) (C_truep (C_blockp (x)) && C_truep (C_structurep (x)) && (C_header_size (x) >= 3)) #define C_swig_is_ptr(x) (C_truep (C_blockp (x)) && C_truep (C_pointerp (x))) enum { SWIG_BARF1_BAD_ARGUMENT_TYPE /* 1 arg */, SWIG_BARF1_ARGUMENT_NULL /* 1 arg */ }; typedef struct swig_chicken_clientdata { void* literal_frame; C_word tag; } swig_chicken_clientdata; #ifdef SWIG_NOINCLUDE SWIGEXPORT(char *) swig_make_string (C_word string); SWIGEXPORT(char *) swig_make_string2 (char *data, int len); SWIGEXPORT(void) swig_barf (int code, C_char *msg, ...) C_noret; SWIGEXPORT(void) swig_panic (C_char *msg) C_noret; SWIGEXPORT(int) swig_convert_ptr(C_word , void **, swig_type_info *, int); SWIGEXPORT(int) swig_convert_packed(C_word , void *, int sz, swig_type_info *, int); SWIGEXPORT(char *) swig_pack_data(char *c, void *, int); SWIGEXPORT(char *) swig_unpack_data(char *c, void *, int); SWIGEXPORT(C_word) swig_new_pointer_obj(void *, swig_type_info *, int own); SWIGEXPORT(C_word) swig_new_packed_obj(void *, int sz, swig_type_info *); #else /* Allocate a zero-terminated string. No error-checking. */ SWIGRUNTIME(char *) swig_make_string2 (char *data, int len) { char *ret; if (data == NULL) return NULL; ret = (char *) malloc (len + 1); strncpy (ret, data, len); ret [len] = 0; return ret; } /* Allocate a zero-terminated string. No error-checking. */ SWIGRUNTIME(char *) swig_make_string (C_word string) { return swig_make_string2 (C_c_string (string), C_header_size (string)); } SWIGRUNTIME(void) swig_panic (C_char *) C_noret; SWIGRUNTIME(void) swig_panic (C_char *msg) { C_word *a = C_alloc (C_SIZEOF_STRING (strlen (msg))); C_word scmmsg = C_string2 (&a, msg); C_halt (scmmsg); exit (5); /* should never get here */ } SWIGRUNTIME(void) swig_barf (int, C_char *, ...) C_noret; SWIGRUNTIME(void) swig_barf (int code, C_char *msg, ...) { char *errorhook = C_text("\003syserror-hook"); C_word *a = C_alloc (C_SIZEOF_STRING (strlen (errorhook))); C_word err = C_intern2 (&a, errorhook); int c = -1; int i, barfval; va_list v; C_temporary_stack = C_temporary_stack_bottom; err = C_block_item(err, 0); if(C_immediatep (err)) swig_panic (C_text ("`##sys#error-hook' is not defined")); switch (code) { case SWIG_BARF1_BAD_ARGUMENT_TYPE: barfval = C_BAD_ARGUMENT_TYPE_ERROR; c = 1; break; case SWIG_BARF1_ARGUMENT_NULL: barfval = C_BAD_ARGUMENT_TYPE_ERROR; c = 1; break; default: swig_panic (C_text (msg)); }; if(c > 0 && !C_immediatep (err)) { C_save (C_fix (barfval)); i = c; if (i) { C_word *b = C_alloc (C_SIZEOF_STRING (strlen (msg))); C_word scmmsg = C_string2 (&b, msg); C_save (scmmsg); i--; } va_start (v, msg); while(i--) C_save (va_arg (v, C_word)); va_end (v); C_do_apply (c + 1, err, C_SCHEME_UNDEFINED); /* <- no continuation is passed: '##sys#error-hook' may not return! */ } else if (msg) { swig_panic (msg); } else { swig_panic (C_text ("unspecified panic")); } } /* Pack binary data into a string */ SWIGRUNTIME(char *) swig_pack_data(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_unpack_data(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; } /* Convert a pointer value */ SWIGRUNTIME(int) swig_convert_ptr(C_word obj, void **ptr, swig_type_info *ty, int flags) { swig_type_info *tc; #ifdef SWIG_POINTER_AS_STRING char *s; char *c; if (obj == C_SCHEME_FALSE) { *ptr = 0; return 0; } c = s = 0; if (!(C_swig_is_string (obj))) goto type_error; s = c = swig_make_string (obj); if (!c) goto type_error; /* Pointer values must start with leading underscore */ if (*c != '_') goto type_error; c++; c = swig_unpack_data (c,ptr,sizeof(void *)); if (ty) { tc = SWIG_TypeCheck(c,ty); if (!tc) goto type_error; *ptr = SWIG_TypeCast(tc,(void*) *ptr); } free (s); #else C_word tag; C_word tag_ptr; if (obj == C_SCHEME_FALSE) { *ptr = 0; return 0; } if (!(C_swig_is_tagged_ptr (obj))) goto type_error; *ptr = (void*) C_pointer_address (obj); if (ty) { tag = C_block_item (obj, 1); if (!(C_swig_is_tag_struct (tag))) goto type_error; tag_ptr = C_block_item (tag, 3); if (!(C_swig_is_ptr (tag_ptr))) goto type_error; tc = (swig_type_info *) C_pointer_address (tag_ptr); if (!tc) goto type_error; *ptr = SWIG_TypeCast(tc,(void*) *ptr); } #endif return 0; type_error: #ifdef SWIG_POINTER_AS_STRING if (s) { free (s); } #endif if (flags & SWIG_POINTER_EXCEPTION) { if (ty) { char *temp = (char *) malloc(64+strlen(ty->name)); sprintf(temp,"Type error. Expected %s", ty->name); swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, temp); free((char *) temp); } else { swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Expected a pointer"); } } return -1; } /* Convert a packed value */ SWIGRUNTIME(int) swig_convert_packed(C_word obj, void *ptr, int sz, swig_type_info *ty, int flags) { swig_type_info *tc; char *c; char *s; if (!C_swig_is_string (obj)) goto type_error; s = c = swig_make_string (obj); /* Pointer values must start with leading underscore */ if (!c || *c != '_') goto type_error; c++; c = swig_unpack_data(c,ptr,sz); if (ty) { tc = SWIG_TypeCheck(c,ty); if (!tc) goto type_error; } free (s); return 0; type_error: free (s); if (flags) { if (ty) { char *temp = (char *) malloc(64+strlen(ty->name)); sprintf(temp,"Type error. Expected %s", ty->name); swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, temp); free((char *) temp); } else { swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Expected a pointer"); } } return -1; } #define SWIG_STRLEN_PACKED_OBJ(obj_sz,name) (2*obj_sz+1+strlen(name)) #define SWIG_ALLOCSZ_PACKED_OBJ(obj_sz,name) (C_SIZEOF_STRING (SWIG_STRLEN_PACKED_OBJ (obj_sz,name))) /* #define SWIG_ALLOCSZ_POINTER(name) SWIG_ALLOCSZ_PACKED_OBJ(sizeof(void*),name) */ #define SWIG_ALLOCSZ_POINTER(name) 3 /* Create a new pointer object. 'a' should be a pointer to some C_alloc result with SWIG_ALLOCSZ_POINTER (type->name) room */ SWIGRUNTIME(C_word) swig_new_pointer_obj(void *ptr, C_word **a, swig_type_info *type) { if (ptr == NULL) return C_SCHEME_FALSE; #ifdef SWIG_POINTER_AS_STRING { char result[1024]; char *r = result; *(r++) = '_'; r = swig_pack_data(r,&ptr,sizeof(void *)); strcpy(r,type->name); return C_string2 (a, result); } #else { /* similar to C_mpointer */ C_word *p = *a, *p0 = p; *(p++) = C_TAGGED_POINTER_TAG; *((void **)(p++)) = ptr; C_mutate ((C_word*)(p++), ((swig_chicken_clientdata*) type->clientdata)->tag); *a = p; return (C_word)p0; } #endif } /* 'a' should be a pointer to some C_alloc result with SWIG_ALLOCSZ_PACKED_OBJ (sz,type->name) room */ SWIGRUNTIME(C_word) swig_new_packed_obj (void *ptr, C_word **a, int sz, swig_type_info *type) { char result[1024]; char *r = result; if (SWIG_STRLEN_PACKED_OBJ (sz, type->name) > 1000) return 0; *(r++) = '_'; r = swig_pack_data(r,ptr,sz); strcpy(r,type->name); return C_string2 (a, result); } /* Standard Chicken function */ static void C_fcall swig_tr2(C_proc2 k) C_regparm C_noret; static void C_fcall swig_tr2(C_proc2 k) { C_word t1=C_pick(0); C_word t0=C_pick(1); C_adjust_stack(-2); (k)(2,t0,t1); } /* Standard Chicken function */ static void C_fcall swig_tr2r(C_proc2 k) C_regparm C_noret; static void C_fcall swig_tr2r(C_proc2 k) { int n; C_word *a,t2; C_word t1=C_pick(0); C_word t0=C_pick(1); C_adjust_stack(-2); n=C_rest_count(0); a=C_alloc(n*3); t2=C_restore_rest(a,n); (k)(t0,t1,t2); } #endif #ifdef __cplusplus } #endif cableswig-0.1.0+git20150808.orig/SWIG/Lib/chicken/precommon.swg0000644000175000000620000000141212561312227022427 0ustar stevestaff/*************************************************************** -*- c -*- * chicken/precommon.swg * * Rename all exported symbols from common.swg, to avoid symbol * clashes if multiple interpreters are included * ************************************************************************/ #define SWIG_TypeRegister SWIG_Chicken_TypeRegister #define SWIG_TypeCheck SWIG_Chicken_TypeCheck #define SWIG_TypeCast SWIG_Chicken_TypeCast #define SWIG_TypeDynamicCast SWIG_Chicken_TypeDynamicCast #define SWIG_TypeName SWIG_Chicken_TypeName #define SWIG_TypeQuery SWIG_Chicken_TypeQuery #define SWIG_TypeClientData SWIG_Chicken_TypeClientData #define SWIG_PackData SWIG_Chicken_PackData #define SWIG_UnpackData SWIG_Chicken_UnpackData cableswig-0.1.0+git20150808.orig/SWIG/Lib/stl.i0000644000175000000620000000042412561312227017260 0ustar stevestaff// // SWIG typemaps for STL types // Luigi Ballabio // Jan 16, 2003 // // the %include directives below will fetch the files from the // appropriate language directory %include std_common.i %include std_string.i %include std_vector.i %include std_map.i %include std_pair.i cableswig-0.1.0+git20150808.orig/SWIG/Lib/pointer.i0000644000175000000620000000016312561312227020136 0ustar stevestaff %echo "pointer.i is deprecated. Use cpointer.i instead." %echo "See http://www.swig.org/Doc1.3/Library.html" cableswig-0.1.0+git20150808.orig/SWIG/Lib/java/0002755000175000000620000000000012561312227017227 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Lib/java/std_string.i0000644000175000000620000001355312561312227021566 0ustar stevestaff// // SWIG typemaps for std::string // Luigi Ballabio, Tal Shalif and William Fulton // May 7, 2002 // // Java implementation // /* ------------------------------------------------------------------------ Typemaps for std::string and const std::string& These are mapped to a Java String and are passed around by value. To use non-const std::string references use the following %apply. Note that they are passed by value. %apply const std::string & {std::string &}; ------------------------------------------------------------------------ */ %include exception.i %{ #include %} namespace std { class string; // string %typemap(jni) string "jstring" %typemap(jtype) string "String" %typemap(jstype) string "String" %typemap(javadirectorin) string "$jniinput" %typemap(javadirectorout) string "$javacall" %typemap(in) string %{if($input) { const char *pstr = (const char *)jenv->GetStringUTFChars($input, 0); if (!pstr) return $null; $1 = std::string(pstr); jenv->ReleaseStringUTFChars($input, pstr); } else { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null std::string"); return $null; } %} %typemap(directorin,descriptor="Ljava/lang/String;") string %{ $input = jenv->NewStringUTF($1.c_str()); %} %typemap(out) string %{ $result = jenv->NewStringUTF($1.c_str()); %} %typemap(javain) string "$javainput" %typemap(javaout) string { return $jnicall; } %typemap(typecheck) string = char *; // const string & %typemap(jni) const string & "jstring" %typemap(jtype) const string & "String" %typemap(jstype) const string & "String" %typemap(javadirectorin) const string & "$jniinput" %typemap(javadirectorout) const string & "$javacall" %typemap(in) const string & %{$1 = NULL; if($input) { const char *pstr = (const char *)jenv->GetStringUTFChars($input, 0); if (!pstr) return $null; $1 = new std::string(pstr); jenv->ReleaseStringUTFChars($input, pstr); } else { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null std::string"); return $null; } %} %typemap(freearg) const string & %{ delete $1; %} %typemap(directorin,descriptor="Ljava/lang/String;") const string & %{ $input = jenv->NewStringUTF($1.c_str()); %} %typemap(out) const string & %{ $result = jenv->NewStringUTF($1->c_str()); %} %typemap(javain) const string & "$javainput" %typemap(javaout) const string & { return $jnicall; } %typemap(typecheck) const string & = char *; } /* ------------------------------------------------------------------------ Typemaps for std::wstring and const std::wstring& These are mapped to a Java String and are passed around by value. Warning: Unicode / multibyte characters are handled differently on different OSs so the std::wstring typemaps may not always work as intended. Therefore a #define is required to use them. To use non-const std::wstring references use the following %apply. Note that they are passed by value. %apply const std::wstring & {std::wstring &}; ------------------------------------------------------------------------ */ #ifdef SWIGJAVA_WSTRING namespace std { class wstring; // wstring %typemap(jni) wstring "jstring" %typemap(jtype) wstring "String" %typemap(jstype) wstring "String" %typemap(javadirectorin) wstring "$jniinput" %typemap(javadirectorout) wstring "$javacall" %typemap(in) wstring %{if($input) { const jchar *pstr = jenv->GetStringChars($input, 0); if (!pstr) return $null; jsize len = jenv->GetStringLength($input); if (len) { wchar_t *conv_buf = new wchar_t[len]; for (jsize i = 0; i < len; ++i) { conv_buf[i] = pstr[i]; } $1 = std::wstring(conv_buf, len); delete [] conv_buf; } jenv->ReleaseStringChars($input, pstr); } else { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null std::wstring"); return $null; } %} %typemap(directorin,descriptor="Ljava/lang/String;") wstring %{jsize len = $1.length(); jchar *conv_buf = new jchar[len]; for (jsize i = 0; i < len; ++i) { conv_buf[i] = (jchar)$1[i]; } $input = jenv->NewString(conv_buf, len); delete [] conv_buf; %} %typemap(out) wstring %{jsize len = $1.length(); jchar *conv_buf = new jchar[len]; for (jsize i = 0; i < len; ++i) { conv_buf[i] = (jchar)$1[i]; } $result = jenv->NewString(conv_buf, len); delete [] conv_buf; %} %typemap(javain) wstring "$javainput" %typemap(javaout) wstring { return $jnicall; } // const wstring & %typemap(jni) const wstring & "jstring" %typemap(jtype) const wstring & "String" %typemap(jstype) const wstring & "String" %typemap(javadirectorin) const wstring & "$jniinput" %typemap(javadirectorout) const wstring & "$javacall" %typemap(in) const wstring & %{$1 = NULL; if($input) { const jchar *pstr = jenv->GetStringChars($input, 0); if (!pstr) return $null; jsize len = jenv->GetStringLength($input); if (len) { wchar_t *conv_buf = new wchar_t[len]; for (jsize i = 0; i < len; ++i) { conv_buf[i] = pstr[i]; } $1 = new std::wstring(conv_buf, len); delete [] conv_buf; } jenv->ReleaseStringChars($input, pstr); } else { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null std::wstring"); return $null; } %} %typemap(directorin,descriptor="Ljava/lang/String;") const wstring & %{jsize len = $1->length(); jchar *conv_buf = new jchar[len]; for (jsize i = 0; i < len; ++i) { conv_buf[i] = (jchar)(*$1)[i]; } $input = jenv->NewString(conv_buf, len); delete [] conv_buf; %} %typemap(out) const wstring & %{jsize len = $1->length(); jchar *conv_buf = new jchar[len]; for (jsize i = 0; i < len; ++i) { conv_buf[i] = (jchar)(*$1)[i]; } $result = jenv->NewString(conv_buf, len); delete [] conv_buf; %} %typemap(javain) const wstring & "$javainput" %typemap(javaout) const wstring & { return $jnicall; } } #endif cableswig-0.1.0+git20150808.orig/SWIG/Lib/java/std_map.i0000644000175000000620000001224712561312227021034 0ustar stevestaff// // SWIG typemaps for std::map // Luigi Ballabio // Jan. 2003 // // Common implementation %include std_common.i %include exception.i %exception std::map::get { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::map::del { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } // ------------------------------------------------------------------------ // std::map // ------------------------------------------------------------------------ %{ #include #include #include %} // exported class namespace std { template class map { // add typemaps here public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T& get(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void set(const K& key, const T& x) { (*self)[key] = x; } void del(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(const K& key) { std::map::iterator i = self->find(key); return i != self->end(); } } }; // specializations for built-ins %define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO) template class map { // add typemaps here public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T& get(K key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void set(K key, const T& x) { (*self)[key] = x; } void del(K key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(K key) { std::map::iterator i = self->find(key); return i != self->end(); } } }; %enddef %define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO) template class map { // add typemaps here public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T get(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void set(const K& key, T x) { (*self)[key] = x; } void del(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(const K& key) { std::map::iterator i = self->find(key); return i != self->end(); } } }; %enddef %define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO) template<> class map { // add typemaps here public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T get(K key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void set(K key, T x) { (*self)[key] = x; } void del(K key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(K key) { std::map::iterator i = self->find(key); return i != self->end(); } } }; %enddef // add specializations here } cableswig-0.1.0+git20150808.orig/SWIG/Lib/java/CMakeLists.txt0000644000175000000620000000035712561312227021772 0ustar stevestaffFILE(GLOB __files1 "${CMAKE_CURRENT_SOURCE_DIR}/*.i") FILE(GLOB __files2 "${CMAKE_CURRENT_SOURCE_DIR}/*.swg") INSTALL(FILES ${__files1} ${__files2} DESTINATION ${CableSwig_INSTALL_ROOT}lib/CableSwig/SWIGLib/java COMPONENT Development) cableswig-0.1.0+git20150808.orig/SWIG/Lib/java/java.swg0000644000175000000620000010264312561312227020676 0ustar stevestaff/* ----------------------------------------------------------------------------- * java.swg * * Java typemaps * ----------------------------------------------------------------------------- */ %include "javahead.swg" /* The jni, jtype and jstype typemaps work together and so there should be one of each. * The jni typemap contains the JNI type used in the JNI (C/C++) code. * The jtype typemap contains the Java type used in the JNI intermediary class. * The jstype typemap contains the Java type used in the Java proxy classes, type wrapper classes and module class. */ /* Primitive types */ %typemap(jni) bool, const bool & "jboolean" %typemap(jni) char, const char & "jchar" %typemap(jni) signed char, const signed char & "jbyte" %typemap(jni) unsigned char, const unsigned char & "jshort" %typemap(jni) short, const short & "jshort" %typemap(jni) unsigned short, const unsigned short & "jint" %typemap(jni) int, const int & "jint" %typemap(jni) unsigned int, const unsigned int & "jlong" %typemap(jni) long, const long & "jint" %typemap(jni) unsigned long, const unsigned long & "jlong" %typemap(jni) long long, const long long & "jlong" %typemap(jni) unsigned long long, const unsigned long long & "jobject" %typemap(jni) float, const float & "jfloat" %typemap(jni) double, const double & "jdouble" %typemap(jni) char * "jstring" %typemap(jni) void "void" %typemap(jtype) bool, const bool & "boolean" %typemap(jtype) char, const char & "char" %typemap(jtype) signed char, const signed char & "byte" %typemap(jtype) unsigned char, const unsigned char & "short" %typemap(jtype) short, const short & "short" %typemap(jtype) unsigned short, const unsigned short & "int" %typemap(jtype) int, const int & "int" %typemap(jtype) unsigned int, const unsigned int & "long" %typemap(jtype) long, const long & "int" %typemap(jtype) unsigned long, const unsigned long & "long" %typemap(jtype) long long, const long long & "long" %typemap(jtype) unsigned long long, const unsigned long long & "java.math.BigInteger" %typemap(jtype) float, const float & "float" %typemap(jtype) double, const double & "double" %typemap(jtype) char * "String" %typemap(jtype) void "void" %typemap(jstype) bool, const bool & "boolean" %typemap(jstype) char, const char & "char" %typemap(jstype) signed char, const signed char & "byte" %typemap(jstype) unsigned char, const unsigned char & "short" %typemap(jstype) short, const short & "short" %typemap(jstype) unsigned short, const unsigned short & "int" %typemap(jstype) int, const int & "int" %typemap(jstype) unsigned int, const unsigned int & "long" %typemap(jstype) long, const long & "int" %typemap(jstype) unsigned long, const unsigned long & "long" %typemap(jstype) long long, const long long & "long" %typemap(jstype) unsigned long long, const unsigned long long & "java.math.BigInteger" %typemap(jstype) float, const float & "float" %typemap(jstype) double, const double & "double" %typemap(jstype) char * "String" %typemap(jstype) void "void" %typemap(jni) char[ANY] "jstring" %typemap(jtype) char[ANY] "String" %typemap(jstype) char[ANY] "String" /* JNI types */ %typemap(jni) jboolean "jboolean" %typemap(jni) jchar "jchar" %typemap(jni) jbyte "jbyte" %typemap(jni) jshort "jshort" %typemap(jni) jint "jint" %typemap(jni) jlong "jlong" %typemap(jni) jfloat "jfloat" %typemap(jni) jdouble "jdouble" %typemap(jni) jstring "jstring" %typemap(jni) jobject "jobject" %typemap(jni) jbooleanArray "jbooleanArray" %typemap(jni) jcharArray "jcharArray" %typemap(jni) jbyteArray "jbyteArray" %typemap(jni) jshortArray "jshortArray" %typemap(jni) jintArray "jintArray" %typemap(jni) jlongArray "jlongArray" %typemap(jni) jfloatArray "jfloatArray" %typemap(jni) jdoubleArray "jdoubleArray" %typemap(jni) jobjectArray "jobjectArray" %typemap(jtype) jboolean "boolean" %typemap(jtype) jchar "char" %typemap(jtype) jbyte "byte" %typemap(jtype) jshort "short" %typemap(jtype) jint "int" %typemap(jtype) jlong "long" %typemap(jtype) jfloat "float" %typemap(jtype) jdouble "double" %typemap(jtype) jstring "String" %typemap(jtype) jobject "Object" %typemap(jtype) jbooleanArray "boolean[]" %typemap(jtype) jcharArray "char[]" %typemap(jtype) jbyteArray "byte[]" %typemap(jtype) jshortArray "short[]" %typemap(jtype) jintArray "int[]" %typemap(jtype) jlongArray "long[]" %typemap(jtype) jfloatArray "float[]" %typemap(jtype) jdoubleArray "double[]" %typemap(jtype) jobjectArray "Object[]" %typemap(jstype) jboolean "boolean" %typemap(jstype) jchar "char" %typemap(jstype) jbyte "byte" %typemap(jstype) jshort "short" %typemap(jstype) jint "int" %typemap(jstype) jlong "long" %typemap(jstype) jfloat "float" %typemap(jstype) jdouble "double" %typemap(jstype) jstring "String" %typemap(jstype) jobject "Object" %typemap(jstype) jbooleanArray "boolean[]" %typemap(jstype) jcharArray "char[]" %typemap(jstype) jbyteArray "byte[]" %typemap(jstype) jshortArray "short[]" %typemap(jstype) jintArray "int[]" %typemap(jstype) jlongArray "long[]" %typemap(jstype) jfloatArray "float[]" %typemap(jstype) jdoubleArray "double[]" %typemap(jstype) jobjectArray "Object[]" /* Non primitive types */ %typemap(jni) SWIGTYPE "jlong" %typemap(jtype) SWIGTYPE "long" %typemap(jstype) SWIGTYPE "$&javaclassname" %typemap(jni) SWIGTYPE [] "jlong" %typemap(jtype) SWIGTYPE [] "long" %typemap(jstype) SWIGTYPE [] "$javaclassname" %typemap(jni) SWIGTYPE * "jlong" %typemap(jtype) SWIGTYPE * "long" %typemap(jstype) SWIGTYPE * "$javaclassname" %typemap(jni) SWIGTYPE & "jlong" %typemap(jtype) SWIGTYPE & "long" %typemap(jstype) SWIGTYPE & "$javaclassname" %typemap(jni) enum SWIGTYPE "jint" %typemap(jtype) enum SWIGTYPE "int" %typemap(jstype) enum SWIGTYPE "int" /* pointer to a class member */ %typemap(jni) SWIGTYPE (CLASS::*) "jlong" %typemap(jtype) SWIGTYPE (CLASS::*) "long" %typemap(jstype) SWIGTYPE (CLASS::*) "$javaclassname" /* The following are the in, out, freearg, argout typemaps. These are the JNI code generating typemaps for converting from Java to C and visa versa. */ /* primitive types */ %typemap(in) bool %{ $1 = $input ? true : false; %} %typemap(javadirectorin) bool "$jniinput" %typemap(javadirectorout) bool "$javacall" %typemap(in) char, signed char, unsigned char, short, unsigned short, int, unsigned int, long, unsigned long, long long, float, double, enum SWIGTYPE %{ $1 = ($1_ltype)$input; %} %typemap(directorin, descriptor="Z") bool "$input = (jboolean) $1;" %typemap(directorin, descriptor="C") char "$input = (jint) $1;" %typemap(directorin, descriptor="B") signed char "$input = (jbyte) $1;" %typemap(directorin, descriptor="S") unsigned char "$input = (jshort) $1;" %typemap(directorin, descriptor="S") short "$input = (jshort) $1;" %typemap(directorin, descriptor="I") unsigned short "$input = (jint) $1;" %typemap(directorin, descriptor="I") int "$input = (jint) $1;" %typemap(directorin, descriptor="J") unsigned int "$input = (jlong) $1;" %typemap(directorin, descriptor="I") long "$input = (jint) $1;" %typemap(directorin, descriptor="J") unsigned long "$input = (jlong) $1;" %typemap(directorin, descriptor="J") long long "$input = (jlong) $1;" %typemap(directorin, descriptor="F") float "$input = (jfloat) $1;" %typemap(directorin, descriptor="D") double "$input = (jdouble) $1;" %typemap(directorin, descriptor="I") enum SWIGTYPE "$input = (jint) $1;" %typemap(javadirectorin) char, signed char, unsigned char, short, unsigned short, int, unsigned int, long, unsigned long, long long, float, double, enum SWIGTYPE "$jniinput" %typemap(javadirectorout) char, signed char, unsigned char, short, unsigned short, int, unsigned int, long, unsigned long, long long, float, double, enum SWIGTYPE "$javacall" %typemap(out) bool %{ $result = (jboolean)$1; %} %typemap(out) char %{ $result = (jchar)$1; %} %typemap(out) signed char %{ $result = (jbyte)$1; %} %typemap(out) unsigned char %{ $result = (jshort)$1; %} %typemap(out) short %{ $result = (jshort)$1; %} %typemap(out) unsigned short %{ $result = (jint)$1; %} %typemap(out) int %{ $result = (jint)$1; %} %typemap(out) unsigned int %{ $result = (jlong)$1; %} %typemap(out) long %{ $result = (jint)$1; %} %typemap(out) unsigned long %{ $result = (jlong)$1; %} %typemap(out) long long %{ $result = (jlong)$1; %} %typemap(out) float %{ $result = (jfloat)$1; %} %typemap(out) double %{ $result = (jdouble)$1; %} %typemap(out) enum SWIGTYPE %{ $result = (jint)$1; %} /* unsigned long long */ /* Convert from BigInteger using the toByteArray member function */ %typemap(in) unsigned long long { jclass clazz; jmethodID mid; jbyteArray ba; jbyte* bae; jsize sz; int i; if (!$input) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "BigInteger null"); return $null; } clazz = JCALL1(GetObjectClass, jenv, $input); mid = JCALL3(GetMethodID, jenv, clazz, "toByteArray", "()[B"); ba = (jbyteArray)JCALL2(CallObjectMethod, jenv, $input, mid); bae = JCALL2(GetByteArrayElements, jenv, ba, 0); sz = JCALL1(GetArrayLength, jenv, ba); $1 = 0; if (bae[0] == 0) { for(i=sz-1; i>0; i-- ) { $1 = ($1 << 8) | (unsigned char)bae[sz-i]; } } else { for(i=sz; i>=0; i-- ) { $1 = ($1 << 8) | (unsigned char)bae[sz-1-i]; } } JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); } /* Convert to BigInteger - byte array holds number in 2's complement big endian format */ %typemap(out) unsigned long long { jbyteArray ba = JCALL1(NewByteArray, jenv, 9); jbyte* bae = JCALL2(GetByteArrayElements, jenv, ba, 0); jclass clazz = JCALL1(FindClass, jenv, "java/math/BigInteger"); jmethodID mid = JCALL3(GetMethodID, jenv, clazz, "", "([B)V"); jobject bigint; int i; bae[0] = 0; for(i=1; i<9; i++ ) { bae[i] = (jbyte)($1>>8*(8-i)); } JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); bigint = JCALL3(NewObject, jenv, clazz, mid, ba); $result = bigint; } /* Convert to BigInteger (see out typemap) */ %typemap(directorin, descriptor="Ljava/math/Biginteger;") unsigned long long, const unsigned long long & { jbyteArray ba = JCALL1(NewByteArray, jenv, 9); jbyte* bae = JCALL2(GetByteArrayElements, jenv, ba, 0); jclass clazz = JCALL1(FindClass, jenv, "java/math/BigInteger"); jmethodID mid = JCALL3(GetMethodID, jenv, clazz, "", "([B)V"); jobject bigint; int i; bae[0] = 0; for(i=1; i<9; i++ ) { bae[i] = (jbyte)($1>>8*(8-i)); } JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); bigint = JCALL3(NewObject, jenv, clazz, mid, ba); $input = bigint; } %typemap(javadirectorin) unsigned long long "$jniinput" %typemap(javadirectorout) unsigned long long "$javacall" /* char * - treat as String */ %typemap(in) char * { $1 = 0; if ($input) { $1 = ($1_ltype)JCALL2(GetStringUTFChars, jenv, $input, 0); if (!$1) return $null; } } %typemap(directorin, descriptor="Ljava/lang/String;") char * { $input = 0; if ($1) { $input = JCALL1(NewStringUTF, jenv, $1); if (!$input) return $null; } } %typemap(freearg) char * { if ($1) JCALL2(ReleaseStringUTFChars, jenv, $input, $1); } %typemap(out) char * { if($1) $result = JCALL1(NewStringUTF, jenv, $1); } %typemap(javadirectorin) char * "$jniinput" %typemap(javadirectorout) char * "$javacall" %typemap(out) void "" %typemap(javadirectorin) void "$jniinput" %typemap(javadirectorout) void "$javacall" %typemap(directorin, descriptor="V") void "" /* primitive types by reference */ %typemap(in) const bool & (bool temp) %{ temp = $input ? true : false; $1 = &temp; %} %typemap(javadirectorin) const bool & "$jniinput" %typemap(javadirectorout) const bool & "$javacall" %typemap(in) const char & (char temp), const signed char & (signed char temp), const unsigned char & (unsigned char temp), const short & (short temp), const unsigned short & (unsigned short temp), const int & (int temp), const unsigned int & (unsigned int temp), const long & (long temp), const unsigned long & (unsigned long temp), const long long & ($*1_ltype temp), const float & (float temp), const double & (double temp) %{ temp = ($*1_ltype)$input; $1 = &temp; %} %typemap(directorin, descriptor="Z") const bool & "$input = (jboolean)$1_name;" %typemap(directorin, descriptor="C") const char & "$input = (jchar)$1_name;" %typemap(directorin, descriptor="B") const signed char & "$input = (jbyte)$1_name;" %typemap(directorin, descriptor="S") const unsigned char & "$input = (jshort)$1_name;" %typemap(directorin, descriptor="S") const short & "$input = (jshort)$1_name;" %typemap(directorin, descriptor="I") const unsigned short & "$input = (jint)$1_name;" %typemap(directorin, descriptor="I") const int & "$input = (jint)$1_name;" %typemap(directorin, descriptor="J") const unsigned int & "$input = (jlong)$1_name;" %typemap(directorin, descriptor="I") const long & "$input = (jint)$1_name;" %typemap(directorin, descriptor="J") const unsigned long & "$input = (jlong)$1_name;" %typemap(directorin, descriptor="J") const long long & "$input = (jlong)$1_name;" %typemap(directorin, descriptor="F") const float & "$input = (jfloat)$1_name;" %typemap(directorin, descriptor="D") const double & "$input = (jdouble)$1_name;" %typemap(javadirectorin) const char & (char temp), const signed char & (signed char temp), const unsigned char & (unsigned char temp), const short & (short temp), const unsigned short & (unsigned short temp), const int & (int temp), const unsigned int & (unsigned int temp), const long & (long temp), const unsigned long & (unsigned long temp), const long long & ($*1_ltype temp), const float & (float temp), const double & (double temp) "$jniinput" %typemap(javadirectorout) const char & (char temp), const signed char & (signed char temp), const unsigned char & (unsigned char temp), const short & (short temp), const unsigned short & (unsigned short temp), const int & (int temp), const unsigned int & (unsigned int temp), const long & (long temp), const unsigned long & (unsigned long temp), const long long & ($*1_ltype temp), const float & (float temp), const double & (double temp) "$javacall" %typemap(out) const bool & %{ $result = (jboolean)*$1; %} %typemap(out) const char & %{ $result = (jchar)*$1; %} %typemap(out) const signed char & %{ $result = (jbyte)*$1; %} %typemap(out) const unsigned char & %{ $result = (jshort)*$1; %} %typemap(out) const short & %{ $result = (jshort)*$1; %} %typemap(out) const unsigned short & %{ $result = (jint)*$1; %} %typemap(out) const int & %{ $result = (jint)*$1; %} %typemap(out) const unsigned int & %{ $result = (jlong)*$1; %} %typemap(out) const long & %{ $result = (jint)*$1; %} %typemap(out) const unsigned long & %{ $result = (jlong)*$1; %} %typemap(out) const long long & %{ $result = (jlong)*$1; %} %typemap(out) const float & %{ $result = (jfloat)*$1; %} %typemap(out) const double & %{ $result = (jdouble)*$1; %} /* const unsigned long long & */ /* Similar to unsigned long long */ %typemap(in) const unsigned long long & ($*1_ltype temp) { jclass clazz; jmethodID mid; jbyteArray ba; jbyte* bae; jsize sz; int i; if (!$input) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "BigInteger null"); return $null; } clazz = JCALL1(GetObjectClass, jenv, $input); mid = JCALL3(GetMethodID, jenv, clazz, "toByteArray", "()[B"); ba = (jbyteArray)JCALL2(CallObjectMethod, jenv, $input, mid); bae = JCALL2(GetByteArrayElements, jenv, ba, 0); sz = JCALL1(GetArrayLength, jenv, ba); $1 = &temp; temp = 0; if (bae[0] == 0) { for(i=sz-1; i>0; i-- ) { temp = (temp << 8) | (unsigned char)bae[sz-i]; } } else { for(i=sz; i>=0; i-- ) { temp = (temp << 8) | (unsigned char)bae[sz-1-i]; } } JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); } %typemap(out) const unsigned long long & { jbyteArray ba = JCALL1(NewByteArray, jenv, 9); jbyte* bae = JCALL2(GetByteArrayElements, jenv, ba, 0); jclass clazz = JCALL1(FindClass, jenv, "java/math/BigInteger"); jmethodID mid = JCALL3(GetMethodID, jenv, clazz, "", "([B)V"); jobject bigint; int i; bae[0] = 0; for(i=1; i<9; i++ ) { bae[i] = (jbyte)(*$1>>8*(8-i)); } JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); bigint = JCALL3(NewObject, jenv, clazz, mid, ba); $result = bigint; } %typemap(javadirectorin) const unsigned long long & "$jniinput" %typemap(javadirectorout) const unsigned long long & "$javacall" /* Default handling. Object passed by value. Convert to a pointer */ %typemap(in) SWIGTYPE ($&1_type argp) %{ argp = *($&1_ltype*)&$input; if (!argp) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Attempt to dereference null $1_type"); return $null; } $1 = *argp; %} %typemap(out) SWIGTYPE #ifdef __cplusplus %{*($&1_ltype*)&$result = new $1_ltype(($1_ltype &)$1); %} #else { $&1_ltype $1ptr = ($&1_ltype) malloc(sizeof($1_ltype)); memmove($1ptr, &$1, sizeof($1_type)); *($&1_ltype*)&$result = $1ptr; } #endif %typemap(directorin,descriptor="L$packagepath/$javaclassname;") SWIGTYPE "*(($&1_type)&$input) = &$1;" %typemap(javadirectorin) SWIGTYPE "new $javaclassname($jniinput, false)" %typemap(javadirectorout) SWIGTYPE "$javaclassname.getCPtr($javacall)" /* Generic pointers and references */ %typemap(in) SWIGTYPE *, SWIGTYPE (CLASS::*) %{ $1 = *($&1_ltype)&$input; %} %typemap(in) SWIGTYPE & %{ $1 = *($&1_ltype)&$input; if(!$1) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "$1_type reference is null"); return $null; } %} %typemap(out) SWIGTYPE *, SWIGTYPE (CLASS::*) %{ *($&1_ltype)&$result = $1; %} %typemap(out) SWIGTYPE & %{ *($&1_ltype)&$result = $1; %} %typemap(directorin,descriptor="L$packagepath/$javaclassname;") SWIGTYPE *, SWIGTYPE (CLASS::*) %{ *(($&1_ltype)&$input) = ($1_ltype) $1; %} %typemap(directorin,descriptor="L$packagepath/$javaclassname;") SWIGTYPE & %{ *($&1_ltype)&$input = ($1_ltype) &$1; %} %typemap(javadirectorin) SWIGTYPE *, SWIGTYPE (CLASS::*), SWIGTYPE &, const SWIGTYPE & "new $javaclassname($jniinput, false)" %typemap(javadirectorout) SWIGTYPE *, SWIGTYPE (CLASS::*), SWIGTYPE &, const SWIGTYPE & "$javaclassname.getCPtr($javacall)" /* Default array handling */ %typemap(in) SWIGTYPE [] %{ $1 = *($&1_ltype)&$input; %} %typemap(out) SWIGTYPE [] %{ *($&1_ltype)&$result = $1; %} /* char[ANY] - treat as String */ %typemap(in) char[ANY] { $1 = 0; if ($input) { $1 = ($1_ltype)JCALL2(GetStringUTFChars, jenv, $input, 0); if (!$1) return $null; } } %typemap(directorin,descriptor="Ljava/lang/String;") char[ANY] "$input = JCALL1(NewStringUTF, jenv, $1_name);" %typemap(argout) char[ANY] "" %typemap(freearg) char[ANY] { if ($1) JCALL2(ReleaseStringUTFChars, jenv, $input, $1); } %typemap(out) char[ANY] { if($1) $result = JCALL1(NewStringUTF, jenv, $1); } %typemap(javadirectorin) char[ANY] "$jniinput" %typemap(javadirectorout) char[ANY] "$javacall" /* JNI types */ %typemap(in) jboolean, jchar, jbyte, jshort, jint, jlong, jfloat, jdouble, jstring, jobject, jbooleanArray, jcharArray, jbyteArray, jshortArray, jintArray, jlongArray, jfloatArray, jdoubleArray, jobjectArray %{ $1 = $input; %} %typemap(out) jboolean, jchar, jbyte, jshort, jint, jlong, jfloat, jdouble, jstring, jobject, jbooleanArray, jcharArray, jbyteArray, jshortArray, jintArray, jlongArray, jfloatArray, jdoubleArray, jobjectArray %{ $result = $1; %} %typemap(directorin,descriptor="Z") jboolean "$input = $1;" %typemap(directorin,descriptor="C") jchar "$input = $1;" %typemap(directorin,descriptor="B") jbyte "$input = $1;" %typemap(directorin,descriptor="S") jshort "$input = $1;" %typemap(directorin,descriptor="I") jint "$input = $1;" %typemap(directorin,descriptor="J") jlong "$input = $1;" %typemap(directorin,descriptor="F") jfloat "$input = $1;" %typemap(directorin,descriptor="D") jdouble "$input = $1;" %typemap(directorin,descriptor="Ljava/lang/String;") jstring "$input = $1;" %typemap(directorin,descriptor="Ljava/lang/Object;") jobject "$input = $1;" %typemap(directorin,descriptor="[Z") jbooleanArray "$input = $1;" %typemap(directorin,descriptor="[C") jcharArray "$input = $1;" %typemap(directorin,descriptor="[B") jbyteArray "$input = $1;" %typemap(directorin,descriptor="[S") jshortArray "$input = $1;" %typemap(directorin,descriptor="[I") jintArray "$input = $1;" %typemap(directorin,descriptor="[J") jlongArray "$input = $1;" %typemap(directorin,descriptor="[F") jfloatArray "$input = $1;" %typemap(directorin,descriptor="[D") jdoubleArray "$input = $1;" %typemap(directorin,descriptor="[Ljava/lang/Object;") jobjectArray "$input = $1;" %typemap(javadirectorin) jboolean, jchar, jbyte, jshort, jint, jlong, jfloat, jdouble, jstring, jobject, jbooleanArray, jcharArray, jbyteArray, jshortArray, jintArray, jlongArray, jfloatArray, jdoubleArray, jobjectArray "$jniinput" %typemap(javadirectorout) jboolean, jchar, jbyte, jshort, jint, jlong, jfloat, jdouble, jstring, jobject, jbooleanArray, jcharArray, jbyteArray, jshortArray, jintArray, jlongArray, jfloatArray, jdoubleArray, jobjectArray "$javacall" /* Typecheck typemaps - The purpose of these is merely to issue a warning for overloaded C++ functions * that cannot be overloaded in Java as more than one C++ type maps to a single Java type */ %typecheck(SWIG_TYPECHECK_BOOL) /* Java boolean */ jboolean, bool, const bool & "" %typecheck(SWIG_TYPECHECK_CHAR) /* Java char */ jchar, char, const char & "" %typecheck(SWIG_TYPECHECK_INT8) /* Java byte */ jbyte, signed char, const signed char & "" %typecheck(SWIG_TYPECHECK_INT16) /* Java short */ jshort, unsigned char, short, const unsigned char &, const short & "" %typecheck(SWIG_TYPECHECK_INT32) /* Java int */ jint, unsigned short, int, long, const unsigned short &, const int &, const long &, enum SWIGTYPE "" %typecheck(SWIG_TYPECHECK_INT64) /* Java long */ jlong, unsigned int, unsigned long, long long, const unsigned int &, const unsigned long &, const long long & "" %typecheck(SWIG_TYPECHECK_INT128) /* Java BigInteger */ unsigned long long "" %typecheck(SWIG_TYPECHECK_FLOAT) /* Java float */ jfloat, float, const float & "" %typecheck(SWIG_TYPECHECK_DOUBLE) /* Java double */ jdouble, double, const double & "" %typecheck(SWIG_TYPECHECK_STRING) /* Java String */ jstring, char *, char[ANY] "" %typecheck(SWIG_TYPECHECK_BOOL_ARRAY) /* Java boolean[] */ jbooleanArray "" %typecheck(SWIG_TYPECHECK_CHAR_ARRAY) /* Java char[] */ jcharArray "" %typecheck(SWIG_TYPECHECK_INT8_ARRAY) /* Java byte[] */ jbyteArray "" %typecheck(SWIG_TYPECHECK_INT16_ARRAY) /* Java short[] */ jshortArray "" %typecheck(SWIG_TYPECHECK_INT32_ARRAY) /* Java int[] */ jintArray "" %typecheck(SWIG_TYPECHECK_INT64_ARRAY) /* Java long[] */ jlongArray "" %typecheck(SWIG_TYPECHECK_FLOAT_ARRAY) /* Java float[] */ jfloatArray "" %typecheck(SWIG_TYPECHECK_DOUBLE_ARRAY) /* Java double[] */ jdoubleArray "" %typecheck(SWIG_TYPECHECK_OBJECT_ARRAY) /* Java jobject[] */ jobjectArray "" %typecheck(SWIG_TYPECHECK_POINTER) /* Default */ SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "" /* Exception handling */ %typemap(throws) int, long, short, unsigned int, unsigned long, unsigned short { char error_msg[256]; sprintf(error_msg, "C++ $1_type exception thrown, value: %d", $1); SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, error_msg); return $null; } %typemap(throws) SWIGTYPE { SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, "C++ $1_type exception thrown"); return $null; } %typemap(throws) char * { SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, $1); return $null; } /* Typemaps for code generation in proxy classes and Java type wrapper classes */ /* The javain typemap is used for converting function parameter types from the type * used in the proxy, module or type wrapper class to the type used in the JNI class. */ %typemap(javain) bool, const bool &, char, const char &, signed char, const signed char &, unsigned char, const unsigned char &, short, const short &, unsigned short, const unsigned short &, int, const int &, unsigned int, const unsigned int &, long, const long &, unsigned long, const unsigned long &, long long, const long long &, unsigned long long, const unsigned long long &, float, const float &, double, const double &, char *, char[ANY], enum SWIGTYPE "$javainput" %typemap(javain) jboolean, jchar, jbyte, jshort, jint, jlong, jfloat, jdouble, jstring, jobject, jbooleanArray, jcharArray, jbyteArray, jshortArray, jintArray, jlongArray, jfloatArray, jdoubleArray, jobjectArray "$javainput" %typemap(javain) SWIGTYPE "$&javaclassname.getCPtr($javainput)" %typemap(javain) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "$javaclassname.getCPtr($javainput)" /* The javaout typemap is used for converting function return types from the return type * used in the JNI class to the type returned by the proxy, module or type wrapper class. */ %typemap(javaout) bool, const bool &, char, const char &, signed char, const signed char &, unsigned char, const unsigned char &, short, const short &, unsigned short, const unsigned short &, int, const int &, unsigned int, const unsigned int &, long, const long &, unsigned long, const unsigned long &, long long, const long long &, unsigned long long, const unsigned long long &, float, const float &, double, const double &, char *, char[ANY], enum SWIGTYPE { return $jnicall; } %typemap(javaout) jboolean, jchar, jbyte, jshort, jint, jlong, jfloat, jdouble, jstring, jobject, jbooleanArray, jcharArray, jbyteArray, jshortArray, jintArray, jlongArray, jfloatArray, jdoubleArray, jobjectArray { return $jnicall; } %typemap(javaout) void { $jnicall; } %typemap(javaout) SWIGTYPE { return new $&javaclassname($jnicall, true); } %typemap(javaout) SWIGTYPE & { return new $javaclassname($jnicall, $owner); } %typemap(javaout) SWIGTYPE *, SWIGTYPE [], SWIGTYPE (CLASS::*) { long cPtr = $jnicall; return (cPtr == 0) ? null : new $javaclassname(cPtr, $owner); } /* Typemaps used for the generation of proxy and type wrapper class code */ %typemap(javabase) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "" %typemap(javaclassmodifiers) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "public" %typemap(javacode) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "" %typemap(javaimports) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "" %typemap(javainterfaces) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "" %typemap(javaptrconstructormodifiers) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "protected" %typemap(javafinalize) SWIGTYPE %{ protected void finalize() { delete(); } %} %typemap(javadestruct, methodname="delete") SWIGTYPE { if(swigCPtr != 0 && swigCMemOwn) { swigCMemOwn = false; $jnicall; } swigCPtr = 0; } %typemap(javadestruct_derived, methodname="delete") SWIGTYPE { if(swigCPtr != 0 && swigCMemOwn) { swigCMemOwn = false; $jnicall; } swigCPtr = 0; super.delete(); } %typemap(javagetcptr) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) %{ protected static long getCPtr($javaclassname obj) { return (obj == null) ? 0 : obj.swigCPtr; } %} /* Java specific directives */ #define %javaconst(flag) %feature("java:const","flag") #define %javamethodmodifiers %feature("java:methodmodifiers") /* Some ANSI C typemaps */ %apply long { size_t }; /* java keywords */ /* please test and activate */ //%include "javakw.swg" cableswig-0.1.0+git20150808.orig/SWIG/Lib/java/std_common.i0000644000175000000620000000021412561312227021536 0ustar stevestaff// // SWIG typemaps for STL - common utilities // Luigi Ballabio // Aug 17, 2003 // // Java implementation %apply size_t { std::size_t }; cableswig-0.1.0+git20150808.orig/SWIG/Lib/java/typemaps.i0000644000175000000620000004073612561312227021253 0ustar stevestaff// // SWIG Typemap library // William Fulton // 4 January 2002 // // Java implementation // // ------------------------------------------------------------------------ // Pointer and reference handling // // These mappings provide support for input/output arguments and common // uses for C/C++ pointers and C++ references. // ------------------------------------------------------------------------ // INPUT typemaps. // These remap a C pointer or C++ reference to be an "INPUT" value which is passed by value // instead of reference. /* The following methods can be applied to turn a pointer or reference into a simple "input" value. That is, instead of passing a pointer or reference to an object, you would use a real value instead. bool *INPUT, bool &INPUT signed char *INPUT, signed char &INPUT unsigned char *INPUT, unsigned char &INPUT short *INPUT, short &INPUT unsigned short *INPUT, unsigned short &INPUT int *INPUT, int &INPUT unsigned int *INPUT, unsigned int &INPUT long *INPUT, long &INPUT unsigned long *INPUT, unsigned long &INPUT long long *INPUT, long long &INPUT unsigned long long *INPUT, unsigned long long &INPUT float *INPUT, float &INPUT double *INPUT, double &INPUT To use these, suppose you had a C function like this : double fadd(double *a, double *b) { return *a+*b; } You could wrap it with SWIG as follows : %include typemaps.i double fadd(double *INPUT, double *INPUT); or you can use the %apply directive : %include typemaps.i %apply double *INPUT { double *a, double *b }; double fadd(double *a, double *b); In Java you could then use it like this: double answer = modulename.fadd(10.0, 20.0); */ %define INPUT_TYPEMAP(CTYPE, JNITYPE, JTYPE, JNIDESC) %typemap(jni) CTYPE *INPUT "JNITYPE" %typemap(jtype) CTYPE *INPUT "JTYPE" %typemap(jstype) CTYPE *INPUT "JTYPE" %typemap(javain) CTYPE *INPUT "$javainput" %typemap(javadirectorin) CTYPE *INPUT "$jniinput" %typemap(javadirectorout) CTYPE *INPUT "$javacall" %typemap(jni) CTYPE &INPUT "JNITYPE" %typemap(jtype) CTYPE &INPUT "JTYPE" %typemap(jstype) CTYPE &INPUT "JTYPE" %typemap(javain) CTYPE &INPUT "$javainput" %typemap(javadirectorin) CTYPE *INPUT "$jniinput" %typemap(javadirectorout) CTYPE *INPUT "$javacall" %typemap(in) CTYPE *INPUT, CTYPE &INPUT %{ $1 = ($1_ltype)&$input; %} %typemap(directorin,descriptor=JNIDESC) CYTPE &INPUT %{ *(($&1_ltype) $input) = (JNITYPE *) &$1; %} %typemap(directorin,descriptor=JNIDESC) CTYPE *INPUT %{ *(($&1_ltype) $input) = (JNITYPE *) $1; %} %typemap(typecheck) CTYPE *INPUT = CTYPE; %typemap(typecheck) CTYPE &INPUT = CTYPE; %enddef INPUT_TYPEMAP(bool, jboolean, boolean, "Z"); INPUT_TYPEMAP(signed char, jbyte, byte, "B"); INPUT_TYPEMAP(unsigned char, jshort, short, "S"); INPUT_TYPEMAP(short, jshort, short, "S"); INPUT_TYPEMAP(unsigned short, jint, int, "I"); INPUT_TYPEMAP(int, jint, int, "I"); INPUT_TYPEMAP(unsigned int, jlong, long, "J"); INPUT_TYPEMAP(long, jint, int, "I"); INPUT_TYPEMAP(unsigned long, jlong, long, "J"); INPUT_TYPEMAP(long long, jlong, long, "J"); INPUT_TYPEMAP(unsigned long long, jobject, java.math.BigInteger, "Ljava/math/BigInteger;"); INPUT_TYPEMAP(float, jfloat, float, "F"); INPUT_TYPEMAP(double, jdouble, double, "D"); #undef INPUT_TYPEMAP /* Convert from BigInteger using the toByteArray member function */ /* Overrides the typemap in the INPUT_TYPEMAP macro */ %typemap(in) unsigned long long *INPUT($*1_ltype temp), unsigned long long &INPUT($*1_ltype temp) { jclass clazz; jmethodID mid; jbyteArray ba; jbyte* bae; jsize sz; int i; if (!$input) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "BigInteger null"); return $null; } clazz = JCALL1(GetObjectClass, jenv, $input); mid = JCALL3(GetMethodID, jenv, clazz, "toByteArray", "()[B"); ba = (jbyteArray)JCALL2(CallObjectMethod, jenv, $input, mid); bae = JCALL2(GetByteArrayElements, jenv, ba, 0); sz = JCALL1(GetArrayLength, jenv, ba); temp = 0; if (bae[0] == 0) { for(i=sz-1; i>0; i-- ) { temp = (temp << 8) | (unsigned char)bae[sz-i]; } } else { for(i=sz; i>=0; i-- ) { temp = (temp << 8) | (unsigned char)bae[sz-1-i]; } } JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); $1 = &temp; } // OUTPUT typemaps. These typemaps are used for parameters that // are output only. An array replaces the c pointer or reference parameter. // The output value is returned in this array passed in. /* The following methods can be applied to turn a pointer or reference into an "output" value. When calling a function, no input value would be given for a parameter, but an output value would be returned. This works by a Java array being passed as a parameter where a c pointer or reference is required. As with any Java function, the array is passed by reference so that any modifications to the array will be picked up in the calling function. Note that the array passed in MUST have at least one element, but as the c function does not require any input, the value can be set to anything. bool *OUTPUT, bool &OUTPUT signed char *OUTPUT, signed char &OUTPUT unsigned char *OUTPUT, unsigned char &OUTPUT short *OUTPUT, short &OUTPUT unsigned short *OUTPUT, unsigned short &OUTPUT int *OUTPUT, int &OUTPUT unsigned int *OUTPUT, unsigned int &OUTPUT long *OUTPUT, long &OUTPUT unsigned long *OUTPUT, unsigned long &OUTPUT long long *OUTPUT, long long &OUTPUT unsigned long long *OUTPUT, unsigned long long &OUTPUT float *OUTPUT, float &OUTPUT double *OUTPUT, double &OUTPUT For example, suppose you were trying to wrap the modf() function in the C math library which splits x into integral and fractional parts (and returns the integer part in one of its parameters): double modf(double x, double *ip); You could wrap it with SWIG as follows : %include typemaps.i double modf(double x, double *OUTPUT); or you can use the %apply directive : %include typemaps.i %apply double *OUTPUT { double *ip }; double modf(double x, double *ip); The Java output of the function would be the function return value and the value in the single element array. In Java you would use it like this: double[] intptr = {0}; double fraction = modulename.modf(5,intptr); */ /* Java BigInteger[] */ %typecheck(SWIG_TYPECHECK_INT128_ARRAY) SWIGBIGINTEGERARRAY "" %define OUTPUT_TYPEMAP(CTYPE, JNITYPE, JTYPE, JAVATYPE, JNIDESC, TYPECHECKTYPE) %typemap(jni) CTYPE *OUTPUT %{JNITYPE##Array%} %typemap(jtype) CTYPE *OUTPUT "JTYPE[]" %typemap(jstype) CTYPE *OUTPUT "JTYPE[]" %typemap(javain) CTYPE *OUTPUT "$javainput" %typemap(javadirectorin) CTYPE *OUTPUT "$jniinput" %typemap(javadirectorout) CTYPE *OUTPUT "$javacall" %typemap(jni) CTYPE &OUTPUT %{JNITYPE##Array%} %typemap(jtype) CTYPE &OUTPUT "JTYPE[]" %typemap(jstype) CTYPE &OUTPUT "JTYPE[]" %typemap(javain) CTYPE &OUTPUT "$javainput" %typemap(javadirectorin) CTYPE &OUTPUT "$jniinput" %typemap(javadirectorout) CTYPE &OUTPUT "$javacall" %typemap(in) CTYPE *OUTPUT($*1_ltype temp), CTYPE &OUTPUT($*1_ltype temp) { if (!$input) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); return $null; } if (JCALL1(GetArrayLength, jenv, $input) == 0) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); return $null; } $1 = &temp; } %typemap(directorin,descriptor=JNIDESC) CTYPE &OUTPUT %{ *(($&1_ltype) $input = &$1; %} %typemap(directorin,descriptor=JNIDESC) CTYPE *OUTPUT %{ #error "Need to provide OUT directorin typemap, CTYPE array length is unknown" %} %typemap(argout) CTYPE *OUTPUT, CTYPE &OUTPUT { JNITYPE jvalue = (JNITYPE)temp$argnum; JCALL4(Set##JAVATYPE##ArrayRegion, jenv, $input, 0, 1, &jvalue); } %typemap(typecheck) CTYPE *INOUT = TYPECHECKTYPE; %typemap(typecheck) CTYPE &INOUT = TYPECHECKTYPE; %enddef OUTPUT_TYPEMAP(bool, jboolean, boolean, Boolean, "[Ljava/lang/Boolean;", jbooleanArray); OUTPUT_TYPEMAP(signed char, jbyte, byte, Byte, "[Ljava/lang/Byte;", jbyteArray); OUTPUT_TYPEMAP(unsigned char, jshort, short, Short, "[Ljava/lang/Short;", jshortArray); OUTPUT_TYPEMAP(short, jshort, short, Short, "[Ljava/lang/Short;", jshortArray); OUTPUT_TYPEMAP(unsigned short, jint, int, Int, "[Ljava/lang/Integer;", jintArray); OUTPUT_TYPEMAP(int, jint, int, Int, "[Ljava/lang/Integer;", jintArray); OUTPUT_TYPEMAP(unsigned int, jlong, long, Long, "[Ljava/lang/Long;", jlongArray); OUTPUT_TYPEMAP(long, jint, int, Int, "[Ljava/lang/Integer;", jintArray); OUTPUT_TYPEMAP(unsigned long, jlong, long, Long, "[Ljava/lang/Long;", jlongArray); OUTPUT_TYPEMAP(long long, jlong, long, Long, "[Ljava/lang/Long;", jlongArray); OUTPUT_TYPEMAP(unsigned long long, jobject, java.math.BigInteger, NOTUSED, "[Ljava/lang/BigInteger;", SWIGBIGINTEGERARRAY); OUTPUT_TYPEMAP(float, jfloat, float, Float, "[Ljava/lang/Float;", jfloatArray); OUTPUT_TYPEMAP(double, jdouble, double, Double, "[Ljava/lang/Double;", jdoubleArray); #undef OUTPUT_TYPEMAP /* Convert to BigInteger - byte array holds number in 2's complement big endian format */ /* Use first element in BigInteger array for output */ /* Overrides the typemap in the OUTPUT_TYPEMAP macro */ %typemap(argout) unsigned long long *OUTPUT, unsigned long long &OUTPUT { jbyteArray ba = JCALL1(NewByteArray, jenv, 9); jbyte* bae = JCALL2(GetByteArrayElements, jenv, ba, 0); jclass clazz = JCALL1(FindClass, jenv, "java/math/BigInteger"); jmethodID mid = JCALL3(GetMethodID, jenv, clazz, "", "([B)V"); jobject bigint; int i; bae[0] = 0; for(i=1; i<9; i++ ) { bae[i] = (jbyte)(temp$argnum>>8*(8-i)); } JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); bigint = JCALL3(NewObject, jenv, clazz, mid, ba); JCALL3(SetObjectArrayElement, jenv, $input, 0, bigint); } // INOUT // Mappings for an argument that is both an input and output // parameter /* The following methods can be applied to make a function parameter both an input and output value. This combines the behavior of both the "INPUT" and "OUTPUT" methods described earlier. Output values are returned as an element in a Java array. bool *INOUT, bool &INOUT signed char *INOUT, signed char &INOUT unsigned char *INOUT, unsigned char &INOUT short *INOUT, short &INOUT unsigned short *INOUT, unsigned short &INOUT int *INOUT, int &INOUT unsigned int *INOUT, unsigned int &INOUT long *INOUT, long &INOUT unsigned long *INOUT, unsigned long &INOUT long long *INOUT, long long &INOUT unsigned long long *INOUT, unsigned long long &INOUT float *INOUT, float &INOUT double *INOUT, double &INOUT For example, suppose you were trying to wrap the following function : void neg(double *x) { *x = -(*x); } You could wrap it with SWIG as follows : %include typemaps.i void neg(double *INOUT); or you can use the %apply directive : %include typemaps.i %apply double *INOUT { double *x }; void neg(double *x); This works similarly to C in that the mapping directly modifies the input value - the input must be an array with a minimum of one element. The element in the array is the input and the output is the element in the array. double x[] = {5}; neg(x); The implementation of the OUTPUT and INOUT typemaps is different to other languages in that other languages will return the output value as part of the function return value. This difference is due to Java being a typed language. */ %define INOUT_TYPEMAP(CTYPE, JNITYPE, JTYPE, JAVATYPE, JNIDESC, TYPECHECKTYPE) %typemap(jni) CTYPE *INOUT %{JNITYPE##Array%} %typemap(jtype) CTYPE *INOUT "JTYPE[]" %typemap(jstype) CTYPE *INOUT "JTYPE[]" %typemap(javain) CTYPE *INOUT "$javainput" %typemap(javadirectorin) CTYPE *INOUT "$jniinput" %typemap(javadirectorout) CTYPE *INOUT "$javacall" %typemap(jni) CTYPE &INOUT %{JNITYPE##Array%} %typemap(jtype) CTYPE &INOUT "JTYPE[]" %typemap(jstype) CTYPE &INOUT "JTYPE[]" %typemap(javain) CTYPE &INOUT "$javainput" %typemap(javadirectorin) CTYPE &INOUT "$jniinput" %typemap(javadirectorout) CTYPE &INOUT "$javacall" %typemap(in) CTYPE *INOUT, CTYPE &INOUT { if (!$input) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); return $null; } if (JCALL1(GetArrayLength, jenv, $input) == 0) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); return $null; } $1 = ($1_ltype) JCALL2(Get##JAVATYPE##ArrayElements, jenv, $input, 0); } %typemap(directorin,descriptor=JNIDESC) CTYPE &INOUT %{ *(($&1_ltype)&$input) = &$1; %} %typemap(directorin,descriptor=JNIDESC) CTYPE *INOUT, CTYPE &INOUT { #error "Need to provide INOUT directorin typemap, CTYPE array length is unknown" } %typemap(argout) CTYPE *INOUT, CTYPE &INOUT { JCALL3(Release##JAVATYPE##ArrayElements, jenv, $input, (JNITYPE *)$1, 0); } %typemap(typecheck) CTYPE *INOUT = TYPECHECKTYPE; %typemap(typecheck) CTYPE &INOUT = TYPECHECKTYPE; %enddef INOUT_TYPEMAP(bool, jboolean, boolean, Boolean, "[Ljava/lang/Boolean;", jbooleanArray); INOUT_TYPEMAP(signed char, jbyte, byte, Byte, "[Ljava/lang/Byte;", jbyteArray); INOUT_TYPEMAP(unsigned char, jshort, short, Short, "[Ljava/lang/Short;", jshortArray); INOUT_TYPEMAP(short, jshort, short, Short, "[Ljava/lang/Short;", jshortArray); INOUT_TYPEMAP(unsigned short, jint, int, Int, "[Ljava/lang/Integer;", jintArray); INOUT_TYPEMAP(int, jint, int, Int, "[Ljava/lang/Integer;", jintArray); INOUT_TYPEMAP(unsigned int, jlong, long, Long, "[Ljava/lang/Long;", jlongArray); INOUT_TYPEMAP(long, jint, int, Int, "[Ljava/lang/Integer;", jintArray); INOUT_TYPEMAP(unsigned long, jlong, long, Long, "[Ljava/lang/Long;", jlongArray); INOUT_TYPEMAP(long long, jlong, long, Long, "[Ljava/lang/Long;", jlongArray); INOUT_TYPEMAP(unsigned long long, jobject, java.math.BigInteger, NOTUSED, "[Ljava.math.BigInteger;", SWIGBIGINTEGERARRAY); INOUT_TYPEMAP(float, jfloat, float, Float, "[Ljava/lang/Float;", jfloatArray); INOUT_TYPEMAP(double, jdouble, double, Double, "[Ljava/lang/Double;", jdoubleArray); #undef INOUT_TYPEMAP /* Override the typemap in the INOUT_TYPEMAP macro */ %typemap(in) unsigned long long *INOUT ($*1_ltype temp), unsigned long long &INOUT ($*1_ltype temp) { jobject bigint; jclass clazz; jmethodID mid; jbyteArray ba; jbyte* bae; jsize sz; int i; if (!$input) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array null"); return $null; } if (JCALL1(GetArrayLength, jenv, $input) == 0) { SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "Array must contain at least 1 element"); return $null; } bigint = JCALL2(GetObjectArrayElement, jenv, $input, 0); if (!bigint) { SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "array element null"); return $null; } clazz = JCALL1(GetObjectClass, jenv, bigint); mid = JCALL3(GetMethodID, jenv, clazz, "toByteArray", "()[B"); ba = (jbyteArray)JCALL2(CallObjectMethod, jenv, bigint, mid); bae = JCALL2(GetByteArrayElements, jenv, ba, 0); sz = JCALL1(GetArrayLength, jenv, ba); temp = 0; if (bae[0] == 0) { for(i=sz-1; i>0; i-- ) { temp = (temp << 8) | (unsigned char)bae[sz-i]; } } else { for(i=sz; i>=0; i-- ) { temp = (temp << 8) | (unsigned char)bae[sz-1-i]; } } JCALL3(ReleaseByteArrayElements, jenv, ba, bae, 0); $1 = &temp; } %typemap(argout) unsigned long long *INOUT = unsigned long long *OUTPUT; %typemap(argout) unsigned long long &INOUT = unsigned long long &OUTPUT; cableswig-0.1.0+git20150808.orig/SWIG/Lib/java/std_pair.i0000644000175000000620000000100612561312227021201 0ustar stevestaff// // SWIG typemaps for std::pair // Luigi Ballabio // July 2003 // // Common implementation %include std_common.i %include exception.i // ------------------------------------------------------------------------ // std::pair // ------------------------------------------------------------------------ %{ #include %} // exported class namespace std { template struct pair { // add typemaps here T first; U second; }; // add specializations here } cableswig-0.1.0+git20150808.orig/SWIG/Lib/java/javakw.swg0000644000175000000620000000233112561312227021231 0ustar stevestaff#ifndef __java_javakw_swg__ #define __java_javakw_swg__ /* Warnings for Java keywords */ #define JAVAKW(x) %namewarn("314:" #x " is a java keyword") #x /* from http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html */ JAVAKW(abstract); JAVAKW(double); JAVAKW(int); JAVAKW(strictfp); JAVAKW(boolean); JAVAKW(else); JAVAKW(interface); JAVAKW(super); JAVAKW(break); JAVAKW(extends); JAVAKW(long); JAVAKW(switch); JAVAKW(byte); JAVAKW(final); JAVAKW(native); JAVAKW(synchronized); JAVAKW(case); JAVAKW(finally); JAVAKW(new); JAVAKW(this); JAVAKW(catch); JAVAKW(float); JAVAKW(package); JAVAKW(throw); JAVAKW(char); JAVAKW(for); JAVAKW(private); JAVAKW(throws); JAVAKW(class); JAVAKW(goto); JAVAKW(protected); JAVAKW(transient); JAVAKW(const); JAVAKW(if); JAVAKW(public); JAVAKW(try); JAVAKW(continue); JAVAKW(implements); JAVAKW(return); JAVAKW(void); JAVAKW(default); JAVAKW(import); JAVAKW(short); JAVAKW(volatile); JAVAKW(do); JAVAKW(instanceof); JAVAKW(static); JAVAKW(while); /* others bad names */ /* Note here that only *::clone() is bad, and *::clone(int) is ok */ %namewarn("321:clone() is a java bad method name") *::clone(); #undef JAVAKW #endif //__java_javakw_swg__ cableswig-0.1.0+git20150808.orig/SWIG/Lib/java/javahead.swg0000644000175000000620000000763612561312227021526 0ustar stevestaff/* ----------------------------------------------------------------------------- * javahead.swg * * Java support code * ----------------------------------------------------------------------------- */ /* JNI function calls require different calling conventions for C and C++. These JCALL macros are used so * that the same typemaps can be used for generating code for both C and C++. The SWIG preprocessor can expand * the macros thereby generating the correct calling convention. It is thus essential that all typemaps that * use the macros are not within %{ %} brackets as they won't be run through the SWIG preprocessor. */ #ifdef __cplusplus # define JCALL0(func, jenv) jenv->func() # define JCALL1(func, jenv, ar1) jenv->func(ar1) # define JCALL2(func, jenv, ar1, ar2) jenv->func(ar1, ar2) # define JCALL3(func, jenv, ar1, ar2, ar3) jenv->func(ar1, ar2, ar3) # define JCALL4(func, jenv, ar1, ar2, ar3, ar4) jenv->func(ar1, ar2, ar3, ar4) # define JCALL5(func, jenv, ar1, ar2, ar3, ar4, ar5) jenv->func(ar1, ar2, ar3, ar4, ar5) # define JCALL6(func, jenv, ar1, ar2, ar3, ar4, ar5, ar6) jenv->func(ar1, ar2, ar3, ar4, ar5, ar6) # define JCALL7(func, jenv, ar1, ar2, ar3, ar4, ar5, ar6, ar7) jenv->func(ar1, ar2, ar3, ar4, ar5, ar6, ar7) #else # define JCALL0(func, jenv) (*jenv)->func(jenv) # define JCALL1(func, jenv, ar1) (*jenv)->func(jenv, ar1) # define JCALL2(func, jenv, ar1, ar2) (*jenv)->func(jenv, ar1, ar2) # define JCALL3(func, jenv, ar1, ar2, ar3) (*jenv)->func(jenv, ar1, ar2, ar3) # define JCALL4(func, jenv, ar1, ar2, ar3, ar4) (*jenv)->func(jenv, ar1, ar2, ar3, ar4) # define JCALL5(func, jenv, ar1, ar2, ar3, ar4, ar5) (*jenv)->func(jenv, ar1, ar2, ar3, ar4, ar5) # define JCALL6(func, jenv, ar1, ar2, ar3, ar4, ar5, ar6) (*jenv)->func(jenv, ar1, ar2, ar3, ar4, ar5, ar6) # define JCALL7(func, jenv, ar1, ar2, ar3, ar4, ar5, ar6, ar7) (*jenv)->func(jenv, ar1, ar2, ar3, ar4, ar5, ar6, ar7) #endif %insert(runtime) %{ #if defined(__GNUC__) typedef long long __int64; /*For gcc on Windows */ #endif #include #include #include %} %insert(runtime) %{ /* Support for throwing Java exceptions */ typedef enum { SWIG_JavaOutOfMemoryError = 1, SWIG_JavaIOException, SWIG_JavaRuntimeException, SWIG_JavaIndexOutOfBoundsException, SWIG_JavaArithmeticException, SWIG_JavaIllegalArgumentException, SWIG_JavaNullPointerException, SWIG_JavaDirectorPureVirtual, SWIG_JavaUnknownError } SWIG_JavaExceptionCodes; typedef struct { SWIG_JavaExceptionCodes code; const char *java_exception; } SWIG_JavaExceptions_t; %} %insert(runtime) { static void SWIG_JavaThrowException(JNIEnv *jenv, SWIG_JavaExceptionCodes code, const char *msg) { jclass excep; static const SWIG_JavaExceptions_t java_exceptions[] = { { SWIG_JavaOutOfMemoryError, "java/lang/OutOfMemoryError" }, { SWIG_JavaIOException, "java/io/IOException" }, { SWIG_JavaRuntimeException, "java/lang/RuntimeException" }, { SWIG_JavaIndexOutOfBoundsException, "java/lang/IndexOutOfBoundsException" }, { SWIG_JavaArithmeticException, "java/lang/ArithmeticException" }, { SWIG_JavaIllegalArgumentException, "java/lang/IllegalArgumentException" }, { SWIG_JavaNullPointerException, "java/lang/NullPointerException" }, { SWIG_JavaDirectorPureVirtual, "java/lang/RuntimeException" }, { SWIG_JavaUnknownError, "java/lang/UnknownError" }, { (SWIG_JavaExceptionCodes)0, "java/lang/UnknownError" } }; const SWIG_JavaExceptions_t *except_ptr = java_exceptions; while (except_ptr->code != code && except_ptr->code) except_ptr++; JCALL0(ExceptionClear, jenv); excep = JCALL1(FindClass, jenv, except_ptr->java_exception); if (excep) JCALL2(ThrowNew, jenv, excep, msg); } } %insert(runtime) %{ /* Contract support */ #define SWIG_contract_assert(nullreturn, expr, msg) if (!(expr)) {SWIG_JavaThrowException(jenv, SWIG_JavaIllegalArgumentException, msg); return nullreturn; } else %} cableswig-0.1.0+git20150808.orig/SWIG/Lib/java/director.swg0000644000175000000620000000353412561312227021567 0ustar stevestaff/*********************************************************************** * director.swg * * This file contains support for director classes that proxy * method calls from C++ to Java extensions. * * Author : Scott Michel (scottm@aero.org) * * This file was adapted from the python director.swg, written by * Mark Rose (mrose@stm.lbl.gov) ************************************************************************/ #ifdef __cplusplus namespace Swig { /* director base class */ class Director { private: /* pointer to Java virtual machine */ JavaVM *swig_jvm; protected: /* pointer to the wrapped Java object */ jobject swig_self; /* Acquire Java VM environment from Java VM */ JNIEnv *swig_acquire_jenv() const { JNIEnv *env = NULL; swig_jvm->AttachCurrentThread((void **) &env, NULL); return env; } public: Director(JNIEnv *jenv) : swig_jvm((JavaVM *) NULL), swig_self(NULL) { /* Acquire the Java VM pointer */ jenv->GetJavaVM(&swig_jvm); } /* Remove the Java object global lock at destruction */ virtual ~Director() { if (swig_self) { JNIEnv *jenv = swig_acquire_jenv(); jmethodID disconn_meth = jenv->GetMethodID(jenv->GetObjectClass(swig_self), "swigDirectorDisconnect", "()V"); if (disconn_meth) jenv->CallVoidMethod(swig_self, disconn_meth); jenv->DeleteGlobalRef(swig_self); swig_self = (jobject) NULL; } } /* Set swig_self and get Java global reference on object */ void swig_set_self(JNIEnv *jenv, jobject jself) { swig_self = jenv->NewGlobalRef(jself); } /* return a pointer to the wrapped Java object */ jobject swig_get_self() const { return swig_self; } }; } #endif /* __cplusplus */ cableswig-0.1.0+git20150808.orig/SWIG/Lib/java/std_vector.i0000644000175000000620000001005312561312227021552 0ustar stevestaff// // SWIG typemaps for std::vector // Luigi Ballabio // May 7, 2002 // // Java implementation %include exception.i // containers // methods which can raise are caused to throw an IndexError %exception std::vector::get { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::vector::set { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } // ------------------------------------------------------------------------ // std::vector // // The aim of all that follows would be to integrate std::vector with // Java as much as possible, namely, to allow the user to pass and // be returned Java (arrays? containers?) // const declarations are used to guess the intent of the function being // exported; therefore, the following rationale is applied: // // -- f(std::vector), f(const std::vector&), f(const std::vector*): // the parameter being read-only, either a Java sequence or a // previously wrapped std::vector can be passed. // -- f(std::vector&), f(std::vector*): // the parameter must be modified; therefore, only a wrapped std::vector // can be passed. // -- std::vector f(): // the vector is returned by copy; therefore, a Java sequence of T:s // is returned which is most easily used in other Java functions // -- std::vector& f(), std::vector* f(), const std::vector& f(), // const std::vector* f(): // the vector is returned by reference; therefore, a wrapped std::vector // is returned // ------------------------------------------------------------------------ %{ #include #include #include %} // exported class namespace std { template class vector { // add generic typemaps here public: vector(unsigned int size = 0); unsigned int size() const; %rename(isEmpty) empty; bool empty() const; void clear(); %rename(add) push_back; void push_back(const T& x); %extend { T& get(int i) { int size = int(self->size()); if (i>=0 && isize()); if (i>=0 && i class vector { // add specialized typemaps here public: vector(unsigned int size = 0); unsigned int size() const; %rename(isEmpty) empty; bool empty() const; void clear(); %rename(add) push_back; void push_back(T x); %extend { T get(int i) { int size = int(self->size()); if (i>=0 && isize()); if (i>=0 && i %} namespace std { // Ruby wants class names to start with a capital letter %rename(String) string; class string; /* Overloading check */ %typemap(typecheck) string = char *; %typemap(typecheck) const string & = char *; %typemap(in) string { if (TYPE($input) == T_STRING) { $1 = std::string(StringValuePtr($input)); } else { SWIG_exception(SWIG_TypeError, "not a string"); } } %typemap(in) const string & (std::string temp) { if (TYPE($input) == T_STRING) { temp = std::string(StringValuePtr($input)); $1 = &temp; } else { SWIG_exception(SWIG_TypeError, "not a string"); } } %typemap(out) string { $result = rb_str_new2($1.c_str()); } %typemap(out) const string & { $result = rb_str_new2($1->c_str()); } %typemap(directorin) string, const string &, string & "$1_name.c_str()"; %typemap(directorin) string *, const string * "$1_name->c_str()"; %typemap(directorout) string { if (TYPE($input) == T_STRING) $result = std::string(StringValuePtr($input)); else throw Swig::DirectorTypeMismatchException("string expected"); } %typemap(directorout) const string & (std::string temp) { if (TYPE($input) == T_STRING) { temp = std::string(StringValuePtr($input)); $result = &temp; } else { throw Swig::DirectorTypeMismatchException("string expected"); } } } cableswig-0.1.0+git20150808.orig/SWIG/Lib/ruby/std_map.i0000644000175000000620000015456212561312227021103 0ustar stevestaff// // SWIG typemaps for std::map // Luigi Ballabio // Jan. 2003 // // Ruby implementation %include std_common.i %include exception.i %exception std::map::__getitem__ { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::map::__delitem__ { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } // ------------------------------------------------------------------------ // std::map // // The aim of all that follows would be to integrate std::map with // Ruby as much as possible, namely, to allow the user to pass and // be returned Ruby hash maps. // const declarations are used to guess the intent of the function being // exported; therefore, the following rationale is applied: // // -- f(std::map), f(const std::map&), f(const std::map*): // the parameter being read-only, either a Ruby hash or a // previously wrapped std::map can be passed. // -- f(std::map&), f(std::map*): // the parameter must be modified; therefore, only a wrapped std::map // can be passed. // -- std::map f(): // the map is returned by copy; therefore, a Ruby hash // is returned which is most easily used in other Ruby functions // -- std::map& f(), std::map* f(), const std::map& f(), // const std::map* f(): // the map is returned by reference; therefore, a wrapped std::map // is returned // ------------------------------------------------------------------------ %{ #include #include #include %} // exported class namespace std { %mixin map "Enumerable"; template class map { %typemap(in) map (std::map* m) { if (rb_obj_is_kind_of($input,rb_cHash)) { $1 = std::map(); VALUE keys = rb_funcall($input,rb_intern("keys"),0); unsigned int size = RARRAY(keys)->len; for (unsigned int i=0; iptr[i]; VALUE val = rb_hash_aref($input,key); SWIG_ConvertPtr(key, (void **) &k, $descriptor(K *), 1); SWIG_ConvertPtr(val, (void **) &x, $descriptor(T *), 1); (($1_type &)$1)[*k] = *x; } } else { SWIG_ConvertPtr($input, (void **) &m, $&1_descriptor, 1); $1 = *m; } } %typemap(in) const map& (std::map temp, std::map* m), const map* (std::map temp, std::map* m) { if (rb_obj_is_kind_of($input,rb_cHash)) { temp = std::map(); $1 = &temp; VALUE keys = rb_funcall($input,rb_intern("keys"),0); unsigned int size = RARRAY(keys)->len; for (unsigned int i=0; iptr[i]; VALUE val = rb_hash_aref($input,key); SWIG_ConvertPtr(key, (void **) &k, $descriptor(K *), 1); SWIG_ConvertPtr(val, (void **) &x, $descriptor(T *), 1); temp[*k] = *x; } } else { SWIG_ConvertPtr($input, (void **) &m, $1_descriptor, 1); $1 = m; } } %typemap(out) map { $result = rb_hash_new(); for (std::map::iterator i=$1.begin(); i!=$1.end(); ++i) { K* key = new K(i->first); T* val = new T(i->second); rb_hash_aset($result, SWIG_NewPointerObj((void *) key, $descriptor(K *), 1), SWIG_NewPointerObj((void *) val, $descriptor(T *), 1)); } } %typecheck(SWIG_TYPECHECK_MAP) map { /* native sequence? */ if (rb_obj_is_kind_of($input,rb_cHash)) { VALUE keys = rb_funcall($input,rb_intern("keys"),0); unsigned int size = RARRAY(keys)->len; if (size == 0) { /* an empty dictionary can be of any type */ $1 = 1; } else { /* check the first element only */ K* k; T* x; VALUE key = RARRAY(keys)->ptr[0]; VALUE val = rb_hash_aref($input,key); if (SWIG_ConvertPtr(key,(void **) &k, $descriptor(K *),0) != -1 && SWIG_ConvertPtr(val,(void **) &x, $descriptor(T *),0) != -1) $1 = 1; else $1 = 0; } } else { /* wrapped map? */ std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $&1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_MAP) const map&, const map* { /* native sequence? */ if (rb_obj_is_kind_of($input,rb_cHash)) { VALUE keys = rb_funcall($input,rb_intern("keys"),0); unsigned int size = RARRAY(keys)->len; if (size == 0) { /* an empty dictionary can be of any type */ $1 = 1; } else { /* check the first element only */ K* k; T* x; VALUE key = RARRAY(keys)->ptr[0]; VALUE val = rb_hash_aref($input,key); if (SWIG_ConvertPtr(key,(void **) &k, $descriptor(K *),0) != -1 && SWIG_ConvertPtr(val,(void **) &x, $descriptor(T *),0) != -1) $1 = 1; else $1 = 0; } } else { /* wrapped map? */ std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } %rename(__len__) size; %rename("empty?") empty; %rename("delete") __delitem__; %rename("has_key?") has_key; public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T& __getitem__(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void __setitem__(const K& key, const T& x) { (*self)[key] = x; } T __delitem__(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) { T x = i->second; self->erase(i); return x; } else throw std::out_of_range("key not found"); } bool has_key(const K& key) { std::map::iterator i = self->find(key); return i != self->end(); } VALUE keys() { VALUE keyList = rb_ary_new2(self->size()); std::map::iterator i; unsigned int j; for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { K* ptr = new K(i->first); rb_ary_store(keyList,j, SWIG_NewPointerObj((void *) ptr, $descriptor(K *),1)); } return keyList; } VALUE values() { VALUE valueList = rb_ary_new2(self->size()); std::map::iterator i; unsigned int j; for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { T* ptr = new T(i->second); rb_ary_store(valueList,j, SWIG_NewPointerObj((void *) ptr, $descriptor(T *),1)); } return valueList; } void each() { std::map::iterator i; for (i=self->begin(); i!=self->end(); ++i) { K* key = new K(i->first); T* val = &(i->second); VALUE entry = rb_ary_new2(2); VALUE k = SWIG_NewPointerObj((void *) key, $descriptor(K *),1); VALUE x = SWIG_NewPointerObj((void *) val, $descriptor(T *),0); rb_ary_store(entry,0,k); rb_ary_store(entry,1,x); rb_yield(entry); } } } }; // specializations for built-ins %define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO) %mixin map "Enumerable"; template class map { %typemap(in) map (std::map* m) { if (rb_obj_is_kind_of($input,rb_cHash)) { $1 = std::map(); VALUE keys = rb_funcall($input,rb_intern("keys"),0); unsigned int size = RARRAY(keys)->len; for (unsigned int i=0; iptr[i]; VALUE val = rb_hash_aref($input,key); if (!CHECK(key)) rb_raise(rb_eTypeError, "wrong argument type" " (expected map<" #K "," #T ">)"); SWIG_ConvertPtr(val,(void **) &x, $descriptor(T *),1); (($1_type &)$1)[CONVERT_FROM(key)] = *x; } } else { SWIG_ConvertPtr($input,(void **) &m, $&1_descriptor,1); $1 = *m; } } %typemap(in) const map& (std::map temp, std::map* m), const map* (std::map temp, std::map* m) { if (rb_obj_is_kind_of($input,rb_cHash)) { temp = std::map(); $1 = &temp; VALUE keys = rb_funcall($input,rb_intern("keys"),0); unsigned int size = RARRAY(keys)->len; for (unsigned int i=0; iptr[i]; VALUE val = rb_hash_aref($input,key); if (!CHECK(key)) rb_raise(rb_eTypeError, "wrong argument type" " (expected map<" #K "," #T ">)"); SWIG_ConvertPtr(val,(void **) &x, $descriptor(T *),1); temp[CONVERT_FROM(key)] = *x; } } else { SWIG_ConvertPtr($input,(void **) &m,$1_descriptor,1); $1 = m; } } %typemap(out) map { $result = rb_hash_new(); for (std::map::iterator i=$1.begin(); i!=$1.end(); ++i) { T* obj = new T(i->second); rb_hash_aset($result, CONVERT_TO(i->first), SWIG_NewPointerObj((void *) obj, $descriptor(T *), 1)); } } %typecheck(SWIG_TYPECHECK_MAP) map { // native sequence? if (rb_obj_is_kind_of($input,rb_cHash)) { VALUE keys = rb_funcall($input,rb_intern("keys"),0); unsigned int size = RARRAY(keys)->len; if (size == 0) { // an empty dictionary can be of any type $1 = 1; } else { // check the first element only T* x; VALUE key = RARRAY(keys)->ptr[0]; VALUE val = rb_hash_aref($input,key); if (CHECK(key) && SWIG_ConvertPtr(val,(void **) &x, $descriptor(T *),0) != -1) $1 = 1; else $1 = 0; } } else { // wrapped map? std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $&1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_MAP) const map&, const map* { // native sequence? if (rb_obj_is_kind_of($input,rb_cHash)) { VALUE keys = rb_funcall($input,rb_intern("keys"),0); unsigned int size = RARRAY(keys)->len; if (size == 0) { // an empty dictionary can be of any type $1 = 1; } else { // check the first element only T* x; VALUE key = RARRAY(keys)->ptr[0]; VALUE val = rb_hash_aref($input,key); if (CHECK(key) && SWIG_ConvertPtr(val,(void **) &x, $descriptor(T *),0) != -1) $1 = 1; else $1 = 0; } } else { // wrapped map? std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } %rename(__len__) size; %rename("empty?") empty; %rename("delete") __delitem__; %rename("has_key?") has_key; public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T& __getitem__(K key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void __setitem__(K key, const T& x) { (*self)[key] = x; } T __delitem__(K key) { std::map::iterator i = self->find(key); if (i != self->end()) { T x = i->second; self->erase(i); return x; } else throw std::out_of_range("key not found"); } bool has_key(K key) { std::map::iterator i = self->find(key); return i != self->end(); } VALUE keys() { VALUE keyList = rb_ary_new2(self->size()); std::map::iterator i; unsigned int j; for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { rb_ary_store(keyList,j, CONVERT_TO(i->first)); } return keyList; } VALUE values() { VALUE valueList = rb_ary_new2(self->size()); std::map::iterator i; unsigned int j; for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { T* ptr = new T(i->second); rb_ary_store(valueList,j, SWIG_NewPointerObj((void *) ptr, $descriptor(T *),1)); } return valueList; } void each() { std::map::iterator i; for (i=self->begin(); i!=self->end(); ++i) { T* val = &(i->second); VALUE entry = rb_ary_new2(2); VALUE k = CONVERT_TO(i->first); VALUE x = SWIG_NewPointerObj((void *) val, $descriptor(T *),0); rb_ary_store(entry,0,k); rb_ary_store(entry,1,x); rb_yield(entry); } } } }; %enddef %define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO) %mixin map "Enumerable"; template class map { %typemap(in) map (std::map* m) { if (rb_obj_is_kind_of($input,rb_cHash)) { $1 = std::map(); VALUE keys = rb_funcall($input,rb_intern("keys"),0); unsigned int size = RARRAY(keys)->len; for (unsigned int i=0; iptr[i]; VALUE val = rb_hash_aref($input,key); if (!CHECK(val)) rb_raise(rb_eTypeError, "wrong argument type" " (expected map<" #K "," #T ">)"); SWIG_ConvertPtr(key,(void **) &k, $descriptor(K *),1); (($1_type &)$1)[*k] = CONVERT_FROM(val); } } else { SWIG_ConvertPtr($input,(void **) &m, $&1_descriptor,1); $1 = *m; } } %typemap(in) const map& (std::map temp, std::map* m), const map* (std::map temp, std::map* m) { if (rb_obj_is_kind_of($input,rb_cHash)) { temp = std::map(); $1 = &temp; VALUE keys = rb_funcall($input,rb_intern("keys"),0); unsigned int size = RARRAY(keys)->len; for (unsigned int i=0; iptr[i]; VALUE val = rb_hash_aref($input,key); if (!CHECK(val)) rb_raise(rb_eTypeError, "wrong argument type" " (expected map<" #K "," #T ">)"); SWIG_ConvertPtr(key,(void **) &k, $descriptor(K *),1); temp[*k] = CONVERT_FROM(val); } } else { SWIG_ConvertPtr($input,(void **) &m, $1_descriptor,1); $1 = m; } } %typemap(out) map { $result = rb_hash_new(); for (std::map::iterator i=$1.begin(); i!=$1.end(); ++i) { K* key = new K(i->first); rb_hash_aset($result, SWIG_NewPointerObj((void *) key, $descriptor(K *), 1), CONVERT_TO(i->second)); } } %typecheck(SWIG_TYPECHECK_MAP) map { // native sequence? if (rb_obj_is_kind_of($input,rb_cHash)) { VALUE keys = rb_funcall($input,rb_intern("keys"),0); unsigned int size = RARRAY(keys)->len; if (size == 0) { // an empty dictionary can be of any type $1 = 1; } else { // check the first element only K* k; VALUE key = RARRAY(keys)->ptr[0]; VALUE val = rb_hash_aref($input,key); if (SWIG_ConvertPtr(val,(void **) &k, $descriptor(K *),0) != -1 && CHECK(val)) $1 = 1; else $1 = 0; } } else { // wrapped map? std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $&1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_MAP) const map&, const map* { // native sequence? if (rb_obj_is_kind_of($input,rb_cHash)) { VALUE keys = rb_funcall($input,rb_intern("keys"),0); unsigned int size = RARRAY(keys)->len; if (size == 0) { // an empty dictionary can be of any type $1 = 1; } else { // check the first element only K* k; VALUE key = RARRAY(keys)->ptr[0]; VALUE val = rb_hash_aref($input,key); if (SWIG_ConvertPtr(val,(void **) &k, $descriptor(K *),0) != -1 && CHECK(val)) $1 = 1; else $1 = 0; } } else { // wrapped map? std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } %rename(__len__) size; %rename("empty?") empty; %rename("delete") __delitem__; %rename("has_key?") has_key; public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T __getitem__(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void __setitem__(const K& key, T x) { (*self)[key] = x; } T __delitem__(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) { T x = i->second; self->erase(i); return x; } else throw std::out_of_range("key not found"); } bool has_key(const K& key) { std::map::iterator i = self->find(key); return i != self->end(); } VALUE keys() { VALUE keyList = rb_ary_new2(self->size()); std::map::iterator i; unsigned int j; for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { K* ptr = new K(i->first); rb_ary_store(keyList,j, SWIG_NewPointerObj((void *) ptr, $descriptor(K *),1)); } return keyList; } VALUE values() { VALUE valueList = rb_ary_new2(self->size()); std::map::iterator i; unsigned int j; for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { rb_ary_store(valueList,j, CONVERT_TO(i->second)); } return valueList; } void each() { std::map::iterator i; for (i=self->begin(); i!=self->end(); ++i) { K* key = new K(i->first); VALUE entry = rb_ary_new2(2); VALUE k = SWIG_NewPointerObj((void *) key, $descriptor(K *),1); VALUE x = CONVERT_TO(i->second); rb_ary_store(entry,0,k); rb_ary_store(entry,1,x); rb_yield(entry); } } } }; %enddef %define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO) %mixin map "Enumerable"; template<> class map { %typemap(in) map (std::map* m) { if (rb_obj_is_kind_of($input,rb_cHash)) { $1 = std::map(); VALUE keys = rb_funcall($input,rb_intern("keys"),0); unsigned int size = RARRAY(keys)->len; for (unsigned int i=0; iptr[i]; VALUE val = rb_hash_aref($input,key); if (!(CHECK_K(key) && CHECK_T(val))) rb_raise(rb_eTypeError, "wrong argument type" " (expected map<" #K "," #T ">)"); (($1_type &)$1)[CONVERT_K_FROM(key)] = CONVERT_T_FROM(val); } } else { SWIG_ConvertPtr($input,(void **) &m, $&1_descriptor,1); $1 = *m; } } %typemap(in) const map& (std::map temp, std::map* m), const map* (std::map temp, std::map* m) { if (rb_obj_is_kind_of($input,rb_cHash)) { temp = std::map(); $1 = &temp; VALUE keys = rb_funcall($input,rb_intern("keys"),0); unsigned int size = RARRAY(keys)->len; for (unsigned int i=0; iptr[i]; VALUE val = rb_hash_aref($input,key); if (!(CHECK_K(key) && CHECK_T(val))) rb_raise(rb_eTypeError, "wrong argument type" " (expected map<" #K "," #T ">)"); temp[CONVERT_K_FROM(key)] = CONVERT_T_FROM(val); } } else { SWIG_ConvertPtr($input,(void **) &m, $1_descriptor,1); $1 = m; } } %typemap(out) map { $result = rb_hash_new(); for (std::map::iterator i=$1.begin(); i!=$1.end(); ++i) { rb_hash_aset($result, CONVERT_K_TO(i->first), CONVERT_T_TO(i->second)); } } %typecheck(SWIG_TYPECHECK_MAP) map { // native sequence? if (rb_obj_is_kind_of($input,rb_cHash)) { VALUE keys = rb_funcall($input,rb_intern("keys"),0); unsigned int size = RARRAY(keys)->len; if (size == 0) { // an empty dictionary can be of any type $1 = 1; } else { // check the first element only VALUE key = RARRAY(keys)->ptr[0]; VALUE val = rb_hash_aref($input,key); if (CHECK_K(key) && CHECK_T(val)) $1 = 1; else $1 = 0; } } else { // wrapped map? std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $&1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_MAP) const map&, const map* { // native sequence? if (rb_obj_is_kind_of($input,rb_cHash)) { VALUE keys = rb_funcall($input,rb_intern("keys"),0); unsigned int size = RARRAY(keys)->len; if (size == 0) { // an empty dictionary can be of any type $1 = 1; } else { // check the first element only VALUE key = RARRAY(keys)->ptr[0]; VALUE val = rb_hash_aref($input,key); if (CHECK_K(key) && CHECK_T(val)) $1 = 1; else $1 = 0; } } else { // wrapped map? std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } %rename(__len__) size; %rename("empty?") empty; %rename("delete") __delitem__; %rename("has_key?") has_key; public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T __getitem__(K key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void __setitem__(K key, T x) { (*self)[key] = x; } T __delitem__(K key) { std::map::iterator i = self->find(key); if (i != self->end()) { T x = i->second; self->erase(i); return x; } else throw std::out_of_range("key not found"); } bool has_key(K key) { std::map::iterator i = self->find(key); return i != self->end(); } VALUE keys() { VALUE keyList = rb_ary_new2(self->size()); std::map::iterator i; unsigned int j; for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { rb_ary_store(keyList,j, CONVERT_K_TO(i->first)); } return keyList; } VALUE values() { VALUE valueList = rb_ary_new2(self->size()); std::map::iterator i; unsigned int j; for (i=self->begin(), j=0; i!=self->end(); ++i, ++j) { rb_ary_store(valueList,j, CONVERT_T_TO(i->second)); } return valueList; } void each() { std::map::iterator i; for (i=self->begin(); i!=self->end(); ++i) { VALUE entry = rb_ary_new2(2); rb_ary_store(entry,0,CONVERT_K_TO(i->first)); rb_ary_store(entry,1,CONVERT_T_TO(i->second)); rb_yield(entry); } } } }; %enddef specialize_std_map_on_key(bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB); specialize_std_map_on_key(int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_key(short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_key(long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_key(unsigned int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_key(unsigned short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_key(unsigned long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_key(double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_map_on_key(float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_map_on_key(std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB); specialize_std_map_on_value(bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB); specialize_std_map_on_value(int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_value(short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_value(long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_value(unsigned int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_value(unsigned short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_value(unsigned long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_value(double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_map_on_value(float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_map_on_value(std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB); specialize_std_map_on_both(bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB, bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB); specialize_std_map_on_both(bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB, int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB, short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB, long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB, unsigned int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB, unsigned short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB, unsigned long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB, double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_map_on_both(bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB, float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_map_on_both(bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB, std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB); specialize_std_map_on_both(int,FIXNUM_P, FIX2INT,INT2NUM, bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB); specialize_std_map_on_both(int,FIXNUM_P, FIX2INT,INT2NUM, int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(int,FIXNUM_P, FIX2INT,INT2NUM, short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(int,FIXNUM_P, FIX2INT,INT2NUM, long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(int,FIXNUM_P, FIX2INT,INT2NUM, unsigned int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(int,FIXNUM_P, FIX2INT,INT2NUM, unsigned short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(int,FIXNUM_P, FIX2INT,INT2NUM, unsigned long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(int,FIXNUM_P, FIX2INT,INT2NUM, double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_map_on_both(int,FIXNUM_P, FIX2INT,INT2NUM, float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_map_on_both(int,FIXNUM_P, FIX2INT,INT2NUM, std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB); specialize_std_map_on_both(short,FIXNUM_P, FIX2INT,INT2NUM, bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB); specialize_std_map_on_both(short,FIXNUM_P, FIX2INT,INT2NUM, int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(short,FIXNUM_P, FIX2INT,INT2NUM, short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(short,FIXNUM_P, FIX2INT,INT2NUM, long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(short,FIXNUM_P, FIX2INT,INT2NUM, unsigned int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(short,FIXNUM_P, FIX2INT,INT2NUM, unsigned short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(short,FIXNUM_P, FIX2INT,INT2NUM, unsigned long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(short,FIXNUM_P, FIX2INT,INT2NUM, double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_map_on_both(short,FIXNUM_P, FIX2INT,INT2NUM, float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_map_on_both(short,FIXNUM_P, FIX2INT,INT2NUM, std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB); specialize_std_map_on_both(long,FIXNUM_P, FIX2INT,INT2NUM, bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB); specialize_std_map_on_both(long,FIXNUM_P, FIX2INT,INT2NUM, int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(long,FIXNUM_P, FIX2INT,INT2NUM, short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(long,FIXNUM_P, FIX2INT,INT2NUM, long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(long,FIXNUM_P, FIX2INT,INT2NUM, unsigned int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(long,FIXNUM_P, FIX2INT,INT2NUM, unsigned short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(long,FIXNUM_P, FIX2INT,INT2NUM, unsigned long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(long,FIXNUM_P, FIX2INT,INT2NUM, double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_map_on_both(long,FIXNUM_P, FIX2INT,INT2NUM, float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_map_on_both(long,FIXNUM_P, FIX2INT,INT2NUM, std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB); specialize_std_map_on_both(unsigned int,FIXNUM_P, FIX2INT,INT2NUM, bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB); specialize_std_map_on_both(unsigned int,FIXNUM_P, FIX2INT,INT2NUM, int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(unsigned int,FIXNUM_P, FIX2INT,INT2NUM, short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(unsigned int,FIXNUM_P, FIX2INT,INT2NUM, long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(unsigned int,FIXNUM_P, FIX2INT,INT2NUM, unsigned int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(unsigned int,FIXNUM_P, FIX2INT,INT2NUM, unsigned short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(unsigned int,FIXNUM_P, FIX2INT,INT2NUM, unsigned long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(unsigned int,FIXNUM_P, FIX2INT,INT2NUM, double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_map_on_both(unsigned int,FIXNUM_P, FIX2INT,INT2NUM, float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_map_on_both(unsigned int,FIXNUM_P, FIX2INT,INT2NUM, std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB); specialize_std_map_on_both(unsigned short,FIXNUM_P, FIX2INT,INT2NUM, bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB); specialize_std_map_on_both(unsigned short,FIXNUM_P, FIX2INT,INT2NUM, int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(unsigned short,FIXNUM_P, FIX2INT,INT2NUM, short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(unsigned short,FIXNUM_P, FIX2INT,INT2NUM, long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(unsigned short,FIXNUM_P, FIX2INT,INT2NUM, unsigned int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(unsigned short,FIXNUM_P, FIX2INT,INT2NUM, unsigned short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(unsigned short,FIXNUM_P, FIX2INT,INT2NUM, unsigned long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(unsigned short,FIXNUM_P, FIX2INT,INT2NUM, double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_map_on_both(unsigned short,FIXNUM_P, FIX2INT,INT2NUM, float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_map_on_both(unsigned short,FIXNUM_P, FIX2INT,INT2NUM, std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB); specialize_std_map_on_both(unsigned long,FIXNUM_P, FIX2INT,INT2NUM, bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB); specialize_std_map_on_both(unsigned long,FIXNUM_P, FIX2INT,INT2NUM, int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(unsigned long,FIXNUM_P, FIX2INT,INT2NUM, short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(unsigned long,FIXNUM_P, FIX2INT,INT2NUM, long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(unsigned long,FIXNUM_P, FIX2INT,INT2NUM, unsigned int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(unsigned long,FIXNUM_P, FIX2INT,INT2NUM, unsigned short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(unsigned long,FIXNUM_P, FIX2INT,INT2NUM, unsigned long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(unsigned long,FIXNUM_P, FIX2INT,INT2NUM, double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_map_on_both(unsigned long,FIXNUM_P, FIX2INT,INT2NUM, float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_map_on_both(unsigned long,FIXNUM_P, FIX2INT,INT2NUM, std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB); specialize_std_map_on_both(double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB); specialize_std_map_on_both(double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, unsigned int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, unsigned short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, unsigned long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_map_on_both(double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_map_on_both(double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB); specialize_std_map_on_both(float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB); specialize_std_map_on_both(float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, unsigned int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, unsigned short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, unsigned long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_map_on_both(float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_map_on_both(float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB); specialize_std_map_on_both(std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB, bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB); specialize_std_map_on_both(std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB, int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB, short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB, long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB, unsigned int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB, unsigned short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB, unsigned long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_map_on_both(std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB, double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_map_on_both(std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB, float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_map_on_both(std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB, std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB); } cableswig-0.1.0+git20150808.orig/SWIG/Lib/ruby/rubydef.swg0000644000175000000620000001072212561312227021451 0ustar stevestaff/* rubydef.swg */ #ifdef __cplusplus extern "C" { #endif static VALUE _mSWIG = Qnil; static VALUE _cSWIG_Pointer = Qnil; /* Initialize Ruby runtime support */ SWIGRUNTIME(void) SWIG_Ruby_InitRuntime(void) { if (_mSWIG == Qnil) { _mSWIG = rb_define_module("SWIG"); } } /* Define Ruby class for C type */ SWIGRUNTIME(void) SWIG_Ruby_define_class(swig_type_info *type) { VALUE klass; char *klass_name = (char *) malloc(4 + strlen(type->name) + 1); sprintf(klass_name, "TYPE%s", type->name); if (NIL_P(_cSWIG_Pointer)) { _cSWIG_Pointer = rb_define_class_under(_mSWIG, "Pointer", rb_cObject); rb_undef_method(CLASS_OF(_cSWIG_Pointer), "new"); } klass = rb_define_class_under(_mSWIG, klass_name, _cSWIG_Pointer); free((void *) klass_name); } /* Create a new pointer object */ SWIGRUNTIME(VALUE) SWIG_Ruby_NewPointerObj(void *ptr, swig_type_info *type, int own) { char *klass_name; swig_class *sklass; VALUE klass; VALUE obj; if (!ptr) return Qnil; if (type->clientdata) { sklass = (swig_class *) type->clientdata; obj = Data_Wrap_Struct(sklass->klass, VOIDFUNC(sklass->mark), (own ? VOIDFUNC(sklass->destroy) : 0), ptr); } else { klass_name = (char *) malloc(4 + strlen(type->name) + 1); sprintf(klass_name, "TYPE%s", type->name); klass = rb_const_get(_mSWIG, rb_intern(klass_name)); free((void *) klass_name); obj = Data_Wrap_Struct(klass, 0, 0, ptr); } rb_iv_set(obj, "__swigtype__", rb_str_new2(type->name)); return obj; } /* Create a new class instance (always owned) */ SWIGRUNTIME(VALUE) SWIG_Ruby_NewClassInstance(VALUE klass, swig_type_info *type) { VALUE obj; swig_class *sklass = (swig_class *) type->clientdata; obj = Data_Wrap_Struct(klass, VOIDFUNC(sklass->mark), VOIDFUNC(sklass->destroy), 0); rb_iv_set(obj, "__swigtype__", rb_str_new2(type->name)); return obj; } /* Get type mangle from class name */ SWIGRUNTIME(char *) SWIG_Ruby_MangleStr(VALUE obj) { VALUE stype = rb_iv_get(obj, "__swigtype__"); return StringValuePtr(stype); } /* Convert a pointer value */ SWIGRUNTIME(int) SWIG_Ruby_ConvertPtr(VALUE obj, void **ptr, swig_type_info *ty, int flags) { char *c; swig_type_info *tc; /* Grab the pointer */ if (NIL_P(obj)) { *ptr = 0; return 0; } else { Data_Get_Struct(obj, void, *ptr); } /* Do type-checking if type info was provided */ if (ty) { if (ty->clientdata) { if (rb_obj_is_kind_of(obj, ((swig_class *) (ty->clientdata))->klass)) { if (*ptr == 0) rb_raise(rb_eRuntimeError, "This %s already released", ty->str); return 0; } } if ((c = SWIG_MangleStr(obj)) == NULL) { if (flags & SWIG_POINTER_EXCEPTION) rb_raise(rb_eTypeError, "Expected %s", ty->str); else return -1; } tc = SWIG_TypeCheck(c, ty); if (!tc) { if (flags & SWIG_POINTER_EXCEPTION) rb_raise(rb_eTypeError, "Expected %s", ty->str); else return -1; } *ptr = SWIG_TypeCast(tc, *ptr); } return 0; } /* Convert a pointer value, signal an exception on a type mismatch */ SWIGRUNTIME(void *) SWIG_Ruby_MustGetPtr(VALUE obj, swig_type_info *ty, int argnum, int flags) { void *result; SWIG_ConvertPtr(obj, &result, ty, flags | SWIG_POINTER_EXCEPTION); return result; } /* Check convert */ SWIGRUNTIME(int) SWIG_Ruby_CheckConvert(VALUE obj, swig_type_info *ty) { char *c = SWIG_MangleStr(obj); if (!c) return 0; return SWIG_TypeCheck(c,ty) != 0; } SWIGRUNTIME(VALUE) SWIG_Ruby_NewPackedObj(void *ptr, int sz, swig_type_info *type) { char result[1024]; char *r = result; if ((2*sz + 1 + strlen(type->name)) > 1000) return 0; *(r++) = '_'; r = SWIG_PackData(r, ptr, sz); strcpy(r, type->name); return rb_str_new2(result); } /* Convert a packed value value */ SWIGRUNTIME(void) SWIG_Ruby_ConvertPacked(VALUE obj, void *ptr, int sz, swig_type_info *ty, int flags) { swig_type_info *tc; char *c; if (TYPE(obj) != T_STRING) goto type_error; c = StringValuePtr(obj); /* Pointer values must start with leading underscore */ if (*c != '_') goto type_error; c++; c = SWIG_UnpackData(c, ptr, sz); if (ty) { tc = SWIG_TypeCheck(c, ty); if (!tc) goto type_error; } return; type_error: if (flags) { if (ty) { rb_raise(rb_eTypeError, "Type error. Expected %s", ty->name); } else { rb_raise(rb_eTypeError, "Expected a pointer"); } } } #ifdef __cplusplus } #endif cableswig-0.1.0+git20150808.orig/SWIG/Lib/ruby/rubykw.swg0000644000175000000620000000165612561312227021342 0ustar stevestaff#ifndef __ruby_rubykw_swg__ #define __ruby_rubykw_swg__ /* Warnings for Ruby keywords */ #define RUBYKW(x) %namewarn("314:" #x " is a ruby keyword") #x /* from http://www.ruby-lang.org/en/man-1.4/syntax.html#resword */ RUBYKW(BEGIN); RUBYKW(class); RUBYKW(ensure); RUBYKW(nil); RUBYKW(self); RUBYKW(when); RUBYKW(END); RUBYKW(def); RUBYKW(false); RUBYKW(not); RUBYKW(super); RUBYKW(while); RUBYKW(alias); RUBYKW(for); RUBYKW(or); RUBYKW(then); RUBYKW(yield); RUBYKW(and); RUBYKW(do); RUBYKW(if); RUBYKW(redo); RUBYKW(true); RUBYKW(begin); RUBYKW(else); RUBYKW(in); RUBYKW(rescue); RUBYKW(undef); RUBYKW(break); RUBYKW(elsif); RUBYKW(module); RUBYKW(retry); RUBYKW(unless); RUBYKW(case); RUBYKW(end); RUBYKW(next); RUBYKW(return); RUBYKW(until); /* swig doesn't like this one in a macro, adding it by hand */ //RUBYKW(defined); %namewarn("314: defined is a ruby keyword") "defined"; #undef RUBYKW #endif //__ruby_rubykw_swg__ cableswig-0.1.0+git20150808.orig/SWIG/Lib/ruby/std_common.i0000644000175000000620000000135612561312227021606 0ustar stevestaff// // SWIG typemaps for STL - common utilities // Luigi Ballabio // Aug 3, 2002 // // Ruby implementation %apply size_t { std::size_t }; %{ #include #define SWIG_FLOAT_P(x) ((TYPE(x) == T_FLOAT) || FIXNUM_P(x)) bool SWIG_BOOL_P(VALUE) { // dummy test, RTEST should take care of everything return true; } bool SWIG_RB2BOOL(VALUE x) { return RTEST(x); } VALUE SWIG_BOOL2RB(bool b) { return b ? Qtrue : Qfalse; } double SWIG_NUM2DBL(VALUE x) { return (FIXNUM_P(x) ? FIX2INT(x) : NUM2DBL(x)); } bool SWIG_STRING_P(VALUE x) { return TYPE(x) == T_STRING; } std::string SWIG_RB2STR(VALUE x) { return std::string(StringValuePtr(x)); } VALUE SWIG_STR2RB(const std::string& s) { return rb_str_new2(s.c_str()); } %} cableswig-0.1.0+git20150808.orig/SWIG/Lib/ruby/Makefile.swig0000644000175000000620000000165712561312227021706 0ustar stevestaff# File : Makefile.swig # Makefile for a SWIG module. Use this file if you are # producing a Ruby extension for general use or distribution. # # 1. Prepare extconf.rb. # 2. Modify this file as appropriate. # 3. Type 'make -f Makefile.swig' to generate wrapper code and Makefile. # 4. Type 'make' to build your extension. # 5. Type 'make install' to install your extension. # MODULE = yourmodule FEATURE = $(MODULE) INTERFACE = $(MODULE).i RUBY = ruby SWIG = swig # for C extension SWIGOPT = -ruby WRAPPER = $(MODULE)_wrap.c ## for C++ extension #SWIGOPT = -ruby -c++ #WRAPPER = $(MODULE)_wrap.cc swigall: $(WRAPPER) Makefile $(WRAPPER): $(INTERFACE) $(SWIG) $(SWIGOPT) -o $@ $(INTERFACE) Makefile: extconf.rb $(RUBY) extconf.rb @if [ -f Makefile ] ; then\ echo "include Makefile.swig" >> Makefile;\ fi swigclean: @if [ -f Makefile ] ; then\ make -f Makefile clean;\ fi rm -f Makefile $(WRAPPER) cableswig-0.1.0+git20150808.orig/SWIG/Lib/ruby/typemaps.i0000644000175000000620000003223212561312227021303 0ustar stevestaff// // typemaps for Ruby // // /cvsroot/SWIG/Lib/ruby/typemaps.i,v 1.6 2003/03/10 22:41:28 cheetah Exp // // Copyright (C) 2000 Network Applied Communication Laboratory, Inc. // Copyright (C) 2000 Information-technology Promotion Agency, Japan // // Masaki Fukushima // /* The SWIG typemap library provides a language independent mechanism for supporting output arguments, input values, and other C function calling mechanisms. The primary use of the library is to provide a better interface to certain C function--especially those involving pointers. */ // ------------------------------------------------------------------------ // Pointer handling // // These mappings provide support for input/output arguments and common // uses for C/C++ pointers. // ------------------------------------------------------------------------ // INPUT typemaps. // These remap a C pointer to be an "INPUT" value which is passed by value // instead of reference. /* The following methods can be applied to turn a pointer into a simple "input" value. That is, instead of passing a pointer to an object, you would use a real value instead. int *INPUT short *INPUT long *INPUT long long *INPUT unsigned int *INPUT unsigned short *INPUT unsigned long *INPUT unsigned long long *INPUT unsigned char *INPUT bool *INPUT float *INPUT double *INPUT To use these, suppose you had a C function like this : double fadd(double *a, double *b) { return *a+*b; } You could wrap it with SWIG as follows : %include typemaps.i double fadd(double *INPUT, double *INPUT); or you can use the %apply directive : %include typemaps.i %apply double *INPUT { double *a, double *b }; double fadd(double *a, double *b); */ %define INPUT_TYPEMAP(type, converter) %typemap(in) type *INPUT($*1_ltype temp), type &INPUT($*1_ltype temp) { temp = ($*1_ltype) converter($input); $1 = &temp; } %typemap(typecheck) type *INPUT = type; %typemap(typecheck) type &INPUT = type; %enddef INPUT_TYPEMAP(float, NUM2DBL); INPUT_TYPEMAP(double, NUM2DBL); INPUT_TYPEMAP(int, NUM2INT); INPUT_TYPEMAP(short, NUM2SHRT); INPUT_TYPEMAP(long, NUM2LONG); INPUT_TYPEMAP(long long, NUM2LL); INPUT_TYPEMAP(unsigned int, NUM2UINT); INPUT_TYPEMAP(unsigned short, NUM2USHRT); INPUT_TYPEMAP(unsigned long, NUM2ULONG); INPUT_TYPEMAP(unsigned long long, NUM2ULL); INPUT_TYPEMAP(unsigned char, NUM2UINT); INPUT_TYPEMAP(signed char, NUM2INT); INPUT_TYPEMAP(bool, RTEST); #undef INPUT_TYPEMAP // OUTPUT typemaps. These typemaps are used for parameters that // are output only. The output value is appended to the result as // a array element. /* The following methods can be applied to turn a pointer into an "output" value. When calling a function, no input value would be given for a parameter, but an output value would be returned. In the case of multiple output values, they are returned in the form of a Ruby Array. int *OUTPUT short *OUTPUT long *OUTPUT long long *OUTPUT unsigned int *OUTPUT unsigned short *OUTPUT unsigned long *OUTPUT unsigned long long *OUTPUT unsigned char *OUTPUT bool *OUTPUT float *OUTPUT double *OUTPUT For example, suppose you were trying to wrap the modf() function in the C math library which splits x into integral and fractional parts (and returns the integer part in one of its parameters).K: double modf(double x, double *ip); You could wrap it with SWIG as follows : %include typemaps.i double modf(double x, double *OUTPUT); or you can use the %apply directive : %include typemaps.i %apply double *OUTPUT { double *ip }; double modf(double x, double *ip); The Ruby output of the function would be a Array containing both output values. */ %include "fragments.i" %define OUTPUT_TYPEMAP(type, converter, convtype) %typemap(in,numinputs=0) type *OUTPUT($*1_ltype temp), type &OUTPUT($*1_ltype temp) "$1 = &temp;"; %typemap(argout, fragment="output_helper") type *OUTPUT, type &OUTPUT { VALUE o = converter(convtype (*$1)); $result = output_helper($result, o); } %enddef OUTPUT_TYPEMAP(int, INT2NUM, (int)); OUTPUT_TYPEMAP(short, INT2NUM, (int)); OUTPUT_TYPEMAP(long, INT2NUM, (int)); OUTPUT_TYPEMAP(long long, LL2NUM, (int)); OUTPUT_TYPEMAP(unsigned int, UINT2NUM, (unsigned int)); OUTPUT_TYPEMAP(unsigned short, UINT2NUM, (unsigned int)); OUTPUT_TYPEMAP(unsigned long, UINT2NUM, (unsigned int)); OUTPUT_TYPEMAP(unsigned long long, ULL2NUM, (unsigned int)); OUTPUT_TYPEMAP(unsigned char, UINT2NUM, (unsigned int)); OUTPUT_TYPEMAP(signed char, INT2NUM, (int)); OUTPUT_TYPEMAP(float, rb_float_new, (double)); OUTPUT_TYPEMAP(double, rb_float_new, (double)); #undef OUTPUT_TYPEMAP %typemap(in,numinputs=0) bool *OUTPUT(bool temp), bool &OUTPUT(bool temp) "$1 = &temp;"; %typemap(argout, fragment="output_helper") bool *OUTPUT, bool &OUTPUT { VALUE o = (*$1) ? Qtrue : Qfalse; $result = output_helper($result, o); } // INOUT // Mappings for an argument that is both an input and output // parameter /* The following methods can be applied to make a function parameter both an input and output value. This combines the behavior of both the "INPUT" and "OUTPUT" methods described earlier. Output values are returned in the form of a Ruby array. int *INOUT short *INOUT long *INOUT long long *INOUT unsigned int *INOUT unsigned short *INOUT unsigned long *INOUT unsigned long long *INOUT unsigned char *INOUT bool *INOUT float *INOUT double *INOUT For example, suppose you were trying to wrap the following function : void neg(double *x) { *x = -(*x); } You could wrap it with SWIG as follows : %include typemaps.i void neg(double *INOUT); or you can use the %apply directive : %include typemaps.i %apply double *INOUT { double *x }; void neg(double *x); Unlike C, this mapping does not directly modify the input value (since this makes no sense in Ruby). Rather, the modified input value shows up as the return value of the function. Thus, to apply this function to a Ruby variable you might do this : x = neg(x) Note : previous versions of SWIG used the symbol 'BOTH' to mark input/output arguments. This is still supported, but will be slowly phased out in future releases. */ %typemap(in) int *INOUT = int *INPUT; %typemap(in) short *INOUT = short *INPUT; %typemap(in) long *INOUT = long *INPUT; %typemap(in) long long *INOUT = long long *INPUT; %typemap(in) unsigned *INOUT = unsigned *INPUT; %typemap(in) unsigned short *INOUT = unsigned short *INPUT; %typemap(in) unsigned long *INOUT = unsigned long *INPUT; %typemap(in) unsigned long long *INOUT = unsigned long long *INPUT; %typemap(in) unsigned char *INOUT = unsigned char *INPUT; %typemap(in) signed char *INOUT = signed char *INPUT; %typemap(in) bool *INOUT = bool *INPUT; %typemap(in) float *INOUT = float *INPUT; %typemap(in) double *INOUT = double *INPUT; %typemap(in) int &INOUT = int &INPUT; %typemap(in) short &INOUT = short &INPUT; %typemap(in) long &INOUT = long &INPUT; %typemap(in) long long &INOUT = long long &INPUT; %typemap(in) unsigned &INOUT = unsigned &INPUT; %typemap(in) unsigned short &INOUT = unsigned short &INPUT; %typemap(in) unsigned long &INOUT = unsigned long &INPUT; %typemap(in) unsigned long long &INOUT = unsigned long long &INPUT; %typemap(in) unsigned char &INOUT = unsigned char &INPUT; %typemap(in) signed char &INOUT = signed char &INPUT; %typemap(in) bool &INOUT = bool &INPUT; %typemap(in) float &INOUT = float &INPUT; %typemap(in) double &INOUT = double &INPUT; %typemap(argout) int *INOUT = int *OUTPUT; %typemap(argout) short *INOUT = short *OUTPUT; %typemap(argout) long *INOUT = long *OUTPUT; %typemap(argout) long long *INOUT = long long *OUTPUT; %typemap(argout) unsigned *INOUT = unsigned *OUTPUT; %typemap(argout) unsigned short *INOUT = unsigned short *OUTPUT; %typemap(argout) unsigned long *INOUT = unsigned long *OUTPUT; %typemap(argout) unsigned long long *INOUT = unsigned long long *OUTPUT; %typemap(argout) unsigned char *INOUT = unsigned char *OUTPUT; %typemap(argout) signed char *INOUT = signed char *OUTPUT; %typemap(argout) bool *INOUT = bool *OUTPUT; %typemap(argout) float *INOUT = float *OUTPUT; %typemap(argout) double *INOUT = double *OUTPUT; %typemap(argout) int &INOUT = int &OUTPUT; %typemap(argout) short &INOUT = short &OUTPUT; %typemap(argout) long &INOUT = long &OUTPUT; %typemap(argout) long long &INOUT = long long &OUTPUT; %typemap(argout) unsigned &INOUT = unsigned &OUTPUT; %typemap(argout) unsigned short &INOUT = unsigned short &OUTPUT; %typemap(argout) unsigned long &INOUT = unsigned long &OUTPUT; %typemap(argout) unsigned long long &INOUT = unsigned long long &OUTPUT; %typemap(argout) unsigned char &INOUT = unsigned char &OUTPUT; %typemap(argout) signed char &INOUT = signed char &OUTPUT; %typemap(argout) bool &INOUT = bool &OUTPUT; %typemap(argout) float &INOUT = float &OUTPUT; %typemap(argout) double &INOUT = double &OUTPUT; // -------------------------------------------------------------------- // Special types // -------------------------------------------------------------------- /* The typemaps.i library also provides the following mappings : struct timeval * time_t Ruby has builtin class Time. INPUT/OUTPUT typemap for timeval and time_t is provided. int PROG_ARGC char **PROG_ARGV Some C function receive argc and argv from C main function. This typemap provides ignore typemap which pass Ruby ARGV contents as argc and argv to C function. */ // struct timeval * %{ #ifdef __cplusplus extern "C" { #endif #ifdef HAVE_SYS_TIME_H # include struct timeval rb_time_timeval(VALUE); #endif #ifdef __cplusplus } #endif %} %typemap(in) struct timeval *INPUT (struct timeval temp) { if (NIL_P($input)) $1 = NULL; else { temp = rb_time_timeval($input); $1 = &temp; } } %typemap(in,numinputs=0) struct timeval *OUTPUT(struct timeval temp) { $1 = &temp; } %typemap(argout) struct timeval *OUTPUT { $result = rb_time_new($1->tv_sec, $1->tv_usec); } %typemap(out) struct timeval * { $result = rb_time_new($1->tv_sec, $1->tv_usec); } %typemap(out) struct timespec * { $result = rb_time_new($1->tv_sec, $1->tv_nsec / 1000); } // time_t %typemap(in) time_t { if (NIL_P($input)) $1 = (time_t)-1; else $1 = NUM2LONG(rb_funcall($input, rb_intern("tv_sec"), 0)); } %typemap(out) time_t { $result = rb_time_new($1, 0); } // argc and argv %typemap(in,numinputs=0) int PROG_ARGC { $1 = RARRAY(rb_argv)->len + 1; } %typemap(in,numinputs=0) char **PROG_ARGV { int i, n; VALUE ary = rb_eval_string("[$0] + ARGV"); n = RARRAY(ary)->len; $1 = (char **)malloc(n + 1); for (i = 0; i < n; i++) { VALUE v = rb_obj_as_string(RARRAY(ary)->ptr[i]); $1[i] = (char *)malloc(RSTRING(v)->len + 1); strcpy($1[i], RSTRING(v)->ptr); } } %typemap(freearg) char **PROG_ARGV { int i, n = RARRAY(rb_argv)->len + 1; for (i = 0; i < n; i++) free($1[i]); free($1); } // FILE * %{ #ifdef __cplusplus extern "C" { #endif #include "rubyio.h" #ifdef __cplusplus } #endif %} %typemap(in) FILE *READ { OpenFile *of; GetOpenFile($input, of); rb_io_check_readable(of); $1 = GetReadFile(of); rb_read_check($1); } %typemap(in) FILE *READ_NOCHECK { OpenFile *of; GetOpenFile($input, of); rb_io_check_readable(of); $1 = GetReadFile(of); } %typemap(in) FILE *WRITE { OpenFile *of; GetOpenFile($input, of); rb_io_check_writable(of); $1 = GetWriteFile(of); } /* Overloading information */ %typemap(typecheck) double *INOUT = double; %typemap(typecheck) signed char *INOUT = signed char; %typemap(typecheck) unsigned char *INOUT = unsigned char; %typemap(typecheck) unsigned long *INOUT = unsigned long; %typemap(typecheck) unsigned long long *INOUT = unsigned long long; %typemap(typecheck) unsigned short *INOUT = unsigned short; %typemap(typecheck) unsigned int *INOUT = unsigned int; %typemap(typecheck) long *INOUT = long; %typemap(typecheck) long long *INOUT = long long; %typemap(typecheck) short *INOUT = short; %typemap(typecheck) int *INOUT = int; %typemap(typecheck) float *INOUT = float; %typemap(typecheck) double &INOUT = double; %typemap(typecheck) signed char &INOUT = signed char; %typemap(typecheck) unsigned char &INOUT = unsigned char; %typemap(typecheck) unsigned long &INOUT = unsigned long; %typemap(typecheck) unsigned long long &INOUT = unsigned long long; %typemap(typecheck) unsigned short &INOUT = unsigned short; %typemap(typecheck) unsigned int &INOUT = unsigned int; %typemap(typecheck) long &INOUT = long; %typemap(typecheck) long long &INOUT = long long; %typemap(typecheck) short &INOUT = short; %typemap(typecheck) int &INOUT = int; %typemap(typecheck) float &INOUT = float; cableswig-0.1.0+git20150808.orig/SWIG/Lib/ruby/rubydec.swg0000644000175000000620000000145412561312227021450 0ustar stevestaff/* rubydec.swg -*- c -*- */ #ifdef __cplusplus extern "C" { #endif SWIGIMPORT(void) SWIG_Ruby_InitRuntime(void); SWIGIMPORT(void) SWIG_Ruby_define_class(swig_type_info *); SWIGIMPORT(VALUE) SWIG_Ruby_NewPointerObj(void *, swig_type_info *, int); SWIGIMPORT(VALUE) SWIG_Ruby_NewClassInstance(VALUE, swig_type_info *); SWIGIMPORT(char *) SWIG_Ruby_MangleStr(VALUE); SWIGIMPORT(int) SWIG_Ruby_ConvertPtr(VALUE, void**, swig_type_info *, int); SWIGIMPORT(void *) SWIG_Ruby_MustGetPtr(VALUE, swig_type_info *, int, int); SWIGIMPORT(int) SWIG_Ruby_CheckConvert(VALUE, swig_type_info *); SWIGIMPORT(VALUE) SWIG_Ruby_NewPackedObj(void *ptr, int sz, swig_type_info *type); SWIGIMPORT(void) SWIG_Ruby_ConvertPacked(VALUE obj, void *ptr, int sz, swig_type_info *ty, int flags); #ifdef __cplusplus } #endif cableswig-0.1.0+git20150808.orig/SWIG/Lib/ruby/std_pair.i0000644000175000000620000012240012561312227021243 0ustar stevestaff// // SWIG typemaps for std::pair // Luigi Ballabio // July 2003 // // Ruby implementation %include std_common.i %include exception.i // ------------------------------------------------------------------------ // std::pair // // See std_vector.i for the rationale of typemap application // ------------------------------------------------------------------------ %{ #include %} // exported class namespace std { template struct pair { %typemap(in) pair (std::pair* p) { if (rb_obj_is_kind_of($input,rb_cArray)) { unsigned int size = RARRAY($input)->len; if (size != 2) SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); T* x; U* y; VALUE first = RARRAY($input)->ptr[0]; VALUE second = RARRAY($input)->ptr[1]; SWIG_ConvertPtr(first, (void **) &x, $descriptor(T *), 1); SWIG_ConvertPtr(second, (void **) &y, $descriptor(U *), 1); $1 = std::make_pair(x,y); } else { SWIG_ConvertPtr($input, (void **) &p, $&1_descriptor, 1); $1 = *p; } } %typemap(in) const pair& (std::pair temp, std::pair* p), const pair* (std::pair temp, std::pair* p) { if (rb_obj_is_kind_of($input,rb_cArray)) { unsigned int size = RARRAY($input)->len; if (size != 2) SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); T* x; U* y; VALUE first = RARRAY($input)->ptr[0]; VALUE second = RARRAY($input)->ptr[1]; SWIG_ConvertPtr(first, (void **) &x, $descriptor(T *), 1); SWIG_ConvertPtr(second, (void **) &y, $descriptor(U *), 1); temp = std::make_pair(x,y); $1 = &temp; } else { SWIG_ConvertPtr($input, (void **) &p, $1_descriptor, 1); $1 = p; } } %typemap(out) pair { $result = rb_ary_new2(2); T* x = new T($1.first); U* y = new U($1.second); rb_ary_store($result,0, SWIG_NewPointerObj((void *) x, $descriptor(T *), 1)); rb_ary_store($result,1, SWIG_NewPointerObj((void *) y, $descriptor(U *), 1)); } %typecheck(SWIG_TYPECHECK_PAIR) pair { /* native sequence? */ if (rb_obj_is_kind_of($input,rb_cArray)) { unsigned int size = RARRAY($input)->len; if (size != 2) { /* not a pair */ $1 = 0; } else { T* x; U* y; VALUE first = RARRAY($input)->ptr[0]; VALUE second = RARRAY($input)->ptr[1]; if (SWIG_ConvertPtr(first,(void **) &x, $descriptor(T *),0) != -1 && SWIG_ConvertPtr(second,(void **) &y, $descriptor(U *),0) != -1) $1 = 1; else $1 = 0; } } else { /* wrapped pair? */ std::pair* p; if (SWIG_ConvertPtr($input,(void **) &p, $&1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_PAIR) const pair&, const pair* { /* native sequence? */ if (rb_obj_is_kind_of($input,rb_cHash)) { unsigned int size = RARRAY($input)->len; if (size != 2) { /* not a pair */ $1 = 0; } else { T* x; U* y; VALUE first = RARRAY($input)->ptr[0]; VALUE second = RARRAY($input)->ptr[1]; if (SWIG_ConvertPtr(first,(void **) &x, $descriptor(T *),0) != -1 && SWIG_ConvertPtr(second,(void **) &y, $descriptor(U *),0) != -1) $1 = 1; else $1 = 0; } } else { /* wrapped map? */ std::pair* p; if (SWIG_ConvertPtr($input,(void **) &p, $1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } T first; U second; }; // specializations for built-ins %define specialize_std_pair_on_first(T,CHECK,CONVERT_FROM,CONVERT_TO) template struct pair { %typemap(in) pair (std::pair* p) { if (rb_obj_is_kind_of($input,rb_cArray)) { unsigned int size = RARRAY($input)->len; if (size != 2) SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); U* y; VALUE first = RARRAY($input)->ptr[0]; VALUE second = RARRAY($input)->ptr[1]; if (!CHECK(first)) SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); SWIG_ConvertPtr(second, (void **) &y, $descriptor(U *), 1); $1 = std::make_pair(CONVERT_FROM(first),y); } else { SWIG_ConvertPtr($input, (void **) &p, $&1_descriptor, 1); $1 = *p; } } %typemap(in) const pair& (std::pair temp, std::pair* p), const pair* (std::pair temp, std::pair* p) { if (rb_obj_is_kind_of($input,rb_cArray)) { unsigned int size = RARRAY($input)->len; if (size != 2) SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); U* y; VALUE first = RARRAY($input)->ptr[0]; VALUE second = RARRAY($input)->ptr[1]; if (!CHECK(first)) SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); SWIG_ConvertPtr(second, (void **) &y, $descriptor(U *), 1); temp = std::make_pair(CONVERT_FROM(first),y); $1 = &temp; } else { SWIG_ConvertPtr($input, (void **) &p, $1_descriptor, 1); $1 = p; } } %typemap(out) pair { $result = rb_ary_new2(2); U* y = new U($1.second); rb_ary_store($result,0,CONVERT_TO($1.first)); rb_ary_store($result,1, SWIG_NewPointerObj((void *) y, $descriptor(U *), 1)); } %typecheck(SWIG_TYPECHECK_MAP) pair { /* native sequence? */ if (rb_obj_is_kind_of($input,rb_cArray)) { unsigned int size = RARRAY($input)->len; if (size != 2) { /* not a pair */ $1 = 0; } else { U* y; VALUE first = RARRAY($input)->ptr[0]; VALUE second = RARRAY($input)->ptr[1]; if (CHECK(first) && SWIG_ConvertPtr(second,(void **) &y, $descriptor(U *),0) != -1) $1 = 1; else $1 = 0; } } else { /* wrapped pair? */ std::pair* p; if (SWIG_ConvertPtr($input,(void **) &p, $&1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_MAP) const pair&, const pair* { /* native sequence? */ if (rb_obj_is_kind_of($input,rb_cHash)) { unsigned int size = RARRAY($input)->len; if (size != 2) { /* not a pair */ $1 = 0; } else { U* y; VALUE first = RARRAY($input)->ptr[0]; VALUE second = RARRAY($input)->ptr[1]; if (CHECK(first) && SWIG_ConvertPtr(second,(void **) &y, $descriptor(U *),0) != -1) $1 = 1; else $1 = 0; } } else { /* wrapped map? */ std::pair* p; if (SWIG_ConvertPtr($input,(void **) &p, $1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } T first; U second; }; %enddef %define specialize_std_pair_on_second(U,CHECK,CONVERT_FROM,CONVERT_TO) template struct pair { %typemap(in) pair (std::pair* p) { if (rb_obj_is_kind_of($input,rb_cArray)) { unsigned int size = RARRAY($input)->len; if (size != 2) { SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); } T* x; VALUE first = RARRAY($input)->ptr[0]; VALUE second = RARRAY($input)->ptr[1]; SWIG_ConvertPtr(first, (void **) &x, $descriptor(T *), 1); if (!CHECK(second)) SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); $1 = std::make_pair(x,CONVERT_FROM(second)); } else { SWIG_ConvertPtr($input, (void **) &p, $&1_descriptor, 1); $1 = *p; } } %typemap(in) const pair& (std::pair temp, std::pair* p), const pair* (std::pair temp, std::pair* p) { if (rb_obj_is_kind_of($input,rb_cArray)) { unsigned int size = RARRAY($input)->len; if (size != 2) { SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); } T* x; VALUE first = RARRAY($input)->ptr[0]; VALUE second = RARRAY($input)->ptr[1]; SWIG_ConvertPtr(first, (void **) &x, $descriptor(T *), 1); if (!CHECK(second)) SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); temp = std::make_pair(x,CONVERT_FROM(second)); $1 = &temp; } else { SWIG_ConvertPtr($input, (void **) &p, $1_descriptor, 1); $1 = p; } } %typemap(out) pair { $result = rb_ary_new2(2); T* x = new T($1.first); rb_ary_store($result,0, SWIG_NewPointerObj((void *) x, $descriptor(T *), 1)); rb_ary_store($result,1,CONVERT_TO($1.second)); } %typecheck(SWIG_TYPECHECK_PAIR) pair { /* native sequence? */ if (rb_obj_is_kind_of($input,rb_cArray)) { unsigned int size = RARRAY($input)->len; if (size != 2) { /* not a pair */ $1 = 0; } else { T* x; VALUE first = RARRAY($input)->ptr[0]; VALUE second = RARRAY($input)->ptr[1]; if (SWIG_ConvertPtr(first,(void **) &x, $descriptor(T *),0) != -1 && CHECK(second)) $1 = 1; else $1 = 0; } } else { /* wrapped pair? */ std::pair* p; if (SWIG_ConvertPtr($input,(void **) &p, $&1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_PAIR) const pair&, const pair* { /* native sequence? */ if (rb_obj_is_kind_of($input,rb_cHash)) { unsigned int size = RARRAY($input)->len; if (size != 2) { /* not a pair */ $1 = 0; } else { T* x; VALUE first = RARRAY($input)->ptr[0]; VALUE second = RARRAY($input)->ptr[1]; if (SWIG_ConvertPtr(first,(void **) &x, $descriptor(T *),0) != -1 && CHECK(second)) $1 = 1; else $1 = 0; } } else { /* wrapped map? */ std::pair* p; if (SWIG_ConvertPtr($input,(void **) &p, $1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } T first; U second; }; %enddef %define specialize_std_pair_on_both(T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO, U,CHECK_U,CONVERT_U_FROM,CONVERT_U_TO) template<> struct pair { %typemap(in) pair (std::pair* p) { if (rb_obj_is_kind_of($input,rb_cArray)) { unsigned int size = RARRAY($input)->len; if (size != 2) { SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); } VALUE first = RARRAY($input)->ptr[0]; VALUE second = RARRAY($input)->ptr[1]; if (!CHECK_T(first) || !CHECK_U(second)) SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); $1 = std::make_pair(CONVERT_T_FROM(first), CONVERT_U_FROM(second)); } else { SWIG_ConvertPtr($input, (void **) &p, $&1_descriptor, 1); $1 = *p; } } %typemap(in) const pair& (std::pair temp, std::pair* p), const pair* (std::pair temp, std::pair* p) { if (rb_obj_is_kind_of($input,rb_cArray)) { unsigned int size = RARRAY($input)->len; if (size != 2) { SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); } VALUE first = RARRAY($input)->ptr[0]; VALUE second = RARRAY($input)->ptr[1]; if (!CHECK_T(first) || !CHECK_U(second)) SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); temp = std::make_pair(CONVERT_T_FROM(first), CONVERT_U_FROM(second)); $1 = &temp; } else { SWIG_ConvertPtr($input, (void **) &p, $1_descriptor, 1); $1 = p; } } %typemap(out) pair { $result = rb_ary_new2(2); rb_ary_store($result,0,CONVERT_T_TO($1.first)); rb_ary_store($result,1,CONVERT_U_TO($1.second)); } %typecheck(SWIG_TYPECHECK_PAIR) pair { /* native sequence? */ if (rb_obj_is_kind_of($input,rb_cArray)) { unsigned int size = RARRAY($input)->len; if (size != 2) { /* not a pair */ $1 = 0; } else { VALUE first = RARRAY($input)->ptr[0]; VALUE second = RARRAY($input)->ptr[1]; if (CHECK_T(first) && CHECK_U(second)) $1 = 1; else $1 = 0; } } else { /* wrapped pair? */ std::pair* p; if (SWIG_ConvertPtr($input,(void **) &p, $&1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_PAIR) const pair&, const pair* { /* native sequence? */ if (rb_obj_is_kind_of($input,rb_cHash)) { unsigned int size = RARRAY($input)->len; if (size != 2) { /* not a pair */ $1 = 0; } else { VALUE first = RARRAY($input)->ptr[0]; VALUE second = RARRAY($input)->ptr[1]; if (CHECK_T(first) && CHECK_U(second)) $1 = 1; else $1 = 0; } } else { /* wrapped map? */ std::pair* p; if (SWIG_ConvertPtr($input,(void **) &p, $1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } T first; U second; }; %enddef specialize_std_pair_on_first(bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB); specialize_std_pair_on_first(int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_first(short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_first(long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_first(unsigned int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_first(unsigned short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_first(unsigned long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_first(double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_pair_on_first(float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_pair_on_first(std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB); specialize_std_pair_on_second(bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB); specialize_std_pair_on_second(int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_second(short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_second(long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_second(unsigned int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_second(unsigned short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_second(unsigned long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_second(double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_pair_on_second(float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_pair_on_second(std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB); specialize_std_pair_on_both(bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB, bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB); specialize_std_pair_on_both(bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB, int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB, short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB, long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB, unsigned int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB, unsigned short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB, unsigned long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB, double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_pair_on_both(bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB, float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_pair_on_both(bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB, std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB); specialize_std_pair_on_both(int,FIXNUM_P, FIX2INT,INT2NUM, bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB); specialize_std_pair_on_both(int,FIXNUM_P, FIX2INT,INT2NUM, int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(int,FIXNUM_P, FIX2INT,INT2NUM, short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(int,FIXNUM_P, FIX2INT,INT2NUM, long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(int,FIXNUM_P, FIX2INT,INT2NUM, unsigned int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(int,FIXNUM_P, FIX2INT,INT2NUM, unsigned short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(int,FIXNUM_P, FIX2INT,INT2NUM, unsigned long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(int,FIXNUM_P, FIX2INT,INT2NUM, double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_pair_on_both(int,FIXNUM_P, FIX2INT,INT2NUM, float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_pair_on_both(int,FIXNUM_P, FIX2INT,INT2NUM, std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB); specialize_std_pair_on_both(short,FIXNUM_P, FIX2INT,INT2NUM, bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB); specialize_std_pair_on_both(short,FIXNUM_P, FIX2INT,INT2NUM, int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(short,FIXNUM_P, FIX2INT,INT2NUM, short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(short,FIXNUM_P, FIX2INT,INT2NUM, long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(short,FIXNUM_P, FIX2INT,INT2NUM, unsigned int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(short,FIXNUM_P, FIX2INT,INT2NUM, unsigned short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(short,FIXNUM_P, FIX2INT,INT2NUM, unsigned long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(short,FIXNUM_P, FIX2INT,INT2NUM, double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_pair_on_both(short,FIXNUM_P, FIX2INT,INT2NUM, float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_pair_on_both(short,FIXNUM_P, FIX2INT,INT2NUM, std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB); specialize_std_pair_on_both(long,FIXNUM_P, FIX2INT,INT2NUM, bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB); specialize_std_pair_on_both(long,FIXNUM_P, FIX2INT,INT2NUM, int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(long,FIXNUM_P, FIX2INT,INT2NUM, short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(long,FIXNUM_P, FIX2INT,INT2NUM, long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(long,FIXNUM_P, FIX2INT,INT2NUM, unsigned int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(long,FIXNUM_P, FIX2INT,INT2NUM, unsigned short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(long,FIXNUM_P, FIX2INT,INT2NUM, unsigned long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(long,FIXNUM_P, FIX2INT,INT2NUM, double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_pair_on_both(long,FIXNUM_P, FIX2INT,INT2NUM, float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_pair_on_both(long,FIXNUM_P, FIX2INT,INT2NUM, std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB); specialize_std_pair_on_both(unsigned int,FIXNUM_P, FIX2INT,INT2NUM, bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB); specialize_std_pair_on_both(unsigned int,FIXNUM_P, FIX2INT,INT2NUM, int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(unsigned int,FIXNUM_P, FIX2INT,INT2NUM, short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(unsigned int,FIXNUM_P, FIX2INT,INT2NUM, long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(unsigned int,FIXNUM_P, FIX2INT,INT2NUM, unsigned int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(unsigned int,FIXNUM_P, FIX2INT,INT2NUM, unsigned short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(unsigned int,FIXNUM_P, FIX2INT,INT2NUM, unsigned long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(unsigned int,FIXNUM_P, FIX2INT,INT2NUM, double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_pair_on_both(unsigned int,FIXNUM_P, FIX2INT,INT2NUM, float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_pair_on_both(unsigned int,FIXNUM_P, FIX2INT,INT2NUM, std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB); specialize_std_pair_on_both(unsigned short,FIXNUM_P, FIX2INT,INT2NUM, bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB); specialize_std_pair_on_both(unsigned short,FIXNUM_P, FIX2INT,INT2NUM, int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(unsigned short,FIXNUM_P, FIX2INT,INT2NUM, short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(unsigned short,FIXNUM_P, FIX2INT,INT2NUM, long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(unsigned short,FIXNUM_P, FIX2INT,INT2NUM, unsigned int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(unsigned short,FIXNUM_P, FIX2INT,INT2NUM, unsigned short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(unsigned short,FIXNUM_P, FIX2INT,INT2NUM, unsigned long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(unsigned short,FIXNUM_P, FIX2INT,INT2NUM, double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_pair_on_both(unsigned short,FIXNUM_P, FIX2INT,INT2NUM, float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_pair_on_both(unsigned short,FIXNUM_P, FIX2INT,INT2NUM, std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB); specialize_std_pair_on_both(unsigned long,FIXNUM_P, FIX2INT,INT2NUM, bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB); specialize_std_pair_on_both(unsigned long,FIXNUM_P, FIX2INT,INT2NUM, int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(unsigned long,FIXNUM_P, FIX2INT,INT2NUM, short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(unsigned long,FIXNUM_P, FIX2INT,INT2NUM, long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(unsigned long,FIXNUM_P, FIX2INT,INT2NUM, unsigned int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(unsigned long,FIXNUM_P, FIX2INT,INT2NUM, unsigned short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(unsigned long,FIXNUM_P, FIX2INT,INT2NUM, unsigned long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(unsigned long,FIXNUM_P, FIX2INT,INT2NUM, double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_pair_on_both(unsigned long,FIXNUM_P, FIX2INT,INT2NUM, float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_pair_on_both(unsigned long,FIXNUM_P, FIX2INT,INT2NUM, std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB); specialize_std_pair_on_both(double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB); specialize_std_pair_on_both(double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, unsigned int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, unsigned short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, unsigned long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_pair_on_both(double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_pair_on_both(double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB); specialize_std_pair_on_both(float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB); specialize_std_pair_on_both(float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, unsigned int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, unsigned short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, unsigned long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_pair_on_both(float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_pair_on_both(float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new, std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB); specialize_std_pair_on_both(std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB, bool,SWIG_BOOL_P, SWIG_RB2BOOL,SWIG_BOOL2RB); specialize_std_pair_on_both(std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB, int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB, short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB, long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB, unsigned int,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB, unsigned short,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB, unsigned long,FIXNUM_P, FIX2INT,INT2NUM); specialize_std_pair_on_both(std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB, double,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_pair_on_both(std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB, float,SWIG_FLOAT_P, SWIG_NUM2DBL,rb_float_new); specialize_std_pair_on_both(std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB, std::string,SWIG_STRING_P, SWIG_RB2STR,SWIG_STR2RB); } cableswig-0.1.0+git20150808.orig/SWIG/Lib/ruby/embed.i0000644000175000000620000000025112561312227020511 0ustar stevestaff%wrapper %{ #include "ruby.h" int main(argc, argv) int argc; char **argv; { ruby_init(); ruby_options(argc, argv); ruby_run(); return 0; } %} cableswig-0.1.0+git20150808.orig/SWIG/Lib/ruby/extra-install.list0000644000175000000620000000006512561312227022752 0ustar stevestaff# see top-level Makefile.in Makefile.swig extconf.rb cableswig-0.1.0+git20150808.orig/SWIG/Lib/ruby/rubyhead.swg0000644000175000000620000000633612561312227021622 0ustar stevestaff/* ruby.swg */ /* Implementation : RUBY */ #define SWIGRUBY 1 #include "ruby.h" /* Flags for pointer conversion */ #define SWIG_POINTER_EXCEPTION 0x1 #define SWIG_POINTER_DISOWN 0x2 #define NUM2USHRT(n) (\ (0 <= NUM2UINT(n) && NUM2UINT(n) <= USHRT_MAX)\ ? (unsigned short) NUM2UINT(n) \ : (rb_raise(rb_eArgError, "integer %d out of range of `unsigned short'",\ NUM2UINT(n)), (short)0)\ ) #define NUM2SHRT(n) (\ (SHRT_MIN <= NUM2INT(n) && NUM2INT(n) <= SHRT_MAX)\ ? (short)NUM2INT(n)\ : (rb_raise(rb_eArgError, "integer %d out of range of `short'",\ NUM2INT(n)), (short)0)\ ) /* Ruby 1.7 defines NUM2LL(), LL2NUM() and ULL2NUM() macros */ #ifndef NUM2LL #define NUM2LL(x) NUM2LONG((x)) #endif #ifndef LL2NUM #define LL2NUM(x) INT2NUM((long) (x)) #endif #ifndef ULL2NUM #define ULL2NUM(x) UINT2NUM((unsigned long) (x)) #endif /* Ruby 1.7 doesn't (yet) define NUM2ULL() */ #ifndef NUM2ULL #ifdef HAVE_LONG_LONG #define NUM2ULL(x) rb_num2ull((x)) #else #define NUM2ULL(x) NUM2ULONG(x) #endif #endif /* * Need to be very careful about how these macros are defined, especially * when compiling C++ code or C code with an ANSI C compiler. * * VALUEFUNC(f) is a macro used to typecast a C function that implements * a Ruby method so that it can be passed as an argument to API functions * like rb_define_method() and rb_define_singleton_method(). * * VOIDFUNC(f) is a macro used to typecast a C function that implements * either the "mark" or "free" stuff for a Ruby Data object, so that it * can be passed as an argument to API functions like Data_Wrap_Struct() * and Data_Make_Struct(). */ #ifdef __cplusplus # ifndef RUBY_METHOD_FUNC /* These definitions should work for Ruby 1.4.6 */ # define VALUEFUNC(f) ((VALUE (*)()) f) # define VOIDFUNC(f) ((void (*)()) f) # else # ifndef ANYARGS /* These definitions should work for Ruby 1.6 */ # define VALUEFUNC(f) ((VALUE (*)()) f) # define VOIDFUNC(f) ((RUBY_DATA_FUNC) f) # else /* These definitions should work for Ruby 1.7 */ # define VALUEFUNC(f) ((VALUE (*)(ANYARGS)) f) # define VOIDFUNC(f) ((RUBY_DATA_FUNC) f) # endif # endif #else # define VALUEFUNC(f) (f) # define VOIDFUNC(f) (f) #endif typedef struct { VALUE klass; VALUE mImpl; void (*mark)(void *); void (*destroy)(void *); } swig_class; /* Don't use for expressions have side effect */ #ifndef RB_STRING_VALUE #define RB_STRING_VALUE(s) (TYPE(s) == T_STRING ? (s) : (*(volatile VALUE *)&(s) = rb_str_to_str(s))) #endif #ifndef StringValue #define StringValue(s) RB_STRING_VALUE(s) #endif #ifndef StringValuePtr #define StringValuePtr(s) RSTRING(RB_STRING_VALUE(s))->ptr #endif #ifndef StringValueLen #define StringValueLen(s) RSTRING(RB_STRING_VALUE(s))->len #endif #ifndef SafeStringValue #define SafeStringValue(v) do {\ StringValue(v);\ rb_check_safe_str(v);\ } while (0) #endif #ifndef HAVE_RB_DEFINE_ALLOC_FUNC #define rb_define_alloc_func(klass, func) rb_define_singleton_method((klass), "new", VALUEFUNC((func)), -1) #define rb_undef_alloc_func(klass) rb_undef_method(CLASS_OF((klass)), "new") #endif /* Contract support */ #define SWIG_contract_assert(expr, msg) if (!(expr)) { rb_raise(rb_eRuntimeError, (char *) msg ); } else cableswig-0.1.0+git20150808.orig/SWIG/Lib/ruby/fragments.i0000644000175000000620000000054012561312227021424 0ustar stevestaff// Helper function for Array output %fragment("output_helper", "header") %{ static VALUE output_helper(VALUE target, VALUE o) { if (NIL_P(target)) { target = o; } else { if (TYPE(target) != T_ARRAY) { VALUE o2 = target; target = rb_ary_new(); rb_ary_push(target, o2); } rb_ary_push(target, o); } return target; } %} cableswig-0.1.0+git20150808.orig/SWIG/Lib/ruby/std_deque.i0000644000175000000620000000040612561312227021414 0ustar stevestaff/* Default std_deque wrapper */ %module std_deque %rename(__getitem__) std::deque::getitem; %rename(__setitem__) std::deque::setitem; %predicate std::deque::empty; %alias std::deque::push_back "<<"; %alias std::deque::size "length"; %include "_std_deque.i" cableswig-0.1.0+git20150808.orig/SWIG/Lib/ruby/ruby.swg0000644000175000000620000005117112561312227020775 0ustar stevestaff/* ---------------------------------------------------------------------- * ruby.swg * * Ruby configuation file. * ---------------------------------------------------------------------- */ %runtime "rubyhead.swg" %runtime "precommon.swg" %runtime "common.swg" #ifdef SWIG_NOINCLUDE %runtime "rubydec.swg" #else %runtime "rubydef.swg" #endif #define %alias %feature("alias") #define %freefunc %feature("freefunc") #define %markfunc %feature("markfunc") #define %mixin %feature("mixin") #define %predicate %feature("predicate", "1") /* ---------------------------------------------------------------------- * Standard Typemaps * ---------------------------------------------------------------------- */ /* --- Input Values --- */ %typemap(in) int "$1 = NUM2INT($input);"; %typemap(in) unsigned int "$1 = NUM2UINT($input);"; %typemap(in) short "$1 = NUM2SHRT($input);"; %typemap(in) unsigned short "$1 = NUM2USHRT($input);"; %typemap(in) long "$1 = NUM2LONG($input);"; %typemap(in) unsigned long "$1 = NUM2ULONG($input);"; %typemap(in) signed char "$1 = ($1_ltype) NUM2INT($input);"; %typemap(in) unsigned char "$1 = ($1_ltype) NUM2INT($input);"; %typemap(in) char "$1 = NUM2CHR($input);"; %typemap(in) float, double "$1 = ($1_ltype) NUM2DBL($input);"; %typemap(in) bool "$1 = RTEST($input);"; %typemap(in) char * "$1 = StringValuePtr($input);"; %typemap(in) char [ANY] "$1 = StringValuePtr($input);"; %typemap(in) enum SWIGTYPE "$1 = ($1_ltype) NUM2INT($input);"; /* Long long */ %typemap(in) long long "$1 = ($1_ltype) NUM2LL($input);"; %typemap(in) unsigned long long "$1 = ($1_ltype) NUM2ULL($input);"; /* Typemaps for pointers. Note: the SWIG run-time type checker works even if a pointer happens to be mapped to a Ruby class */ %typemap(in) SWIGTYPE *, SWIGTYPE [] "SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 1);" /* Additional check for null references */ %typemap(in) SWIGTYPE & "SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 1); if ($1 == NULL) rb_raise(rb_eTypeError, \"null reference\");" /* Void pointer. Accepts any kind of pointer */ %typemap(in) void * "SWIG_ConvertPtr($input, (void **) &$1, 0, 1);"; /* Object passed by value. Convert to a pointer */ %typemap(in) SWIGTYPE { $&1_ltype ptr; SWIG_ConvertPtr($input, (void **) &ptr, $&1_descriptor, 1); if (ptr) $1 = *ptr; } /* Pointer to a class member */ %typemap(in) SWIGTYPE (CLASS::*) "SWIG_ConvertPacked($input, (void *) &$1, sizeof($1_type), $1_descriptor, 1);"; /* Const primitive references. Passed by value */ %typemap(in) const int & (int temp), const signed char & (signed char temp), const unsigned char & (unsigned char temp) "temp = ($*1_ltype) NUM2INT($input); $1 = &temp;"; %typemap(in) const short & (short temp) "temp = ($*1_ltype) NUM2SHRT($input); $1 = &temp;"; %typemap(in) const long & (long temp) "temp = ($*1_ltype) NUM2LONG($input); $1 = &temp;"; %typemap(in) const unsigned int & (unsigned int temp) "temp = ($*1_ltype) NUM2UINT($input); $1 = &temp;"; %typemap(in) const unsigned short & (unsigned short temp) "temp = ($*1_ltype) NUM2USHRT($input); $1 = &temp;"; %typemap(in) const unsigned long & (unsigned long temp) "temp = ($*1_ltype) NUM2ULONG($input); $1 = &temp;"; %typemap(in) const bool & (bool temp) "temp = ($*1_ltype) RTEST($input); $1 = &temp;"; %typemap(in) const float & (float temp), const double & (double temp) "temp = ($*1_ltype) NUM2DBL($input); $1 = &temp;"; %typemap(in) const long long & ($*1_ltype temp) "temp = ($*1_ltype) NUM2LL($input); $1 = &temp;"; %typemap(in) const unsigned long long & ($*1_ltype temp) "temp = ($*1_ltype) NUM2ULL($input); $1 = &temp;"; %typemap(in) const char &(char temp) { char *stemp = StringValuePtr($input); temp = *stemp; $1 = &temp; } /* --- Output typemaps --- */ %typemap(out) int, short, long, signed char, enum SWIGTYPE "$result = INT2NUM($1);"; %typemap(out) unsigned int, unsigned short, unsigned long, unsigned char "$result = UINT2NUM($1);"; /* Long long */ %typemap(out) long long "$result = LL2NUM($1);"; %typemap(out) unsigned long long "$result = ULL2NUM($1);"; /* Floating point output values */ %typemap(out) double, float "$result = rb_float_new($1);"; /* Character */ %typemap(out) char "$result = rb_str_new(&$1,1);"; /* Boolean */ %typemap(out) bool "$result = $1 ? Qtrue : Qfalse;"; /* C string */ %typemap(out) char * "$result = rb_str_new2($1);"; /* Pointers, references, and arrays */ %typemap(out) SWIGTYPE*, SWIGTYPE &, SWIGTYPE [] "$result = SWIG_NewPointerObj((void *) $1, $1_descriptor,$owner);"; /* Dynamic casts */ %typemap(out) SWIGTYPE *DYNAMIC, SWIGTYPE &DYNAMIC { swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor, (void **) &$1); $result = SWIG_NewPointerObj((void *) $1, ty,$owner); } /* Member pointer */ %typemap(out) SWIGTYPE (CLASS::*) "$result = SWIG_NewPackedObj((void *) &$1, sizeof($1_type), $1_descriptor);"; /* Void */ %typemap(out) void "$result = Qnil;"; /* Special typemap for character array return values */ %typemap(out) char [ANY], const char [ANY] "$result = rb_str_new2($1);"; /* Primitive types--return by value */ %typemap(out) SWIGTYPE #ifdef __cplusplus { $&1_ltype resultptr; resultptr = new $1_ltype(($1_ltype &)$1); $result = SWIG_NewPointerObj((void *) resultptr, $&1_descriptor, 1); } #else { $&1_ltype resultptr; resultptr = ($&1_ltype) malloc(sizeof($1_type)); memmove(resultptr, &$1, sizeof($1_type)); $result = SWIG_NewPointerObj((void *) resultptr, $&1_descriptor, 1); } #endif /* References to primitive types. Return by value */ %typemap(out) const int &, const short &, const long &, const signed char & "$result = INT2NUM((long) *($1));"; %typemap(out) const unsigned int &, const unsigned short &, const unsigned long &, const unsigned char & "$result = UINT2NUM((unsigned long) *($1));"; %typemap(out) const bool & "$result = *($1) ? Qtrue : Qfalse;"; %typemap(out) const float &, const double & "$result = rb_float_new((double) *($1));"; %typemap(out) const long long & "$result = LL2NUM(*($1));"; %typemap(out) const unsigned long long & "$result = ULL2NUM(*($1));"; %typemap(out) const char & "$result = rb_str_new($1, 1);"; /* --- Variable Input --- */ %typemap(varin) int "$1 = NUM2INT($input);"; %typemap(varin) unsigned int "$1 = NUM2UINT($input);"; %typemap(varin) short "$1 = NUM2SHRT($input);"; %typemap(varin) unsigned short "$1 = NUM2USHRT($input);"; %typemap(varin) long "$1 = NUM2LONG($input);"; %typemap(varin) unsigned long "$1 = NUM2ULONG($input);"; %typemap(varin) signed char "$1 = (signed char) NUM2INT($input);"; %typemap(varin) unsigned char "$1 = (unsigned char) NUM2INT($input);"; %typemap(varin) char "$1 = NUM2CHR($input);"; %typemap(varin) float, double "$1 = ($1_ltype) NUM2DBL($input);"; %typemap(varin) bool "$1 = RTEST($input);"; %typemap(varin) long long "$1 = NUM2LL($input);"; %typemap(varin) unsigned long long "$1 = NUM2ULL($input);"; %typemap(varin) enum SWIGTYPE "$1 = ($1_type) NUM2INT($input);"; /* A string */ #ifdef __cplusplus %typemap(varin) char * { char *temp = (char *) StringValuePtr($input); if ($1) delete [] $1; $1 = ($type) new char[strlen(temp)+1]; strcpy((char*)$1,temp); } %typemap(varin,warning="451:Setting const char * variable may leak memory") const char * { char *temp = (char *) StringValuePtr($input); $1 = ($type) new char[strlen(temp)+1]; strcpy((char*)$1,temp); } #else %typemap(varin) char * { char *temp = (char *) StringValuePtr($input); if ($1) free((char*) $1); $1 = ($type) malloc(strlen(temp)+1); strcpy((char*)$1,temp); } %typemap(varin,warning="451:Setting const char * variable may leak memory") const char * { char *temp = (char *) StringValuePtr($input); $1 = ($type) malloc(strlen(temp)+1); strcpy((char*)$1,temp); } #endif %typemap(varin) SWIGTYPE [ANY] { void *temp; int ii; $1_basetype *b = 0; if ((SWIG_ConvertPtr($input,(void **) &temp, $1_descriptor, 0)) == -1) { rb_raise(rb_eTypeError, "C variable '$name ($1_ltype)'"); } b = ($1_basetype *) $1; for (ii = 0; ii < $1_size; ii++) b[ii] = *(($1_basetype *) temp + ii); } /* Special case for string array variables */ %typemap(varin) char [ANY] "strncpy($1,StringValuePtr($input),$1_dim0);"; /* Typemaps for pointers. Note: the SWIG run-time type checker works even if a pointer happens to be mapped to a Ruby class */ %typemap(varin) SWIGTYPE * "SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 1);" %typemap(varin) SWIGTYPE & { void *temp; SWIG_ConvertPtr($input, (void **) &temp, $1_descriptor, 1); $1 = *($1_ltype) temp; } %typemap(varin) void * "SWIG_ConvertPtr($input, (void **) &$1, 0, 1);"; %typemap(varin) SWIGTYPE { $&1_ltype ptr; SWIG_ConvertPtr($input, (void **) &ptr, $&1_descriptor, 1); if (ptr) $1 = *ptr; } %typemap(varin) SWIGTYPE (CLASS::*) { char temp[sizeof($1_type)]; SWIG_ConvertPacked($input, (void *) temp, sizeof($1_type), $1_descriptor, 1); memmove((void *) &$1, temp, sizeof($1_type)); } /* --- Output typemaps --- */ %typemap(varout) int, short, long, signed char, enum SWIGTYPE "$result = INT2NUM($1);"; %typemap(varout) unsigned int, unsigned short, unsigned long, unsigned char "$result = UINT2NUM($1);"; %typemap(varout) long long "$result = LL2NUM($1);"; %typemap(varout) unsigned long long "$result = ULL2NUM($1);"; /* Floats and doubles */ %typemap(varout) double, float "$result = rb_float_new($1);"; /* Character */ %typemap(varout) char "$result = rb_str_new(&$1,1);"; /* Boolean */ %typemap(varout) bool "$result = $1 ? Qtrue : Qfalse;"; /* C string */ %typemap(varout) char * "$result = rb_str_new2($1);"; /* Pointers, references, and arrays */ %typemap(varout) SWIGTYPE*, SWIGTYPE [] "$result = SWIG_NewPointerObj((void *) $1, $1_descriptor,0);"; %typemap(varout) SWIGTYPE & "$result = SWIG_NewPointerObj((void *) &$1, $1_descriptor,0);"; /* Void */ %typemap(varout) void "$result = Qnil;"; /* Copy by value */ %typemap(varout) SWIGTYPE "$result = SWIG_NewPointerObj((void *) &$1, $&1_descriptor, 1);"; /* Special typemap for character array return values */ %typemap(varout) char [ANY], const char [ANY] "$result = rb_str_new2($1);"; /* Member pointer */ %typemap(varout) SWIGTYPE (CLASS::*) "$result = SWIG_NewPackedObj((void *) &$1, sizeof($1_type), $1_descriptor);"; /* --- Constants --- */ %typemap(constant) int, short, long, signed char, enum SWIGTYPE "rb_define_const($module,\"$symname\", INT2NUM($1));"; %typemap(constant) unsigned int, unsigned short, unsigned long, unsigned char "rb_define_const($module,\"$symname\", UINT2NUM($1));"; %typemap(constant) long long "rb_define_const($module,\"$symname\", LL2NUM($1));"; %typemap(constant) unsigned long long "rb_define_const($module,\"$symname\", ULL2NUM($1));"; %typemap(constant) double, float "rb_define_const($module,\"$symname\", rb_float_new($1));"; %typemap(constant) char "rb_define_const($module,\"$symname\", rb_str_new(\"$1\",1));"; %typemap(constant) bool "rb_define_const($module,\"$symname\", ($1 ? Qtrue : Qfalse));"; %typemap(constant) char * "rb_define_const($module,\"$symname\", rb_str_new2(\"$1\"));"; %typemap(constant) SWIGTYPE*, SWIGTYPE &, SWIGTYPE [] "rb_define_const($module,\"$symname\", SWIG_NewPointerObj((void *) $1, $1_descriptor,0));"; %typemap(constant) SWIGTYPE "rb_define_const($module,\"$symname\", SWIG_NewPointerObj((void *) &$1, $&1_descriptor, 0));"; %typemap(constant) SWIGTYPE (CLASS::*) "rb_define_const($module, \"$symname\", SWIG_NewPackedObj((void *) &$1, sizeof($type), $1_descriptor));"; /***************************************************************************** * * Inverse argument typemaps are for marshaling C/C++ parameters to call Python * methods from C++ proxy wrapper classes. * *****************************************************************************/ /* directorin typemaps */ /* Primitive datatypes */ %typemap(directorin) int "$input = INT2NUM($1);"; %typemap(directorin) short "$input = INT2NUM($1);"; %typemap(directorin) long "$input = LONG2NUM($1);"; %typemap(directorin) signed char "$input = INT2NUM($1);"; %typemap(directorin) float "$input = rb_float_new($1);"; %typemap(directorin) double "$input = rb_float_new($1);"; %typemap(directorin) char* "$input = rb_str_new2($1);"; %typemap(directorin) bool "$input = $1 ? Qtrue : Qfalse;"; %typemap(directorin) unsigned int "$input = UINT2NUM($1);"; %typemap(directorin) unsigned short "$input = UINT2NUM($1);"; %typemap(directorin) unsigned long "$input = ULONG2NUM($1);"; %typemap(directorin) unsigned char "$input = UINT2NUM($1);"; %typemap(directorin) VALUE "$input = $1;"; /* %typemap(directorin, parse="s") SWIGTYPE { { $&1_ltype resultptr; resultptr = new $1_ltype(($1_ltype &) $1); $result = SWIG_NewPointerObj((void *) resultptr, $&1_descriptor, 1); } } */ /* no can do... see python.cxx %typemap(directorin) DIRECTORTYPE * { { SwigDirector::$1_ltype proxy = dynamic_cast($1_name); if (!proxy) { $input = SWIG_NewPointerObj((void *) $1_name, $1_descriptor, 0); } else { $input = proxy->swig_get_self(); } } } %typemap(directorin) SWIGTYPE * { $input = SWIG_NewPointerObj((void *) $1_name, $1_descriptor, 0); } */ /* %typemap(directorin, parse="s") void "0"; */ /* %typemap(directorin) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { $input = SWIG_NewPointerObj((void *) $1_name, $1_descriptor, $owner); } */ /* --- directorout typemaps --- */ %define DIRECTOROUT_TYPEMAP(type, converter) %typemap(directorargout) type *DIRECTOROUT "*$result = (type) converter($input);"; %typemap(directorout) type "$result = (type) converter($input);"; %typemap(directorout) type &DIRECTOROUT = type %enddef DIRECTOROUT_TYPEMAP(char, NUM2INT); DIRECTOROUT_TYPEMAP(unsigned char, NUM2UINT); DIRECTOROUT_TYPEMAP(short, NUM2INT); DIRECTOROUT_TYPEMAP(unsigned short, NUM2INT); DIRECTOROUT_TYPEMAP(int, NUM2INT); DIRECTOROUT_TYPEMAP(unsigned int, NUM2INT); DIRECTOROUT_TYPEMAP(long, NUM2INT); DIRECTOROUT_TYPEMAP(unsigned long, NUM2INT); DIRECTOROUT_TYPEMAP(long long, NUM2INT); DIRECTOROUT_TYPEMAP(unsigned long long, NUM2INT); DIRECTOROUT_TYPEMAP(float, NUM2DBL); DIRECTOROUT_TYPEMAP(double, NUM2DBL); DIRECTOROUT_TYPEMAP(bool, RTEST); %typemap(directorout) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] "if ((SWIG_ConvertPtr($input,(void **) &$result, $descriptor,SWIG_POINTER_EXCEPTION | $disown )) == -1) throw Swig::DirectorTypeMismatchException(\"Pointer conversion failed.\");"; %typemap(directorout) void * "if ((SWIG_ConvertPtr($input,(void **) &$result, 0, SWIG_POINTER_EXCEPTION | $disown )) == -1) throw Swig::DirectorTypeMismatchException(\"Pointer conversion failed.\");"; /* --------------------------------------------------------------------- * typedef & typemaps for VALUE (passed through unmodified and unchecked) * --------------------------------------------------------------------- */ typedef unsigned long VALUE; %typemap(ruby,in) VALUE "$1 = $input;"; %typemap(ruby,out) VALUE "$result = $1;"; %typecheck(SWIG_TYPECHECK_POINTER) VALUE "$1 = 1;"; /* ------------------------------------------------------------ * String & length * ------------------------------------------------------------ */ %typemap(in) (char *STRING, int LENGTH) { $1 = ($1_ltype) StringValuePtr($input); $2 = ($2_ltype) StringValueLen($input); } /* Some ANSI C typemaps */ %apply long { size_t }; /* ------------------------------------------------------------ * Typechecking rules * ------------------------------------------------------------ */ %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE { void *ptr; $1 = (NIL_P($input) || (TYPE($input) == T_DATA && SWIG_ConvertPtr($input, &ptr, $&1_descriptor, 0) != -1)) ? 1 : 0; } %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { void *ptr; $1 = (NIL_P($input) || (TYPE($input) == T_DATA && SWIG_ConvertPtr($input, &ptr, $1_descriptor, 0) != -1)) ? 1 : 0; } %typecheck(SWIG_TYPECHECK_VOIDPTR) void * { void *ptr; $1 = (NIL_P($input) || (TYPE($input) == T_DATA && SWIG_ConvertPtr($input, &ptr, 0, 0) != -1)) ? 1 : 0; } %typecheck(SWIG_TYPECHECK_BOOL) bool { $1 = ($input == Qtrue || $input == Qfalse) ? 1 : 0; } %typecheck(SWIG_TYPECHECK_INTEGER) int, short, long, unsigned int, unsigned short, unsigned long, signed char, unsigned char, long long, unsigned long long, const int &, const short &, const long &, const unsigned int &, const unsigned short &, const unsigned long &, const long long &, const unsigned long long &, enum SWIGTYPE { $1 = ((TYPE($input) == T_FIXNUM) || (TYPE($input) == T_BIGNUM)) ? 1 : 0; } %typecheck(SWIG_TYPECHECK_DOUBLE) float, double, const float &, const double & { $1 = ((TYPE($input) == T_FLOAT) || (TYPE($input) == T_FIXNUM) || (TYPE($input) == T_BIGNUM)) ? 1 : 0; } %typecheck(SWIG_TYPECHECK_CHAR) char { $1 = (TYPE($input) == T_STRING && (RSTRING($input)->len == 1)) ? 1 : 0; } %typecheck(SWIG_TYPECHECK_STRING) char * { $1 = (TYPE($input) == T_STRING) ? 1 : 0; } /* ------------------------------------------------------------ * Exception handling * ------------------------------------------------------------ */ %typemap(throws) int, long, short, unsigned int, unsigned long, unsigned short { rb_exc_raise(rb_exc_new3(rb_eRuntimeError, INT2NUM($1))); } %typemap(throws) SWIGTYPE { $&1_ltype temp = new $1_ltype($1); if ($&1_descriptor->clientdata) { rb_exc_raise(rb_exc_new3(((swig_class *) ($&1_descriptor->clientdata))->klass, SWIG_NewPointerObj(temp, $&1_descriptor, 1))); } else { rb_exc_raise(rb_exc_new3(rb_eRuntimeError, SWIG_NewPointerObj(temp, $&1_descriptor, 1))); } } %typemap(throws) char * { rb_raise(rb_eRuntimeError, $1); } /* ------------------------------------------------------------ * Overloaded operator support * ------------------------------------------------------------ */ #ifdef __cplusplus %rename(__add__) *::operator+; %rename(__pos__) *::operator+(); %rename(__pos__) *::operator+() const; %rename(__sub__) *::operator-; %rename(__neg__) *::operator-(); %rename(__neg__) *::operator-() const; %rename(__mul__) *::operator*; %rename(__div__) *::operator/; %rename(__mod__) *::operator%; %rename(__lshift__) *::operator<<; %rename(__rshift__) *::operator>>; %rename(__and__) *::operator&; %rename(__or__) *::operator|; %rename(__xor__) *::operator^; %rename(__invert__) *::operator~; %rename(__lt__) *::operator<; %rename(__le__) *::operator<=; %rename(__gt__) *::operator>; %rename(__ge__) *::operator>=; %rename(__eq__) *::operator==; /* Special cases */ %rename(__call__) *::operator(); /* Ignored operators */ %ignorewarn("378:operator!= ignored") operator!=; %ignorewarn("365:operator+= ignored") operator+=; %ignorewarn("366:operator-= ignored") operator-=; %ignorewarn("367:operator*= ignored") operator*=; %ignorewarn("368:operator/= ignored") operator/=; %ignorewarn("369:operator%= ignored") operator%=; %ignorewarn("375:operator<<= ignored") operator<<=; %ignorewarn("376:operator>>= ignored") operator>>=; %ignorewarn("371:operator&= ignored") operator&=; %ignorewarn("372:operator|= ignored") operator|=; %ignorewarn("370:operator^= ignored") operator^=; %ignorewarn("362:operator= ignored") operator=; %ignorewarn("383:operator++ ignored") operator++; %ignorewarn("384:operator-- ignored") operator--; %ignorewarn("381:operator&& ignored") operator&&; %ignorewarn("382:operator|| ignored") operator||; // %ignorewarn("387:operator-> ignored") operator->; %ignorewarn("386:operator->* ignored") operator->*; %ignorewarn("389:operator[] ignored (consider using %extend)") operator[]; /* ruby keywords */ /* please test and activate */ // %include "rubykw.swg" #endif /* __cplusplus */ cableswig-0.1.0+git20150808.orig/SWIG/Lib/ruby/director.swg0000644000175000000620000001172512561312227021630 0ustar stevestaff/*********************************************************************** * director.swg * * This file contains support for director classes that proxy * method calls from C++ to Ruby extensions. * * Author : Lyle Johnson (lyle@users.sourceforge.net) * Based on the original Python implementation by * Mark Rose (mrose@stm.lbl.gov). ************************************************************************/ #ifdef __cplusplus #include namespace Swig { struct body_args { VALUE recv; ID id; int argc; VALUE *argv; }; /* Base class for director exceptions */ class DirectorException { protected: VALUE swig_error; protected: DirectorException(VALUE error=Qnil) : swig_error(error) {} public: VALUE getType() const { return CLASS_OF(swig_error); } VALUE getError() const { return swig_error; } virtual ~DirectorException() {} }; /* Type mismatch in the return value from a Ruby method call */ class DirectorTypeMismatchException : public Swig::DirectorException { public: DirectorTypeMismatchException(const char *msg="") { VALUE str = rb_str_new2("Swig director type mismatch: "); rb_str_concat(str, rb_str_new2(msg)); swig_error = rb_exc_new3(rb_eTypeError, str); } }; /* Any Ruby exception that occurs during a director method call */ class DirectorMethodException : public Swig::DirectorException { public: DirectorMethodException(VALUE error) : Swig::DirectorException(error) {} }; /* Attempted to call a pure virtual method via a director method */ class DirectorPureVirtualException : public Swig::DirectorException {}; /* Simple thread abstraction for pthreads on win32 */ #ifdef __THREAD__ #define __PTHREAD__ #if defined(_WIN32) || defined(__WIN32__) #define pthread_mutex_lock EnterCriticalSection #define pthread_mutex_unlock LeaveCriticalSection #define pthread_mutex_t CRITICAL_SECTION #define MUTEX_INIT(var) CRITICAL_SECTION var #else #include #define MUTEX_INIT(var) pthread_mutex_t var = PTHREAD_MUTEX_INITIALIZER #endif #endif /* director base class */ class Director { private: /* pointer to the wrapped Ruby object */ VALUE swig_self; /* flag indicating whether the object is owned by Ruby or c++ */ mutable bool swig_disown_flag; /* shared flag for breaking recursive director calls */ static bool swig_up; #ifdef __PTHREAD__ /* locks for sharing the swig_up flag in a threaded environment */ static pthread_mutex_t swig_mutex_up; static bool swig_mutex_active; static pthread_t swig_mutex_thread; #endif /* reset the swig_up flag once the routing direction has been determined */ #ifdef __PTHREAD__ void swig_clear_up() const { Swig::Director::swig_up = false; Swig::Director::swig_mutex_active = false; pthread_mutex_unlock(&swig_mutex_up); } #else void swig_clear_up() const { Swig::Director::swig_up = false; } #endif public: /* wrap a Ruby object, optionally taking ownership */ Director(VALUE self, bool disown) : swig_self(self), swig_disown_flag(disown) { } /* discard our reference at destruction */ virtual ~Director() { } /* return a pointer to the wrapped Ruby object */ VALUE swig_get_self() const { return swig_self; } /* get the swig_up flag to determine if the method call should be routed * to the c++ base class or through the wrapped Ruby object */ #ifdef __PTHREAD__ bool swig_get_up() const { if (Swig::Director::swig_mutex_active) { if (pthread_equal(Swig::Director::swig_mutex_thread, pthread_self())) { bool up = swig_up; swig_clear_up(); return up; } } return false; } #else bool swig_get_up() const { bool up = swig_up; swig_up = false; return up; } #endif /* set the swig_up flag if the next method call should be directed to * the c++ base class rather than the wrapped Ruby object */ #ifdef __PTHREAD__ void swig_set_up() const { pthread_mutex_lock(&Swig::Director::swig_mutex_up); Swig::Director::swig_mutex_thread = pthread_self(); Swig::Director::swig_mutex_active = true; Swig::Director::swig_up = true; } #else void swig_set_up() const { Swig::Director::swig_up = true; } #endif /* acquire ownership of the wrapped Ruby object (the sense of "disown" * is from Ruby) */ void swig_disown() const { if (!swig_disown_flag) { swig_disown_flag = true; } } }; bool Swig::Director::swig_up = false; #ifdef __PTHREAD__ MUTEX_INIT(Swig::Director::swig_mutex_up); pthread_t Swig::Director::swig_mutex_thread; bool Swig::Director::swig_mutex_active = false; #endif } #endif /* __cplusplus */ cableswig-0.1.0+git20150808.orig/SWIG/Lib/ruby/std_vector.i0000644000175000000620000004515012561312227021620 0ustar stevestaff// // SWIG typemaps for std::vector // Luigi Ballabio // Apr 8, 2002 // // Ruby implementation %include std_common.i %include exception.i %exception std::vector::__getitem__ { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::vector::__setitem__ { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::vector::pop { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } // ------------------------------------------------------------------------ // std::vector // // The aim of all that follows would be to integrate std::vector with // Ruby as much as possible, namely, to allow the user to pass and // be returned Ruby arrays // const declarations are used to guess the intent of the function being // exported; therefore, the following rationale is applied: // // -- f(std::vector), f(const std::vector&), f(const std::vector*): // the parameter being read-only, either a Ruby array or a // previously wrapped std::vector can be passed. // -- f(std::vector&), f(std::vector*): // the parameter must be modified; therefore, only a wrapped std::vector // can be passed. // -- std::vector f(): // the vector is returned by copy; therefore, a Ruby array of T:s // is returned which is most easily used in other Ruby functions // -- std::vector& f(), std::vector* f(), const std::vector& f(), // const std::vector* f(): // the vector is returned by reference; therefore, a wrapped std::vector // is returned // ------------------------------------------------------------------------ %{ #include #include #include %} // exported class namespace std { %mixin vector "Enumerable"; template class vector { %typemap(in) vector { if (rb_obj_is_kind_of($input,rb_cArray)) { unsigned int size = RARRAY($input)->len; $1 = std::vector(size); for (unsigned int i=0; iptr[i]; T* x; SWIG_ConvertPtr(o, (void **) &x, $descriptor(T *), 1); (($1_type &)$1)[i] = *x; } } else { void *ptr; SWIG_ConvertPtr($input, &ptr, $&1_descriptor, 1); $1 = *(($&1_type) ptr); } } %typemap(in) const vector& (std::vector temp), const vector* (std::vector temp) { if (rb_obj_is_kind_of($input,rb_cArray)) { unsigned int size = RARRAY($input)->len; temp = std::vector(size); $1 = &temp; for (unsigned int i=0; iptr[i]; T* x; SWIG_ConvertPtr(o, (void **) &x, $descriptor(T *), 1); temp[i] = *x; } } else { SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 1); } } %typemap(out) vector { $result = rb_ary_new2($1.size()); for (unsigned int i=0; i<$1.size(); i++) { T* x = new T((($1_type &)$1)[i]); rb_ary_store($result,i, SWIG_NewPointerObj((void *) x, $descriptor(T *), 1)); } } %typecheck(SWIG_TYPECHECK_VECTOR) vector { /* native sequence? */ if (rb_obj_is_kind_of($input,rb_cArray)) { unsigned int size = RARRAY($input)->len; if (size == 0) { /* an empty sequence can be of any type */ $1 = 1; } else { /* check the first element only */ T* x; VALUE o = RARRAY($input)->ptr[0]; if ((SWIG_ConvertPtr(o,(void **) &x, $descriptor(T *),0)) != -1) $1 = 1; else $1 = 0; } } else { /* wrapped vector? */ std::vector* v; if (SWIG_ConvertPtr($input,(void **) &v, $&1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_VECTOR) const vector&, const vector* { /* native sequence? */ if (rb_obj_is_kind_of($input,rb_cArray)) { unsigned int size = RARRAY($input)->len; if (size == 0) { /* an empty sequence can be of any type */ $1 = 1; } else { /* check the first element only */ T* x; VALUE o = RARRAY($input)->ptr[0]; if ((SWIG_ConvertPtr(o,(void **) &x, $descriptor(T *),0)) != -1) $1 = 1; else $1 = 0; } } else { /* wrapped vector? */ std::vector* v; if (SWIG_ConvertPtr($input,(void **) &v, $1_descriptor,1) != -1) $1 = 1; else $1 = 0; } } public: vector(unsigned int size = 0); vector(unsigned int size, const T& value); vector(const vector &); %rename(__len__) size; unsigned int size() const; %rename("empty?") empty; bool empty() const; void clear(); %rename(push) push_back; void push_back(const T& x); %extend { T pop() { if (self->size() == 0) throw std::out_of_range("pop from empty vector"); T x = self->back(); self->pop_back(); return x; } T& __getitem__(int i) { int size = int(self->size()); if (i<0) i += size; if (i>=0 && isize()); if (i<0) i+= size; if (i>=0 && isize(); i++) { T* x = &((*self)[i]); rb_yield(SWIG_NewPointerObj((void *) x, $descriptor(T *), 0)); } } } }; // Partial specialization for vectors of pointers. [ beazley ] %mixin vector "Enumerable"; template class vector { %typemap(in) vector { if (rb_obj_is_kind_of($input,rb_cArray)) { unsigned int size = RARRAY($input)->len; $1 = std::vector(size); for (unsigned int i=0; iptr[i]; T* x; SWIG_ConvertPtr(o, (void **) &x, $descriptor(T *), 1); (($1_type &)$1)[i] = x; } } else { void *ptr; SWIG_ConvertPtr($input, &ptr, $&1_descriptor, 1); $1 = *(($&1_type) ptr); } } %typemap(in) const vector& (std::vector temp), const vector* (std::vector temp) { if (rb_obj_is_kind_of($input,rb_cArray)) { unsigned int size = RARRAY($input)->len; temp = std::vector(size); $1 = &temp; for (unsigned int i=0; iptr[i]; T* x; SWIG_ConvertPtr(o, (void **) &x, $descriptor(T *), 1); temp[i] = x; } } else { SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 1); } } %typemap(out) vector { $result = rb_ary_new2($1.size()); for (unsigned int i=0; i<$1.size(); i++) { T* x = new T((($1_type &)$1)[i]); rb_ary_store($result,i, SWIG_NewPointerObj((void *) x, $descriptor(T *), 0)); } } %typecheck(SWIG_TYPECHECK_VECTOR) vector { /* native sequence? */ if (rb_obj_is_kind_of($input,rb_cArray)) { unsigned int size = RARRAY($input)->len; if (size == 0) { /* an empty sequence can be of any type */ $1 = 1; } else { /* check the first element only */ T* x; VALUE o = RARRAY($input)->ptr[0]; if ((SWIG_ConvertPtr(o,(void **) &x, $descriptor(T *),0)) != -1) $1 = 1; else $1 = 0; } } else { /* wrapped vector? */ std::vector* v; if (SWIG_ConvertPtr($input,(void **) &v, $&1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_VECTOR) const vector&, const vector* { /* native sequence? */ if (rb_obj_is_kind_of($input,rb_cArray)) { unsigned int size = RARRAY($input)->len; if (size == 0) { /* an empty sequence can be of any type */ $1 = 1; } else { /* check the first element only */ T* x; VALUE o = RARRAY($input)->ptr[0]; if ((SWIG_ConvertPtr(o,(void **) &x, $descriptor(T *),0)) != -1) $1 = 1; else $1 = 0; } } else { /* wrapped vector? */ std::vector* v; if (SWIG_ConvertPtr($input,(void **) &v, $1_descriptor,1) != -1) $1 = 1; else $1 = 0; } } public: vector(unsigned int size = 0); vector(unsigned int size, T * &value); vector(const vector &); %rename(__len__) size; unsigned int size() const; %rename("empty?") empty; bool empty() const; void clear(); %rename(push) push_back; void push_back(T* x); %extend { T* pop() { if (self->size() == 0) throw std::out_of_range("pop from empty vector"); T* x = self->back(); self->pop_back(); return x; } T* __getitem__(int i) { int size = int(self->size()); if (i<0) i += size; if (i>=0 && isize()); if (i<0) i+= size; if (i>=0 && isize(); i++) { T* x = (*self)[i]; rb_yield(SWIG_NewPointerObj((void *) x, $descriptor(T *), 0)); } } } }; // specializations for built-ins %define specialize_std_vector(T,CHECK,CONVERT_FROM,CONVERT_TO) %mixin vector "Enumerable"; template<> class vector { %typemap(in) vector { if (rb_obj_is_kind_of($input,rb_cArray)) { unsigned int size = RARRAY($input)->len; $1 = std::vector(size); for (unsigned int i=0; iptr[i]; if (CHECK(o)) (($1_type &)$1)[i] = (T)(CONVERT_FROM(o)); else rb_raise(rb_eTypeError, "wrong argument type" " (expected vector<" #T ">)"); } } else { void *ptr; SWIG_ConvertPtr($input, &ptr, $&1_descriptor, 1); $1 = *(($&1_type) ptr); } } %typemap(in) const vector& (std::vector temp), const vector* (std::vector temp) { if (rb_obj_is_kind_of($input,rb_cArray)) { unsigned int size = RARRAY($input)->len; temp = std::vector(size); $1 = &temp; for (unsigned int i=0; iptr[i]; if (CHECK(o)) temp[i] = (T)(CONVERT_FROM(o)); else rb_raise(rb_eTypeError, "wrong argument type" " (expected vector<" #T ">)"); } } else { SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 1); } } %typemap(out) vector { $result = rb_ary_new2($1.size()); for (unsigned int i=0; i<$1.size(); i++) rb_ary_store($result,i,CONVERT_TO((($1_type &)$1)[i])); } %typecheck(SWIG_TYPECHECK_VECTOR) vector { /* native sequence? */ if (rb_obj_is_kind_of($input,rb_cArray)) { unsigned int size = RARRAY($input)->len; if (size == 0) { /* an empty sequence can be of any type */ $1 = 1; } else { /* check the first element only */ VALUE o = RARRAY($input)->ptr[0]; if (CHECK(o)) $1 = 1; else $1 = 0; } } else { /* wrapped vector? */ std::vector* v; if (SWIG_ConvertPtr($input,(void **) &v, $&1_descriptor,0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_VECTOR) const vector&, const vector* { /* native sequence? */ if (rb_obj_is_kind_of($input,rb_cArray)) { unsigned int size = RARRAY($input)->len; if (size == 0) { /* an empty sequence can be of any type */ $1 = 1; } else { /* check the first element only */ VALUE o = RARRAY($input)->ptr[0]; if (CHECK(o)) $1 = 1; else $1 = 0; } } else { /* wrapped vector? */ std::vector* v; if (SWIG_ConvertPtr($input,(void **) &v, $1_descriptor,1) != -1) $1 = 1; else $1 = 0; } } public: vector(unsigned int size = 0); vector(unsigned int size, const T& value); vector(const vector &); %rename(__len__) size; unsigned int size() const; %rename("empty?") empty; bool empty() const; void clear(); %rename(push) push_back; void push_back(T x); %extend { T pop() { if (self->size() == 0) throw std::out_of_range("pop from empty vector"); T x = self->back(); self->pop_back(); return x; } T __getitem__(int i) { int size = int(self->size()); if (i<0) i += size; if (i>=0 && isize()); if (i<0) i+= size; if (i>=0 && isize(); i++) rb_yield(CONVERT_TO((*self)[i])); } } }; %enddef specialize_std_vector(bool,SWIG_BOOL_P,SWIG_RB2BOOL,SWIG_BOOL2RB); specialize_std_vector(char,FIXNUM_P,FIX2INT,INT2NUM); specialize_std_vector(int,FIXNUM_P,FIX2INT,INT2NUM); specialize_std_vector(short,FIXNUM_P,FIX2INT,INT2NUM); specialize_std_vector(long,FIXNUM_P,FIX2INT,INT2NUM); specialize_std_vector(unsigned char,FIXNUM_P,FIX2INT,INT2NUM); specialize_std_vector(unsigned int,FIXNUM_P,FIX2INT,INT2NUM); specialize_std_vector(unsigned short,FIXNUM_P,FIX2INT,INT2NUM); specialize_std_vector(unsigned long,FIXNUM_P,FIX2INT,INT2NUM); specialize_std_vector(double,SWIG_FLOAT_P,SWIG_NUM2DBL,rb_float_new); specialize_std_vector(float,SWIG_FLOAT_P,SWIG_NUM2DBL,rb_float_new); specialize_std_vector(std::string,SWIG_STRING_P,SWIG_RB2STR,SWIG_STR2RB); } cableswig-0.1.0+git20150808.orig/SWIG/Lib/ruby/extconf.rb0000644000175000000620000000035212561312227021260 0ustar stevestaffrequire 'mkmf' dir_config('yourlib') if have_header('yourlib.h') and have_library('yourlib', 'yourlib_init') # If you use swig -c option, you may have to link libswigrb. # have_library('swigrb') create_makefile('yourlib') end cableswig-0.1.0+git20150808.orig/SWIG/Lib/ruby/precommon.swg0000644000175000000620000000317012561312227022007 0ustar stevestaff/*************************************************************** -*- c -*- * ruby/precommon.swg * * Rename all exported symbols from common.swg, to avoid symbol * clashes if multiple interpreters are included * ************************************************************************/ #define SWIG_TypeRegister SWIG_Ruby_TypeRegister #define SWIG_TypeCheck SWIG_Ruby_TypeCheck #define SWIG_TypeCast SWIG_Ruby_TypeCast #define SWIG_TypeDynamicCast SWIG_Ruby_TypeDynamicCast #define SWIG_TypeName SWIG_Ruby_TypeName #define SWIG_TypeQuery SWIG_Ruby_TypeQuery #define SWIG_TypeClientData SWIG_Ruby_TypeClientData #define SWIG_PackData SWIG_Ruby_PackData #define SWIG_UnpackData SWIG_Ruby_UnpackData /* Also rename all exported symbols from rubydef.swig */ /* Common SWIG API */ #define SWIG_ConvertPtr(obj, pp, type, flags) \ SWIG_Ruby_ConvertPtr(obj, pp, type, flags) #define SWIG_NewPointerObj(p, type, flags) \ SWIG_Ruby_NewPointerObj(p, type, flags) #define SWIG_MustGetPtr(p, type, argnum, flags) \ SWIG_Ruby_MustGetPtr(p, type, argnum, flags) /* Ruby-specific SWIG API */ #define SWIG_InitRuntime() \ SWIG_Ruby_InitRuntime() #define SWIG_define_class(ty) \ SWIG_Ruby_define_class(ty) #define SWIG_NewClassInstance(value, ty) \ SWIG_Ruby_NewClassInstance(value, ty) #define SWIG_MangleStr(value) \ SWIG_Ruby_MangleStr(value) #define SWIG_CheckConvert(value, ty) \ SWIG_Ruby_CheckConvert(value, ty) #define SWIG_NewPackedObj(ptr, sz, ty) \ SWIG_Ruby_NewPackedObj(ptr, sz, ty) #define SWIG_ConvertPacked(obj, ptr, sz, ty, flags) \ SWIG_Ruby_ConvertPacked(obj, ptr, sz, ty, flags) cableswig-0.1.0+git20150808.orig/SWIG/Lib/pike/0002755000175000000620000000000012561312227017236 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Lib/pike/std_string.i0000644000175000000620000000273412561312227021574 0ustar stevestaff// // SWIG typemaps for std::string // Lyle Johnson // May 1, 2003 // // Pike implementation %{ #include %} namespace std { class string; /* Overloading check */ %typemap(typecheck) string = char *; %typemap(typecheck) const string & = char *; %typemap(in, pikedesc="tStr") string { if ($input.type != T_STRING) Pike_error("Bad argument: Expected a string.\n"); $1 = std::string(STR0($input.u.string)); } %typemap(in, pikedesc="tStr") const string & (std::string temp) { if ($input.type != T_STRING) Pike_error("Bad argument: Expected a string.\n"); temp = std::string(STR0($input.u.string)); $1 = &temp; } %typemap(out, pikedesc="tStr") string "push_text($1.c_str());"; %typemap(out, pikedesc="tStr") const string & "push_text($1->c_str());"; %typemap(directorin) string, const string &, string & "$1_name.c_str()"; %typemap(directorin) string *, const string * "$1_name->c_str()"; %typemap(directorout) string { if ($input.type == T_STRING) $result = std::string(STR0($input.u.string)); else throw Swig::DirectorTypeMismatchException("string expected"); } %typemap(directorout) const string & (std::string temp) { if ($input.type == T_STRING) { temp = std::string(STR0($input.u.string)); $result = &temp; } else { throw Swig::DirectorTypeMismatchException("string expected"); } } } cableswig-0.1.0+git20150808.orig/SWIG/Lib/pike/pikerun.swg0000644000175000000620000000307212561312227021435 0ustar stevestaff/*********************************************************************** * pikerun.swg * * This file contains the runtime support for Pike modules * and includes code for managing global variables and pointer * type checking. * * Author : Lyle Johnson (lyle@users.sourceforge.net) ************************************************************************/ #ifdef __cplusplus extern "C" { #endif #include "object.h" #include "program.h" #ifdef __cplusplus } #endif /* Stores information about a wrapped object */ typedef struct swig_object_wrapper { void *self; } swig_object_wrapper; #ifdef THIS #undef THIS #endif #define THIS (((swig_object_wrapper *) Pike_fp->current_storage)->self) #define SWIG_ConvertPtr SWIG_Pike_ConvertPtr #define SWIG_NewPointerObj SWIG_Pike_NewPointerObj #ifdef SWIG_NOINCLUDE SWIGEXPORT(int) SWIG_Pike_ConvertPtr(struct object *, void **, swig_type_info *, int); SWIGEXPORT(struct object *) SWIG_Pike_NewPointerObj(void *, swig_type_info *, int); #else /* Convert a pointer value */ SWIGRUNTIME(int) SWIG_Pike_ConvertPtr(struct object *obj, void **ptr, swig_type_info *ty, int flags) { char *storage; struct program *pr; if (ty) { pr = (struct program *) ty->clientdata; storage = get_storage(obj, pr); if (storage) { *ptr = ((swig_object_wrapper *) storage)->self; return 0; } } return -1; } /* Create a new pointer object */ SWIGRUNTIME(struct object *) SWIG_Pike_NewPointerObj(void *ptr, swig_type_info *type, int own) { return 0; } #endif cableswig-0.1.0+git20150808.orig/SWIG/Lib/pike/pike.swg0000644000175000000620000002417512561312227020717 0ustar stevestaff/* ----------------------------------------------------------------------------- * pike.swg * * Pike configuration module. * ----------------------------------------------------------------------------- */ %insert(runtime) "precommon.swg" %insert(runtime) "common.swg"; // Common type-checking code %insert(runtime) "pikerun.swg"; // Pike run-time code %insert(runtime) %{ #ifdef __cplusplus extern "C" { #endif #include "global.h" #include "module.h" #include "interpret.h" #ifdef __cplusplus } #endif %} /* ----------------------------------------------------------------------------- * standard typemaps * ----------------------------------------------------------------------------- */ /* --- Input arguments --- */ /* Primitive datatypes. */ %typemap(in, pikedesc="tInt") int, unsigned int, short, unsigned short, long, unsigned long, char, signed char, unsigned char, bool, enum SWIGTYPE, long long, unsigned long long { if ($input.type != T_INT) Pike_error("Bad argument: Expected an integer.\n"); $1 = ($1_ltype) $input.u.integer; } %typemap(in, pikedesc="tFloat") float, double { if ($input.type != T_FLOAT) Pike_error("Bad argument: Expected a float.\n"); $1 = ($1_ltype) $input.u.float_number; } %typemap(in, pikedesc="tStr") char *, char [ANY] { if ($input.type != T_STRING) Pike_error("Bad argument: Expected a string.\n"); $1 = ($1_ltype) STR0($input.u.string); } /* Pointers, references and arrays */ %typemap(in) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] "SWIG_ConvertPtr($input.u.object, (void **) &$1, $1_descriptor, 1);" /* Void pointer. Accepts any kind of pointer */ %typemap(in) void * "/* FIXME */"; /* Object passed by value. Convert to a pointer */ %typemap(in) SWIGTYPE ($&1_ltype argp) "/* FIXME */"; /* Pointer to a class member */ %typemap(in) SWIGTYPE (CLASS::*) "/* FIXME */"; /* Const primitive references. Passed by value */ %typemap(in, pikedesc="tInt") const int & (int temp), const short & (short temp), const long & (long temp), const unsigned int & (unsigned int temp), const unsigned short & (unsigned short temp), const unsigned long & (unsigned long temp), const char & (char temp), const signed char & (signed char temp), const unsigned char & (unsigned char temp), const bool & (bool temp), const long long & ($*1_ltype temp), const unsigned long long & ($*1_ltype temp) { if ($input.type != T_INT) Pike_error("Bad argument: Expected an integer.\n"); temp = ($*1_ltype) $input.u.integer; $1 = &temp; } %typemap(in, pikedesc="tFloat") const float & (float temp), const double & (double temp) { if ($input.type != T_FLOAT) Pike_error("Bad argument: Expected a float.\n"); temp = ($*1_ltype) $input.u.float_number; $1 = &temp; } /************************ Output Typemaps *****************************/ %typemap(out, pikedesc="tInt") int, unsigned int, short, unsigned short, long, unsigned long, char, signed char, unsigned char, bool, enum SWIGTYPE "push_int($1);"; %typemap(out, pikedesc="tInt") long long "push_int64($1);"; %typemap(out, pikedesc="tInt") unsigned long long "push_int64($1);"; %typemap(out, pikedesc="tFloat") float, double "push_float($1);"; %typemap(out, pikedesc="tStr") char * "push_text($1);"; /* Pointers, references, and arrays */ %typemap(out, pikedesc="tObj") SWIGTYPE*, SWIGTYPE &, SWIGTYPE [] "push_object(SWIG_NewPointerObj((void *) $1, $1_descriptor, $owner));"; /* Void return value; don't push anything */ %typemap(out, pikedesc="tVoid") void ""; /* Dynamic casts */ %typemap(out) SWIGTYPE *DYNAMIC, SWIGTYPE &DYNAMIC "/* FIXME */"; /* Member pointer */ %typemap(out) SWIGTYPE (CLASS::*) "/* FIXME */"; /* Special typemap for character array return values */ %typemap(out, pikedesc="tStr") char [ANY], const char [ANY] "push_text($1);"; /* Primitive types--return by value */ %typemap(out, "tObj") SWIGTYPE #ifdef __cplusplus { $&1_ltype resultptr; resultptr = new $1_ltype(($1_ltype &) $1); push_object(SWIG_NewPointerObj((void *) resultptr, $&1_descriptor, 1)); } #else { $&1_ltype resultptr; resultptr = ($&1_ltype) malloc(sizeof($1_type)); memmove(resultptr, &$1, sizeof($1_type)); push_object(SWIG_NewPointerObj((void *) resultptr, $&1_descriptor, 1)); } #endif /* References to primitive types. Return by value */ %typemap(out, pikedesc="tInt") const int &, const unsigned int &, const short &, const unsigned short &, const long &, const unsigned long &, const char &, const signed char &, const unsigned char &, const bool &, const long long &, const unsigned long long & "push_int(*($1));"; %typemap(out, pikedesc="tFloat") const float &, const double & "push_float(*($1));"; /************************ Constant Typemaps *****************************/ %typemap(constant) int, unsigned int, short, unsigned short, long, unsigned long, signed char, unsigned char, bool, enum SWIGTYPE, long long, unsigned long long "add_integer_constant(\"$symname\", $1, 0);"; %typemap(constant) char "add_integer_constant(\"$symname\", '$1', 0);"; %typemap(constant) long long, unsigned long long "add_integer_constant(\"$symname\", $1, 0);"; %typemap(constant) float, double "add_float_constant(\"$symname\", $1, 0);"; %typemap(constant) char * "add_string_constant(\"$symname\", \"$1\", 0);"; /* ------------------------------------------------------------ * String & length * ------------------------------------------------------------ */ %typemap(in, pikedesc="tStr") (char *STRING, int LENGTH) { if ($input.type != T_STRING) Pike_error("Bad argument: Expected a string.\n"); $1 = ($1_ltype) STR0($input.u.string); $2 = ($2_ltype) $input.u.string->length; } /* ------------------------------------------------------------ * ANSI C typemaps * ------------------------------------------------------------ */ %typemap(in, pikedesc="tInt") size_t { if ($input.type != T_INT) Pike_error("Bad argument: Expected an integer.\n"); $1 = ($1_ltype) $input.u.integer; } %typemap(out) size_t = long; /* ------------------------------------------------------------ * Typechecking rules * ------------------------------------------------------------ */ %typecheck(SWIG_TYPECHECK_INTEGER) int, short, long, unsigned int, unsigned short, unsigned long, signed char, unsigned char, long long, unsigned long long, const int &, const short &, const long &, const unsigned int &, const unsigned short &, const unsigned long &, const long long &, const unsigned long long &, enum SWIGTYPE, bool, const bool & { $1 = ($input.type == T_INT) ? 1 : 0; } %typecheck(SWIG_TYPECHECK_DOUBLE) float, double, const float &, const double & { $1 = (($input.type == T_FLOAT) || ($input.type == T_INT)) ? 1 : 0; } %typecheck(SWIG_TYPECHECK_CHAR) char { $1 = ($input.type == T_INT) ? 1 : 0; } %typecheck(SWIG_TYPECHECK_STRING) char * { $1 = ($input.type == T_STRING) ? 1 : 0; } %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { void *ptr; if (SWIG_ConvertPtr($input.u.object, (void **) &ptr, $1_descriptor, 0) == -1) { $1 = 0; } else { $1 = 1; } } %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE { void *ptr; if (SWIG_ConvertPtr($input.u.object, (void **) &ptr, $&1_descriptor, 0) == -1) { $1 = 0; } else { $1 = 1; } } %typecheck(SWIG_TYPECHECK_VOIDPTR) void * { void *ptr; if (SWIG_ConvertPtr($input.u.object, (void **) &ptr, 0, 0) == -1) { $1 = 0; } else { $1 = 1; } } /* ------------------------------------------------------------ * Overloaded operator support * ------------------------------------------------------------ */ #ifdef __cplusplus %rename("`+") *::operator+; %rename("`-") *::operator-; %rename("`*") *::operator*; %rename("`/") *::operator/; %rename("`%") *::operator%; %rename("`<<") *::operator<<; %rename("`>>") *::operator>>; %rename("`&") *::operator&; %rename("`|") *::operator|; %rename("`^") *::operator^; %rename("`~") *::operator~; %rename("`<") *::operator<; %rename("`>") *::operator>; %rename("`==") *::operator==; /* Special cases */ %rename("`()") *::operator(); /* Ignored operators */ %ignorewarn("362:operator= ignored") operator=; %ignorewarn("365:operator+= ignored") operator+=; %ignorewarn("366:operator-= ignored") operator-=; %ignorewarn("367:operator*= ignored") operator*=; %ignorewarn("368:operator/= ignored") operator/=; %ignorewarn("369:operator%= ignored") operator%=; %ignorewarn("370:operator^= ignored") operator^=; %ignorewarn("371:operator&= ignored") operator&=; %ignorewarn("372:operator|= ignored") operator|=; %ignorewarn("375:operator<<= ignored") operator<<=; %ignorewarn("376:operator>>= ignored") operator>>=; %ignorewarn("378:operator!= ignored") operator!=; %ignorewarn("379:operator<= ignored") operator<=; %ignorewarn("380:operator>= ignored") operator>=; %ignorewarn("381:operator&& ignored") operator&&; %ignorewarn("382:operator|| ignored") operator||; %ignorewarn("383:operator++ ignored") operator++; %ignorewarn("384:operator-- ignored") operator--; %ignorewarn("386:operator->* ignored") operator->*; %ignorewarn("389:operator[] ignored (consider using %extend)") operator[]; %ignorewarn("390:operator+() ignored") operator+(); %ignorewarn("390:operator+() const ignored") operator+() const; %ignorewarn("391:operator-() ignored") operator-(); %ignorewarn("391:operator-() const ignored") operator-() const; #endif /* ------------------------------------------------------------ * The start of the Pike initialization function * ------------------------------------------------------------ */ %init %{ #ifdef __cplusplus extern "C" #endif PIKE_MODULE_EXIT {} #ifdef __cplusplus extern "C" #endif PIKE_MODULE_INIT { struct program *pr; int i; for (i = 0; swig_types_initial[i]; i++) { swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]); } %} /* pike keywords */ /* please test and activate */ //%include "pikekw.swg" cableswig-0.1.0+git20150808.orig/SWIG/Lib/pike/precommon.swg0000644000175000000620000000135412561312227021760 0ustar stevestaff/*************************************************************** -*- c -*- * pike/precommon.swg * * Rename all exported symbols from common.swg, to avoid symbol * clashes if multiple interpreters are included * ************************************************************************/ #define SWIG_TypeRegister SWIG_Pike_TypeRegister #define SWIG_TypeCheck SWIG_Pike_TypeCheck #define SWIG_TypeCast SWIG_Pike_TypeCast #define SWIG_TypeDynamicCast SWIG_Pike_TypeDynamicCast #define SWIG_TypeName SWIG_Pike_TypeName #define SWIG_TypeQuery SWIG_Pike_TypeQuery #define SWIG_TypeClientData SWIG_Pike_TypeClientData #define SWIG_PackData SWIG_Pike_PackData #define SWIG_UnpackData SWIG_Pike_UnpackData cableswig-0.1.0+git20150808.orig/SWIG/Lib/pike/pikekw.swg0000644000175000000620000000152712561312227021255 0ustar stevestaff#ifndef __pike_pikekw_swg__ #define __pike_pikekw_swg__ /* Warnings for Pike keywords */ #define PIKEKW(x) %namewarn("314:" #x " is a pike keyword") #x /* from http://www.http://docs.linux.cz/pike/tutorial_C.html */ PIKEKW(array); PIKEKW(break); PIKEKW(case); PIKEKW(catch); PIKEKW(continue); PIKEKW(default); PIKEKW(do); PIKEKW(else); PIKEKW(float); PIKEKW(for); PIKEKW(foreach); PIKEKW(function); PIKEKW(gauge); PIKEKW(if); PIKEKW(inherit); PIKEKW(inline); PIKEKW(int); PIKEKW(lambda); PIKEKW(mapping); PIKEKW(mixed); PIKEKW(multiset); PIKEKW(nomask); PIKEKW(object); PIKEKW(predef); PIKEKW(private); PIKEKW(program); PIKEKW(protected); PIKEKW(public); PIKEKW(return); PIKEKW(sscanf); PIKEKW(static); PIKEKW(string); PIKEKW(switch); PIKEKW(typeof); PIKEKW(varargs); PIKEKW(void); PIKEKW(while); #undef PIKEKW #endif //__pike_pikekw_swg__ cableswig-0.1.0+git20150808.orig/SWIG/Lib/mzscheme/0002755000175000000620000000000012561312227020121 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Lib/mzscheme/std_string.i0000644000175000000620000000243212561312227022452 0ustar stevestaff// // SWIG typemaps for std::string types // Luigi Ballabio // Apr 8, 2002 // // MzScheme implementation // ------------------------------------------------------------------------ // std::string is typemapped by value // This can prevent exporting methods which return a string // in order for the user to modify it. // However, I think I'll wait until someone asks for it... // ------------------------------------------------------------------------ %include exception.i %{ #include %} namespace std { class string; /* Overloading check */ %typemap(typecheck) string = char *; %typemap(typecheck) const string & = char *; %typemap(in) string { if (SCHEME_STRINGP($input)) $1 = std::string(SCHEME_STR_VAL($input)); else SWIG_exception(SWIG_TypeError, "string expected"); } %typemap(in) const string & (std::string temp) { if (SCHEME_STRINGP($input)) { temp = std::string(SCHEME_STR_VAL($input)); $1 = &temp; } else { SWIG_exception(SWIG_TypeError, "string expected"); } } %typemap(out) string { $result = scheme_make_string($1.c_str()); } %typemap(out) const string & { $result = scheme_make_string($1->c_str()); } } cableswig-0.1.0+git20150808.orig/SWIG/Lib/mzscheme/std_map.i0000644000175000000620000017601212561312227021727 0ustar stevestaff// // SWIG typemaps for std::map // Luigi Ballabio // Jan. 2003 // // MzScheme implementation %include std_common.i %include exception.i %exception std::map::__getitem__ { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::map::__delitem__ { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } // ------------------------------------------------------------------------ // std::map // // The aim of all that follows would be to integrate std::map with // MzScheme as much as possible, namely, to allow the user to pass and // be returned Scheme association lists. // const declarations are used to guess the intent of the function being // exported; therefore, the following rationale is applied: // // -- f(std::map), f(const std::map&), f(const std::map*): // the parameter being read-only, either a Scheme alist or a // previously wrapped std::map can be passed. // -- f(std::map&), f(std::map*): // the parameter must be modified; therefore, only a wrapped std::map // can be passed. // -- std::map f(): // the map is returned by copy; therefore, a Scheme alist // is returned which is most easily used in other Scheme functions // -- std::map& f(), std::map* f(), const std::map& f(), // const std::map* f(): // the map is returned by reference; therefore, a wrapped std::map // is returned // ------------------------------------------------------------------------ %{ #include #include #include %} // exported class namespace std { template class map { %typemap(in) map (std::map* m) { if (SCHEME_NULLP($input)) { $1 = std::map(); } else if (SCHEME_PAIRP($input)) { $1 = std::map(); Scheme_Object* alist = $input; while (!SCHEME_NULLP(alist)) { K* k; T* x; Scheme_Object *entry, *key, *val; entry = scheme_car(alist); if (!SCHEME_PAIRP(entry)) SWIG_exception(SWIG_TypeError,"alist expected"); key = scheme_car(entry); val = scheme_cdr(entry); k = (K*) SWIG_MustGetPtr(key,$descriptor(K *),$argnum, 0); if (SWIG_ConvertPtr(val,(void**) &x, $descriptor(T *), 0) == -1) { if (!SCHEME_PAIRP(val)) SWIG_exception(SWIG_TypeError,"alist expected"); val = scheme_car(val); x = (T*) SWIG_MustGetPtr(val,$descriptor(T *),$argnum, 0); } (($1_type &)$1)[*k] = *x; alist = scheme_cdr(alist); } } else { $1 = *(($&1_type) SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0)); } } %typemap(in) const map& (std::map temp, std::map* m), const map* (std::map temp, std::map* m) { if (SCHEME_NULLP($input)) { temp = std::map(); $1 = &temp; } else if (SCHEME_PAIRP($input)) { temp = std::map(); $1 = &temp; Scheme_Object* alist = $input; while (!SCHEME_NULLP(alist)) { K* k; T* x; Scheme_Object *entry, *key, *val; entry = scheme_car(alist); if (!SCHEME_PAIRP(entry)) SWIG_exception(SWIG_TypeError,"alist expected"); key = scheme_car(entry); val = scheme_cdr(entry); k = (K*) SWIG_MustGetPtr(key,$descriptor(K *),$argnum, 0); if (SWIG_ConvertPtr(val,(void**) &x, $descriptor(T *), 0) == -1) { if (!SCHEME_PAIRP(val)) SWIG_exception(SWIG_TypeError,"alist expected"); val = scheme_car(val); x = (T*) SWIG_MustGetPtr(val,$descriptor(T *),$argnum, 0); } temp[*k] = *x; alist = scheme_cdr(alist); } } else { $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0); } } %typemap(out) map { Scheme_Object* alist = scheme_null; for (std::map::reverse_iterator i=$1.rbegin(); i!=$1.rend(); ++i) { K* key = new K(i->first); T* val = new T(i->second); Scheme_Object* k = SWIG_NewPointerObj(key,$descriptor(K *), 1); Scheme_Object* x = SWIG_NewPointerObj(val,$descriptor(T *), 1); Scheme_Object* entry = scheme_make_pair(k,x); alist = scheme_make_pair(entry,alist); } $result = alist; } %typecheck(SWIG_TYPECHECK_MAP) map { /* native sequence? */ if (SCHEME_NULLP($input)) { /* an empty sequence can be of any type */ $1 = 1; } else if (SCHEME_PAIRP($input)) { /* check the first element only */ K* k; T* x; Scheme_Object* head = scheme_car($input); if (SCHEME_PAIRP(head)) { Scheme_Object* key = scheme_car(head); Scheme_Object* val = scheme_cdr(head); if (SWIG_ConvertPtr(key,(void**) &k, $descriptor(K *), 0) == -1) { $1 = 0; } else { if (SWIG_ConvertPtr(val,(void**) &x, $descriptor(T *), 0) != -1) { $1 = 1; } else if (SCHEME_PAIRP(val)) { val = scheme_car(val); if (SWIG_ConvertPtr(val,(void**) &x, $descriptor(T *), 0) != -1) $1 = 1; else $1 = 0; } else { $1 = 0; } } } else { $1 = 0; } } else { /* wrapped map? */ std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $&1_descriptor, 0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_MAP) const map&, const map* { /* native sequence? */ if (SCHEME_NULLP($input)) { /* an empty sequence can be of any type */ $1 = 1; } else if (SCHEME_PAIRP($input)) { /* check the first element only */ K* k; T* x; Scheme_Object* head = scheme_car($input); if (SCHEME_PAIRP(head)) { Scheme_Object* key = scheme_car(head); Scheme_Object* val = scheme_cdr(head); if (SWIG_ConvertPtr(key,(void**) &k, $descriptor(K *), 0) == -1) { $1 = 0; } else { if (SWIG_ConvertPtr(val,(void**) &x, $descriptor(T *), 0) != -1) { $1 = 1; } else if (SCHEME_PAIRP(val)) { val = scheme_car(val); if (SWIG_ConvertPtr(val,(void**) &x, $descriptor(T *), 0) != -1) $1 = 1; else $1 = 0; } else { $1 = 0; } } } else { $1 = 0; } } else { /* wrapped map? */ std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $1_descriptor, 0) != -1) $1 = 1; else $1 = 0; } } %rename("length") size; %rename("null?") empty; %rename("clear!") clear; %rename("ref") __getitem__; %rename("set!") __setitem__; %rename("delete!") __delitem__; %rename("has-key?") has_key; public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T& __getitem__(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void __setitem__(const K& key, const T& x) { (*self)[key] = x; } void __delitem__(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(const K& key) { std::map::iterator i = self->find(key); return i != self->end(); } Scheme_Object* keys() { Scheme_Object* result = scheme_null; for (std::map::reverse_iterator i=$1.rbegin(); i!=$1.rend(); ++i) { K* key = new K(i->first); Scheme_Object* k = SWIG_NewPointerObj(key,$descriptor(K *), 1); result = scheme_make_pair(k,result); } return result; } } }; // specializations for built-ins %define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO) template class map { %typemap(in) map (std::map* m) { if (SCHEME_NULLP($input)) { $1 = std::map(); } else if (SCHEME_PAIRP($input)) { $1 = std::map(); Scheme_Object* alist = $input; while (!SCHEME_NULLP(alist)) { T* x; Scheme_Object *entry, *key, *val; entry = scheme_car(alist); if (!SCHEME_PAIRP(entry)) SWIG_exception(SWIG_TypeError,"alist expected"); key = scheme_car(entry); val = scheme_cdr(entry); if (!CHECK(key)) SWIG_exception(SWIG_TypeError, "map<" #K "," #T "> expected"); if (SWIG_ConvertPtr(val,(void**) &x, $descriptor(T *), 0) == -1) { if (!SCHEME_PAIRP(val)) SWIG_exception(SWIG_TypeError,"alist expected"); val = scheme_car(val); x = (T*) SWIG_MustGetPtr(val,$descriptor(T *),$argnum, 0); } (($1_type &)$1)[CONVERT_FROM(key)] = *x; alist = scheme_cdr(alist); } } else { $1 = *(($&1_type) SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0)); } } %typemap(in) const map& (std::map temp, std::map* m), const map* (std::map temp, std::map* m) { if (SCHEME_NULLP($input)) { temp = std::map(); $1 = &temp; } else if (SCHEME_PAIRP($input)) { temp = std::map(); $1 = &temp; Scheme_Object* alist = $input; while (!SCHEME_NULLP(alist)) { T* x; Scheme_Object *entry, *key, *val; entry = scheme_car(alist); if (!SCHEME_PAIRP(entry)) SWIG_exception(SWIG_TypeError,"alist expected"); key = scheme_car(entry); val = scheme_cdr(entry); if (!CHECK(key)) SWIG_exception(SWIG_TypeError, "map<" #K "," #T "> expected"); if (SWIG_ConvertPtr(val,(void**) &x, $descriptor(T *), 0) == -1) { if (!SCHEME_PAIRP(val)) SWIG_exception(SWIG_TypeError,"alist expected"); val = scheme_car(val); x = (T*) SWIG_MustGetPtr(val,$descriptor(T *),$argnum, 0); } temp[CONVERT_FROM(key)] = *x; alist = scheme_cdr(alist); } } else { $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0); } } %typemap(out) map { Scheme_Object* alist = scheme_null; for (std::map::reverse_iterator i=$1.rbegin(); i!=$1.rend(); ++i) { T* val = new T(i->second); Scheme_Object* k = CONVERT_TO(i->first); Scheme_Object* x = SWIG_NewPointerObj(val,$descriptor(T *), 1); Scheme_Object* entry = scheme_make_pair(k,x); alist = scheme_make_pair(entry,alist); } $result = alist; } %typecheck(SWIG_TYPECHECK_MAP) map { // native sequence? if (SCHEME_NULLP($input)) { /* an empty sequence can be of any type */ $1 = 1; } else if (SCHEME_PAIRP($input)) { // check the first element only T* x; Scheme_Object* head = scheme_car($input); if (SCHEME_PAIRP(head)) { Scheme_Object* key = scheme_car(head); Scheme_Object* val = scheme_cdr(head); if (!CHECK(key)) { $1 = 0; } else { if (SWIG_ConvertPtr(val,(void**) &x, $descriptor(T *), 0) != -1) { $1 = 1; } else if (SCHEME_PAIRP(val)) { val = scheme_car(val); if (SWIG_ConvertPtr(val,(void**) &x, $descriptor(T *), 0) != -1) $1 = 1; else $1 = 0; } else { $1 = 0; } } } else { $1 = 0; } } else { // wrapped map? std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $&1_descriptor, 0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_MAP) const map&, const map* { // native sequence? if (SCHEME_NULLP($input)) { /* an empty sequence can be of any type */ $1 = 1; } else if (SCHEME_PAIRP($input)) { // check the first element only T* x; Scheme_Object* head = scheme_car($input); if (SCHEME_PAIRP(head)) { Scheme_Object* key = scheme_car(head); Scheme_Object* val = scheme_cdr(head); if (!CHECK(key)) { $1 = 0; } else { if (SWIG_ConvertPtr(val,(void**) &x, $descriptor(T *), 0) != -1) { $1 = 1; } else if (SCHEME_PAIRP(val)) { val = scheme_car(val); if (SWIG_ConvertPtr(val,(void**) &x, $descriptor(T *), 0) != -1) $1 = 1; else $1 = 0; } else { $1 = 0; } } } else { $1 = 0; } } else { // wrapped map? std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $1_descriptor, 0) != -1) $1 = 1; else $1 = 0; } } %rename("length") size; %rename("null?") empty; %rename("clear!") clear; %rename("ref") __getitem__; %rename("set!") __setitem__; %rename("delete!") __delitem__; %rename("has-key?") has_key; public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T& __getitem__(K key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void __setitem__(K key, const T& x) { (*self)[key] = x; } void __delitem__(K key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(K key) { std::map::iterator i = self->find(key); return i != self->end(); } Scheme_Object* keys() { Scheme_Object* result = scheme_null; for (std::map::reverse_iterator i=$1.rbegin(); i!=$1.rend(); ++i) { Scheme_Object* k = CONVERT_TO(i->first); result = scheme_make_pair(k,result); } return result; } } }; %enddef %define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO) template class map { %typemap(in) map (std::map* m) { if (SCHEME_NULLP($input)) { $1 = std::map(); } else if (SCHEME_PAIRP($input)) { $1 = std::map(); Scheme_Object* alist = $input; while (!SCHEME_NULLP(alist)) { K* k; Scheme_Object *entry, *key, *val; entry = scheme_car(alist); if (!SCHEME_PAIRP(entry)) SWIG_exception(SWIG_TypeError,"alist expected"); key = scheme_car(entry); val = scheme_cdr(entry); k = (K*) SWIG_MustGetPtr(key,$descriptor(K *),$argnum, 0); if (!CHECK(val)) { if (!SCHEME_PAIRP(val)) SWIG_exception(SWIG_TypeError,"alist expected"); val = scheme_car(val); if (!CHECK(val)) SWIG_exception(SWIG_TypeError, "map<" #K "," #T "> expected"); } (($1_type &)$1)[*k] = CONVERT_FROM(val); alist = scheme_cdr(alist); } } else { $1 = *(($&1_type) SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0)); } } %typemap(in) const map& (std::map temp, std::map* m), const map* (std::map temp, std::map* m) { if (SCHEME_NULLP($input)) { temp = std::map(); $1 = &temp; } else if (SCHEME_PAIRP($input)) { temp = std::map(); $1 = &temp; Scheme_Object* alist = $input; while (!SCHEME_NULLP(alist)) { K* k; Scheme_Object *entry, *key, *val; entry = scheme_car(alist); if (!SCHEME_PAIRP(entry)) SWIG_exception(SWIG_TypeError,"alist expected"); key = scheme_car(entry); val = scheme_cdr(entry); k = (K*) SWIG_MustGetPtr(key,$descriptor(K *),$argnum, 0); if (!CHECK(val)) { if (!SCHEME_PAIRP(val)) SWIG_exception(SWIG_TypeError,"alist expected"); val = scheme_car(val); if (!CHECK(val)) SWIG_exception(SWIG_TypeError, "map<" #K "," #T "> expected"); } temp[*k] = CONVERT_FROM(val); alist = scheme_cdr(alist); } } else { $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0); } } %typemap(out) map { Scheme_Object* alist = scheme_null; for (std::map::reverse_iterator i=$1.rbegin(); i!=$1.rend(); ++i) { K* key = new K(i->first); Scheme_Object* k = SWIG_NewPointerObj(key,$descriptor(K *), 1); Scheme_Object* x = CONVERT_TO(i->second); Scheme_Object* entry = scheme_make_pair(k,x); alist = scheme_make_pair(entry,alist); } $result = alist; } %typecheck(SWIG_TYPECHECK_MAP) map { // native sequence? if (SCHEME_NULLP($input)) { /* an empty sequence can be of any type */ $1 = 1; } else if (SCHEME_PAIRP($input)) { // check the first element only K* k; Scheme_Object* head = scheme_car($input); if (SCHEME_PAIRP(head)) { Scheme_Object* key = scheme_car(head); Scheme_Object* val = scheme_cdr(head); if (SWIG_ConvertPtr(val,(void **) &k, $descriptor(K *), 0) == -1) { $1 = 0; } else { if (CHECK(val)) { $1 = 1; } else if (SCHEME_PAIRP(val)) { val = scheme_car(val); if (CHECK(val)) $1 = 1; else $1 = 0; } else { $1 = 0; } } } else { $1 = 0; } } else { // wrapped map? std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $&1_descriptor, 0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_MAP) const map&, const map* { // native sequence? if (SCHEME_NULLP($input)) { /* an empty sequence can be of any type */ $1 = 1; } else if (SCHEME_PAIRP($input)) { // check the first element only K* k; Scheme_Object* head = scheme_car($input); if (SCHEME_PAIRP(head)) { Scheme_Object* key = scheme_car(head); Scheme_Object* val = scheme_cdr(head); if (SWIG_ConvertPtr(val,(void **) &k, $descriptor(K *), 0) == -1) { $1 = 0; } else { if (CHECK(val)) { $1 = 1; } else if (SCHEME_PAIRP(val)) { val = scheme_car(val); if (CHECK(val)) $1 = 1; else $1 = 0; } else { $1 = 0; } } } else { $1 = 0; } } else { // wrapped map? std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $1_descriptor, 0) != -1) $1 = 1; else $1 = 0; } } %rename("length") size; %rename("null?") empty; %rename("clear!") clear; %rename("ref") __getitem__; %rename("set!") __setitem__; %rename("delete!") __delitem__; %rename("has-key?") has_key; public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T __getitem__(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void __setitem__(const K& key, T x) { (*self)[key] = x; } void __delitem__(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(const K& key) { std::map::iterator i = self->find(key); return i != self->end(); } Scheme_Object* keys() { Scheme_Object* result = scheme_null; for (std::map::reverse_iterator i=$1.rbegin(); i!=$1.rend(); ++i) { K* key = new K(i->first); Scheme_Object* k = SWIG_NewPointerObj(key,$descriptor(K *), 1); result = scheme_make_pair(k,result); } return result; } } }; %enddef %define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO) template<> class map { %typemap(in) map (std::map* m) { if (SCHEME_NULLP($input)) { $1 = std::map(); } else if (SCHEME_PAIRP($input)) { $1 = std::map(); Scheme_Object* alist = $input; while (!SCHEME_NULLP(alist)) { Scheme_Object *entry, *key, *val; entry = scheme_car(alist); if (!SCHEME_PAIRP(entry)) SWIG_exception(SWIG_TypeError,"alist expected"); key = scheme_car(entry); val = scheme_cdr(entry); if (!CHECK_K(key)) SWIG_exception(SWIG_TypeError, "map<" #K "," #T "> expected"); if (!CHECK_T(val)) { if (!SCHEME_PAIRP(val)) SWIG_exception(SWIG_TypeError,"alist expected"); val = scheme_car(val); if (!CHECK_T(val)) SWIG_exception(SWIG_TypeError, "map<" #K "," #T "> expected"); } (($1_type &)$1)[CONVERT_K_FROM(key)] = CONVERT_T_FROM(val); alist = scheme_cdr(alist); } } else { $1 = *(($&1_type) SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0)); } } %typemap(in) const map& (std::map temp, std::map* m), const map* (std::map temp, std::map* m) { if (SCHEME_NULLP($input)) { temp = std::map(); $1 = &temp; } else if (SCHEME_PAIRP($input)) { temp = std::map(); $1 = &temp; Scheme_Object* alist = $input; while (!SCHEME_NULLP(alist)) { Scheme_Object *entry, *key, *val; entry = scheme_car(alist); if (!SCHEME_PAIRP(entry)) SWIG_exception(SWIG_TypeError,"alist expected"); key = scheme_car(entry); val = scheme_cdr(entry); if (!CHECK_K(key)) SWIG_exception(SWIG_TypeError, "map<" #K "," #T "> expected"); if (!CHECK_T(val)) { if (!SCHEME_PAIRP(val)) SWIG_exception(SWIG_TypeError,"alist expected"); val = scheme_car(val); if (!CHECK_T(val)) SWIG_exception(SWIG_TypeError, "map<" #K "," #T "> expected"); } temp[CONVERT_K_FROM(key)] = CONVERT_T_FROM(val); alist = scheme_cdr(alist); } } else { $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0); } } %typemap(out) map { Scheme_Object* alist = scheme_null; for (std::map::reverse_iterator i=$1.rbegin(); i!=$1.rend(); ++i) { Scheme_Object* k = CONVERT_K_TO(i->first); Scheme_Object* x = CONVERT_T_TO(i->second); Scheme_Object* entry = scheme_make_pair(k,x); alist = scheme_make_pair(entry,alist); } $result = alist; } %typecheck(SWIG_TYPECHECK_MAP) map { // native sequence? if (SCHEME_NULLP($input)) { /* an empty sequence can be of any type */ $1 = 1; } else if (SCHEME_PAIRP($input)) { // check the first element only Scheme_Object* head = scheme_car($input); if (SCHEME_PAIRP(head)) { Scheme_Object* key = scheme_car(head); Scheme_Object* val = scheme_cdr(head); if (!CHECK_K(key)) { $1 = 0; } else { if (CHECK_T(val)) { $1 = 1; } else if (SCHEME_PAIRP(val)) { val = scheme_car(val); if (CHECK_T(val)) $1 = 1; else $1 = 0; } else { $1 = 0; } } } else { $1 = 0; } } else { // wrapped map? std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $&1_descriptor, 0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_MAP) const map&, const map* { // native sequence? if (SCHEME_NULLP($input)) { /* an empty sequence can be of any type */ $1 = 1; } else if (SCHEME_PAIRP($input)) { // check the first element only Scheme_Object* head = scheme_car($input); if (SCHEME_PAIRP(head)) { Scheme_Object* key = scheme_car(head); Scheme_Object* val = scheme_cdr(head); if (!CHECK_K(key)) { $1 = 0; } else { if (CHECK_T(val)) { $1 = 1; } else if (SCHEME_PAIRP(val)) { val = scheme_car(val); if (CHECK_T(val)) $1 = 1; else $1 = 0; } else { $1 = 0; } } } else { $1 = 0; } } else { // wrapped map? std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $1_descriptor, 0) != -1) $1 = 1; else $1 = 0; } } %rename("length") size; %rename("null?") empty; %rename("clear!") clear; %rename("ref") __getitem__; %rename("set!") __setitem__; %rename("delete!") __delitem__; %rename("has-key?") has_key; public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T __getitem__(K key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void __setitem__(K key, T x) { (*self)[key] = x; } void __delitem__(K key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(K key) { std::map::iterator i = self->find(key); return i != self->end(); } Scheme_Object* keys() { Scheme_Object* result = scheme_null; for (std::map::reverse_iterator i=$1.rbegin(); i!=$1.rend(); ++i) { Scheme_Object* k = CONVERT_K_TO(i->first); result = scheme_make_pair(k,result); } return result; } } }; %enddef specialize_std_map_on_key(bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean); specialize_std_map_on_key(int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_key(short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_key(long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_key(unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_key(unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_key(unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_key(double,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_map_on_key(float,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_map_on_key(std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string); specialize_std_map_on_value(bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean); specialize_std_map_on_value(int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_value(short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_value(long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_value(unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_value(unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_value(unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_value(double,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_map_on_value(float,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_map_on_value(std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string); specialize_std_map_on_both(bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean, bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean); specialize_std_map_on_both(bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean, int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean, short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean, long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean, unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean, unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean, unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean, double,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_map_on_both(bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean, float,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_map_on_both(bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean, std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string); specialize_std_map_on_both(int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean); specialize_std_map_on_both(int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, double,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_map_on_both(int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, float,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_map_on_both(int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string); specialize_std_map_on_both(short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean); specialize_std_map_on_both(short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, double,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_map_on_both(short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, float,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_map_on_both(short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string); specialize_std_map_on_both(long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean); specialize_std_map_on_both(long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, double,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_map_on_both(long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, float,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_map_on_both(long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string); specialize_std_map_on_both(unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean); specialize_std_map_on_both(unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, double,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_map_on_both(unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, float,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_map_on_both(unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string); specialize_std_map_on_both(unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean); specialize_std_map_on_both(unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, double,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_map_on_both(unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, float,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_map_on_both(unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string); specialize_std_map_on_both(unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean); specialize_std_map_on_both(unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, double,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_map_on_both(unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, float,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_map_on_both(unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string); specialize_std_map_on_both(double,SCHEME_REALP, scheme_real_to_double,scheme_make_double, bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean); specialize_std_map_on_both(double,SCHEME_REALP, scheme_real_to_double,scheme_make_double, int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(double,SCHEME_REALP, scheme_real_to_double,scheme_make_double, short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(double,SCHEME_REALP, scheme_real_to_double,scheme_make_double, long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(double,SCHEME_REALP, scheme_real_to_double,scheme_make_double, unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(double,SCHEME_REALP, scheme_real_to_double,scheme_make_double, unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(double,SCHEME_REALP, scheme_real_to_double,scheme_make_double, unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(double,SCHEME_REALP, scheme_real_to_double,scheme_make_double, double,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_map_on_both(double,SCHEME_REALP, scheme_real_to_double,scheme_make_double, float,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_map_on_both(double,SCHEME_REALP, scheme_real_to_double,scheme_make_double, std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string); specialize_std_map_on_both(float,SCHEME_REALP, scheme_real_to_double,scheme_make_double, bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean); specialize_std_map_on_both(float,SCHEME_REALP, scheme_real_to_double,scheme_make_double, int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(float,SCHEME_REALP, scheme_real_to_double,scheme_make_double, short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(float,SCHEME_REALP, scheme_real_to_double,scheme_make_double, long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(float,SCHEME_REALP, scheme_real_to_double,scheme_make_double, unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(float,SCHEME_REALP, scheme_real_to_double,scheme_make_double, unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(float,SCHEME_REALP, scheme_real_to_double,scheme_make_double, unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(float,SCHEME_REALP, scheme_real_to_double,scheme_make_double, double,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_map_on_both(float,SCHEME_REALP, scheme_real_to_double,scheme_make_double, float,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_map_on_both(float,SCHEME_REALP, scheme_real_to_double,scheme_make_double, std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string); specialize_std_map_on_both(std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string, bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean); specialize_std_map_on_both(std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string, int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string, short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string, long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string, unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string, unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string, unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_map_on_both(std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string, double,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_map_on_both(std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string, float,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_map_on_both(std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string, std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string); } cableswig-0.1.0+git20150808.orig/SWIG/Lib/mzscheme/std_common.i0000644000175000000620000000055412561312227022437 0ustar stevestaff// // SWIG typemaps for STL - common utilities // Luigi Ballabio // Aug 3, 2002 // // MzScheme implementation %apply size_t { std::size_t }; %{ #include std::string swig_scm_to_string(Scheme_Object* x) { return std::string(SCHEME_STR_VAL(x)); } Scheme_Object* swig_make_string(const std::string& s) { return scheme_make_string(s.c_str()); } %} cableswig-0.1.0+git20150808.orig/SWIG/Lib/mzscheme/mzscheme.swg0000644000175000000620000000146712561312227022464 0ustar stevestaff/* SWIG Configuration File for MzScheme. -*-c-*- This file is parsed by SWIG before reading any other interface file. */ /* Include headers */ %runtime "precommon.swg" %runtime "common.swg" %runtime "mzrun.swg" %define SWIG_APPEND_VALUE(value) values[lenv++] = value %enddef /* Definitions */ #define SWIG_malloc(size) swig_malloc(size, FUNC_NAME) #define SWIG_free(mem) free(mem) /* Guile compatibility kludges */ #define SCM_VALIDATE_VECTOR(argnum, value) (void)0 #define SCM_VALIDATE_LIST(argnum, value) (void)0 /* Read in standard typemaps. */ %include "typemaps.i" %init %{ static int _swig_init = 0; if (!_swig_init) { int i; for (i = 0; swig_types_initial[i]; i++) { swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]); } _swig_init = 1; } SWIG_MzScheme_Init(); %} cableswig-0.1.0+git20150808.orig/SWIG/Lib/mzscheme/typemaps.i0000644000175000000620000002246012561312227022137 0ustar stevestaff/* typemaps.i --- mzscheme typemaps -*- c -*- Copyright 2000, 2001 Matthias Koeppe Based on code written by Oleg Tolmatcev. typemaps.i,v 1.7 2003/06/10 21:53:39 mkoeppe Exp */ /* The MzScheme module handles all types uniformly via typemaps. Here are the definitions. */ /* Pointers */ %typemap(in) SWIGTYPE * { $1 = ($ltype) SWIG_MustGetPtr($input, $descriptor, $argnum, 0); } %typemap(in) void * { $1 = SWIG_MustGetPtr($input, NULL, $argnum, 0); } %typemap(varin) SWIGTYPE * { $1 = ($ltype) SWIG_MustGetPtr($input, $descriptor, 1, 0); } %typemap(varin) SWIGTYPE & { $1 = *(($1_ltype)SWIG_MustGetPtr($input, $descriptor, 1, 0)); } %typemap(varin) SWIGTYPE [ANY] { void *temp; int ii; $1_basetype *b = 0; temp = SWIG_MustGetPtr($input, $1_descriptor, 1, 0); b = ($1_basetype *) $1; for (ii = 0; ii < $1_size; ii++) b[ii] = *(($1_basetype *) temp + ii); } %typemap(varin) void * { $1 = SWIG_MustGetPtr($input, NULL, 1, 0); } %typemap(out) SWIGTYPE * { $result = SWIG_NewPointerObj ($1, $descriptor, $owner); } %typemap(out) SWIGTYPE *DYNAMIC { swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor,(void **) &$1); $result = SWIG_NewPointerObj ($1, ty, $owner); } %typemap(varout) SWIGTYPE *, SWIGTYPE [] { $result = SWIG_NewPointerObj ($1, $descriptor, 0); } %typemap(varout) SWIGTYPE & { $result = SWIG_NewPointerObj((void *) &$1, $1_descriptor, 0); } /* C++ References */ #ifdef __cplusplus %typemap(in) SWIGTYPE &, const SWIGTYPE & { $1 = ($ltype) SWIG_MustGetPtr($input, $descriptor, $argnum, 0); if ($1 == NULL) scheme_signal_error("swig-type-error (null reference)"); } %typemap(out) SWIGTYPE &, const SWIGTYPE & { $result = SWIG_NewPointerObj ($1, $descriptor, $owner); } %typemap(out) SWIGTYPE &DYNAMIC { swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor,(void **) &$1); $result = SWIG_NewPointerObj ($1, ty, $owner); } #endif /* Arrays */ %typemap(in) SWIGTYPE[] { $1 = ($ltype) SWIG_MustGetPtr($input, $descriptor, $argnum, 0); } %typemap(out) SWIGTYPE[] { $result = SWIG_NewPointerObj ($1, $descriptor, $owner); } /* Enums */ %typemap(in) enum SWIGTYPE { if (!SCHEME_INTP($input)) scheme_wrong_type("$name", "integer", $argnum, argc, argv); $1 = SCHEME_INT_VAL($input); } %typemap(varin) enum SWIGTYPE { if (!SCHEME_INTP($input)) scheme_wrong_type("$name", "integer", 1, argc, argv); $1 = ($1_type) SCHEME_INT_VAL($input); } %typemap(out) enum SWIGTYPE "$result = scheme_make_integer_value($1);"; %typemap(varout) enum SWIGTYPE "$result = scheme_make_integer_value($1);"; /* Pass-by-value */ %typemap(in) SWIGTYPE($&1_ltype argp) { argp = ($&1_ltype) SWIG_MustGetPtr($input, $&1_descriptor, $argnum, 0); $1 = *argp; } %typemap(varin) SWIGTYPE { $&1_ltype argp; argp = ($&1_ltype) SWIG_MustGetPtr($input, $&1_descriptor, 1, 0); $1 = *argp; } %typemap(out) SWIGTYPE #ifdef __cplusplus { $&1_ltype resultptr; resultptr = new $1_ltype(($1_ltype &) $1); $result = SWIG_NewPointerObj (resultptr, $&1_descriptor, 1); } #else { $&1_ltype resultptr; resultptr = ($&1_ltype) malloc(sizeof($1_type)); memmove(resultptr, &$1, sizeof($1_type)); $result = SWIG_NewPointerObj(resultptr, $&1_descriptor, 1); } #endif %typemap(varout) SWIGTYPE #ifdef __cplusplus { $&1_ltype resultptr; resultptr = new $1_ltype(($1_ltype &) $1); $result = SWIG_NewPointerObj (resultptr, $&1_descriptor, 0); } #else { $&1_ltype resultptr; resultptr = ($&1_ltype) malloc(sizeof($1_type)); memmove(resultptr, &$1, sizeof($1_type)); $result = SWIG_NewPointerObj(resultptr, $&1_descriptor, 0); } #endif /* The SIMPLE_MAP macro below defines the whole set of typemaps needed for simple types. */ %define SIMPLE_MAP(C_NAME, MZ_PREDICATE, MZ_TO_C, C_TO_MZ, MZ_NAME) %typemap(in) C_NAME { if (!MZ_PREDICATE($input)) scheme_wrong_type("$name", #MZ_NAME, $argnum, argc, argv); $1 = MZ_TO_C($input); } %typemap(varin) C_NAME { if (!MZ_PREDICATE($input)) scheme_wrong_type("$name", #MZ_NAME, 1, argc, argv); $1 = MZ_TO_C($input); } %typemap(out) C_NAME { $result = C_TO_MZ($1); } %typemap(varout) C_NAME { $result = C_TO_MZ($1); } %typemap(in) C_NAME *INPUT (C_NAME temp) { temp = (C_NAME) MZ_TO_C($input); $1 = &temp; } %typemap(in,numinputs=0) C_NAME *OUTPUT (C_NAME temp) { $1 = &temp; } %typemap(argout) C_NAME *OUTPUT { Scheme_Object *s; s = C_TO_MZ(*$1); SWIG_APPEND_VALUE(s); } %typemap(in) C_NAME *BOTH = C_NAME *INPUT; %typemap(argout) C_NAME *BOTH = C_NAME *OUTPUT; %typemap(in) C_NAME *INOUT = C_NAME *INPUT; %typemap(argout) C_NAME *INOUT = C_NAME *OUTPUT; %enddef SIMPLE_MAP(bool, SCHEME_BOOLP, SCHEME_TRUEP, swig_make_boolean, boolean); SIMPLE_MAP(char, SCHEME_CHARP, SCHEME_CHAR_VAL, scheme_make_character, character); SIMPLE_MAP(unsigned char, SCHEME_CHARP, SCHEME_CHAR_VAL, scheme_make_character, character); SIMPLE_MAP(int, SCHEME_INTP, SCHEME_INT_VAL, scheme_make_integer_value, integer); SIMPLE_MAP(short, SCHEME_INTP, SCHEME_INT_VAL, scheme_make_integer_value, integer); SIMPLE_MAP(long, SCHEME_INTP, SCHEME_INT_VAL, scheme_make_integer_value, integer); SIMPLE_MAP(ptrdiff_t, SCHEME_INTP, SCHEME_INT_VAL, scheme_make_integer_value, integer); SIMPLE_MAP(unsigned int, SCHEME_INTP, SCHEME_INT_VAL, scheme_make_integer_value_from_unsigned, integer); SIMPLE_MAP(unsigned short, SCHEME_INTP, SCHEME_INT_VAL, scheme_make_integer_value_from_unsigned, integer); SIMPLE_MAP(unsigned long, SCHEME_INTP, SCHEME_INT_VAL, scheme_make_integer_value_from_unsigned, integer); SIMPLE_MAP(size_t, SCHEME_INTP, SCHEME_INT_VAL, scheme_make_integer_value_from_unsigned, integer); SIMPLE_MAP(float, SCHEME_REALP, scheme_real_to_double, scheme_make_double, real); SIMPLE_MAP(double, SCHEME_REALP, scheme_real_to_double, scheme_make_double, real); SIMPLE_MAP(char *, SCHEME_STRINGP, SCHEME_STR_VAL, scheme_make_string_without_copying, string); SIMPLE_MAP(const char *, SCHEME_STRINGP, SCHEME_STR_VAL, scheme_make_string_without_copying, string); /* Const primitive references. Passed by value */ %define REF_MAP(C_NAME, MZ_PREDICATE, MZ_TO_C, C_TO_MZ, MZ_NAME) %typemap(in) const C_NAME & (C_NAME temp) { if (!MZ_PREDICATE($input)) scheme_wrong_type("$name", #MZ_NAME, $argnum, argc, argv); temp = MZ_TO_C($input); $1 = &temp; } %typemap(out) const C_NAME & { $result = C_TO_MZ(*$1); } %enddef REF_MAP(bool, SCHEME_BOOLP, SCHEME_TRUEP, swig_make_boolean, boolean); REF_MAP(char, SCHEME_CHARP, SCHEME_CHAR_VAL, scheme_make_character, character); REF_MAP(unsigned char, SCHEME_CHARP, SCHEME_CHAR_VAL, scheme_make_character, character); REF_MAP(int, SCHEME_INTP, SCHEME_INT_VAL, scheme_make_integer_value, integer); REF_MAP(short, SCHEME_INTP, SCHEME_INT_VAL, scheme_make_integer_value, integer); REF_MAP(long, SCHEME_INTP, SCHEME_INT_VAL, scheme_make_integer_value, integer); REF_MAP(unsigned int, SCHEME_INTP, SCHEME_INT_VAL, scheme_make_integer_value_from_unsigned, integer); REF_MAP(unsigned short, SCHEME_INTP, SCHEME_INT_VAL, scheme_make_integer_value_from_unsigned, integer); REF_MAP(unsigned long, SCHEME_INTP, SCHEME_INT_VAL, scheme_make_integer_value_from_unsigned, integer); REF_MAP(float, SCHEME_REALP, scheme_real_to_double, scheme_make_double, real); REF_MAP(double, SCHEME_REALP, scheme_real_to_double, scheme_make_double, real); /* Void */ %typemap(out) void "$result = scheme_void;"; /* Pass through Scheme_Object * */ %typemap (in) Scheme_Object * "$1=$input;"; %typemap (out) Scheme_Object * "$result=$1;"; %typecheck(SWIG_TYPECHECK_POINTER) Scheme_Object * "$1=1;"; /* ------------------------------------------------------------ * String & length * ------------------------------------------------------------ */ //%typemap(in) (char *STRING, int LENGTH) { // int temp; // $1 = ($1_ltype) gh_scm2newstr($input, &temp); // $2 = ($2_ltype) temp; //} /* ------------------------------------------------------------ * Typechecking rules * ------------------------------------------------------------ */ %typecheck(SWIG_TYPECHECK_INTEGER) int, short, long, unsigned int, unsigned short, unsigned long, signed char, unsigned char, long long, unsigned long long, const int &, const short &, const long &, const unsigned int &, const unsigned short &, const unsigned long &, const long long &, const unsigned long long &, enum SWIGTYPE { $1 = (SCHEME_INTP($input)) ? 1 : 0; } %typecheck(SWIG_TYPECHECK_BOOL) bool, bool &, const bool & { $1 = (SCHEME_BOOLP($input)) ? 1 : 0; } %typecheck(SWIG_TYPECHECK_DOUBLE) float, double, const float &, const double & { $1 = (SCHEME_REALP($input)) ? 1 : 0; } %typecheck(SWIG_TYPECHECK_STRING) char { $1 = (SCHEME_STRINGP($input)) ? 1 : 0; } %typecheck(SWIG_TYPECHECK_STRING) char * { $1 = (SCHEME_STRINGP($input)) ? 1 : 0; } %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { void *ptr; if (SWIG_ConvertPtr($input, (void **) &ptr, $1_descriptor, 0)) { $1 = 0; } else { $1 = 1; } } %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE { void *ptr; if (SWIG_ConvertPtr($input, (void **) &ptr, $&1_descriptor, 0)) { $1 = 0; } else { $1 = 1; } } %typecheck(SWIG_TYPECHECK_VOIDPTR) void * { void *ptr; if (SWIG_ConvertPtr($input, (void **) &ptr, 0, 0)) { $1 = 0; } else { $1 = 1; } } cableswig-0.1.0+git20150808.orig/SWIG/Lib/mzscheme/std_pair.i0000644000175000000620000012405412561312227022104 0ustar stevestaff// // SWIG typemaps for std::pair // Luigi Ballabio // July 2003 // // MzScheme implementation %include std_common.i %include exception.i // ------------------------------------------------------------------------ // std::pair // // See std_vector.i for the rationale of typemap application // ------------------------------------------------------------------------ %{ #include %} // exported class namespace std { template struct pair { %typemap(in) pair (std::pair* m) { if (SCHEME_PAIRP($input)) { T* x; U* y; Scheme_Object *first, *second; first = scheme_car($input); second = scheme_cdr($input); x = (T*) SWIG_MustGetPtr(first,$descriptor(T *),$argnum, 0); y = (U*) SWIG_MustGetPtr(second,$descriptor(U *),$argnum, 0); $1 = make_pair(x,y); } else { $1 = *(($&1_type) SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0)); } } %typemap(in) const pair& (std::pair temp, std::pair* m), const pair* (std::pair temp, std::pair* m) { if (SCHEME_PAIRP($input)) { T* x; U* y; Scheme_Object *first, *second; first = scheme_car($input); second = scheme_cdr($input); x = (T*) SWIG_MustGetPtr(first,$descriptor(T *),$argnum, 0); y = (U*) SWIG_MustGetPtr(second,$descriptor(U *),$argnum, 0); temp = make_pair(x,y); $1 = &temp; } else { $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0); } } %typemap(out) pair { T* x = new T($1.first); U* y = new U($1.second); Scheme_Object* first = SWIG_NewPointerObj(x,$descriptor(T *), 1); Scheme_Object* second = SWIG_NewPointerObj(y,$descriptor(U *), 1); $result = scheme_make_pair(first,second); } %typecheck(SWIG_TYPECHECK_PAIR) pair { /* native pair? */ if (SCHEME_PAIRP($input)) { T* x; U* y; Scheme_Object* first = scheme_car($input); Scheme_Object* second = scheme_cdr($input); if (SWIG_ConvertPtr(first,(void**) &x, $descriptor(T *), 0) != -1 && SWIG_ConvertPtr(second,(void**) &y, $descriptor(U *), 0) != -1) { $1 = 1; } else { $1 = 0; } } else { /* wrapped pair? */ std::pair* p; if (SWIG_ConvertPtr($input,(void **) &p, $&1_descriptor, 0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_PAIR) const pair&, const pair* { /* native pair? */ if (SCHEME_PAIRP($input)) { T* x; U* y; Scheme_Object* first = scheme_car($input); Scheme_Object* second = scheme_cdr($input); if (SWIG_ConvertPtr(first,(void**) &x, $descriptor(T *), 0) != -1 && SWIG_ConvertPtr(second,(void**) &y, $descriptor(U *), 0) != -1) { $1 = 1; } else { $1 = 0; } } else { /* wrapped pair? */ std::pair* p; if (SWIG_ConvertPtr($input,(void **) &p, $1_descriptor, 0) != -1) $1 = 1; else $1 = 0; } } T first; U second; }; // specializations for built-ins %define specialize_std_pair_on_first(T,CHECK,CONVERT_FROM,CONVERT_TO) template struct pair { %typemap(in) pair (std::pair* m) { if (SCHEME_PAIRP($input)) { U* y; Scheme_Object *first, *second; first = scheme_car($input); second = scheme_cdr($input); if (!CHECK(first)) SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); y = (U*) SWIG_MustGetPtr(second,$descriptor(U *),$argnum, 0); $1 = make_pair(CONVERT_FROM(first),y); } else { $1 = *(($&1_type) SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0)); } } %typemap(in) const pair& (std::pair temp, std::pair* m), const pair* (std::pair temp, std::pair* m) { if (SCHEME_PAIRP($input)) { U* y; Scheme_Object *first, *second; first = scheme_car($input); second = scheme_cdr($input); if (!CHECK(first)) SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); y = (U*) SWIG_MustGetPtr(second,$descriptor(U *),$argnum, 0); temp = make_pair(CONVERT_FROM(first),y); $1 = &temp; } else { $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0); } } %typemap(out) pair { U* y = new U($1.second); Scheme_Object* second = SWIG_NewPointerObj(y,$descriptor(U *), 1); $result = scheme_make_pair(CONVERT_TO($1.first),second); } %typecheck(SWIG_TYPECHECK_PAIR) pair { /* native pair? */ if (SCHEME_PAIRP($input)) { U* y; Scheme_Object* first = scheme_car($input); Scheme_Object* second = scheme_cdr($input); if (CHECK(first) && SWIG_ConvertPtr(second,(void**) &y, $descriptor(U *), 0) != -1) { $1 = 1; } else { $1 = 0; } } else { /* wrapped pair? */ std::pair* p; if (SWIG_ConvertPtr($input,(void **) &p, $&1_descriptor, 0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_PAIR) const pair&, const pair* { /* native pair? */ if (SCHEME_PAIRP($input)) { U* y; Scheme_Object* first = scheme_car($input); Scheme_Object* second = scheme_cdr($input); if (CHECK(first) && SWIG_ConvertPtr(second,(void**) &y, $descriptor(U *), 0) != -1) { $1 = 1; } else { $1 = 0; } } else { /* wrapped pair? */ std::pair* p; if (SWIG_ConvertPtr($input,(void **) &p, $1_descriptor, 0) != -1) $1 = 1; else $1 = 0; } } T first; U second; }; %enddef %define specialize_std_pair_on_second(U,CHECK,CONVERT_FROM,CONVERT_TO) template struct pair { %typemap(in) pair (std::pair* m) { if (SCHEME_PAIRP($input)) { T* x; Scheme_Object *first, *second; first = scheme_car($input); second = scheme_cdr($input); x = (T*) SWIG_MustGetPtr(first,$descriptor(T *),$argnum, 0); if (!CHECK(second)) SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); $1 = make_pair(x,CONVERT_FROM(second)); } else { $1 = *(($&1_type) SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0)); } } %typemap(in) const pair& (std::pair temp, std::pair* m), const pair* (std::pair temp, std::pair* m) { if (SCHEME_PAIRP($input)) { T* x; Scheme_Object *first, *second; first = scheme_car($input); second = scheme_cdr($input); x = (T*) SWIG_MustGetPtr(first,$descriptor(T *),$argnum, 0); if (!CHECK(second)) SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); temp = make_pair(x,CONVERT_FROM(second)); $1 = &temp; } else { $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0); } } %typemap(out) pair { T* x = new T($1.first); Scheme_Object* first = SWIG_NewPointerObj(x,$descriptor(T *), 1); $result = scheme_make_pair(first,CONVERT_TO($1.second)); } %typecheck(SWIG_TYPECHECK_PAIR) pair { /* native pair? */ if (SCHEME_PAIRP($input)) { T* x; Scheme_Object* first = scheme_car($input); Scheme_Object* second = scheme_cdr($input); if (SWIG_ConvertPtr(first,(void**) &x, $descriptor(T *), 0) != -1 && CHECK(second)) { $1 = 1; } else { $1 = 0; } } else { /* wrapped pair? */ std::pair* p; if (SWIG_ConvertPtr($input,(void **) &p, $&1_descriptor, 0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_PAIR) const pair&, const pair* { /* native pair? */ if (SCHEME_PAIRP($input)) { T* x; Scheme_Object* first = scheme_car($input); Scheme_Object* second = scheme_cdr($input); if (SWIG_ConvertPtr(first,(void**) &x, $descriptor(T *), 0) != -1 && CHECK(second)) { $1 = 1; } else { $1 = 0; } } else { /* wrapped pair? */ std::pair* p; if (SWIG_ConvertPtr($input,(void **) &p, $1_descriptor, 0) != -1) $1 = 1; else $1 = 0; } } T first; U second; }; %enddef %define specialize_std_pair_on_both(T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO, U,CHECK_U,CONVERT_U_FROM,CONVERT_U_TO) template<> struct pair { %typemap(in) pair (std::pair* m) { if (SCHEME_PAIRP($input)) { Scheme_Object *first, *second; first = scheme_car($input); second = scheme_cdr($input); if (!CHECK_T(first) || !CHECK_U(second)) SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); $1 = make_pair(CONVERT_T_FROM(first), CONVERT_U_FROM(second)); } else { $1 = *(($&1_type) SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0)); } } %typemap(in) const pair& (std::pair temp, std::pair* m), const pair* (std::pair temp, std::pair* m) { if (SCHEME_PAIRP($input)) { Scheme_Object *first, *second; T *x; first = scheme_car($input); second = scheme_cdr($input); x = (T*) SWIG_MustGetPtr(first,$descriptor(T *),$argnum, 0); if (!CHECK_T(first) || !CHECK_U(second)) SWIG_exception(SWIG_TypeError, "pair<" #T "," #U "> expected"); temp = make_pair(CONVERT_T_FROM(first), CONVERT_U_FROM(second)); $1 = &temp; } else { $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0); } } %typemap(out) pair { $result = scheme_make_pair(CONVERT_T_TO($1.first), CONVERT_U_TO($1.second)); } %typecheck(SWIG_TYPECHECK_PAIR) pair { /* native pair? */ if (SCHEME_PAIRP($input)) { Scheme_Object* first = scheme_car($input); Scheme_Object* second = scheme_cdr($input); if (CHECK_T(first) && CHECK_U(second)) { $1 = 1; } else { $1 = 0; } } else { /* wrapped pair? */ std::pair* p; if (SWIG_ConvertPtr($input,(void **) &p, $&1_descriptor, 0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_PAIR) const pair&, const pair* { /* native pair? */ if (SCHEME_PAIRP($input)) { Scheme_Object* first = scheme_car($input); Scheme_Object* second = scheme_cdr($input); if (CHECK_T(first) && CHECK_U(second)) { $1 = 1; } else { $1 = 0; } } else { /* wrapped pair? */ std::pair* p; if (SWIG_ConvertPtr($input,(void **) &p, $1_descriptor, 0) != -1) $1 = 1; else $1 = 0; } } T first; U second; }; %enddef specialize_std_pair_on_first(bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean); specialize_std_pair_on_first(int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_first(short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_first(long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_first(unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_first(unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_first(unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_first(double,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_pair_on_first(float,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_pair_on_first(std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string); specialize_std_pair_on_second(bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean); specialize_std_pair_on_second(int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_second(short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_second(long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_second(unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_second(unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_second(unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_second(double,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_pair_on_second(float,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_pair_on_second(std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string); specialize_std_pair_on_both(bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean, bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean); specialize_std_pair_on_both(bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean, int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean, short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean, long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean, unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean, unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean, unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean, double,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_pair_on_both(bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean, float,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_pair_on_both(bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean, std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string); specialize_std_pair_on_both(int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean); specialize_std_pair_on_both(int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, double,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_pair_on_both(int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, float,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_pair_on_both(int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string); specialize_std_pair_on_both(short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean); specialize_std_pair_on_both(short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, double,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_pair_on_both(short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, float,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_pair_on_both(short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string); specialize_std_pair_on_both(long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean); specialize_std_pair_on_both(long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, double,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_pair_on_both(long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, float,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_pair_on_both(long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string); specialize_std_pair_on_both(unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean); specialize_std_pair_on_both(unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, double,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_pair_on_both(unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, float,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_pair_on_both(unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string); specialize_std_pair_on_both(unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean); specialize_std_pair_on_both(unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, double,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_pair_on_both(unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, float,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_pair_on_both(unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string); specialize_std_pair_on_both(unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean); specialize_std_pair_on_both(unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, double,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_pair_on_both(unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, float,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_pair_on_both(unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value, std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string); specialize_std_pair_on_both(double,SCHEME_REALP, scheme_real_to_double,scheme_make_double, bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean); specialize_std_pair_on_both(double,SCHEME_REALP, scheme_real_to_double,scheme_make_double, int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(double,SCHEME_REALP, scheme_real_to_double,scheme_make_double, short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(double,SCHEME_REALP, scheme_real_to_double,scheme_make_double, long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(double,SCHEME_REALP, scheme_real_to_double,scheme_make_double, unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(double,SCHEME_REALP, scheme_real_to_double,scheme_make_double, unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(double,SCHEME_REALP, scheme_real_to_double,scheme_make_double, unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(double,SCHEME_REALP, scheme_real_to_double,scheme_make_double, double,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_pair_on_both(double,SCHEME_REALP, scheme_real_to_double,scheme_make_double, float,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_pair_on_both(double,SCHEME_REALP, scheme_real_to_double,scheme_make_double, std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string); specialize_std_pair_on_both(float,SCHEME_REALP, scheme_real_to_double,scheme_make_double, bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean); specialize_std_pair_on_both(float,SCHEME_REALP, scheme_real_to_double,scheme_make_double, int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(float,SCHEME_REALP, scheme_real_to_double,scheme_make_double, short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(float,SCHEME_REALP, scheme_real_to_double,scheme_make_double, long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(float,SCHEME_REALP, scheme_real_to_double,scheme_make_double, unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(float,SCHEME_REALP, scheme_real_to_double,scheme_make_double, unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(float,SCHEME_REALP, scheme_real_to_double,scheme_make_double, unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(float,SCHEME_REALP, scheme_real_to_double,scheme_make_double, double,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_pair_on_both(float,SCHEME_REALP, scheme_real_to_double,scheme_make_double, float,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_pair_on_both(float,SCHEME_REALP, scheme_real_to_double,scheme_make_double, std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string); specialize_std_pair_on_both(std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string, bool,SCHEME_BOOLP, SCHEME_TRUEP,swig_make_boolean); specialize_std_pair_on_both(std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string, int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string, short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string, long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string, unsigned int,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string, unsigned short,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string, unsigned long,SCHEME_INTP, SCHEME_INT_VAL,scheme_make_integer_value); specialize_std_pair_on_both(std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string, double,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_pair_on_both(std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string, float,SCHEME_REALP, scheme_real_to_double,scheme_make_double); specialize_std_pair_on_both(std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string, std::string,SCHEME_STRINGP, swig_scm_to_string,swig_make_string); } cableswig-0.1.0+git20150808.orig/SWIG/Lib/mzscheme/std_vector.i0000644000175000000620000004322312561312227022451 0ustar stevestaff// // SWIG typemaps for std::vector // Luigi Ballabio // Apr 8, 2002 // // MzScheme implementation %include std_common.i %include exception.i // containers %exception std::vector::ref { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::vector::set { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::vector::pop { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } // ------------------------------------------------------------------------ // std::vector // // The aim of all that follows would be to integrate std::vector with // MzScheme as much as possible, namely, to allow the user to pass and // be returned MzScheme vectors or lists. // const declarations are used to guess the intent of the function being // exported; therefore, the following rationale is applied: // // -- f(std::vector), f(const std::vector&), f(const std::vector*): // the parameter being read-only, either a MzScheme sequence or a // previously wrapped std::vector can be passed. // -- f(std::vector&), f(std::vector*): // the parameter must be modified; therefore, only a wrapped std::vector // can be passed. // -- std::vector f(): // the vector is returned by copy; therefore, a MzScheme vector of T:s // is returned which is most easily used in other MzScheme functions // -- std::vector& f(), std::vector* f(), const std::vector& f(), // const std::vector* f(): // the vector is returned by reference; therefore, a wrapped std::vector // is returned // ------------------------------------------------------------------------ %{ #include #include #include %} // exported class namespace std { template class vector { %typemap(in) vector { if (SCHEME_VECTORP($input)) { unsigned int size = SCHEME_VEC_SIZE($input); $1 = std::vector(size); Scheme_Object** items = SCHEME_VEC_ELS($input); for (unsigned int i=0; i(); } else if (SCHEME_PAIRP($input)) { Scheme_Object *head, *tail; $1 = std::vector(); tail = $input; while (!SCHEME_NULLP(tail)) { head = scheme_car(tail); tail = scheme_cdr(tail); $1.push_back(*((T*)SWIG_MustGetPtr(head, $descriptor(T *), $argnum, 0))); } } else { $1 = *(($&1_type) SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0)); } } %typemap(in) const vector& (std::vector temp), const vector* (std::vector temp) { if (SCHEME_VECTORP($input)) { unsigned int size = SCHEME_VEC_SIZE($input); temp = std::vector(size); $1 = &temp; Scheme_Object** items = SCHEME_VEC_ELS($input); for (unsigned int i=0; i(); $1 = &temp; } else if (SCHEME_PAIRP($input)) { temp = std::vector(); $1 = &temp; Scheme_Object *head, *tail; tail = $input; while (!SCHEME_NULLP(tail)) { head = scheme_car(tail); tail = scheme_cdr(tail); temp.push_back(*((T*) SWIG_MustGetPtr(head, $descriptor(T *), $argnum, 0))); } } else { $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0); } } %typemap(out) vector { $result = scheme_make_vector($1.size(),scheme_undefined); Scheme_Object** els = SCHEME_VEC_ELS($result); for (unsigned int i=0; i<$1.size(); i++) { T* x = new T((($1_type &)$1)[i]); els[i] = SWIG_NewPointerObj(x,$descriptor(T *), 1); } } %typecheck(SWIG_TYPECHECK_VECTOR) vector { /* native sequence? */ if (SCHEME_VECTORP($input)) { unsigned int size = SCHEME_VEC_SIZE($input); if (size == 0) { /* an empty sequence can be of any type */ $1 = 1; } else { /* check the first element only */ T* x; Scheme_Object** items = SCHEME_VEC_ELS($input); if (SWIG_ConvertPtr(items[0],(void**) &x, $descriptor(T *), 0) != -1) $1 = 1; else $1 = 0; } } else if (SCHEME_NULLP($input)) { /* again, an empty sequence can be of any type */ $1 = 1; } else if (SCHEME_PAIRP($input)) { /* check the first element only */ T* x; Scheme_Object *head = scheme_car($input); if (SWIG_ConvertPtr(head,(void**) &x, $descriptor(T *), 0) != -1) $1 = 1; else $1 = 0; } else { /* wrapped vector? */ std::vector* v; if (SWIG_ConvertPtr($input,(void **) &v, $&1_descriptor, 0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_VECTOR) const vector&, const vector* { /* native sequence? */ if (SCHEME_VECTORP($input)) { unsigned int size = SCHEME_VEC_SIZE($input); if (size == 0) { /* an empty sequence can be of any type */ $1 = 1; } else { /* check the first element only */ T* x; Scheme_Object** items = SCHEME_VEC_ELS($input); if (SWIG_ConvertPtr(items[0],(void**) &x, $descriptor(T *), 0) != -1) $1 = 1; else $1 = 0; } } else if (SCHEME_NULLP($input)) { /* again, an empty sequence can be of any type */ $1 = 1; } else if (SCHEME_PAIRP($input)) { /* check the first element only */ T* x; Scheme_Object *head = scheme_car($input); if (SWIG_ConvertPtr(head,(void**) &x, $descriptor(T *), 0) != -1) $1 = 1; else $1 = 0; } else { /* wrapped vector? */ std::vector* v; if (SWIG_ConvertPtr($input,(void **) &v, $1_descriptor, 0) != -1) $1 = 1; else $1 = 0; } } public: vector(unsigned int size = 0); vector(unsigned int size, const T& value); vector(const vector&); %rename(length) size; unsigned int size() const; %rename("empty?") empty; bool empty() const; %rename("clear!") clear; void clear(); %rename("set!") set; %rename("pop!") pop; %rename("push!") push_back; void push_back(const T& x); %extend { T pop() { if (self->size() == 0) throw std::out_of_range("pop from empty vector"); T x = self->back(); self->pop_back(); return x; } T& ref(int i) { int size = int(self->size()); if (i>=0 && isize()); if (i>=0 && i class vector { %typemap(in) vector { if (SCHEME_VECTORP($input)) { unsigned int size = SCHEME_VEC_SIZE($input); $1 = std::vector(size); Scheme_Object** items = SCHEME_VEC_ELS($input); for (unsigned int i=0; i", $argnum, argc, argv); } } else if (SCHEME_NULLP($input)) { $1 = std::vector(); } else if (SCHEME_PAIRP($input)) { Scheme_Object *head, *tail; $1 = std::vector(); tail = $input; while (!SCHEME_NULLP(tail)) { head = scheme_car(tail); tail = scheme_cdr(tail); if (CHECK(head)) $1.push_back((T)(CONVERT_FROM(head))); else scheme_wrong_type(FUNC_NAME, "vector<" #T ">", $argnum, argc, argv); } } else { $1 = *(($&1_type) SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0)); } } %typemap(in) const vector& (std::vector temp), const vector* (std::vector temp) { if (SCHEME_VECTORP($input)) { unsigned int size = SCHEME_VEC_SIZE($input); temp = std::vector(size); $1 = &temp; Scheme_Object** items = SCHEME_VEC_ELS($input); for (unsigned int i=0; i", $argnum, argc, argv); } } else if (SCHEME_NULLP($input)) { temp = std::vector(); $1 = &temp; } else if (SCHEME_PAIRP($input)) { temp = std::vector(); $1 = &temp; Scheme_Object *head, *tail; tail = $input; while (!SCHEME_NULLP(tail)) { head = scheme_car(tail); tail = scheme_cdr(tail); if (CHECK(head)) temp.push_back((T)(CONVERT_FROM(head))); else scheme_wrong_type(FUNC_NAME, "vector<" #T ">", $argnum, argc, argv); } } else { $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0); } } %typemap(out) vector { $result = scheme_make_vector($1.size(),scheme_undefined); Scheme_Object** els = SCHEME_VEC_ELS($result); for (unsigned int i=0; i<$1.size(); i++) els[i] = CONVERT_TO((($1_type &)$1)[i]); } %typecheck(SWIG_TYPECHECK_VECTOR) vector { /* native sequence? */ if (SCHEME_VECTORP($input)) { unsigned int size = SCHEME_VEC_SIZE($input); if (size == 0) { /* an empty sequence can be of any type */ $1 = 1; } else { /* check the first element only */ T* x; Scheme_Object** items = SCHEME_VEC_ELS($input); $1 = CHECK(items[0]) ? 1 : 0; } } else if (SCHEME_NULLP($input)) { /* again, an empty sequence can be of any type */ $1 = 1; } else if (SCHEME_PAIRP($input)) { /* check the first element only */ T* x; Scheme_Object *head = scheme_car($input); $1 = CHECK(head) ? 1 : 0; } else { /* wrapped vector? */ std::vector* v; $1 = (SWIG_ConvertPtr($input,(void **) &v, $&1_descriptor, 0) != -1) ? 1 : 0; } } %typecheck(SWIG_TYPECHECK_VECTOR) const vector&, const vector* { /* native sequence? */ if (SCHEME_VECTORP($input)) { unsigned int size = SCHEME_VEC_SIZE($input); if (size == 0) { /* an empty sequence can be of any type */ $1 = 1; } else { /* check the first element only */ T* x; Scheme_Object** items = SCHEME_VEC_ELS($input); $1 = CHECK(items[0]) ? 1 : 0; } } else if (SCHEME_NULLP($input)) { /* again, an empty sequence can be of any type */ $1 = 1; } else if (SCHEME_PAIRP($input)) { /* check the first element only */ T* x; Scheme_Object *head = scheme_car($input); $1 = CHECK(head) ? 1 : 0; } else { /* wrapped vector? */ std::vector* v; $1 = (SWIG_ConvertPtr($input,(void **) &v, $1_descriptor, 0) != -1) ? 1 : 0; } } public: vector(unsigned int size = 0); vector(unsigned int size, const T& value); vector(const vector&); %rename(length) size; unsigned int size() const; %rename("empty?") empty; bool empty() const; %rename("clear!") clear; void clear(); %rename("set!") set; %rename("pop!") pop; %rename("push!") push_back; void push_back(T x); %extend { T pop() { if (self->size() == 0) throw std::out_of_range("pop from empty vector"); T x = self->back(); self->pop_back(); return x; } T ref(int i) { int size = int(self->size()); if (i>=0 && isize()); if (i>=0 && i * ----------------------------------------------------------------------- */ #include #include #include #include #ifdef __cplusplus extern "C" { #endif /* Common SWIG API */ #define SWIG_ConvertPtr(s, result, type, flags) \ SWIG_MzScheme_ConvertPtr(s, result, type, flags) #define SWIG_NewPointerObj(ptr, type, owner) \ SWIG_MzScheme_NewPointerObj((void *)ptr, type, owner) #define SWIG_MustGetPtr(s, type, argnum, flags) \ SWIG_MzScheme_MustGetPtr(s, type, argnum, flags, FUNC_NAME, argc, argv) /* MzScheme-specific SWIG API */ #define SWIG_malloc(size) SWIG_MzScheme_Malloc(size, FUNC_NAME) #define SWIG_free(mem) free(mem) #define MAXVALUES 6 #define swig_make_boolean(b) (b ? scheme_true : scheme_false) #ifdef SWIG_NOINCLUDE SWIGIMPORT(void) SWIG_MzScheme_Init(); /* If there is a type-mismatch, return nonzero; on success, return 0. */ SWIGIMPORT(int) SWIG_MzScheme_ConvertPtr(Scheme_Object *s, void **result, swig_type_info *type, int flags); /* If there is a type-mismatch, signal a wrong-type-arg error for the given argument number. */ SWIGIMPORT(void *) SWIG_MzScheme_MustGetPtr(Scheme_Object *s, swig_type_info *type, int argnum, int flags, const char *func_name, int argc, Scheme_Object **argv); SWIGIMPORT(Scheme_Object *) SWIG_MzScheme_NewPointerObj(void *ptr, swig_type_info *type, int owner); SWIGIMPORT(void *) SWIG_MzScheme_Malloc(size_t size, const char *func_name); SWIGIMPORT(Scheme_Object *) SWIG_MzScheme_PackageValues(int num, Scheme_Object **values); #else struct swig_mz_proxy { Scheme_Type mztype; swig_type_info *type; void *object; }; static Scheme_Type swig_type; static int swig_mz_initialized = 0; static void mz_free_swig(void *p, void *data) { struct swig_mz_proxy *proxy = (struct swig_mz_proxy *) p; if (SCHEME_NULLP((Scheme_Object*)p) || SCHEME_TYPE((Scheme_Object*)p) != swig_type) return; if (proxy->type) { if (proxy->type->clientdata) { ((Scheme_Prim *)proxy->type->clientdata)(1, (Scheme_Object **)&proxy); } } } SWIGRUNTIME(Scheme_Object *) SWIG_MzScheme_NewPointerObj(void *ptr, swig_type_info *type, int owner) { struct swig_mz_proxy *new_proxy; new_proxy = (struct swig_mz_proxy *) scheme_malloc(sizeof(struct swig_mz_proxy)); new_proxy->mztype = swig_type; new_proxy->type = type; new_proxy->object = ptr; if (owner) { scheme_add_finalizer(new_proxy, mz_free_swig, NULL); } return (Scheme_Object *) new_proxy; } SWIGRUNTIME(int) SWIG_MzScheme_ConvertPtr(Scheme_Object *s, void **result, swig_type_info *type, int flags) { swig_type_info *cast; if (SCHEME_NULLP(s)) { *result = NULL; return 0; } else if (SCHEME_TYPE(s) == swig_type) { struct swig_mz_proxy *proxy = (struct swig_mz_proxy *) s; if (type) { cast = SWIG_TypeCheck((char *)proxy->type->name, type); if (cast) { *result = SWIG_TypeCast(cast, proxy->object); return 0; } else { return 1; } } else { *result = proxy->object; return 0; } } return 1; } SWIGRUNTIME(void *) SWIG_MzScheme_MustGetPtr(Scheme_Object *s, swig_type_info *type, int argnum, int flags, const char *func_name, int argc, Scheme_Object **argv) { void *result; if (SWIG_MzScheme_ConvertPtr(s, &result, type, flags)) { scheme_wrong_type(func_name, type->str ? type->str : "void *", argnum, argc, argv); } return result; } SWIGRUNTIME(void) SWIG_MzScheme_Init() { if (!swig_mz_initialized) { swig_type = scheme_make_type((char *)"swig"); swig_mz_initialized = 1; } } SWIGRUNTIME(void *) SWIG_MzScheme_Malloc(size_t size, const char *func_name) { void *p = malloc(size); if (p == NULL) { scheme_signal_error("swig-memory-error"); } else return p; } SWIGIMPORT(Scheme_Object *) SWIG_MzScheme_PackageValues(int num, Scheme_Object **values) { /* ignore first value if void */ if (num > 0 && SCHEME_VOIDP(values[0])) num--, values++; if (num == 0) return scheme_void; else if (num == 1) return values[0]; else return scheme_values(num, values); } #endif #ifdef __cplusplus } #endif cableswig-0.1.0+git20150808.orig/SWIG/Lib/mzscheme/precommon.swg0000644000175000000620000000142412561312227022641 0ustar stevestaff/*************************************************************** -*- c -*- * mzscheme/precommon.swg * * Rename all exported symbols from common.swg, to avoid symbol * clashes if multiple interpreters are included * ************************************************************************/ #define SWIG_TypeRegister SWIG_MzScheme_TypeRegister #define SWIG_TypeCheck SWIG_MzScheme_TypeCheck #define SWIG_TypeCast SWIG_MzScheme_TypeCast #define SWIG_TypeDynamicCast SWIG_MzScheme_TypeDynamicCast #define SWIG_TypeName SWIG_MzScheme_TypeName #define SWIG_TypeQuery SWIG_MzScheme_TypeQuery #define SWIG_TypeClientData SWIG_MzScheme_TypeClientData #define SWIG_PackData SWIG_MzScheme_PackData #define SWIG_UnpackData SWIG_MzScheme_UnpackData cableswig-0.1.0+git20150808.orig/SWIG/Lib/std_deque.i0000644000175000000620000000016612561312227020436 0ustar stevestaff/* Default std_deque wrapper */ %module std_deque /* Include implementation specific code */ %include "_std_deque.i" cableswig-0.1.0+git20150808.orig/SWIG/Lib/carrays.i0000644000175000000620000000550412561312227020126 0ustar stevestaff/* ----------------------------------------------------------------------------- * carrays.i * * Author(s): David Beazley (beazley@cs.uchicago.edu) * * This library file contains macros that can be used to manipulate simple * pointers as arrays. * * /cvsroot/SWIG/Lib/carrays.i,v 1.4 2003/03/08 04:21:41 ljohnson Exp * ----------------------------------------------------------------------------- */ /* ----------------------------------------------------------------------------- * %array_functions(TYPE,NAME) * * Generates functions for creating and accessing elements of a C array * (as pointers). Creates the following functions: * * TYPE *new_NAME(int nelements) * void delete_NAME(TYPE *); * TYPE NAME_getitem(TYPE *, int index); * void NAME_setitem(TYPE *, int index, TYPE value); * * ----------------------------------------------------------------------------- */ %define %array_functions(TYPE,NAME) %{ static TYPE *new_##NAME(int nelements) { %} #if __cplusplus %{ return new TYPE[nelements]; %} #else %{ return (TYPE *) calloc(nelements,sizeof(TYPE)); %} #endif %{} static void delete_##NAME(TYPE *ary) { %} #if __cplusplus %{ delete [] ary; %} #else %{ free(ary); %} #endif %{} static TYPE NAME##_getitem(TYPE *ary, int index) { return ary[index]; } static void NAME##_setitem(TYPE *ary, int index, TYPE value) { ary[index] = value; } %} TYPE *new_##NAME(int nelements); void delete_##NAME(TYPE *ary); TYPE NAME##_getitem(TYPE *ary, int index); void NAME##_setitem(TYPE *ary, int index, TYPE value); %enddef /* ----------------------------------------------------------------------------- * %array_class(TYPE,NAME) * * Generates a class wrapper around a C array. The class has the following * interface: * * struct NAME { * NAME(int nelements); * ~NAME(); * TYPE getitem(int index); * void setitem(int index, TYPE value); * TYPE * cast(); * static NAME *frompointer(TYPE *t); * } * * ----------------------------------------------------------------------------- */ %define %array_class(TYPE,NAME) %{ typedef TYPE NAME; %} typedef struct NAME { /* Put language specific enhancements here */ #if defined(SWIGPYTHON) || defined(SWIGRUBY) %rename(__getitem__) getitem; %rename(__setitem__) setitem; #endif } NAME; %extend NAME { #if __cplusplus NAME(int nelements) { return new TYPE[nelements]; } ~NAME() { delete [] self; } #else NAME(int nelements) { return (TYPE *) calloc(nelements,sizeof(TYPE)); } ~NAME() { free(self); } #endif TYPE getitem(int index) { return self[index]; } void setitem(int index, TYPE value) { self[index] = value; } TYPE * cast() { return self; } static NAME *frompointer(TYPE *t) { return (NAME *) t; } }; %types(NAME = TYPE); %enddef cableswig-0.1.0+git20150808.orig/SWIG/Lib/cdata.i0000644000175000000620000000463212561312227017537 0ustar stevestaff/* ----------------------------------------------------------------------------- * cdata.i * * Author(s): David Beazley (beazley@cs.uchicago.edu) * * This library file contains macros for manipulating raw C data as strings. * * /cvsroot/SWIG/Lib/cdata.i,v 1.3 2002/11/30 22:10:07 beazley Exp * ----------------------------------------------------------------------------- */ %{ typedef struct SWIGCDATA { char *data; int len; } SWIGCDATA; %} /* ----------------------------------------------------------------------------- * Typemaps for returning binary data * ----------------------------------------------------------------------------- */ #if SWIGPYTHON %typemap(out) SWIGCDATA { $result = PyString_FromStringAndSize($1.data,$1.len); } %typemap(in) (const void *indata, int inlen) = (char *STRING, int LENGTH); #elif SWIGPERL %typemap(out) SWIGCDATA { ST(argvi) = sv_newmortal(); sv_setpvn((SV*)ST(argvi++),$1.data,$1.len); } %typemap(in) (const void *indata, int inlen) = (char *STRING, int LENGTH); #elif SWIGTCL %typemap(out) SWIGCDATA { Tcl_SetObjResult(interp,Tcl_NewStringObj($1.data,$1.len)); } %typemap(in) (const void *indata, int inlen) = (char *STRING, int LENGTH); #elif SWIGRUBY %typemap(out) SWIGCDATA { $result = rb_str_new($1.data,$1.len); } %typemap(in) (const void *indata, int inlen) = (char *STRING, int LENGTH); #elif SWIGGUILE %typemap(out) SWIGCDATA { $result = gh_str2scm($1.data,$1.len); } %typemap(in) (const void *indata, int inlen) = (char *STRING, int LENGTH); #else %echo "cdata.i module not supported." #endif /* ----------------------------------------------------------------------------- * %cdata(TYPE [, NAME]) * * Convert raw C data to a binary string. * ----------------------------------------------------------------------------- */ %define %cdata(TYPE,...) %insert("header") { #if #__VA_ARGS__ == "" static SWIGCDATA cdata_##TYPE(TYPE *ptr, int nelements) { #else static SWIGCDATA cdata_##__VA_ARGS__(TYPE *ptr, int nelements) { #endif SWIGCDATA d; d.data = (char *) ptr; #if #TYPE != "void" d.len = nelements*sizeof(TYPE); #else d.len = nelements; #endif return d; } } #if #__VA_ARGS__ == "" SWIGCDATA cdata_##TYPE(TYPE *ptr, int nelements = 1); #else SWIGCDATA cdata_##__VA_ARGS__(TYPE *ptr, int nelements = 1); #endif %enddef %name(cdata) %cdata(void); /* Memory move function */ void memmove(void *data, const void *indata, int inlen); cableswig-0.1.0+git20150808.orig/SWIG/Lib/guile/0002755000175000000620000000000012561312227017413 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Lib/guile/std_string.i0000644000175000000620000000270212561312227021744 0ustar stevestaff// // SWIG typemaps for std::string // Luigi Ballabio // Apr 8, 2002 // // Guile implementation // ------------------------------------------------------------------------ // std::string is typemapped by value // This can prevent exporting methods which return a string // in order for the user to modify it. // However, I think I'll wait until someone asks for it... // ------------------------------------------------------------------------ %include exception.i %{ #include %} namespace std { class string; %typemap(typecheck) string = char *; %typemap(typecheck) const string & = char *; %typemap(in) string (char* tempptr) { if (gh_string_p($input)) { tempptr = SWIG_scm2str($input); $1 = std::string(tempptr); if (tempptr) SWIG_free(tempptr); } else { SWIG_exception(SWIG_TypeError, "string expected"); } } %typemap(in) const string & (std::string temp, char* tempptr) { if (gh_string_p($input)) { tempptr = SWIG_scm2str($input); temp = std::string(tempptr); if (tempptr) SWIG_free(tempptr); $1 = &temp; } else { SWIG_exception(SWIG_TypeError, "string expected"); } } %typemap(out) string { $result = gh_str02scm($1.c_str()); } %typemap(out) const string & { $result = gh_str02scm($1->c_str()); } } cableswig-0.1.0+git20150808.orig/SWIG/Lib/guile/std_map.i0000644000175000000620000016527412561312227021231 0ustar stevestaff// // SWIG typemaps for std::map // Luigi Ballabio // Jan. 2003 // // Guile implementation %include std_common.i %include exception.i %exception std::map::__getitem__ { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::map::__delitem__ { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } // ------------------------------------------------------------------------ // std::map // // The aim of all that follows would be to integrate std::map with // Guile as much as possible, namely, to allow the user to pass and // be returned Scheme association lists. // const declarations are used to guess the intent of the function being // exported; therefore, the following rationale is applied: // // -- f(std::map), f(const std::map&), f(const std::map*): // the parameter being read-only, either a Scheme alist or a // previously wrapped std::map can be passed. // -- f(std::map&), f(std::map*): // the parameter must be modified; therefore, only a wrapped std::map // can be passed. // -- std::map f(): // the map is returned by copy; therefore, a Scheme alist // is returned which is most easily used in other Scheme functions // -- std::map& f(), std::map* f(), const std::map& f(), // const std::map* f(): // the map is returned by reference; therefore, a wrapped std::map // is returned // ------------------------------------------------------------------------ %{ #include #include #include %} // exported class namespace std { template class map { %typemap(in) map (std::map* m) { if (gh_null_p($input)) { $1 = std::map(); } else if (gh_pair_p($input)) { $1 = std::map(); SCM alist = $input; while (!gh_null_p(alist)) { K* k; T* x; SCM entry, key, val; entry = gh_car(alist); if (!gh_pair_p(entry)) SWIG_exception(SWIG_TypeError,"alist expected"); key = gh_car(entry); val = gh_cdr(entry); k = (K*) SWIG_MustGetPtr(key,$descriptor(K *),$argnum, 0); if (SWIG_ConvertPtr(val,(void**) &x, $descriptor(T *), 0) != 0) { if (!gh_pair_p(val)) SWIG_exception(SWIG_TypeError,"alist expected"); val = gh_car(val); x = (T*) SWIG_MustGetPtr(val,$descriptor(T *),$argnum, 0); } (($1_type &)$1)[*k] = *x; alist = gh_cdr(alist); } } else { $1 = *(($&1_type) SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0)); } } %typemap(in) const map& (std::map temp, std::map* m), const map* (std::map temp, std::map* m) { if (gh_null_p($input)) { temp = std::map(); $1 = &temp; } else if (gh_pair_p($input)) { temp = std::map(); $1 = &temp; SCM alist = $input; while (!gh_null_p(alist)) { K* k; T* x; SCM entry, key, val; entry = gh_car(alist); if (!gh_pair_p(entry)) SWIG_exception(SWIG_TypeError,"alist expected"); key = gh_car(entry); val = gh_cdr(entry); k = (K*) SWIG_MustGetPtr(key,$descriptor(K *),$argnum, 0); if (SWIG_ConvertPtr(val,(void**) &x, $descriptor(T *), 0) != 0) { if (!gh_pair_p(val)) SWIG_exception(SWIG_TypeError,"alist expected"); val = gh_car(val); x = (T*) SWIG_MustGetPtr(val,$descriptor(T *),$argnum, 0); } temp[*k] = *x; alist = gh_cdr(alist); } } else { $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0); } } %typemap(out) map { SCM alist = SCM_EOL; for (std::map::reverse_iterator i=$1.rbegin(); i!=$1.rend(); ++i) { K* key = new K(i->first); T* val = new T(i->second); SCM k = SWIG_NewPointerObj(key,$descriptor(K *), 1); SCM x = SWIG_NewPointerObj(val,$descriptor(T *), 1); SCM entry = gh_cons(k,x); alist = gh_cons(entry,alist); } $result = alist; } %typecheck(SWIG_TYPECHECK_MAP) map { /* native sequence? */ if (gh_null_p($input)) { /* an empty sequence can be of any type */ $1 = 1; } else if (gh_pair_p($input)) { /* check the first element only */ K* k; T* x; SCM head = gh_car($input); if (gh_pair_p(head)) { SCM key = gh_car(head); SCM val = gh_cdr(head); if (SWIG_ConvertPtr(key,(void**) &k, $descriptor(K *), 0) != 0) { $1 = 0; } else { if (SWIG_ConvertPtr(val,(void**) &x, $descriptor(T *), 0) == 0) { $1 = 1; } else if (gh_pair_p(val)) { val = gh_car(val); if (SWIG_ConvertPtr(val,(void**) &x, $descriptor(T *), 0) == 0) $1 = 1; else $1 = 0; } else { $1 = 0; } } } else { $1 = 0; } } else { /* wrapped map? */ std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $&1_descriptor, 0) == 0) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_MAP) const map&, const map* { /* native sequence? */ if (gh_null_p($input)) { /* an empty sequence can be of any type */ $1 = 1; } else if (gh_pair_p($input)) { /* check the first element only */ K* k; T* x; SCM head = gh_car($input); if (gh_pair_p(head)) { SCM key = gh_car(head); SCM val = gh_cdr(head); if (SWIG_ConvertPtr(key,(void**) &k, $descriptor(K *), 0) != 0) { $1 = 0; } else { if (SWIG_ConvertPtr(val,(void**) &x, $descriptor(T *), 0) == 0) { $1 = 1; } else if (gh_pair_p(val)) { val = gh_car(val); if (SWIG_ConvertPtr(val,(void**) &x, $descriptor(T *), 0) == 0) $1 = 1; else $1 = 0; } else { $1 = 0; } } } else { $1 = 0; } } else { /* wrapped map? */ std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $1_descriptor, 0) == 0) $1 = 1; else $1 = 0; } } %rename("length") size; %rename("null?") empty; %rename("clear!") clear; %rename("ref") __getitem__; %rename("set!") __setitem__; %rename("delete!") __delitem__; %rename("has-key?") has_key; public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T& __getitem__(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void __setitem__(const K& key, const T& x) { (*self)[key] = x; } void __delitem__(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(const K& key) { std::map::iterator i = self->find(key); return i != self->end(); } SCM keys() { SCM result = SCM_EOL; for (std::map::reverse_iterator i=$1.rbegin(); i!=$1.rend(); ++i) { K* key = new K(i->first); SCM k = SWIG_NewPointerObj(key,$descriptor(K *), 1); result = gh_cons(k,result); } return result; } } }; // specializations for built-ins %define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO) template class map { %typemap(in) map (std::map* m) { if (gh_null_p($input)) { $1 = std::map(); } else if (gh_pair_p($input)) { $1 = std::map(); SCM alist = $input; while (!gh_null_p(alist)) { T* x; SCM entry, key, val; entry = gh_car(alist); if (!gh_pair_p(entry)) SWIG_exception(SWIG_TypeError,"alist expected"); key = gh_car(entry); val = gh_cdr(entry); if (!CHECK(key)) SWIG_exception(SWIG_TypeError, "map<" #K "," #T "> expected"); if (SWIG_ConvertPtr(val,(void**) &x, $descriptor(T *), 0) != 0) { if (!gh_pair_p(val)) SWIG_exception(SWIG_TypeError,"alist expected"); val = gh_car(val); x = (T*) SWIG_MustGetPtr(val,$descriptor(T *),$argnum, 0); } (($1_type &)$1)[CONVERT_FROM(key)] = *x; alist = gh_cdr(alist); } } else { $1 = *(($&1_type) SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0)); } } %typemap(in) const map& (std::map temp, std::map* m), const map* (std::map temp, std::map* m) { if (gh_null_p($input)) { temp = std::map(); $1 = &temp; } else if (gh_pair_p($input)) { temp = std::map(); $1 = &temp; SCM alist = $input; while (!gh_null_p(alist)) { T* x; SCM entry, key, val; entry = gh_car(alist); if (!gh_pair_p(entry)) SWIG_exception(SWIG_TypeError,"alist expected"); key = gh_car(entry); val = gh_cdr(entry); if (!CHECK(key)) SWIG_exception(SWIG_TypeError, "map<" #K "," #T "> expected"); if (SWIG_ConvertPtr(val,(void**) &x, $descriptor(T *), 0) != 0) { if (!gh_pair_p(val)) SWIG_exception(SWIG_TypeError,"alist expected"); val = gh_car(val); x = (T*) SWIG_MustGetPtr(val,$descriptor(T *),$argnum, 0); } temp[CONVERT_FROM(key)] = *x; alist = gh_cdr(alist); } } else { $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0); } } %typemap(out) map { SCM alist = SCM_EOL; for (std::map::reverse_iterator i=$1.rbegin(); i!=$1.rend(); ++i) { T* val = new T(i->second); SCM k = CONVERT_TO(i->first); SCM x = SWIG_NewPointerObj(val,$descriptor(T *), 1); SCM entry = gh_cons(k,x); alist = gh_cons(entry,alist); } $result = alist; } %typecheck(SWIG_TYPECHECK_MAP) map { // native sequence? if (gh_null_p($input)) { /* an empty sequence can be of any type */ $1 = 1; } else if (gh_pair_p($input)) { // check the first element only T* x; SCM head = gh_car($input); if (gh_pair_p(head)) { SCM key = gh_car(head); SCM val = gh_cdr(head); if (!CHECK(key)) { $1 = 0; } else { if (SWIG_ConvertPtr(val,(void**) &x, $descriptor(T *), 0) == 0) { $1 = 1; } else if (gh_pair_p(val)) { val = gh_car(val); if (SWIG_ConvertPtr(val,(void**) &x, $descriptor(T *), 0) == 0) $1 = 1; else $1 = 0; } else { $1 = 0; } } } else { $1 = 0; } } else { // wrapped map? std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $&1_descriptor, 0) == 0) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_MAP) const map&, const map* { // native sequence? if (gh_null_p($input)) { /* an empty sequence can be of any type */ $1 = 1; } else if (gh_pair_p($input)) { // check the first element only T* x; SCM head = gh_car($input); if (gh_pair_p(head)) { SCM key = gh_car(head); SCM val = gh_cdr(head); if (!CHECK(key)) { $1 = 0; } else { if (SWIG_ConvertPtr(val,(void**) &x, $descriptor(T *), 0) == 0) { $1 = 1; } else if (gh_pair_p(val)) { val = gh_car(val); if (SWIG_ConvertPtr(val,(void**) &x, $descriptor(T *), 0) == 0) $1 = 1; else $1 = 0; } else { $1 = 0; } } } else { $1 = 0; } } else { // wrapped map? std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $1_descriptor, 0) == 0) $1 = 1; else $1 = 0; } } %rename("length") size; %rename("null?") empty; %rename("clear!") clear; %rename("ref") __getitem__; %rename("set!") __setitem__; %rename("delete!") __delitem__; %rename("has-key?") has_key; public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T& __getitem__(K key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void __setitem__(K key, const T& x) { (*self)[key] = x; } void __delitem__(K key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(K key) { std::map::iterator i = self->find(key); return i != self->end(); } SCM keys() { SCM result = SCM_EOL; for (std::map::reverse_iterator i=$1.rbegin(); i!=$1.rend(); ++i) { SCM k = CONVERT_TO(i->first); result = gh_cons(k,result); } return result; } } }; %enddef %define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO) template class map { %typemap(in) map (std::map* m) { if (gh_null_p($input)) { $1 = std::map(); } else if (gh_pair_p($input)) { $1 = std::map(); SCM alist = $input; while (!gh_null_p(alist)) { K* k; SCM entry, key, val; entry = gh_car(alist); if (!gh_pair_p(entry)) SWIG_exception(SWIG_TypeError,"alist expected"); key = gh_car(entry); val = gh_cdr(entry); k = (K*) SWIG_MustGetPtr(key,$descriptor(K *),$argnum, 0); if (!CHECK(val)) { if (!gh_pair_p(val)) SWIG_exception(SWIG_TypeError,"alist expected"); val = gh_car(val); if (!CHECK(val)) SWIG_exception(SWIG_TypeError, "map<" #K "," #T "> expected"); } (($1_type &)$1)[*k] = CONVERT_FROM(val); alist = gh_cdr(alist); } } else { $1 = *(($&1_type) SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0)); } } %typemap(in) const map& (std::map temp, std::map* m), const map* (std::map temp, std::map* m) { if (gh_null_p($input)) { temp = std::map(); $1 = &temp; } else if (gh_pair_p($input)) { temp = std::map(); $1 = &temp; SCM alist = $input; while (!gh_null_p(alist)) { K* k; SCM entry, key, val; entry = gh_car(alist); if (!gh_pair_p(entry)) SWIG_exception(SWIG_TypeError,"alist expected"); key = gh_car(entry); val = gh_cdr(entry); k = (K*) SWIG_MustGetPtr(key,$descriptor(K *),$argnum, 0); if (!CHECK(val)) { if (!gh_pair_p(val)) SWIG_exception(SWIG_TypeError,"alist expected"); val = gh_car(val); if (!CHECK(val)) SWIG_exception(SWIG_TypeError, "map<" #K "," #T "> expected"); } temp[*k] = CONVERT_FROM(val); alist = gh_cdr(alist); } } else { $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0); } } %typemap(out) map { SCM alist = SCM_EOL; for (std::map::reverse_iterator i=$1.rbegin(); i!=$1.rend(); ++i) { K* key = new K(i->first); SCM k = SWIG_NewPointerObj(key,$descriptor(K *), 1); SCM x = CONVERT_TO(i->second); SCM entry = gh_cons(k,x); alist = gh_cons(entry,alist); } $result = alist; } %typecheck(SWIG_TYPECHECK_MAP) map { // native sequence? if (gh_null_p($input)) { /* an empty sequence can be of any type */ $1 = 1; } else if (gh_pair_p($input)) { // check the first element only K* k; SCM head = gh_car($input); if (gh_pair_p(head)) { SCM key = gh_car(head); SCM val = gh_cdr(head); if (SWIG_ConvertPtr(val,(void **) &k, $descriptor(K *), 0) != 0) { $1 = 0; } else { if (CHECK(val)) { $1 = 1; } else if (gh_pair_p(val)) { val = gh_car(val); if (CHECK(val)) $1 = 1; else $1 = 0; } else { $1 = 0; } } } else { $1 = 0; } } else { // wrapped map? std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $&1_descriptor, 0) == 0) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_MAP) const map&, const map* { // native sequence? if (gh_null_p($input)) { /* an empty sequence can be of any type */ $1 = 1; } else if (gh_pair_p($input)) { // check the first element only K* k; SCM head = gh_car($input); if (gh_pair_p(head)) { SCM key = gh_car(head); SCM val = gh_cdr(head); if (SWIG_ConvertPtr(val,(void **) &k, $descriptor(K *), 0) != 0) { $1 = 0; } else { if (CHECK(val)) { $1 = 1; } else if (gh_pair_p(val)) { val = gh_car(val); if (CHECK(val)) $1 = 1; else $1 = 0; } else { $1 = 0; } } } else { $1 = 0; } } else { // wrapped map? std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $1_descriptor, 0) == 0) $1 = 1; else $1 = 0; } } %rename("length") size; %rename("null?") empty; %rename("clear!") clear; %rename("ref") __getitem__; %rename("set!") __setitem__; %rename("delete!") __delitem__; %rename("has-key?") has_key; public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T __getitem__(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void __setitem__(const K& key, T x) { (*self)[key] = x; } void __delitem__(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(const K& key) { std::map::iterator i = self->find(key); return i != self->end(); } SCM keys() { SCM result = SCM_EOL; for (std::map::reverse_iterator i=$1.rbegin(); i!=$1.rend(); ++i) { K* key = new K(i->first); SCM k = SWIG_NewPointerObj(key,$descriptor(K *), 1); result = gh_cons(k,result); } return result; } } }; %enddef %define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO) template<> class map { %typemap(in) map (std::map* m) { if (gh_null_p($input)) { $1 = std::map(); } else if (gh_pair_p($input)) { $1 = std::map(); SCM alist = $input; while (!gh_null_p(alist)) { SCM entry, key, val; entry = gh_car(alist); if (!gh_pair_p(entry)) SWIG_exception(SWIG_TypeError,"alist expected"); key = gh_car(entry); val = gh_cdr(entry); if (!CHECK_K(key)) SWIG_exception(SWIG_TypeError, "map<" #K "," #T "> expected"); if (!CHECK_T(val)) { if (!gh_pair_p(val)) SWIG_exception(SWIG_TypeError,"alist expected"); val = gh_car(val); if (!CHECK_T(val)) SWIG_exception(SWIG_TypeError, "map<" #K "," #T "> expected"); } (($1_type &)$1)[CONVERT_K_FROM(key)] = CONVERT_T_FROM(val); alist = gh_cdr(alist); } } else { $1 = *(($&1_type) SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0)); } } %typemap(in) const map& (std::map temp, std::map* m), const map* (std::map temp, std::map* m) { if (gh_null_p($input)) { temp = std::map(); $1 = &temp; } else if (gh_pair_p($input)) { temp = std::map(); $1 = &temp; SCM alist = $input; while (!gh_null_p(alist)) { SCM entry, key, val; entry = gh_car(alist); if (!gh_pair_p(entry)) SWIG_exception(SWIG_TypeError,"alist expected"); key = gh_car(entry); val = gh_cdr(entry); if (!CHECK_K(key)) SWIG_exception(SWIG_TypeError, "map<" #K "," #T "> expected"); if (!CHECK_T(val)) { if (!gh_pair_p(val)) SWIG_exception(SWIG_TypeError,"alist expected"); val = gh_car(val); if (!CHECK_T(val)) SWIG_exception(SWIG_TypeError, "map<" #K "," #T "> expected"); } temp[CONVERT_K_FROM(key)] = CONVERT_T_FROM(val); alist = gh_cdr(alist); } } else { $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0); } } %typemap(out) map { SCM alist = SCM_EOL; for (std::map::reverse_iterator i=$1.rbegin(); i!=$1.rend(); ++i) { SCM k = CONVERT_K_TO(i->first); SCM x = CONVERT_T_TO(i->second); SCM entry = gh_cons(k,x); alist = gh_cons(entry,alist); } $result = alist; } %typecheck(SWIG_TYPECHECK_MAP) map { // native sequence? if (gh_null_p($input)) { /* an empty sequence can be of any type */ $1 = 1; } else if (gh_pair_p($input)) { // check the first element only SCM head = gh_car($input); if (gh_pair_p(head)) { SCM key = gh_car(head); SCM val = gh_cdr(head); if (!CHECK_K(key)) { $1 = 0; } else { if (CHECK_T(val)) { $1 = 1; } else if (gh_pair_p(val)) { val = gh_car(val); if (CHECK_T(val)) $1 = 1; else $1 = 0; } else { $1 = 0; } } } else { $1 = 0; } } else { // wrapped map? std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $&1_descriptor, 0) == 0) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_MAP) const map&, const map* { // native sequence? if (gh_null_p($input)) { /* an empty sequence can be of any type */ $1 = 1; } else if (gh_pair_p($input)) { // check the first element only SCM head = gh_car($input); if (gh_pair_p(head)) { SCM key = gh_car(head); SCM val = gh_cdr(head); if (!CHECK_K(key)) { $1 = 0; } else { if (CHECK_T(val)) { $1 = 1; } else if (gh_pair_p(val)) { val = gh_car(val); if (CHECK_T(val)) $1 = 1; else $1 = 0; } else { $1 = 0; } } } else { $1 = 0; } } else { // wrapped map? std::map* m; if (SWIG_ConvertPtr($input,(void **) &m, $1_descriptor, 0) == 0) $1 = 1; else $1 = 0; } } %rename("length") size; %rename("null?") empty; %rename("clear!") clear; %rename("ref") __getitem__; %rename("set!") __setitem__; %rename("delete!") __delitem__; %rename("has-key?") has_key; public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T __getitem__(K key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void __setitem__(K key, T x) { (*self)[key] = x; } void __delitem__(K key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(K key) { std::map::iterator i = self->find(key); return i != self->end(); } SCM keys() { SCM result = SCM_EOL; for (std::map::reverse_iterator i=$1.rbegin(); i!=$1.rend(); ++i) { SCM k = CONVERT_K_TO(i->first); result = gh_cons(k,result); } return result; } } }; %enddef specialize_std_map_on_key(bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm); specialize_std_map_on_key(int,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_key(short,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_key(long,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_key(unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_key(unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_key(unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_key(double,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_map_on_key(float,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_map_on_key(std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm); specialize_std_map_on_value(bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm); specialize_std_map_on_value(int,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_value(short,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_value(long,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_value(unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_value(unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_value(unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_value(double,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_map_on_value(float,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_map_on_value(std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm); specialize_std_map_on_both(bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm, bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm); specialize_std_map_on_both(bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm, int,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_both(bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm, short,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_both(bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm, long,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_both(bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm, unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_both(bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm, unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_both(bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm, unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_both(bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm, double,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_map_on_both(bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm, float,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_map_on_both(bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm, std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm); specialize_std_map_on_both(int,gh_number_p, gh_scm2long,gh_long2scm, bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm); specialize_std_map_on_both(int,gh_number_p, gh_scm2long,gh_long2scm, int,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_both(int,gh_number_p, gh_scm2long,gh_long2scm, short,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_both(int,gh_number_p, gh_scm2long,gh_long2scm, long,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_both(int,gh_number_p, gh_scm2long,gh_long2scm, unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_both(int,gh_number_p, gh_scm2long,gh_long2scm, unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_both(int,gh_number_p, gh_scm2long,gh_long2scm, unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_both(int,gh_number_p, gh_scm2long,gh_long2scm, double,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_map_on_both(int,gh_number_p, gh_scm2long,gh_long2scm, float,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_map_on_both(int,gh_number_p, gh_scm2long,gh_long2scm, std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm); specialize_std_map_on_both(short,gh_number_p, gh_scm2long,gh_long2scm, bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm); specialize_std_map_on_both(short,gh_number_p, gh_scm2long,gh_long2scm, int,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_both(short,gh_number_p, gh_scm2long,gh_long2scm, short,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_both(short,gh_number_p, gh_scm2long,gh_long2scm, long,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_both(short,gh_number_p, gh_scm2long,gh_long2scm, unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_both(short,gh_number_p, gh_scm2long,gh_long2scm, unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_both(short,gh_number_p, gh_scm2long,gh_long2scm, unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_both(short,gh_number_p, gh_scm2long,gh_long2scm, double,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_map_on_both(short,gh_number_p, gh_scm2long,gh_long2scm, float,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_map_on_both(short,gh_number_p, gh_scm2long,gh_long2scm, std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm); specialize_std_map_on_both(long,gh_number_p, gh_scm2long,gh_long2scm, bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm); specialize_std_map_on_both(long,gh_number_p, gh_scm2long,gh_long2scm, int,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_both(long,gh_number_p, gh_scm2long,gh_long2scm, short,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_both(long,gh_number_p, gh_scm2long,gh_long2scm, long,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_both(long,gh_number_p, gh_scm2long,gh_long2scm, unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_both(long,gh_number_p, gh_scm2long,gh_long2scm, unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_both(long,gh_number_p, gh_scm2long,gh_long2scm, unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_both(long,gh_number_p, gh_scm2long,gh_long2scm, double,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_map_on_both(long,gh_number_p, gh_scm2long,gh_long2scm, float,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_map_on_both(long,gh_number_p, gh_scm2long,gh_long2scm, std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm); specialize_std_map_on_both(unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm, bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm); specialize_std_map_on_both(unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm, int,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_both(unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm, short,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_both(unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm, long,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_both(unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm, unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_both(unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm, unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_both(unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm, unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_both(unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm, double,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_map_on_both(unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm, float,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_map_on_both(unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm, std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm); specialize_std_map_on_both(unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm, bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm); specialize_std_map_on_both(unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm, int,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_both(unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm, short,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_both(unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm, long,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_both(unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm, unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_both(unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm, unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_both(unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm, unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_both(unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm, double,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_map_on_both(unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm, float,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_map_on_both(unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm, std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm); specialize_std_map_on_both(unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm, bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm); specialize_std_map_on_both(unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm, int,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_both(unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm, short,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_both(unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm, long,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_both(unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm, unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_both(unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm, unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_both(unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm, unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_both(unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm, double,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_map_on_both(unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm, float,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_map_on_both(unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm, std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm); specialize_std_map_on_both(double,gh_number_p, gh_scm2double,gh_double2scm, bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm); specialize_std_map_on_both(double,gh_number_p, gh_scm2double,gh_double2scm, int,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_both(double,gh_number_p, gh_scm2double,gh_double2scm, short,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_both(double,gh_number_p, gh_scm2double,gh_double2scm, long,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_both(double,gh_number_p, gh_scm2double,gh_double2scm, unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_both(double,gh_number_p, gh_scm2double,gh_double2scm, unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_both(double,gh_number_p, gh_scm2double,gh_double2scm, unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_both(double,gh_number_p, gh_scm2double,gh_double2scm, double,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_map_on_both(double,gh_number_p, gh_scm2double,gh_double2scm, float,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_map_on_both(double,gh_number_p, gh_scm2double,gh_double2scm, std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm); specialize_std_map_on_both(float,gh_number_p, gh_scm2double,gh_double2scm, bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm); specialize_std_map_on_both(float,gh_number_p, gh_scm2double,gh_double2scm, int,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_both(float,gh_number_p, gh_scm2double,gh_double2scm, short,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_both(float,gh_number_p, gh_scm2double,gh_double2scm, long,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_both(float,gh_number_p, gh_scm2double,gh_double2scm, unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_both(float,gh_number_p, gh_scm2double,gh_double2scm, unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_both(float,gh_number_p, gh_scm2double,gh_double2scm, unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_both(float,gh_number_p, gh_scm2double,gh_double2scm, double,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_map_on_both(float,gh_number_p, gh_scm2double,gh_double2scm, float,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_map_on_both(float,gh_number_p, gh_scm2double,gh_double2scm, std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm); specialize_std_map_on_both(std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm, bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm); specialize_std_map_on_both(std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm, int,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_both(std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm, short,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_both(std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm, long,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_map_on_both(std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm, unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_both(std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm, unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_both(std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm, unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_map_on_both(std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm, double,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_map_on_both(std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm, float,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_map_on_both(std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm, std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm); } cableswig-0.1.0+git20150808.orig/SWIG/Lib/guile/interpreter.i0000644000175000000620000000303412561312227022126 0ustar stevestaff// // /cvsroot/SWIG/Lib/guile/interpreter.i,v 1.1 2000/01/11 21:15:50 beazley Exp // // SWIG file for a simple Guile interpreter // /* Revision History * interpreter.i,v * Revision 1.1 2000/01/11 21:15:50 beazley * Added files * * Revision 1.1.1.1 1999/02/28 02:00:54 beazley * Swig1.1 * * Revision 1.1 1996/05/22 20:02:10 beazley * Initial revision * */ %{ #include GSCM_status guile_init(); int main(int argc, char **argv) { GSCM_status status; GSCM_top_level toplev; char *eval_answer; char input_str[16384]; int done; /* start a scheme interpreter */ status = gscm_run_scm(argc, argv, 0, stdout, stderr, guile_init, 0, "#t"); if (status != GSCM_OK) { fputs(gscm_error_msg(status), stderr); fputc('\n', stderr); printf("Error in startup.\n"); exit(1); } /* create the top level environment */ status = gscm_create_top_level(&toplev); if (status != GSCM_OK) { fputs(gscm_error_msg(status), stderr); fputc('\n', stderr); exit(1); } /* now sit in a scheme eval loop: I input the expressions, have guile * evaluate them, and then get another expression. */ done = 0; fprintf(stdout,"Guile > "); while (!done) { if (fgets(input_str,16384,stdin) == NULL) { exit(1); } else { if (strncmp(input_str,"quit",4) == 0) exit(1); status = gscm_eval_str(&eval_answer, toplev, input_str); fprintf(stdout,"%s\n", eval_answer); fprintf(stdout,"Guile > "); } } /* now clean up and quit */ gscm_destroy_top_level(toplev); } %} cableswig-0.1.0+git20150808.orig/SWIG/Lib/guile/std_common.i0000644000175000000620000000065012561312227021726 0ustar stevestaff// // SWIG typemaps for STL - common utilities // Luigi Ballabio // Aug 3, 2002 // // Guile implementation %apply size_t { std::size_t }; #define SWIG_bool2scm(b) gh_bool2scm(b ? 1 : 0) #define SWIG_string2scm(s) gh_str02scm(s.c_str()) %{ #include inline std::string SWIG_scm2string(SCM x) { char* temp; temp = SWIG_scm2str(x); std::string s(temp); if (temp) SWIG_free(temp); return s; } %} cableswig-0.1.0+git20150808.orig/SWIG/Lib/guile/typemaps.i0000644000175000000620000002603512561312227021433 0ustar stevestaff/* typemaps.i --- guile-specific typemaps -*- c -*- Copyright (C) 2000 Matthias Koeppe /cvsroot/SWIG/Lib/guile/typemaps.i,v 1.23 2003/11/18 15:52:49 mkoeppe Exp */ /* Pointers */ %typemap(in) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { $1 = ($1_ltype)SWIG_MustGetPtr($input, $descriptor, $argnum, 0); } %typemap(in) void * { $1 = SWIG_MustGetPtr($input, NULL, $argnum, 0); } %typemap(varin) SWIGTYPE * { $1 = ($1_ltype)SWIG_MustGetPtr($input, $descriptor, 1, 0); } %typemap(varin) SWIGTYPE & { $1 = *(($1_ltype)SWIG_MustGetPtr($input, $descriptor, 1, 0)); } %typemap(varin) SWIGTYPE [] { scm_wrong_type_arg((char *) FUNC_NAME, 1, $input); } %typemap(varin) SWIGTYPE [ANY] { void *temp; int ii; $1_basetype *b = 0; temp = SWIG_MustGetPtr($input, $1_descriptor, 1, 0); b = ($1_basetype *) $1; for (ii = 0; ii < $1_size; ii++) b[ii] = *(($1_basetype *) temp + ii); } %typemap(varin) void * { $1 = SWIG_MustGetPtr($input, NULL, 1, 0); } %typemap(out) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { $result = SWIG_NewPointerObj ($1, $descriptor, $owner); } %typemap(out) SWIGTYPE *DYNAMIC, SWIGTYPE &DYNAMIC { swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor,(void **) &$1); $result = SWIG_NewPointerObj ($1, ty, $owner); } %typemap(varout) SWIGTYPE *, SWIGTYPE [] { $result = SWIG_NewPointerObj ($1, $descriptor, 0); } %typemap(varout) SWIGTYPE & { $result = SWIG_NewPointerObj((void *) &$1, $1_descriptor, 0); } /* Change of object ownership, and interaction of destructor-like functions and the garbage-collector */ %typemap(in, doc="$NAME is of type <$type> and gets destroyed by the function") SWIGTYPE *DESTROYED { $1 = ($1_ltype)SWIG_MustGetPtr($input, $descriptor, $argnum, 0); } %typemap(freearg) SWIGTYPE *DESTROYED { SWIG_Guile_MarkPointerDestroyed($input); } %typemap(in, doc="$NAME is of type <$type> and is consumed by the function") SWIGTYPE *CONSUMED { $1 = ($1_ltype)SWIG_MustGetPtr($input, $descriptor, $argnum, 0); SWIG_Guile_MarkPointerNoncollectable($input); } /* Pass-by-value */ %typemap(in) SWIGTYPE($&1_ltype argp) { argp = ($&1_ltype)SWIG_MustGetPtr($input, $&1_descriptor, $argnum, 0); $1 = *argp; } %typemap(varin) SWIGTYPE { $&1_ltype argp; argp = ($&1_ltype)SWIG_MustGetPtr($input, $&1_descriptor, 1, 0); $1 = *argp; } %typemap(out) SWIGTYPE #ifdef __cplusplus { $&1_ltype resultptr; resultptr = new $1_ltype(($1_ltype &) $1); $result = SWIG_NewPointerObj (resultptr, $&1_descriptor, 1); } #else { $&1_ltype resultptr; resultptr = ($&1_ltype) malloc(sizeof($1_type)); memmove(resultptr, &$1, sizeof($1_type)); $result = SWIG_NewPointerObj(resultptr, $&1_descriptor, 1); } #endif %typemap(varout) SWIGTYPE #ifdef __cplusplus { $&1_ltype resultptr; resultptr = new $1_ltype(($1_ltype&) $1); $result = SWIG_NewPointerObj (resultptr, $&1_descriptor, 0); } #else { $&1_ltype resultptr; resultptr = ($&1_ltype) malloc(sizeof($1_type)); memmove(resultptr, &$1, sizeof($1_type)); $result = SWIG_NewPointerObj(resultptr, $&1_descriptor, 0); } #endif /* Enums */ %typemap(in) enum SWIGTYPE { $1 = gh_scm2int($input); } %typemap(varin) enum SWIGTYPE { $1 = ($1_type) gh_scm2int($input); } %typemap(out) enum SWIGTYPE { $result = gh_int2scm($1); } %typemap(varout) enum SWIGTYPE { $result = gh_int2scm($1); } /* The SIMPLE_MAP_WITH_EXPR macro below defines the whole set of typemaps needed for simple types. -- SCM_TO_C_EXPR is a C expression that translates the Scheme value "swig_scm_value" to a C value. -- C_TO_SCM_EXPR is a C expression that translates the C value "swig_c_value" to a Scheme value. */ %define SIMPLE_MAP_WITH_EXPR(C_NAME, SCM_TO_C_EXPR, C_TO_SCM_EXPR, SCM_NAME) %typemap (in, doc="$NAME is of type <" #SCM_NAME ">") C_NAME { SCM swig_scm_value = $input; $1 = SCM_TO_C_EXPR; } %typemap (varin, doc="NEW-VALUE is of type <" #SCM_NAME ">") C_NAME { SCM swig_scm_value = $input; $1 = SCM_TO_C_EXPR; } %typemap (out, doc="<" #SCM_NAME ">") C_NAME { C_NAME swig_c_value = $1; $result = C_TO_SCM_EXPR; } %typemap (varout, doc="<" #SCM_NAME ">") C_NAME { C_NAME swig_c_value = $1; $result = C_TO_SCM_EXPR; } /* INPUT and OUTPUT */ %typemap (in, doc="$NAME is of type <" #SCM_NAME ">)") C_NAME *INPUT(C_NAME temp) { SCM swig_scm_value = $input; temp = (C_NAME) SCM_TO_C_EXPR; $1 = &temp; } %typemap (in,numinputs=0) C_NAME *OUTPUT (C_NAME temp) {$1 = &temp;} %typemap (argout,doc="$name (of type <" #SCM_NAME ">)") C_NAME *OUTPUT { C_NAME swig_c_value = *$1; SWIG_APPEND_VALUE(C_TO_SCM_EXPR); } %typemap (in) C_NAME *BOTH = C_NAME *INPUT; %typemap (argout) C_NAME *BOTH = C_NAME *OUTPUT; %typemap (in) C_NAME *INOUT = C_NAME *INPUT; %typemap (argout) C_NAME *INOUT = C_NAME *OUTPUT; /* Const primitive references. Passed by value */ %typemap(in, doc="$NAME is of type <" #SCM_NAME ">") const C_NAME & (C_NAME temp) { SCM swig_scm_value = $input; temp = SCM_TO_C_EXPR; $1 = &temp; } %typemap(out, doc="<" #SCM_NAME ">") const C_NAME & { C_NAME swig_c_value = *$1; $result = C_TO_SCM_EXPR; } %enddef /* The SIMPLE_MAP macro below defines the whole set of typemaps needed for simple types. It generates slightly simpler code than the macro above, but it is only suitable for very simple conversion expressions. */ %define SIMPLE_MAP(C_NAME, SCM_TO_C, C_TO_SCM, SCM_NAME) %typemap (in, doc="$NAME is of type <" #SCM_NAME ">") C_NAME {$1 = SCM_TO_C($input);} %typemap (varin, doc="NEW-VALUE is of type <" #SCM_NAME ">") C_NAME {$1 = SCM_TO_C($input);} %typemap (out, doc="<" #SCM_NAME ">") C_NAME {$result = C_TO_SCM($1);} %typemap (varout, doc="<" #SCM_NAME ">") C_NAME {$result = C_TO_SCM($1);} /* INPUT and OUTPUT */ %typemap (in, doc="$NAME is of type <" #SCM_NAME ">)") C_NAME *INPUT(C_NAME temp), C_NAME &INPUT(C_NAME temp) { temp = (C_NAME) SCM_TO_C($input); $1 = &temp; } %typemap (in,numinputs=0) C_NAME *OUTPUT (C_NAME temp), C_NAME &OUTPUT(C_NAME temp) {$1 = &temp;} %typemap (argout,doc="$name (of type <" #SCM_NAME ">)") C_NAME *OUTPUT, C_NAME &OUTPUT {SWIG_APPEND_VALUE(C_TO_SCM(*$1));} %typemap (in) C_NAME *BOTH = C_NAME *INPUT; %typemap (argout) C_NAME *BOTH = C_NAME *OUTPUT; %typemap (in) C_NAME *INOUT = C_NAME *INPUT; %typemap (argout) C_NAME *INOUT = C_NAME *OUTPUT; %typemap (in) C_NAME &INOUT = C_NAME &INPUT; %typemap (argout) C_NAME &INOUT = C_NAME &OUTPUT; /* Const primitive references. Passed by value */ %typemap(in, doc="$NAME is of type <" #SCM_NAME ">") const C_NAME & (C_NAME temp) { temp = SCM_TO_C($input); $1 = &temp; } %typemap(out, doc="<" #SCM_NAME ">") const C_NAME & { $result = C_TO_SCM(*$1); } %enddef SIMPLE_MAP(bool, gh_scm2bool, gh_bool2scm, boolean); SIMPLE_MAP(char, gh_scm2char, gh_char2scm, char); SIMPLE_MAP(unsigned char, gh_scm2char, gh_char2scm, char); SIMPLE_MAP(signed char, gh_scm2char, gh_char2scm, char); SIMPLE_MAP(int, gh_scm2int, gh_int2scm, integer); SIMPLE_MAP(short, gh_scm2int, gh_int2scm, integer); SIMPLE_MAP(long, gh_scm2long, gh_long2scm, integer); SIMPLE_MAP(ptrdiff_t, gh_scm2long, gh_long2scm, integer); SIMPLE_MAP(unsigned int, gh_scm2ulong, gh_ulong2scm, integer); SIMPLE_MAP(unsigned short, gh_scm2ulong, gh_ulong2scm, integer); SIMPLE_MAP(unsigned long, gh_scm2ulong, gh_ulong2scm, integer); SIMPLE_MAP(size_t, gh_scm2ulong, gh_ulong2scm, integer); SIMPLE_MAP(float, gh_scm2double, gh_double2scm, real); SIMPLE_MAP(double, gh_scm2double, gh_double2scm, real); // SIMPLE_MAP(char *, SWIG_scm2str, gh_str02scm, string); // SIMPLE_MAP(const char *, SWIG_scm2str, gh_str02scm, string); /* Strings */ %typemap (in, doc="$NAME is a string") char *(int must_free = 0) { $1 = SWIG_scm2str($input); must_free = 1; } %typemap (varin, doc="NEW-VALUE is a string") char * {$1 = SWIG_scm2str($input);} %typemap (out, doc="") char * {$result = gh_str02scm($1);} %typemap (varout, doc="") char * {$result = gh_str02scm($1);} %typemap (in, doc="$NAME is a string") char * *INPUT(char * temp, int must_free = 0) { temp = (char *) SWIG_scm2str($input); $1 = &temp; must_free = 1; } %typemap (in,numinputs=0) char * *OUTPUT (char * temp) {$1 = &temp;} %typemap (argout,doc="$NAME (a string)") char * *OUTPUT {SWIG_APPEND_VALUE(gh_str02scm(*$1));} %typemap (in) char * *BOTH = char * *INPUT; %typemap (argout) char * *BOTH = char * *OUTPUT; %typemap (in) char * *INOUT = char * *INPUT; %typemap (argout) char * *INOUT = char * *OUTPUT; /* SWIG_scm2str makes a malloc'ed copy of the string, so get rid of it after the function call. */ %typemap (freearg) char * "if (must_free$argnum && $1) SWIG_free($1);"; %typemap (freearg) char **INPUT, char **BOTH "if (must_free$argnum && (*$1)) SWIG_free(*$1);" %typemap (freearg) char **OUTPUT "SWIG_free(*$1);" /* But this shall not apply if we try to pass a single char by reference. */ %typemap (freearg) char *OUTPUT, char *BOTH ""; /* If we set a string variable, delete the old result first. */ %typemap (varin) char * { if ($1) free($1); $1 = SWIG_scm2str($input); } /* Void */ %typemap (out,doc="") void "gswig_result = SCM_UNSPECIFIED;"; /* SCM is passed through */ typedef unsigned long SCM; %typemap (in) SCM "$1=$input;"; %typemap (out) SCM "$result=$1;"; %typecheck(SWIG_TYPECHECK_POINTER) SCM "$1=1;"; /* Some ANSI C typemaps */ %apply long { size_t }; /* ------------------------------------------------------------ * String & length * ------------------------------------------------------------ */ %typemap(in) (char *STRING, int LENGTH) { size_t temp; $1 = ($1_ltype) gh_scm2newstr($input, &temp); $2 = ($2_ltype) temp; } /* ------------------------------------------------------------ * Typechecking rules * ------------------------------------------------------------ */ /* adapted from python.swg */ %typecheck(SWIG_TYPECHECK_INTEGER) int, short, long, unsigned int, unsigned short, unsigned long, signed char, unsigned char, long long, unsigned long long, const int &, const short &, const long &, const unsigned int &, const unsigned short &, const unsigned long &, const long long &, const unsigned long long &, enum SWIGTYPE { $1 = SCM_NFALSEP(scm_integer_p($input)) ? 1 : 0; } %typecheck(SWIG_TYPECHECK_BOOL) bool, bool&, const bool& { $1 = SCM_BOOLP($input) ? 1 : 0; } %typecheck(SWIG_TYPECHECK_DOUBLE) float, double, const float &, const double & { $1 = SCM_NFALSEP(scm_real_p($input)) ? 1 : 0; } %typecheck(SWIG_TYPECHECK_CHAR) char { $1 = SCM_CHARP($input) ? 1 : 0; } %typecheck(SWIG_TYPECHECK_STRING) char * { $1 = SCM_STRINGP($input) ? 1 : 0; } %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { void *ptr; $1 = !SWIG_ConvertPtr($input, &ptr, $1_descriptor, 0); } %typecheck(SWIG_TYPECHECK_VOIDPTR) void * { void *ptr; $1 = !SWIG_ConvertPtr($input, &ptr, 0, 0); } /* typemaps.i ends here */ cableswig-0.1.0+git20150808.orig/SWIG/Lib/guile/std_pair.i0000644000175000000620000011476012561312227021401 0ustar stevestaff// // SWIG typemaps for std::pair // Luigi Ballabio // July 2003 // // Guile implementation %include std_common.i %include exception.i // ------------------------------------------------------------------------ // std::pair // // See std_vector.i for the rationale of typemap application // ------------------------------------------------------------------------ %{ #include %} // exported class namespace std { template struct pair { %typemap(in) pair (std::pair* m) { if (gh_pair_p($input)) { T* x; U* y; SCM first, second; first = gh_car($input); second = gh_cdr($input); x = (T*) SWIG_MustGetPtr(first,$descriptor(T *),$argnum, 0); y = (U*) SWIG_MustGetPtr(second,$descriptor(U *),$argnum, 0); $1 = std::make_pair(x,y); } else { $1 = *(($&1_type) SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0)); } } %typemap(in) const pair& (std::pair temp, std::pair* m), const pair* (std::pair temp, std::pair* m) { if (gh_pair_p($input)) { T* x; U* y; SCM first, second; first = gh_car($input); second = gh_cdr($input); x = (T*) SWIG_MustGetPtr(first,$descriptor(T *),$argnum, 0); y = (U*) SWIG_MustGetPtr(second,$descriptor(U *),$argnum, 0); temp = std::make_pair(x,y); $1 = &temp; } else { $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0); } } %typemap(out) pair { T* x = new T($1.first); U* y = new U($1.second); SCM first = SWIG_NewPointerObj(x,$descriptor(T *), 1); SCM second = SWIG_NewPointerObj(y,$descriptor(U *), 1); $result = gh_cons(first,second); } %typecheck(SWIG_TYPECHECK_PAIR) pair { /* native pair? */ if (gh_pair_p($input)) { T* x; U* y; SCM first = gh_car($input); SCM second = gh_cdr($input); if (SWIG_ConvertPtr(first,(void**) &x, $descriptor(T *), 0) == 0 && SWIG_ConvertPtr(second,(void**) &y, $descriptor(U *), 0) == 0) { $1 = 1; } else { $1 = 0; } } else { /* wrapped pair? */ std::pair* m; if (SWIG_ConvertPtr($input,(void **) &m, $&1_descriptor, 0) == 0) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_PAIR) const pair&, const pair* { /* native pair? */ if (gh_pair_p($input)) { T* x; U* y; SCM first = gh_car($input); SCM second = gh_cdr($input); if (SWIG_ConvertPtr(first,(void**) &x, $descriptor(T *), 0) == 0 && SWIG_ConvertPtr(second,(void**) &y, $descriptor(U *), 0) == 0) { $1 = 1; } else { $1 = 0; } } else { /* wrapped pair? */ std::pair* m; if (SWIG_ConvertPtr($input,(void **) &m, $1_descriptor, 0) == 0) $1 = 1; else $1 = 0; } } T first; U second; }; // specializations for built-ins %define specialize_std_pair_on_first(T,CHECK,CONVERT_FROM,CONVERT_TO) template struct pair { %typemap(in) pair (std::pair* m) { if (gh_pair_p($input)) { U* y; SCM first, second; first = gh_car($input); second = gh_cdr($input); if (!CHECK(first)) SWIG_exception(SWIG_TypeError, "map<" #T "," #U "> expected"); y = (U*) SWIG_MustGetPtr(second,$descriptor(U *),$argnum, 0); $1 = std::make_pair(CONVERT_FROM(first),y); } else { $1 = *(($&1_type) SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0)); } } %typemap(in) const pair& (std::pair temp, std::pair* m), const pair* (std::pair temp, std::pair* m) { if (gh_pair_p($input)) { U* y; SCM first, second; first = gh_car($input); second = gh_cdr($input); if (!CHECK(first)) SWIG_exception(SWIG_TypeError, "map<" #T "," #U "> expected"); y = (U*) SWIG_MustGetPtr(second,$descriptor(U *),$argnum, 0); temp = std::make_pair(CONVERT_FROM(first),y); $1 = &temp; } else { $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0); } } %typemap(out) pair { U* y = new U($1.second); SCM second = SWIG_NewPointerObj(y,$descriptor(U *), 1); $result = gh_cons(CONVERT_TO($1.first),second); } %typecheck(SWIG_TYPECHECK_PAIR) pair { /* native pair? */ if (gh_pair_p($input)) { U* y; SCM first = gh_car($input); SCM second = gh_cdr($input); if (CHECK(first) && SWIG_ConvertPtr(second,(void**) &y, $descriptor(U *), 0) == 0) { $1 = 1; } else { $1 = 0; } } else { /* wrapped pair? */ std::pair* m; if (SWIG_ConvertPtr($input,(void **) &m, $&1_descriptor, 0) == 0) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_PAIR) const pair&, const pair* { /* native pair? */ if (gh_pair_p($input)) { U* y; SCM first = gh_car($input); SCM second = gh_cdr($input); if (CHECK(first) && SWIG_ConvertPtr(second,(void**) &y, $descriptor(U *), 0) == 0) { $1 = 1; } else { $1 = 0; } } else { /* wrapped pair? */ std::pair* m; if (SWIG_ConvertPtr($input,(void **) &m, $1_descriptor, 0) == 0) $1 = 1; else $1 = 0; } } T first; U second; }; %enddef %define specialize_std_pair_on_second(U,CHECK,CONVERT_FROM,CONVERT_TO) template struct pair { %typemap(in) pair (std::pair* m) { if (gh_pair_p($input)) { T* x; SCM first, second; first = gh_car($input); second = gh_cdr($input); x = (T*) SWIG_MustGetPtr(first,$descriptor(T *),$argnum, 0); if (!CHECK(second)) SWIG_exception(SWIG_TypeError, "map<" #T "," #U "> expected"); $1 = std::make_pair(x,CONVERT_FROM(second)); } else { $1 = *(($&1_type) SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0)); } } %typemap(in) const pair& (std::pair temp, std::pair* m), const pair* (std::pair temp, std::pair* m) { if (gh_pair_p($input)) { T* x; SCM first, second; first = gh_car($input); second = gh_cdr($input); x = (T*) SWIG_MustGetPtr(first,$descriptor(T *),$argnum, 0); if (!CHECK(second)) SWIG_exception(SWIG_TypeError, "map<" #T "," #U "> expected"); temp = std::make_pair(x,CONVERT_FROM(second)); $1 = &temp; } else { $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0); } } %typemap(out) pair { T* x = new T($1.first); SCM first = SWIG_NewPointerObj(x,$descriptor(T *), 1); $result = gh_cons(first,CONVERT_TO($1.second)); } %typecheck(SWIG_TYPECHECK_PAIR) pair { /* native pair? */ if (gh_pair_p($input)) { T* x; SCM first = gh_car($input); SCM second = gh_cdr($input); if (SWIG_ConvertPtr(first,(void**) &x, $descriptor(T *), 0) == 0 && CHECK(second)) { $1 = 1; } else { $1 = 0; } } else { /* wrapped pair? */ std::pair* m; if (SWIG_ConvertPtr($input,(void **) &m, $&1_descriptor, 0) == 0) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_PAIR) const pair&, const pair* { /* native pair? */ if (gh_pair_p($input)) { T* x; SCM first = gh_car($input); SCM second = gh_cdr($input); if (SWIG_ConvertPtr(first,(void**) &x, $descriptor(T *), 0) == 0 && CHECK(second)) { $1 = 1; } else { $1 = 0; } } else { /* wrapped pair? */ std::pair* m; if (SWIG_ConvertPtr($input,(void **) &m, $1_descriptor, 0) == 0) $1 = 1; else $1 = 0; } } T first; U second; }; %enddef %define specialize_std_pair_on_both(T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO, U,CHECK_U,CONVERT_U_FROM,CONVERT_U_TO) template<> struct pair { %typemap(in) pair (std::pair* m) { if (gh_pair_p($input)) { SCM first, second; first = gh_car($input); second = gh_cdr($input); if (!CHECK_T(first) || !CHECK_U(second)) SWIG_exception(SWIG_TypeError, "map<" #T "," #U "> expected"); $1 = std::make_pair(CONVERT_T_FROM(first), CONVERT_U_FROM(second)); } else { $1 = *(($&1_type) SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0)); } } %typemap(in) const pair& (std::pair temp, std::pair* m), const pair* (std::pair temp, std::pair* m) { if (gh_pair_p($input)) { SCM first, second; first = gh_car($input); second = gh_cdr($input); if (!CHECK_T(first) || !CHECK_U(second)) SWIG_exception(SWIG_TypeError, "map<" #T "," #U "> expected"); temp = std::make_pair(CONVERT_T_FROM(first), CONVERT_U_FROM(second)); $1 = &temp; } else { $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0); } } %typemap(out) pair { $result = gh_cons(CONVERT_T_TO($1.first), CONVERT_U_TO($1.second)); } %typecheck(SWIG_TYPECHECK_PAIR) pair { /* native pair? */ if (gh_pair_p($input)) { SCM first = gh_car($input); SCM second = gh_cdr($input); if (CHECK_T(first) && CHECK_U(second)) { $1 = 1; } else { $1 = 0; } } else { /* wrapped pair? */ std::pair* m; if (SWIG_ConvertPtr($input,(void **) &m, $&1_descriptor, 0) == 0) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_PAIR) const pair&, const pair* { /* native pair? */ if (gh_pair_p($input)) { SCM first = gh_car($input); SCM second = gh_cdr($input); if (CHECK_T(first) && CHECK_U(second)) { $1 = 1; } else { $1 = 0; } } else { /* wrapped pair? */ std::pair* m; if (SWIG_ConvertPtr($input,(void **) &m, $1_descriptor, 0) == 0) $1 = 1; else $1 = 0; } } T first; U second; }; %enddef specialize_std_pair_on_first(bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm); specialize_std_pair_on_first(int,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_first(short,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_first(long,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_first(unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_first(unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_first(unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_first(double,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_pair_on_first(float,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_pair_on_first(std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm); specialize_std_pair_on_second(bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm); specialize_std_pair_on_second(int,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_second(short,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_second(long,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_second(unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_second(unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_second(unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_second(double,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_pair_on_second(float,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_pair_on_second(std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm); specialize_std_pair_on_both(bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm, bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm); specialize_std_pair_on_both(bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm, int,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_both(bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm, short,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_both(bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm, long,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_both(bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm, unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_both(bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm, unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_both(bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm, unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_both(bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm, double,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_pair_on_both(bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm, float,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_pair_on_both(bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm, std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm); specialize_std_pair_on_both(int,gh_number_p, gh_scm2long,gh_long2scm, bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm); specialize_std_pair_on_both(int,gh_number_p, gh_scm2long,gh_long2scm, int,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_both(int,gh_number_p, gh_scm2long,gh_long2scm, short,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_both(int,gh_number_p, gh_scm2long,gh_long2scm, long,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_both(int,gh_number_p, gh_scm2long,gh_long2scm, unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_both(int,gh_number_p, gh_scm2long,gh_long2scm, unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_both(int,gh_number_p, gh_scm2long,gh_long2scm, unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_both(int,gh_number_p, gh_scm2long,gh_long2scm, double,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_pair_on_both(int,gh_number_p, gh_scm2long,gh_long2scm, float,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_pair_on_both(int,gh_number_p, gh_scm2long,gh_long2scm, std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm); specialize_std_pair_on_both(short,gh_number_p, gh_scm2long,gh_long2scm, bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm); specialize_std_pair_on_both(short,gh_number_p, gh_scm2long,gh_long2scm, int,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_both(short,gh_number_p, gh_scm2long,gh_long2scm, short,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_both(short,gh_number_p, gh_scm2long,gh_long2scm, long,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_both(short,gh_number_p, gh_scm2long,gh_long2scm, unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_both(short,gh_number_p, gh_scm2long,gh_long2scm, unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_both(short,gh_number_p, gh_scm2long,gh_long2scm, unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_both(short,gh_number_p, gh_scm2long,gh_long2scm, double,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_pair_on_both(short,gh_number_p, gh_scm2long,gh_long2scm, float,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_pair_on_both(short,gh_number_p, gh_scm2long,gh_long2scm, std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm); specialize_std_pair_on_both(long,gh_number_p, gh_scm2long,gh_long2scm, bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm); specialize_std_pair_on_both(long,gh_number_p, gh_scm2long,gh_long2scm, int,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_both(long,gh_number_p, gh_scm2long,gh_long2scm, short,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_both(long,gh_number_p, gh_scm2long,gh_long2scm, long,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_both(long,gh_number_p, gh_scm2long,gh_long2scm, unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_both(long,gh_number_p, gh_scm2long,gh_long2scm, unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_both(long,gh_number_p, gh_scm2long,gh_long2scm, unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_both(long,gh_number_p, gh_scm2long,gh_long2scm, double,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_pair_on_both(long,gh_number_p, gh_scm2long,gh_long2scm, float,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_pair_on_both(long,gh_number_p, gh_scm2long,gh_long2scm, std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm); specialize_std_pair_on_both(unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm, bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm); specialize_std_pair_on_both(unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm, int,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_both(unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm, short,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_both(unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm, long,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_both(unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm, unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_both(unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm, unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_both(unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm, unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_both(unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm, double,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_pair_on_both(unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm, float,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_pair_on_both(unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm, std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm); specialize_std_pair_on_both(unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm, bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm); specialize_std_pair_on_both(unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm, int,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_both(unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm, short,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_both(unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm, long,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_both(unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm, unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_both(unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm, unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_both(unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm, unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_both(unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm, double,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_pair_on_both(unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm, float,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_pair_on_both(unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm, std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm); specialize_std_pair_on_both(unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm, bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm); specialize_std_pair_on_both(unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm, int,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_both(unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm, short,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_both(unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm, long,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_both(unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm, unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_both(unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm, unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_both(unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm, unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_both(unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm, double,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_pair_on_both(unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm, float,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_pair_on_both(unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm, std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm); specialize_std_pair_on_both(double,gh_number_p, gh_scm2double,gh_double2scm, bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm); specialize_std_pair_on_both(double,gh_number_p, gh_scm2double,gh_double2scm, int,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_both(double,gh_number_p, gh_scm2double,gh_double2scm, short,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_both(double,gh_number_p, gh_scm2double,gh_double2scm, long,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_both(double,gh_number_p, gh_scm2double,gh_double2scm, unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_both(double,gh_number_p, gh_scm2double,gh_double2scm, unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_both(double,gh_number_p, gh_scm2double,gh_double2scm, unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_both(double,gh_number_p, gh_scm2double,gh_double2scm, double,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_pair_on_both(double,gh_number_p, gh_scm2double,gh_double2scm, float,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_pair_on_both(double,gh_number_p, gh_scm2double,gh_double2scm, std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm); specialize_std_pair_on_both(float,gh_number_p, gh_scm2double,gh_double2scm, bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm); specialize_std_pair_on_both(float,gh_number_p, gh_scm2double,gh_double2scm, int,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_both(float,gh_number_p, gh_scm2double,gh_double2scm, short,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_both(float,gh_number_p, gh_scm2double,gh_double2scm, long,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_both(float,gh_number_p, gh_scm2double,gh_double2scm, unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_both(float,gh_number_p, gh_scm2double,gh_double2scm, unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_both(float,gh_number_p, gh_scm2double,gh_double2scm, unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_both(float,gh_number_p, gh_scm2double,gh_double2scm, double,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_pair_on_both(float,gh_number_p, gh_scm2double,gh_double2scm, float,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_pair_on_both(float,gh_number_p, gh_scm2double,gh_double2scm, std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm); specialize_std_pair_on_both(std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm, bool,gh_boolean_p, gh_scm2bool,SWIG_bool2scm); specialize_std_pair_on_both(std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm, int,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_both(std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm, short,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_both(std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm, long,gh_number_p, gh_scm2long,gh_long2scm); specialize_std_pair_on_both(std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm, unsigned int,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_both(std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm, unsigned short,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_both(std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm, unsigned long,gh_number_p, gh_scm2ulong,gh_ulong2scm); specialize_std_pair_on_both(std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm, double,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_pair_on_both(std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm, float,gh_number_p, gh_scm2double,gh_double2scm); specialize_std_pair_on_both(std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm, std::string,gh_string_p, SWIG_scm2string,SWIG_string2scm); } cableswig-0.1.0+git20150808.orig/SWIG/Lib/guile/guile.i0000644000175000000620000000161312561312227020671 0ustar stevestaff/* SWIG Configuration File for Guile. -*-c-*-*/ /* Macro for inserting Scheme code into the stub */ #define %scheme %insert("scheme") #define %goops %insert("goops") /* Return-styles */ %pragma(guile) return_nothing_doc = "Returns unspecified." %pragma(guile) return_one_doc = "Returns $values." %define %values_as_list %pragma(guile) beforereturn = "" %pragma(guile) return_multi_doc = "Returns a list of $num_values values: $values." %enddef %values_as_list /* the default style */ %define %values_as_vector %pragma(guile) beforereturn = "GUILE_MAYBE_VECTOR" %pragma(guile) return_multi_doc = "Returns a vector of $num_values values: $values." %enddef %define %multiple_values %pragma(guile) beforereturn = "GUILE_MAYBE_VALUES" %pragma(guile) return_multi_doc = "Returns $num_values values: $values." %enddef #define GUILE_APPEND_RESULT SWIG_APPEND_VALUE %include "typemaps.i" cableswig-0.1.0+git20150808.orig/SWIG/Lib/guile/extra-install.list0000644000175000000620000000004712561312227023076 0ustar stevestaff# see top-level Makefile.in common.scm cableswig-0.1.0+git20150808.orig/SWIG/Lib/guile/common.scm0000644000175000000620000000275312561312227021414 0ustar stevestaff;;;************************************************************************ ;;;*common.scm ;;;* ;;;* This file contains generic SWIG GOOPS classes for generated ;;;* GOOPS file support ;;;* ;;;* Copyright (C) 2003 John Lenz (jelenz@wisc.edu) ;;;* ;;;* This file may be freely redistributed without license or fee provided ;;;* this copyright message remains intact. ;;;************************************************************************ (define-module (Swig common)) (use-modules (oop goops)) (define-class () (new-function #:init-value #f)) (define-method (initialize (class ) initargs) (slot-set! class 'new-function (get-keyword #:new-function initargs #f)) (next-method)) (define-class () (swig-smob #:init-value #f) #:metaclass ) (define-method (initialize (obj ) initargs) (next-method) (slot-set! obj 'swig-smob (let ((arg (get-keyword #:init-smob initargs #f))) (if arg arg (let ((ret (apply (slot-ref (class-of obj) 'new-function) (get-keyword #:args initargs '())))) ;; if the class is registered with runtime environment, ;; new-Function will return a goops class. In that case, extract the smob ;; from that goops class and set it as the current smob. (if (slot-exists? ret 'swig-smob) (slot-ref ret 'swig-smob) ret)))))) (export ) cableswig-0.1.0+git20150808.orig/SWIG/Lib/guile/pointer-in-out.i0000644000175000000620000000641012561312227022455 0ustar stevestaff/* pointer-in-out.i --- Guile typemaps for passing -*- c -*- pointers indirectly Copyright (C) 2001, 2003 Matthias Koeppe /cvsroot/SWIG/Lib/guile/pointer-in-out.i,v 1.5 2003/11/18 15:52:49 mkoeppe Exp */ /* Here is a macro that will define typemaps for passing C pointers indirectly. TYPEMAP_POINTER_INPUT_OUTPUT(PTRTYPE, SCM_TYPE) Supported calling conventions (in this example, PTRTYPE is int *): func(int **INPUT) Scheme wrapper will take one argument, a wrapped C pointer. The address of a variable containing this pointer will be passed to the function. func(int **INPUT_CONSUMED) Likewise, but mark the pointer object as not garbage collectable. func(int **INPUT_DESTROYED) Likewise, but mark the pointer object as destroyed. func(int **OUTPUT) Scheme wrapper will take no arguments. The address of an int * variable will be passed to the function. The function is expected to modify the variable; its value is wrapped and becomes an extra return value. (See the documentation on how to deal with multiple values.) func(int **OUTPUT_NONCOLLECTABLE) Likewise, but make the pointer object not garbage collectable. func(int **BOTH) func(int **INOUT) This annotation combines INPUT and OUTPUT. */ %define TYPEMAP_POINTER_INPUT_OUTPUT(PTRTYPE, SCM_TYPE) %typemap(in, doc="$NAME is of type <" #SCM_TYPE ">") PTRTYPE *INPUT(PTRTYPE temp) { if (SWIG_ConvertPtr($input, (void **) &temp, $*descriptor, 0)) { scm_wrong_type_arg(FUNC_NAME, $argnum, $input); } $1 = &temp; } %typemap(in, doc="$NAME is of type <" #SCM_TYPE "> and is consumed by the function") PTRTYPE *INPUT_CONSUMED(PTRTYPE temp) { if (SWIG_ConvertPtr($input, (void **) &temp, $*descriptor, 0)) { scm_wrong_type_arg(FUNC_NAME, $argnum, $input); } SWIG_Guile_MarkPointerNoncollectable($input); $1 = &temp; } %typemap(in, doc="$NAME is of type <" #SCM_TYPE "> and is consumed by the function") PTRTYPE *INPUT_DESTROYED(PTRTYPE temp) { if (SWIG_ConvertPtr($input, (void **) &temp, $*descriptor, 0)) { scm_wrong_type_arg(FUNC_NAME, $argnum, $input); } SWIG_Guile_MarkPointerDestroyed($input); $1 = &temp; } %typemap(in, numinputs=0) PTRTYPE *OUTPUT(PTRTYPE temp), PTRTYPE *OUTPUT_NONCOLLECTABLE(PTRTYPE temp) "$1 = &temp;"; %typemap(argout, doc="<" #SCM_TYPE ">") PTRTYPE *OUTPUT "SWIG_APPEND_VALUE(SWIG_NewPointerObj(*$1, $*descriptor, 1));"; %typemap(argout, doc="<" #SCM_TYPE ">") PTRTYPE *OUTPUT_NONCOLLECTABLE "SWIG_APPEND_VALUE(SWIG_NewPointerObj(*$1, $*descriptor, 0));"; %typemap(in) PTRTYPE *BOTH = PTRTYPE *INPUT; %typemap(argout) PTRTYPE *BOTH = PTRTYPE *OUTPUT; %typemap(in) PTRTYPE *INOUT = PTRTYPE *INPUT; %typemap(argout) PTRTYPE *INOUT = PTRTYPE *OUTPUT; /* As a special convenience measure, also attach docs involving SCM_TYPE to the standard pointer typemaps */ %typemap(in, doc="$NAME is of type <" #SCM_TYPE ">") PTRTYPE { if (SWIG_ConvertPtr($input, (void **) &$1, $descriptor, 0)) scm_wrong_type_arg(FUNC_NAME, $argnum, $input); } %typemap(out, doc="<" #SCM_TYPE ">") PTRTYPE { $result = SWIG_NewPointerObj ($1, $descriptor, $owner); } %enddef cableswig-0.1.0+git20150808.orig/SWIG/Lib/guile/std_vector.i0000644000175000000620000004114112561312227021740 0ustar stevestaff// // SWIG typemaps for std::vector // Luigi Ballabio // Apr 8, 2002 // // Guile implementation %include std_common.i %include exception.i %exception std::vector::ref { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::vector::set { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::vector::pop { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } // ------------------------------------------------------------------------ // std::vector // // The aim of all that follows would be to integrate std::vector with // Guile as much as possible, namely, to allow the user to pass and // be returned Guile vectors or lists. // const declarations are used to guess the intent of the function being // exported; therefore, the following rationale is applied: // // -- f(std::vector), f(const std::vector&), f(const std::vector*): // the parameter being read-only, either a Guile sequence or a // previously wrapped std::vector can be passed. // -- f(std::vector&), f(std::vector*): // the parameter must be modified; therefore, only a wrapped std::vector // can be passed. // -- std::vector f(): // the vector is returned by copy; therefore, a Guile vector of T:s // is returned which is most easily used in other Guile functions // -- std::vector& f(), std::vector* f(), const std::vector& f(), // const std::vector* f(): // the vector is returned by reference; therefore, a wrapped std::vector // is returned // ------------------------------------------------------------------------ %{ #include #include #include %} // exported class namespace std { template class vector { %typemap(in) vector { if (gh_vector_p($input)) { unsigned long size = gh_vector_length($input); $1 = std::vector(size); for (unsigned long i=0; i(); } else if (gh_pair_p($input)) { SCM head, tail; $1 = std::vector(); tail = $input; while (!gh_null_p(tail)) { head = gh_car(tail); tail = gh_cdr(tail); $1.push_back(*((T*)SWIG_MustGetPtr(head, $descriptor(T *), $argnum, 0))); } } else { $1 = *(($&1_type) SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0)); } } %typemap(in) const vector& (std::vector temp), const vector* (std::vector temp) { if (gh_vector_p($input)) { unsigned long size = gh_vector_length($input); temp = std::vector(size); $1 = &temp; for (unsigned long i=0; i(); $1 = &temp; } else if (gh_pair_p($input)) { temp = std::vector(); $1 = &temp; SCM head, tail; tail = $input; while (!gh_null_p(tail)) { head = gh_car(tail); tail = gh_cdr(tail); temp.push_back(*((T*) SWIG_MustGetPtr(head, $descriptor(T *), $argnum, 0))); } } else { $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0); } } %typemap(out) vector { $result = gh_make_vector(gh_long2scm($1.size()),SCM_UNSPECIFIED); for (unsigned int i=0; i<$1.size(); i++) { T* x = new T((($1_type &)$1)[i]); gh_vector_set_x($result,gh_long2scm(i), SWIG_NewPointerObj(x, $descriptor(T *), 1)); } } %typecheck(SWIG_TYPECHECK_VECTOR) vector { /* native sequence? */ if (gh_vector_p($input)) { unsigned int size = gh_vector_length($input); if (size == 0) { /* an empty sequence can be of any type */ $1 = 1; } else { /* check the first element only */ SCM o = gh_vector_ref($input,gh_ulong2scm(0)); T* x; if (SWIG_ConvertPtr(o,(void**) &x, $descriptor(T *), 0) != -1) $1 = 1; else $1 = 0; } } else if (gh_null_p($input)) { /* again, an empty sequence can be of any type */ $1 = 1; } else if (gh_pair_p($input)) { /* check the first element only */ T* x; SCM head = gh_car($input); if (SWIG_ConvertPtr(head,(void**) &x, $descriptor(T *), 0) != -1) $1 = 1; else $1 = 0; } else { /* wrapped vector? */ std::vector* v; if (SWIG_ConvertPtr($input,(void **) &v, $&1_descriptor, 0) != -1) $1 = 1; else $1 = 0; } } %typecheck(SWIG_TYPECHECK_VECTOR) const vector&, const vector* { /* native sequence? */ if (gh_vector_p($input)) { unsigned int size = gh_vector_length($input); if (size == 0) { /* an empty sequence can be of any type */ $1 = 1; } else { /* check the first element only */ T* x; SCM o = gh_vector_ref($input,gh_ulong2scm(0)); if (SWIG_ConvertPtr(o,(void**) &x, $descriptor(T *), 0) != -1) $1 = 1; else $1 = 0; } } else if (gh_null_p($input)) { /* again, an empty sequence can be of any type */ $1 = 1; } else if (gh_pair_p($input)) { /* check the first element only */ T* x; SCM head = gh_car($input); if (SWIG_ConvertPtr(head,(void**) &x, $descriptor(T *), 0) != -1) $1 = 1; else $1 = 0; } else { /* wrapped vector? */ std::vector* v; if (SWIG_ConvertPtr($input,(void **) &v, $1_descriptor, 0) != -1) $1 = 1; else $1 = 0; } } public: vector(unsigned int size = 0); vector(unsigned int size, const T& value); vector(const vector&); %rename(length) size; unsigned int size() const; %rename("empty?") empty; bool empty() const; %rename("clear!") clear; void clear(); %rename("set!") set; %rename("pop!") pop; %rename("push!") push_back; void push_back(const T& x); %extend { T pop() { if (self->size() == 0) throw std::out_of_range("pop from empty vector"); T x = self->back(); self->pop_back(); return x; } T& ref(int i) { int size = int(self->size()); if (i>=0 && isize()); if (i>=0 && i class vector { %typemap(in) vector { if (gh_vector_p($input)) { unsigned long size = gh_vector_length($input); $1 = std::vector(size); for (unsigned long i=0; i(); } else if (gh_pair_p($input)) { SCM v = gh_list_to_vector($input); unsigned long size = gh_vector_length(v); $1 = std::vector(size); for (unsigned long i=0; i& (std::vector temp), const vector* (std::vector temp) { if (gh_vector_p($input)) { unsigned long size = gh_vector_length($input); temp = std::vector(size); $1 = &temp; for (unsigned long i=0; i(); $1 = &temp; } else if (gh_pair_p($input)) { SCM v = gh_list_to_vector($input); unsigned long size = gh_vector_length(v); temp = std::vector(size); $1 = &temp; for (unsigned long i=0; i { $result = gh_make_vector(gh_long2scm($1.size()),SCM_UNSPECIFIED); for (unsigned int i=0; i<$1.size(); i++) { SCM x = CONVERT_TO((($1_type &)$1)[i]); gh_vector_set_x($result,gh_long2scm(i),x); } } %typecheck(SWIG_TYPECHECK_VECTOR) vector { /* native sequence? */ if (gh_vector_p($input)) { unsigned int size = gh_vector_length($input); if (size == 0) { /* an empty sequence can be of any type */ $1 = 1; } else { /* check the first element only */ T* x; SCM o = gh_vector_ref($input,gh_ulong2scm(0)); $1 = CHECK(o) ? 1 : 0; } } else if (gh_null_p($input)) { /* again, an empty sequence can be of any type */ $1 = 1; } else if (gh_pair_p($input)) { /* check the first element only */ T* x; SCM head = gh_car($input); $1 = CHECK(head) ? 1 : 0; } else { /* wrapped vector? */ std::vector* v; $1 = (SWIG_ConvertPtr($input,(void **) &v, $&1_descriptor, 0) != -1) ? 1 : 0; } } %typecheck(SWIG_TYPECHECK_VECTOR) const vector&, const vector* { /* native sequence? */ if (gh_vector_p($input)) { unsigned int size = gh_vector_length($input); if (size == 0) { /* an empty sequence can be of any type */ $1 = 1; } else { /* check the first element only */ T* x; SCM o = gh_vector_ref($input,gh_ulong2scm(0)); $1 = CHECK(o) ? 1 : 0; } } else if (gh_null_p($input)) { /* again, an empty sequence can be of any type */ $1 = 1; } else if (gh_pair_p($input)) { /* check the first element only */ T* x; SCM head = gh_car($input); $1 = CHECK(head) ? 1 : 0; } else { /* wrapped vector? */ std::vector* v; $1 = (SWIG_ConvertPtr($input,(void **) &v, $1_descriptor, 0) != -1) ? 1 : 0; } } public: vector(unsigned int size = 0); vector(unsigned int size, const T& value); vector(const vector&); %rename(length) size; unsigned int size() const; %rename("empty?") empty; bool empty() const; %rename("clear!") clear; void clear(); %rename("set!") set; %rename("pop!") pop; %rename("push!") push_back; void push_back(T x); %extend { T pop() { if (self->size() == 0) throw std::out_of_range("pop from empty vector"); T x = self->back(); self->pop_back(); return x; } T ref(int i) { int size = int(self->size()); if (i>=0 && isize()); if (i>=0 && i * * PURPOSE OF THIS FILE: The main functions for a user augmented guile * version that can handle wrapped calls as generated by the Simplified * Wrapper and Interface Generator (SWIG 1.1) * * - Automatic Version Information via RCS/CVS: * guilemain.i,v 1.6 2002/11/30 22:10:07 beazley Exp * /cvsroot/SWIG/Lib/guile/guilemain.i,v * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ %{ #include #ifdef __cplusplus extern "C" { #endif /* Debugger interface (don't change the order of the following lines) */ #define GDB_TYPE SCM #include GDB_INTERFACE; static void inner_main(void *closure, int argc, char **argv) { #ifdef SWIGINIT SWIGINIT #else SWIG_init(); /* SWIG init function */ #endif scm_shell(argc, argv); /* scheme interpreter */ /* never reached: scm_shell will perform an exit */ } #ifdef __cplusplus } #endif int main(int argc, char **argv) { /* put any default initialisation code here: e.g. exit handlers */ scm_boot_guile(argc, argv, inner_main, 0); /* make a stack entry for the garbage collector */ return 0; /* never reached, but avoids a warning */ } %} cableswig-0.1.0+git20150808.orig/SWIG/Lib/guile/cplusplus.i0000644000175000000620000000116712561312227021622 0ustar stevestaff/* SWIG typemaps for C++ */ /* By Marcio Luis Teixeira : */ %typemap(guile,out) string, std::string { $result = gh_str02scm(const_cast($1.c_str())); } %typemap(guile,in) string, std::string { $1 = SWIG_scm2str($input); } %typemap(guile,out) complex, complex, std::complex { $result = scm_make_rectangular( gh_double2scm ($1.real ()), gh_double2scm ($1.imag ()) ); } %typemap(guile,in) complex, complex, std::complex { $1 = std::complex( gh_scm2double (scm_real_part ($input)), gh_scm2double (scm_imag_part ($input)) ); } cableswig-0.1.0+git20150808.orig/SWIG/Lib/guile/ports.i0000644000175000000620000000176612561312227020744 0ustar stevestaff/* ports.i --- Guile typemaps for handling ports -*- c -*- Copyright (C) 2000 Matthias Koeppe /cvsroot/SWIG/Lib/guile/ports.i,v 1.4 2002/11/30 22:10:07 beazley Exp */ %{ #ifndef _POSIX_SOURCE /* This is needed on Solaris for fdopen(). */ # define _POSIX_SOURCE 199506L #endif #include #include #include %} /* Feed temporary FILE * arguments from file ports */ %typemap(in, doc="$NAME is a port") FILE * { if(!(SCM_FPORTP($input))) scm_wrong_type_arg("$name", $argnum, $input); else { int fd; if (SCM_OUTPUT_PORT_P($input)) scm_force_output($input); fd=dup(SCM_FPORT_FDES($input)); if(fd==-1) scm_misc_error("$name", strerror(errno), SCM_EOL); $1=fdopen(fd, SCM_OUTPUT_PORT_P($input) ? (SCM_INPUT_PORT_P($input) ? "rw" : "w") : "r"); if($1==NULL) scm_misc_error("$name", strerror(errno), SCM_EOL); } } %typemap(freearg) FILE* { fclose($1); } cableswig-0.1.0+git20150808.orig/SWIG/Lib/guile/guile_gh_run.swg0000644000175000000620000003174412561312227022613 0ustar stevestaff/* -*- c -*- * ----------------------------------------------------------------------- * Lib/guile/guile_gh_run.swg * * Guile GH runtime file * Copyright (C) 2000 Matthias Koeppe * ----------------------------------------------------------------------- */ #include "guile/gh.h" #include #include #include #ifdef __cplusplus extern "C" { #endif #define SWIG_malloc(size) \ SCM_MUST_MALLOC(size) #define SWIG_free(mem) \ scm_must_free(mem) #define SWIG_ConvertPtr(s, result, type, flags) \ SWIG_Guile_GetPtr(s, result, type) #define SWIG_MustGetPtr(s, type, argnum, flags) \ SWIG_Guile_MustGetPtr(s, type, argnum, FUNC_NAME) #define SWIG_NewPointerObj(ptr, type, owner) \ SWIG_Guile_MakePtr((void*)ptr, type) /* Ignore object-ownership changes in gh mode */ #define SWIG_Guile_MarkPointerNoncollectable(s) (s) #define SWIG_Guile_MarkPointerDestroyed(s) (s) #define SWIG_contract_assert(expr, msg) \ if (!(expr)) \ scm_error(gh_symbol2scm("swig-contract-assertion-failed"), \ (char *) FUNC_NAME, (char *) msg, \ SCM_EOL, SCM_BOOL_F); else #if defined(SWIG_NOINCLUDE) # define SWIGSTATIC #elif defined(SWIG_GLOBAL) # define SWIGSTATIC #else # define SWIGSTATIC static #endif #define GH_NOT_PASSED SCM_UNDEFINED #define GH_UNSPECIFIED SCM_UNSPECIFIED #define SWIG_APPEND_VALUE(object) \ if (gswig_result == GH_UNSPECIFIED) \ gswig_result = object; \ else { \ if (!gswig_list_p) { \ gswig_list_p = 1; \ gswig_result = gh_list(gswig_result, object, GH_NOT_PASSED); \ } \ else \ gswig_result = gh_append2(gswig_result, \ gh_list(object, GH_NOT_PASSED)); \ } #define GUILE_APPEND_RESULT SWIG_APPEND_VALUE /* scm_values was implemented on C level in 1.4.1, and the prototype is not included in libguile.h, so play safe and lookup `values'... */ #define GUILE_MAYBE_VALUES \ if (gswig_list_p) \ gswig_result = gh_apply(gh_lookup("values"), gswig_result); #define GUILE_MAYBE_VECTOR \ if (gswig_list_p) \ gswig_result = gh_list_to_vector(gswig_result); static char * SWIG_scm2str (SCM s) { return gh_scm2newstr (s, NULL); } #define GSWIG_scm2str SWIG_scm2str /* SCM_CHAR and SCM_CHARP were introduced in Guile 1.4; the following is for 1.3.4 compatibility. */ #ifndef SCM_CHAR # define SCM_CHAR SCM_ICHR #endif #ifndef SCM_CHARP # define SCM_CHARP SCM_ICHRP #endif /* This function replaces gh_scm2char, which is broken in Guile 1.4 */ static char GSWIG_scm2char (SCM s) { if (SCM_CHARP(s)) return SCM_CHAR(s); scm_wrong_type_arg(NULL, 0, s); } #define gh_scm2char GSWIG_scm2char /* More 1.3.4 compatibility */ #ifndef SCM_INPUT_PORT_P # define SCM_INPUT_PORT_P SCM_INPORTP # define SCM_OUTPUT_PORT_P SCM_OUTPORTP #endif /* Type system */ typedef void *(*swig_converter_func)(void *); typedef struct swig_type_info *(*swig_dycast_func)(void **); typedef struct SwigPtrType SwigPtrType; typedef struct swig_type_info { const char *name; swig_converter_func converter; const char *str; void *clientdata; size_t tag; swig_dycast_func dcast; } swig_type_info; SWIGSTATIC void SWIG_Guile_RegisterTypes (swig_type_info **table, swig_type_info **init); /* Register a new type-mapping with the type-checker. origtype is the original datatype and newtype is an equivalent type. cast is optional pointer to a function to cast pointer values between types (this is typically used to cast pointers from derived classes to base classes in C++). */ SWIGSTATIC void SWIG_RegisterMapping (const char *origtype, const char *newtype, swig_converter_func cast); /* Dynamic pointer casting. Down an inheritance hierarchy */ SWIGSTATIC swig_type_info * SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr); /* Register SWIG smobs with Guile. */ SWIGSTATIC void SWIG_Guile_Init(); /* Initialization function for this SWIG module; actually renamed by a #define */ /* extern void SWIG_init(); */ /* Get a pointer value from a smob. If there is a type-mismatch, return nonzero; on success, return 0. */ SWIGSTATIC int SWIG_Guile_GetPtr (SCM s, void **result, swig_type_info *type); /* Get a pointer value from a smob. If there is a type-mismatch, signal a wrong-type-arg error for the given argument number. */ SWIGSTATIC void * SWIG_Guile_MustGetPtr (SCM s, swig_type_info *type, int argnum, const char *func_name); /* Make a smob from a pointer and typeinfo. */ SWIGSTATIC SCM SWIG_Guile_MakePtr (void *ptr, swig_type_info *type); /* Get arguments from an argument list */ SWIGSTATIC int SWIG_Guile_GetArgs (SCM *dest, SCM rest, int reqargs, int optargs, const char *procname); typedef SCM (*swig_guile_proc)(); #ifdef __cplusplus } #endif /* guiledec.swg ends here */ #ifndef SWIG_NOINCLUDE /* SWIG pointer structure */ #ifdef __cplusplus extern "C" { #endif struct SwigCast { unsigned short type; /* Index into SwigPtrTbl */ void *(*cast)(void *); /* Pointer casting function */ struct SwigCast *next; /* Linked list pointer */ }; struct SwigPtrType { const char *name; /* Datatype name */ const char *prettyname; /* Pretty datatype name */ unsigned short tag; /* Index in SwigPtrTable */ struct SwigCast *cast; /* List of compatible types */ }; /* Some variables */ static int SwigPtrMax = 64; /* Max entries that can be held */ /* (may be adjusted dynamically) */ static int SwigPtrN = 0; /* Current number of entries */ static int SwigPtrSort = 0; /* Status flag indicating sort */ /* Pointer table */ static SwigPtrType *SwigPtrList = 0; /* Table containing types and equivalences; items will only be appended */ static size_t *SwigPtrTbl = 0; /* Sorted indirect table; items will be inserted */ /* Sort comparison function */ static int swigsort (const void *data1, const void *data2) { size_t index1 = * (size_t *) data1; size_t index2 = * (size_t *) data2; return strcmp(SwigPtrList[index1].name, SwigPtrList[index2].name); } /* Register a new datatype with the type-checker */ SWIGSTATIC size_t SWIG_RegisterType (const char *type, const char *prettyname) { int i; /* Allocate the pointer table if necessary */ if (!SwigPtrList) { SwigPtrList = (SwigPtrType *) malloc(SwigPtrMax*sizeof(SwigPtrType)); SwigPtrTbl = (size_t *) malloc(SwigPtrMax*sizeof(size_t)); SwigPtrN = 0; } /* Grow the table if necessary */ if (SwigPtrN >= SwigPtrMax) { SwigPtrMax = 2*SwigPtrMax; SwigPtrList = (SwigPtrType *) realloc((char *) SwigPtrList, SwigPtrMax*sizeof(SwigPtrType)); SwigPtrTbl = (size_t *) realloc((char *) SwigPtrTbl, SwigPtrMax*sizeof(size_t)); } /* Look up type */ for (i = 0; i < SwigPtrN; i++) if (strcmp(SwigPtrList[i].name,type) == 0) { if (prettyname!=NULL) SwigPtrList[i].prettyname = prettyname; return i; } { struct SwigPtrType *t; size_t tag; #if 0 fprintf(stderr, "New type: %s\n", type); #endif tag = SwigPtrTbl[SwigPtrN] = SwigPtrN; t = &SwigPtrList[tag]; t->name = type; t->prettyname = prettyname; t->tag = SwigPtrN; t->cast = NULL; SwigPtrN++; SwigPtrSort = 0; return tag; } } /* Register two data types and their mapping with the type checker. */ SWIGSTATIC void SWIG_RegisterMapping (const char *origtype, const char *newtype, swig_converter_func cast) { size_t t = SWIG_RegisterType(origtype, NULL); if (newtype!=NULL) { size_t t1 = SWIG_RegisterType(newtype, NULL); struct SwigCast *c; /* Check for existing cast */ for (c = SwigPtrList[t].cast; c && c->type!=t1; c=c->next) /* nothing */; if (c) { if (cast) c->cast = cast; } else { c = (struct SwigCast *) malloc(sizeof(struct SwigCast)); c->type = t1; c->cast = cast; c->next = SwigPtrList[t].cast; SwigPtrList[t].cast = c; } } } /* Sort table */ static void SWIG_SortTable (void) { qsort ((void *) SwigPtrTbl, SwigPtrN, sizeof(size_t), swigsort); /* Indicate that everything is sorted */ SwigPtrSort = 1; } /* Look up pointer-type entry in table */ static int swigcmp (const void *key, const void *data) { char *k = (char *) key; size_t index = *(size_t *)data; return strcmp(k, SwigPtrList[index].name); } static SwigPtrType * SWIG_GetPtrType (const char *_t) { size_t *result; if (!SwigPtrSort) SWIG_SortTable(); result = (size_t *) bsearch(_t, SwigPtrTbl, SwigPtrN, sizeof(size_t), swigcmp); if (result!=NULL) return SwigPtrList+*result; else return NULL; } /* Cast a pointer if possible; returns 1 if successful */ static int SWIG_Cast (void *source, size_t source_type, void **ptr, size_t dest_type) { if (dest_type != source_type) { /* We have a type mismatch. Will have to look through our type mapping table to figure out whether or not we can accept this datatype. */ struct SwigCast *c; for (c = SwigPtrList[dest_type].cast; c && c->type!=source_type; c = c->next) /* nothing */; if (c) { /* Get pointer value. */ if (c->cast) *ptr = (*(c->cast))(source); else *ptr = source; return 1; } /* Didn't find any sort of match for this data. Get the pointer value and return false. */ *ptr = source; return 0; } else { /* Found a match on the first try. Return pointer value. */ *ptr = source; return 1; } } /* Dynamic pointer casting. Down an inheritance hierarchy */ SWIGSTATIC 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; } /* Function for getting a pointer value */ static unsigned long swig_tag = 0; SWIGSTATIC SCM SWIG_Guile_MakePtr (void *ptr, swig_type_info *type) { if (ptr==NULL) return SCM_EOL; SCM_RETURN_NEWSMOB((((unsigned long)type->tag << 16) | swig_tag), ptr); } /* Return 0 if successful. */ SWIGSTATIC int SWIG_Guile_GetPtr(SCM s, void **result, swig_type_info *type) { if (SCM_NULLP(s)) { *result = NULL; return 0; } else if (SCM_NIMP(s) && (unsigned long) SCM_TYP16(s) == swig_tag) { if (type) return !SWIG_Cast((void *) SCM_CDR(s), (long) SCM_CAR(s) >> 16, result, type->tag); else { *result = (void *) SCM_CDR(s); return 0; } } return 1; } SWIGSTATIC void * SWIG_Guile_MustGetPtr (SCM s, swig_type_info *type, int argnum, const char *func_name) { void *result; if (SWIG_Guile_GetPtr(s, &result, type)) { /* type mismatch */ scm_wrong_type_arg((char *) func_name, argnum, s); } return result; } /* Init */ static int print_swig (SCM swig_smob, SCM port, scm_print_state *pstate) { scm_puts((char *) "#> 16].prettyname != NULL) scm_puts((char*) SwigPtrList[(long) SCM_CAR(swig_smob) >> 16].prettyname, port); else scm_puts((char*) SwigPtrList[(long) SCM_CAR(swig_smob) >> 16].name, port); scm_puts((char *) " ", port); scm_intprint((long) SCM_CDR(swig_smob), 16, port); scm_puts((char *) ">", port); /* non-zero means success */ return 1; } static SCM equalp_swig (SCM A, SCM B) { if (SCM_CAR(A) == SCM_CAR(B) && SCM_CDR(A) == SCM_CDR(B)) return SCM_BOOL_T; else return SCM_BOOL_F; } SWIGSTATIC void SWIG_Guile_Init (void) { if (swig_tag == 0) { swig_tag = scm_make_smob_type_mfpe((char *) "swig", 0, NULL, NULL, print_swig, equalp_swig); } } /* Convert datatype table */ SWIGSTATIC void SWIG_Guile_RegisterTypes(swig_type_info **table, swig_type_info **init) { for (; *init; table++, init++) { swig_type_info *type = *table = *init; const char *origname = type->name; /* Register datatype itself and store pointer back */ type->tag = SWIG_RegisterType(origname, type->str); /* Register compatible types */ for (type++; type->name; type++) SWIG_RegisterMapping(origname, type->name, type->converter); } } SWIGSTATIC int SWIG_Guile_GetArgs (SCM *dest, SCM rest, int reqargs, int optargs, const char *procname) { int i; int num_args_passed = 0; for (i = 0; i * ----------------------------------------------------------------------- */ #include #include #include #include #ifdef __cplusplus extern "C" { #endif typedef SCM (*swig_guile_proc)(); typedef SCM (*guile_destructor)(SCM); typedef struct swig_guile_clientdata { guile_destructor destroy; SCM goops_class; } swig_guile_clientdata; #define SWIG_scm2str(s) \ SWIG_Guile_scm2newstr(s, NULL) #define SWIG_malloc(size) \ SCM_MUST_MALLOC(size) #define SWIG_free(mem) \ scm_must_free(mem) #define SWIG_ConvertPtr(s, result, type, flags) \ SWIG_Guile_ConvertPtr(s, result, type, flags) #define SWIG_MustGetPtr(s, type, argnum, flags) \ SWIG_Guile_MustGetPtr(s, type, argnum, flags, FUNC_NAME) #define SWIG_NewPointerObj(ptr, type, owner) \ SWIG_Guile_NewPointerObj((void*)ptr, type, owner) #define SWIG_PropagateClientData(type) \ SWIG_Guile_PropagateClientData(type) #define SWIG_contract_assert(expr, msg) \ if (!(expr)) \ scm_error(scm_str2symbol("swig-contract-assertion-failed"), \ (char *) FUNC_NAME, (char *) msg, \ SCM_EOL, SCM_BOOL_F); else #ifdef SWIG_NOINCLUDE /* Interface helper function */ SWIGIMPORT(char *) SWIG_Guile_scm2newstr(SCM str, size_t *len); /* Register SWIG smobs with Guile. */ SWIGIMPORT(void) SWIG_Guile_Init(); /* Get a pointer value from a smob. If there is a type-mismatch, return nonzero; on success, return 0. */ SWIGIMPORT(int) SWIG_Guile_ConvertPtr(SCM s, void **result, swig_type_info *type, int flags); /* Get a pointer value from a smob. If there is a type-mismatch, signal a wrong-type-arg error for the given argument number. */ SWIGIMPORT(void *) SWIG_Guile_MustGetPtr(SCM s, swig_type_info *type, int argnum, int flags, const char *func_name); /* Make a smob from a pointer and typeinfo. */ SWIGIMPORT(SCM) SWIG_Guile_NewPointerObj(void *ptr, swig_type_info *type, int owner); /* Get arguments from an argument list */ SWIGIMPORT(int) SWIG_Guile_GetArgs(SCM *dest, SCM rest, int reqargs, int optargs, const char *procname); /* Propagate client data to equivalent types */ SWIGIMPORT(void) SWIG_Guile_PropagateClientData(swig_type_info *type); /* Make a pointer object non-collectable */ SWIGIMPORT(void) SWIG_Guile_MarkPointerNoncollectable(SCM s); /* Mark a pointer object destroyed */ SWIGIMPORT(void) SWIG_Guile_MarkPointerDestroyed(SCM s); #else SWIGRUNTIME(char *) SWIG_Guile_scm2newstr(SCM str, size_t *len) { #define FUNC_NAME "SWIG_Guile_scm2newstr" char *ret; size_t l; l = SCM_STRING_LENGTH(str); ret = (char *) SWIG_malloc( (l + 1) * sizeof(char)); if (!ret) return NULL; memcpy(ret, SCM_STRING_CHARS(str), l); ret[l] = '\0'; if (len) *len = l; return ret; #undef FUNC_NAME } static scm_t_bits swig_tag = 0; static scm_t_bits swig_collectable_tag = 0; static scm_t_bits swig_destroyed_tag = 0; static SCM swig_make_func = SCM_EOL; static SCM swig_keyword = SCM_EOL; static SCM swig_symbol = SCM_EOL; #define SWIG_Guile_GetSmob(x) \ ( SCM_NNULLP(x) && SCM_INSTANCEP(x) && SCM_NFALSEP(scm_slot_exists_p(x, swig_symbol)) \ ? scm_slot_ref(x, swig_symbol) : (x) ) SWIGRUNTIME(SCM) SWIG_Guile_NewPointerObj(void *ptr, swig_type_info *type, int owner) { if (ptr == NULL) return SCM_EOL; else { SCM smob; swig_guile_clientdata *cdata = (swig_guile_clientdata *) type->clientdata; if (owner) SCM_NEWSMOB2(smob, swig_collectable_tag, ptr, (void *) type); else SCM_NEWSMOB2(smob, swig_tag, ptr, (void *) type); if (!cdata || SCM_NULLP(cdata->goops_class) || swig_make_func == SCM_EOL ) { return smob; } else { /* the scm_make() C function only handles the creation of gf, methods and classes (no instances) the (make ...) function is later redefined in goops.scm. So we need to call that Scheme function. */ return scm_apply(swig_make_func, scm_list_3(cdata->goops_class, swig_keyword, smob), SCM_EOL); } } } /* Return 0 if successful. */ SWIGRUNTIME(int) SWIG_Guile_ConvertPtr(SCM s, void **result, swig_type_info *type, int flags) { swig_type_info *cast; swig_type_info *from; SCM smob = SWIG_Guile_GetSmob(s); if (SCM_NULLP(smob)) { *result = NULL; return 0; } else if (SCM_SMOB_PREDICATE(swig_tag, smob) || SCM_SMOB_PREDICATE(swig_collectable_tag, smob)) { /* we do not accept smobs representing destroyed pointers */ from = (swig_type_info *) SCM_CELL_WORD_2(smob); if (!from) return 1; if (type) { cast = SWIG_TypeCheck((char*)from->name, type); if (cast) { *result = SWIG_TypeCast(cast, (void *) SCM_CELL_WORD_1(smob)); return 0; } else { return 1; } } else { *result = (void *) SCM_CELL_WORD_1(smob); return 0; } } return 1; } SWIGRUNTIME(void *) SWIG_Guile_MustGetPtr (SCM s, swig_type_info *type, int argnum, int flags, const char *func_name) { void *result; if (SWIG_Guile_ConvertPtr(s, &result, type, flags)) { /* type mismatch */ scm_wrong_type_arg((char *) func_name, argnum, s); } return result; } /* Mark a pointer object non-collectable */ SWIGRUNTIME(void) SWIG_Guile_MarkPointerNoncollectable(SCM s) { SCM smob = SWIG_Guile_GetSmob(s); if (!SCM_NULLP(smob)) { if (SCM_SMOB_PREDICATE(swig_tag, smob) || SCM_SMOB_PREDICATE(swig_collectable_tag, smob)) { SCM_SET_CELL_TYPE(smob, swig_tag); } else scm_wrong_type_arg(NULL, 0, s); } } /* Mark a pointer object destroyed */ SWIGIMPORT(void) SWIG_Guile_MarkPointerDestroyed(SCM s) { SCM smob = SWIG_Guile_GetSmob(s); if (!SCM_NULLP(smob)) { if (SCM_SMOB_PREDICATE(swig_tag, smob) || SCM_SMOB_PREDICATE(swig_collectable_tag, smob)) { SCM_SET_CELL_TYPE(smob, swig_destroyed_tag); } else scm_wrong_type_arg(NULL, 0, s); } } /* Init */ static int print_swig_aux (SCM swig_smob, SCM port, scm_print_state *pstate, const char *attribute) { swig_type_info *type; type = (swig_type_info *) SCM_CELL_WORD_2(swig_smob); if (type) { scm_puts((char *) "#<", port); scm_puts(attribute, port); scm_puts("swig-pointer ", port); if (type->str != NULL) scm_puts(type->str, port); else scm_puts(type->name, port); scm_puts((char *) " ", port); scm_intprint((long) SCM_CELL_WORD_1(swig_smob), 16, port); scm_puts((char *) ">", port); /* non-zero means success */ return 1; } else { return 0; } } static int print_swig (SCM swig_smob, SCM port, scm_print_state *pstate) { return print_swig_aux(swig_smob, port, pstate, ""); } static int print_collectable_swig (SCM swig_smob, SCM port, scm_print_state *pstate) { return print_swig_aux(swig_smob, port, pstate, "collectable-"); } static int print_destroyed_swig (SCM swig_smob, SCM port, scm_print_state *pstate) { return print_swig_aux(swig_smob, port, pstate, "destroyed-"); } static SCM equalp_swig (SCM A, SCM B) { if (SCM_CELL_WORD_0(A) == SCM_CELL_WORD_0(B) && SCM_CELL_WORD_1(A) == SCM_CELL_WORD_1(B) && SCM_CELL_WORD_2(A) == SCM_CELL_WORD_2(B)) return SCM_BOOL_T; else return SCM_BOOL_F; } static size_t free_swig(SCM A) { swig_type_info *type = (swig_type_info *) SCM_CELL_WORD_2(A); if (type) { if (type->clientdata) ((swig_guile_clientdata *)type->clientdata)->destroy(A); } return 0; } SWIGRUNTIME(void) SWIG_Guile_Init () { if (!swig_tag) { swig_tag = scm_make_smob_type((char*)"swig-pointer", 0); scm_set_smob_print(swig_tag, print_swig); scm_set_smob_equalp(swig_tag, equalp_swig); } if (!swig_collectable_tag) { swig_collectable_tag = scm_make_smob_type((char*)"collectable-swig-pointer", 0); scm_set_smob_print(swig_collectable_tag, print_collectable_swig); scm_set_smob_equalp(swig_collectable_tag, equalp_swig); scm_set_smob_free(swig_collectable_tag, free_swig); } if (!swig_destroyed_tag) { swig_destroyed_tag = scm_make_smob_type((char*)"destroyed-swig-pointer", 0); scm_set_smob_print(swig_destroyed_tag, print_destroyed_swig); scm_set_smob_equalp(swig_destroyed_tag, equalp_swig); } swig_make_func = scm_permanent_object( scm_variable_ref(scm_c_module_lookup(scm_c_resolve_module("oop goops"), "make"))); swig_keyword = scm_permanent_object(scm_c_make_keyword((char*) "init-smob")); swig_symbol = scm_permanent_object(scm_str2symbol("swig-smob")); } SWIGRUNTIME(int) SWIG_Guile_GetArgs (SCM *dest, SCM rest, int reqargs, int optargs, const char *procname) { int i; int num_args_passed = 0; for (i = 0; inext; swig_type_info *tc; if (!type->clientdata) return; while (equiv) { if (!equiv->converter) { tc = swig_type_list; while (tc) { if ((strcmp(tc->name, equiv->name) == 0) && !tc->clientdata) SWIG_TypeClientData(tc, type->clientdata); tc = tc->prev; } } equiv = equiv->next; } } #endif #ifdef __cplusplus } #endif cableswig-0.1.0+git20150808.orig/SWIG/Lib/guile/precommon.swg0000644000175000000620000000136612561312227022140 0ustar stevestaff/*************************************************************** -*- c -*- * guile/precommon.swg * * Rename all exported symbols from common.swg, to avoid symbol * clashes if multiple interpreters are included * ************************************************************************/ #define SWIG_TypeRegister SWIG_Guile_TypeRegister #define SWIG_TypeCheck SWIG_Guile_TypeCheck #define SWIG_TypeCast SWIG_Guile_TypeCast #define SWIG_TypeDynamicCast SWIG_Guile_TypeDynamicCast #define SWIG_TypeName SWIG_Guile_TypeName #define SWIG_TypeQuery SWIG_Guile_TypeQuery #define SWIG_TypeClientData SWIG_Guile_TypeClientData #define SWIG_PackData SWIG_Guile_PackData #define SWIG_UnpackData SWIG_Guile_UnpackData cableswig-0.1.0+git20150808.orig/SWIG/Lib/guile/list-vector.i0000644000175000000620000004332212561312227022042 0ustar stevestaff/* list-vector.i --- Guile typemaps for converting between -*- c -*- arrays and Scheme lists or vectors Copyright (C) 2001, 2002 Matthias Koeppe /cvsroot/SWIG/Lib/guile/list-vector.i,v 1.6 2003/09/10 11:22:12 mkoeppe Exp */ /* Here is a macro that will define typemaps for converting between C arrays and Scheme lists or vectors when passing arguments to the C function. TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(C_TYPE, SCM_TO_C, C_TO_SCM, SCM_TYPE) Supported calling conventions: func(int VECTORLENINPUT, [const] C_TYPE *VECTORINPUT) Scheme wrapper will take one argument, a vector. A temporary C array of elements of type C_TYPE will be allocated and filled with the elements of the vectors, converted to C with the SCM_TO_C function. Length and address of the array are passed to the C function. SCM_TYPE is used to describe the Scheme type of the elements in the Guile procedure documentation. func(int LISTLENINPUT, [const] C_TYPE *LISTINPUT) Likewise, but the Scheme wrapper will take one argument, a list. func(int *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT) Scheme wrapper will take no arguments. Addresses of an integer and a C_TYPE * variable will be passed to the C function. The C function is expected to return address and length of a freshly allocated array of elements of type C_TYPE through these pointers. The elements of this array are converted to Scheme with the C_TO_SCM function and returned as a Scheme vector. If the function has a void return value, the vector constructed by this typemap becomes the return value of the Scheme wrapper. Otherwise, the function returns multiple values. (See the documentation on how to deal with multiple values.) func(int *LISTLENOUTPUT, C_TYPE **LISTOUTPUT) Likewise, but the Scheme wrapper will return a list instead of a vector. It is also allowed to use "size_t LISTLENINPUT" rather than "int LISTLENINPUT". */ %define TYPEMAP_LIST_VECTOR_INPUT_WITH_EXPR(C_TYPE, SCM_TO_C_EXPR, SCM_TYPE) /* input */ /* We make use of the new multi-dispatch typemaps here. */ %typemap(in, doc="$NAME is a vector of " #SCM_TYPE " values") (int VECTORLENINPUT, C_TYPE *VECTORINPUT), (size_t VECTORLENINPUT, C_TYPE *VECTORINPUT) { SCM_VALIDATE_VECTOR($argnum, $input); $1 = gh_vector_length($input); if ($1 > 0) { $1_ltype i; $2 = (C_TYPE *) SWIG_malloc(sizeof(C_TYPE) * $1); for (i = 0; i<$1; i++) { SCM swig_scm_value = gh_vector_ref($input, gh_int2scm(i)); $2[i] = SCM_TO_C_EXPR; } } else $2 = NULL; } %typemap(in, doc="$NAME is a list of " #SCM_TYPE " values") (int LISTLENINPUT, C_TYPE *LISTINPUT), (size_t LISTLENINPUT, C_TYPE *LISTINPUT) { SCM_VALIDATE_LIST($argnum, $input); $1 = gh_length($input); if ($1 > 0) { $1_ltype i; SCM rest; $2 = (C_TYPE *) SWIG_malloc(sizeof(C_TYPE) * $1); for (i = 0, rest = $input; i<$1; i++, rest = gh_cdr(rest)) { SCM swig_scm_value = gh_car(rest); $2[i] = SCM_TO_C_EXPR; } } else $2 = NULL; } /* Do not check for NULL pointers (override checks). */ %typemap(check) (int VECTORLENINPUT, C_TYPE *VECTORINPUT), (size_t VECTORLENINPUT, C_TYPE *VECTORINPUT), (int LISTLENINPUT, C_TYPE *LISTINPUT), (size_t LISTLENINPUT, C_TYPE *LISTINPUT) "/* no check for NULL pointer */"; /* Discard the temporary array after the call. */ %typemap(freearg) (int VECTORLENINPUT, C_TYPE *VECTORINPUT), (size_t VECTORLENINPUT, C_TYPE *VECTORINPUT), (int LISTLENINPUT, C_TYPE *LISTINPUT), (size_t LISTLENINPUT, C_TYPE *LISTINPUT) {if ($2!=NULL) SWIG_free($2);} %enddef /* output */ %define TYPEMAP_LIST_VECTOR_OUTPUT_WITH_EXPR(C_TYPE, C_TO_SCM_EXPR, SCM_TYPE) /* First we make temporary variables ARRAYLENTEMP and ARRAYTEMP, whose addresses we pass to the C function. We ignore both arguments for Scheme. */ %typemap(in,numinputs=0) (int *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT) (int arraylentemp, C_TYPE *arraytemp), (int *LISTLENOUTPUT, C_TYPE **LISTOUTPUT) (int arraylentemp, C_TYPE *arraytemp), (size_t *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT) (int arraylentemp, C_TYPE *arraytemp), (size_t *LISTLENOUTPUT, C_TYPE **LISTOUTPUT) (int arraylentemp, C_TYPE *arraytemp) %{ $1 = &arraylentemp; $2 = &arraytemp; %} /* In the ARGOUT typemaps, we convert the array into a vector or a list and append it to the results. */ %typemap(argout, doc="$NAME (a vector of " #SCM_TYPE " values)") (int *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT), (size_t *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT) { $*1_ltype i; SCM res = gh_make_vector(gh_int2scm(*$1), SCM_BOOL_F); for (i = 0; i<*$1; i++) { C_TYPE swig_c_value = (*$2)[i]; SCM elt = C_TO_SCM_EXPR; gh_vector_set_x(res, gh_int2scm(i), elt); } SWIG_APPEND_VALUE(res); } %typemap(argout, doc="$NAME (a list of " #SCM_TYPE " values)") (int *LISTLENOUTPUT, C_TYPE **LISTOUTPUT), (size_t *LISTLENOUTPUT, C_TYPE **LISTOUTPUT) { int i; SCM res = SCM_EOL; for (i = ((int)(*$1)) - 1; i>=0; i--) { C_TYPE swig_c_value = (*$2)[i]; SCM elt = C_TO_SCM_EXPR; res = gh_cons(elt, res); } SWIG_APPEND_VALUE(res); } /* In the FREEARG typemaps, get rid of the C vector. (This can be overridden if you want to keep the C vector.) */ %typemap(freearg) (int *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT), (size_t *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT), (int *LISTLENOUTPUT, C_TYPE **LISTOUTPUT), (size_t *LISTLENOUTPUT, C_TYPE **LISTOUTPUT) { if ((*$2)!=NULL) free(*$2); } %enddef %define TYPEMAP_LIST_VECTOR_INPUT_OUTPUT_WITH_EXPR(C_TYPE, SCM_TO_C_EXPR, C_TO_SCM_EXPR, SCM_TYPE) TYPEMAP_LIST_VECTOR_INPUT_WITH_EXPR(C_TYPE, SCM_TO_C_EXPR, SCM_TYPE) TYPEMAP_LIST_VECTOR_OUTPUT_WITH_EXPR(C_TYPE, C_TO_SCM_EXPR, SCM_TYPE) %enddef %define TYPEMAP_LIST_VECTOR_INPUT(C_TYPE, SCM_TO_C, SCM_TYPE) TYPEMAP_LIST_VECTOR_INPUT_WITH_EXPR (C_TYPE, SCM_TO_C(swig_scm_value), SCM_TYPE) %enddef %define TYPEMAP_LIST_VECTOR_OUTPUT(C_TYPE, C_TO_SCM, SCM_TYPE) TYPEMAP_LIST_VECTOR_OUTPUT_WITH_EXPR (C_TYPE, C_TO_SCM(swig_c_value), SCM_TYPE) %enddef %define TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(C_TYPE, SCM_TO_C, C_TO_SCM, SCM_TYPE) TYPEMAP_LIST_VECTOR_INPUT_OUTPUT_WITH_EXPR (C_TYPE, SCM_TO_C(swig_scm_value), C_TO_SCM(swig_c_value), SCM_TYPE) %enddef /* We use the macro to define typemaps for some standard types. */ TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(bool, gh_scm2bool, gh_bool2scm, boolean); TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(char, gh_scm2char, gh_char2scm, char); TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(unsigned char, gh_scm2char, gh_char2scm, char); TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(int, gh_scm2int, gh_int2scm, integer); TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(short, gh_scm2int, gh_int2scm, integer); TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(long, gh_scm2long, gh_long2scm, integer); TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(ptrdiff_t, gh_scm2long, gh_long2scm, integer); TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(unsigned int, gh_scm2ulong, gh_ulong2scm, integer); TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(unsigned short, gh_scm2ulong, gh_ulong2scm, integer); TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(unsigned long, gh_scm2ulong, gh_ulong2scm, integer); TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(size_t, gh_scm2ulong, gh_ulong2scm, integer); TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(float, gh_scm2double, gh_double2scm, real); TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(double, gh_scm2double, gh_double2scm, real); TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(char *, SWIG_scm2str, gh_str02scm, string); TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(const char *, SWIG_scm2str, gh_str02scm, string); /* For the char *, free all strings after converting */ %typemap(freearg) (int *VECTORLENOUTPUT, char ***VECTOROUTPUT), (size_t *VECTORLENOUTPUT, char ***VECTOROUTPUT), (int *LISTLENOUTPUT, char ***LISTOUTPUT), (size_t *LISTLENOUTPUT, char ***LISTOUTPUT), (int *VECTORLENOUTPUT, const char ***VECTOROUTPUT), (size_t *VECTORLENOUTPUT, const char ***VECTOROUTPUT), (int *LISTLENOUTPUT, const char ***LISTOUTPUT), (size_t *LISTLENOUTPUT, const char ***LISTOUTPUT) { if ((*$2)!=NULL) { int i; for (i = 0; i < *$1; i++) { if ((*$2)[i] != NULL) free((*$2)[i]); } free(*$2); } } %typemap(freearg) (int VECTORLENINPUT, char **VECTORINPUT), (size_t VECTORLENINPUT, char **VECTORINPUT), (int LISTLENINPUT, char **LISTINPUT), (size_t LISTLENINPUT, char **LISTINPUT), (int VECTORLENINPUT, const char **VECTORINPUT), (size_t VECTORLENINPUT, const char **VECTORINPUT), (int LISTLENINPUT, const char **LISTINPUT), (size_t LISTLENINPUT, const char **LISTINPUT) { if (($2)!=NULL) { int i; for (i = 0; i< $1; i++) if (($2)[i] != NULL) free(($2)[i]); free($2); } } /* Following is a macro that emits typemaps that are much more flexible. (They are also messier.) It supports multiple parallel lists and vectors (sharing one length argument each). TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(C_TYPE, SCM_TO_C, C_TO_SCM, SCM_TYPE) Supported calling conventions: func(int PARALLEL_VECTORLENINPUT, [const] C_TYPE *PARALLEL_VECTORINPUT, ...) or func([const] C_TYPE *PARALLEL_VECTORINPUT, ..., int PARALLEL_VECTORLENINPUT) func(int PARALLEL_LISTLENINPUT, [const] C_TYPE *PARALLEL_LISTINPUT, ...) or func([const] C_TYPE *PARALLEL_LISTINPUT, ..., int PARALLEL_LISTLENINPUT) func(int *PARALLEL_VECTORLENOUTPUT, C_TYPE **PARALLEL_VECTOROUTPUT, ...) or func(C_TYPE **PARALLEL_VECTOROUTPUT, int *PARALLEL_VECTORLENOUTPUT, ...) func(int *PARALLEL_LISTLENOUTPUT, C_TYPE **PARALLEL_LISTOUTPUT) or func(C_TYPE **PARALLEL_LISTOUTPUT, int *PARALLEL_LISTLENOUTPUT) It is also allowed to use "size_t PARALLEL_LISTLENINPUT" rather than "int PARALLEL_LISTLENINPUT". */ %define TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_WITH_EXPR(C_TYPE, SCM_TO_C_EXPR, SCM_TYPE) /* input */ /* Passing data is a little complicated here; just remember: IGNORE typemaps come first, then IN, then CHECK. But if IGNORE is given, IN won't be used for this type. We need to "ignore" one of the parameters because there shall be only one argument on the Scheme side. Here we only initialize the array length to 0 but save its address for a later change. */ %typemap(in,numinputs=0) int PARALLEL_VECTORLENINPUT (int *_global_vector_length), size_t PARALLEL_VECTORLENINPUT (size_t *_global_vector_length) { $1 = 0; _global_vector_length = &$1; } %typemap(in,numinputs=0) int PARALLEL_LISTLENINPUT (int *_global_list_length), size_t PARALLEL_LISTLENINPUT (int *_global_list_length) { $1 = 0; _global_list_length = &$1; } /* All the work is done in IN. */ %typemap(in, doc="$NAME is a vector of " #SCM_TYPE " values") C_TYPE *PARALLEL_VECTORINPUT, const C_TYPE *PARALLEL_VECTORINPUT { SCM_VALIDATE_VECTOR($argnum, $input); *_global_vector_length = gh_vector_length($input); if (*_global_vector_length > 0) { int i; $1 = (C_TYPE *) SWIG_malloc(sizeof(C_TYPE) * (*_global_vector_length)); for (i = 0; i<*_global_vector_length; i++) { SCM swig_scm_value = gh_vector_ref($input, gh_int2scm(i)); $1[i] = SCM_TO_C_EXPR; } } else $1 = NULL; } %typemap(in, doc="$NAME is a list of " #SCM_TYPE " values") C_TYPE *PARALLEL_LISTINPUT, const C_TYPE *PARALLEL_LISTINPUT { SCM_VALIDATE_LIST($argnum, $input); *_global_list_length = gh_length($input); if (*_global_list_length > 0) { int i; SCM rest; $1 = (C_TYPE *) SWIG_malloc(sizeof(C_TYPE) * (*_global_list_length)); for (i = 0, rest = $input; i<*_global_list_length; i++, rest = gh_cdr(rest)) { SCM swig_scm_value = gh_car(rest); $1[i] = SCM_TO_C_EXPR; } } else $1 = NULL; } /* Don't check for NULL pointers (override checks). */ %typemap(check) C_TYPE *PARALLEL_VECTORINPUT, const C_TYPE *PARALLEL_VECTORINPUT, C_TYPE *PARALLEL_LISTINPUT, const C_TYPE *PARALLEL_LISTINPUT "/* no check for NULL pointer */"; /* Discard the temporary array after the call. */ %typemap(freearg) C_TYPE *PARALLEL_VECTORINPUT, const C_TYPE *PARALLEL_VECTORINPUT, C_TYPE *PARALLEL_LISTINPUT, const C_TYPE *PARALLEL_LISTINPUT {if ($1!=NULL) SWIG_free($1);} %enddef %define TYPEMAP_PARALLEL_LIST_VECTOR_OUTPUT_WITH_EXPR(C_TYPE, C_TO_SCM_EXPR, SCM_TYPE) /* output */ /* First we make a temporary variable ARRAYLENTEMP, use its address as the ...LENOUTPUT argument for the C function and "ignore" the ...LENOUTPUT argument for Scheme. */ %typemap(in,numinputs=0) int *PARALLEL_VECTORLENOUTPUT (int _global_arraylentemp), size_t *PARALLEL_VECTORLENOUTPUT (size_t _global_arraylentemp), int *PARALLEL_LISTLENOUTPUT (int _global_arraylentemp), size_t *PARALLEL_LISTLENOUTPUT (size_t _global_arraylentemp) "$1 = &_global_arraylentemp;"; /* We also need to ignore the ...OUTPUT argument. */ %typemap(in,numinputs=0) C_TYPE **PARALLEL_VECTOROUTPUT (C_TYPE *arraytemp), C_TYPE **PARALLEL_LISTOUTPUT (C_TYPE *arraytemp) "$1 = &arraytemp;"; /* In the ARGOUT typemaps, we convert the array into a vector or a list and append it to the results. */ %typemap(argout, doc="$NAME (a vector of " #SCM_TYPE " values)") C_TYPE **PARALLEL_VECTOROUTPUT { int i; SCM res = gh_make_vector(gh_int2scm(_global_arraylentemp), SCM_BOOL_F); for (i = 0; i<_global_arraylentemp; i++) { C_TYPE swig_c_value = (*$1)[i]; SCM elt = C_TO_SCM_EXPR; gh_vector_set_x(res, gh_int2scm(i), elt); } SWIG_APPEND_VALUE(res); } %typemap(argout, doc="$NAME (a list of " #SCM_TYPE " values)") C_TYPE **PARALLEL_LISTOUTPUT { int i; SCM res = SCM_EOL; if (_global_arraylentemp > 0) { for (i = _global_arraylentemp - 1; i>=0; i--) { C_TYPE swig_c_value = (*$1)[i]; SCM elt = C_TO_SCM_EXPR; res = gh_cons(elt, res); } } SWIG_APPEND_VALUE(res); } /* In the FREEARG typemaps, get rid of the C vector. (This can be overridden if you want to keep the C vector.) */ %typemap(freearg) C_TYPE **PARALLEL_VECTOROUTPUT, C_TYPE **PARALLEL_LISTOUTPUT { if ((*$1)!=NULL) free(*$1); } %enddef %define TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT_WITH_EXPR(C_TYPE, SCM_TO_C_EXPR, C_TO_SCM_EXPR, SCM_TYPE) TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_WITH_EXPR(C_TYPE, SCM_TO_C_EXPR, SCM_TYPE) TYPEMAP_PARALLEL_LIST_VECTOR_OUTPUT_WITH_EXPR(C_TYPE, C_TO_SCM_EXPR, SCM_TYPE) %enddef %define TYPEMAP_PARALLEL_LIST_VECTOR_INPUT(C_TYPE, SCM_TO_C, SCM_TYPE) TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_WITH_EXPR (C_TYPE, SCM_TO_C(swig_scm_value), SCM_TYPE) %enddef %define TYPEMAP_PARALLEL_LIST_VECTOR_OUTPUT(C_TYPE, C_TO_SCM, SCM_TYPE) TYPEMAP_PARALLEL_LIST_VECTOR_OUTPUT_WITH_EXPR (C_TYPE, C_TO_SCM(swig_c_value), SCM_TYPE) %enddef %define TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(C_TYPE, SCM_TO_C, C_TO_SCM, SCM_TYPE) TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT_WITH_EXPR (C_TYPE, SCM_TO_C(swig_scm_value), C_TO_SCM(swig_c_value), SCM_TYPE) %enddef /* We use the macro to define typemaps for some standard types. */ TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(bool, gh_scm2bool, gh_bool2scm, boolean); TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(char, gh_scm2char, gh_char2scm, char); TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(unsigned char, gh_scm2char, gh_char2scm, char); TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(int, gh_scm2int, gh_int2scm, integer); TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(short, gh_scm2int, gh_int2scm, integer); TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(long, gh_scm2long, gh_long2scm, integer); TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(ptrdiff_t, gh_scm2long, gh_long2scm, integer); TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(unsigned int, gh_scm2ulong, gh_ulong2scm, integer); TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(unsigned short, gh_scm2ulong, gh_ulong2scm, integer); TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(unsigned long, gh_scm2ulong, gh_ulong2scm, integer); TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(size_t, gh_scm2ulong, gh_ulong2scm, integer); TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(float, gh_scm2double, gh_double2scm, real); TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(double, gh_scm2double, gh_double2scm, real); TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(char *, SWIG_scm2str, gh_str02scm, string); TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(const char *, SWIG_scm2str, gh_str02scm, string); %typemap(freearg) char **PARALLEL_LISTINPUT, char **PARALLEL_VECTORINPUT, const char **PARALLEL_LISTINPUT, const char **PARALLEL_VECTORINPUT { if (($1)!=NULL) { int i; for (i = 0; i<*_global_list_length; i++) if (($1)[i] != NULL) SWIG_free(($1)[i]); SWIG_free($1); } } %typemap(freearg) char ***PARALLEL_LISTOUTPUT, char ***PARALLEL_VECTOROUTPUT, const char ***PARALLEL_LISTOUTPUT, const char ***PARALLEL_VECTOROUTPUT { if ((*$1)!=NULL) { int i; for (i = 0; i<_global_arraylentemp; i++) if ((*$1)[i] != NULL) free((*$1)[i]); free(*$1); } } cableswig-0.1.0+git20150808.orig/SWIG/Lib/guile/ghinterface.i0000644000175000000620000000236612561312227022051 0ustar stevestaff#define gh_append2(a, b) scm_append(scm_listify(a, b, SCM_UNDEFINED)) #define gh_apply(a, b) scm_apply(a, b, SCM_EOL) #define gh_bool2scm SCM_BOOL #define gh_boolean_p SCM_BOOLP #define gh_car SCM_CAR #define gh_cdr SCM_CDR #define gh_cons scm_cons #define gh_double2scm scm_make_real #define gh_int2scm scm_long2num #define gh_length(lst) scm_num2ulong(scm_length(lst), SCM_ARG1, FUNC_NAME) #define gh_list scm_listify #define gh_list_to_vector scm_vector #define gh_make_vector scm_make_vector #define gh_null_p SCM_NULLP #define gh_number_p SCM_NUMBERP #define gh_pair_p SCM_CONSP #define gh_scm2bool SCM_NFALSEP #define gh_scm2char SCM_CHAR #define gh_scm2double(a) scm_num2dbl(a, FUNC_NAME) #define gh_scm2int(a) scm_num2int(a, SCM_ARG1, FUNC_NAME) #define gh_scm2long(a) scm_num2long(a, SCM_ARG1, FUNC_NAME) #define gh_scm2newstr SWIG_Guile_scm2newstr #define gh_scm2ulong(a) scm_num2ulong(a, SCM_ARG1, FUNC_NAME) #define gh_ulong2scm scm_ulong2num #define gh_long2scm scm_long2num #define gh_str02scm scm_makfrom0str #define gh_string_p SCM_STRINGP #define gh_vector_length SCM_VECTOR_LENGTH #define gh_vector_p SCM_VECTORP #define gh_vector_ref scm_vector_ref #define gh_vector_set_x scm_vector_set_x #define gh_char2scm SCM_MAKE_CHAR cableswig-0.1.0+git20150808.orig/SWIG/Lib/guile/guile_gh.swg0000644000175000000620000000050412561312227021715 0ustar stevestaff/* -*- c -*- This SWIG interface file is processed if the Guile module is run with gh_ flavor. */ %runtime "guile_gh_run.swg" %include "guile.i" %init %{ static int _swig_init = 0; if (!_swig_init) { SWIG_Guile_RegisterTypes(swig_types, swig_types_initial); _swig_init = 1; } SWIG_Guile_Init(); %} cableswig-0.1.0+git20150808.orig/SWIG/Lib/guile/guile_scm.swg0000644000175000000620000000253112561312227022103 0ustar stevestaff/* -*- c -*- This SWIG interface file is processed if the Guile module is run with SCM_ flavor. */ %runtime "precommon.swg" %runtime "common.swg" %runtime "guile_scm_run.swg" %include "ghinterface.i" %include "guile.i" %runtime %{ #define GUILE_MAYBE_VALUES \ if (gswig_list_p) gswig_result = scm_values(gswig_result); #define GUILE_MAYBE_VECTOR \ if (gswig_list_p) gswig_result = scm_vector(gswig_result); #define SWIG_APPEND_VALUE(object) \ if (gswig_result == SCM_UNSPECIFIED) \ gswig_result = object; \ else { \ if (!gswig_list_p) { \ gswig_list_p = 1; \ gswig_result = scm_listify(gswig_result, object, SCM_UNDEFINED); \ } \ else \ gswig_result = scm_append(scm_listify(gswig_result, scm_listify(object, SCM_UNDEFINED), SCM_UNDEFINED)); \ } /* used by Lib/exception.i */ #define gh_symbol2scm scm_str2symbol /* useb by Lib/cdata.i */ #define gh_str2scm scm_mem2string %} %init %{ static int _swig_init = 0; if (!_swig_init) { int i; for (i = 0; swig_types_initial[i]; i++) { swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]); } for (i = 0; swig_types_initial[i]; i++) { SWIG_PropagateClientData(swig_types[i]); } _swig_init = 1; } SWIG_Guile_Init(); %} cableswig-0.1.0+git20150808.orig/SWIG/Lib/php4/0002755000175000000620000000000012561312227017161 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Lib/php4/std_string.i0000644000175000000620000000203112561312227021505 0ustar stevestaff// // SWIG typemaps for std::string types // Luigi Ballabio // May 7, 2002 // // PHP implementation // ------------------------------------------------------------------------ // std::string is typemapped by value // This can prevent exporting methods which return a string // in order for the user to modify it. // However, I think I'll wait until someone asks for it... // ------------------------------------------------------------------------ %include exception.i %{ #include %} namespace std { class string; %typemap(in) string { convert_to_string_ex($input); $1 = std::string(Z_STRVAL_PP($input)); } %typemap(in) const string & (std::string temp) { convert_to_string_ex($input); temp = std::string(Z_STRVAL_PP($input)); $1 = &temp; } %typemap(out) string { ZVAL_STRINGL($result,const_cast($1.c_str()),$1.length(),1); } %typemap(out) const string & { ZVAL_STRINGL($result,const_cast($1->c_str()),$1->length(),1); } } cableswig-0.1.0+git20150808.orig/SWIG/Lib/php4/std_map.i0000644000175000000620000001224712561312227020766 0ustar stevestaff// // SWIG typemaps for std::map // Luigi Ballabio // Jan. 2003 // // Common implementation %include std_common.i %include exception.i %exception std::map::get { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::map::del { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } // ------------------------------------------------------------------------ // std::map // ------------------------------------------------------------------------ %{ #include #include #include %} // exported class namespace std { template class map { // add typemaps here public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T& get(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void set(const K& key, const T& x) { (*self)[key] = x; } void del(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(const K& key) { std::map::iterator i = self->find(key); return i != self->end(); } } }; // specializations for built-ins %define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO) template class map { // add typemaps here public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T& get(K key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void set(K key, const T& x) { (*self)[key] = x; } void del(K key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(K key) { std::map::iterator i = self->find(key); return i != self->end(); } } }; %enddef %define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO) template class map { // add typemaps here public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T get(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void set(const K& key, T x) { (*self)[key] = x; } void del(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(const K& key) { std::map::iterator i = self->find(key); return i != self->end(); } } }; %enddef %define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO) template<> class map { // add typemaps here public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T get(K key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void set(K key, T x) { (*self)[key] = x; } void del(K key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(K key) { std::map::iterator i = self->find(key); return i != self->end(); } } }; %enddef // add specializations here } cableswig-0.1.0+git20150808.orig/SWIG/Lib/php4/php4.swg0000644000175000000620000003236612561312227020566 0ustar stevestaff/* * php4.swg * * PHP 4 configuration file * */ %runtime "precommon.swg" %runtime "common.swg" // common type checking code %runtime "php4run.swg" // Php4 runtime functions %include "utils.i" // building blocks /* Typemaps for input parameters by value */ %typemap(in) int, unsigned int, unsigned short, short, unsigned short, long, unsigned long, signed char, unsigned char, enum SWIGTYPE %{ convert_to_long_ex($input); $1 = ($1_ltype) Z_LVAL_PP($input); %} %typemap(in) bool %{ convert_to_boolean_ex($input); $1 = ($1_ltype) Z_LVAL_PP($input); %} %typemap(in) char %{ convert_to_string_ex($input); $1 = ($1_ltype) *Z_STRVAL_PP($input); %} %typemap(in) float,double %{ convert_to_double_ex($input); $1 = ($1_ltype) Z_DVAL_PP($input); %} // char * is input only normally %typemap(in) char * %{ convert_to_string_ex($input); $1 = ($1_ltype) Z_STRVAL_PP($input); %} // char array can be in/out, though the passed string may not be big enough... // so we have to size it strarray_inout(char [ANY]) %typemap(in) SWIGTYPE *, SWIGTYPE [], SWIGTYPE & %{ if(SWIG_ConvertPtr(*$input, (void **) &$1, $1_descriptor) < 0) { zend_error(E_ERROR, "Type error in argument %d of $symname. Expected %s", $argnum-argbase, $1_descriptor->name); } %} %typemap(in) void * %{ if(SWIG_ConvertPtr(*$input, (void **) &$1, 0) < 0) { /* Allow NULL from php for void* */ if ((*$input)->type==IS_NULL) $1=0; else zend_error(E_ERROR, "Type error in argument %d of $symname. Expected %s", $argnum-argbase, $1_descriptor->name); } %} /* Special case when void* is passed by reference so it can be made to point to opaque api structs */ %typemap(in) void ** ($*1_ltype ptr, int force), void *& ($*1_ltype ptr, int force) %{ /* If they pass NULL by reference, make it into a void* This bit should go in arginit if arginit support init-ing scripting args */ if(SWIG_ConvertPtr(*$input, (void **) &$1, $1_descriptor) < 0) { /* So... we didn't get a ref or ptr, but we'll accept NULL by reference */ if ((*$input)->type==IS_NULL && PZVAL_IS_REF(*$input)) { #if __cplusplus ptr=new $*1_ltype; #else ptr=($*1_ltype) calloc(1,sizeof($*1_ltype)); #endif $1=&ptr; /* have to passback arg$arg too */ force=1; } else { /* wasn't a pre/ref/thing, OR anything like an int thing */ force=0; zend_error(E_ERROR, "Type error in argument %d of $symname. Expected %s or %s or at least NULL passed by reference", $argnum-argbase, $1_descriptor->name,$*1_descriptor->name); } } else force=0; %} %typemap(argout) void **, void *& %{ if (force$argnum) { /* pass back arg$argnum through params ($arg) if we can */ if(! PZVAL_IS_REF(*$arg)) { zend_error(E_WARNING, "Parameter %d of $symname wasn't passed by reference: [argout void**, void*&]",$argnum-argbase); } else { SWIG_SetPointerZval(*$arg, (void *) ptr$argnum, $*1_descriptor, 1); } } %} /* Object passed by value. Convert to a pointer */ %typemap(in) SWIGTYPE { $&1_ltype argp; if(SWIG_ConvertPtr(*$input, (void **) &argp, $&1_descriptor) < 0) { zend_error(E_ERROR, "Type error in argument %d of $symname. Expected %s", $argnum-argbase, $&1_descriptor->name); } $1 = *argp; } /* Typemap for output values */ %typemap(out) int, unsigned int, short, unsigned short, long, unsigned long, signed char, unsigned char, bool, enum SWIGTYPE %{ ZVAL_LONG(return_value,$1); %} %typemap(out) bool %{ ZVAL_BOOL(return_value,($1)?1:0); %} %typemap(out) float, double %{ ZVAL_DOUBLE(return_value,$1); %} %typemap(out) char %{ // out char ZVAL_STRINGL(return_value,$1, 1, 1); %} %typemap(out) char * %{ ZVAL_STRING(return_value,$1, 1); %} %typemap(out) SWIGTYPE *, SWIGTYPE [], SWIGTYPE & %{ SWIG_SetPointerZval(return_value, (void *)$1, $1_descriptor, $owner); %} %typemap(out) SWIGTYPE *DYNAMIC, SWIGTYPE &DYNAMIC { swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor, (void **) &$1); SWIG_SetPointerZval(return_value, (void *)$1, ty, $owner); } %typemap(out) SWIGTYPE #ifdef __cplusplus { $&1_ltype resultobj = new $1_ltype(($1_ltype &) $1); SWIG_SetPointerZval(return_value, (void *)resultobj, $&1_descriptor, $owner); } #else { $&1_ltype resultobj = ($&1_ltype) emalloc(sizeof($1_type)); memmove(resultobj, &$1, sizeof($1_type)); SWIG_SetPointerZval(return_value, (void *)resultobj, $&1_descriptor, $owner); } #endif %typemap(out) void ""; /* Typemap for character array returns */ %typemap(out) char [ANY] { // out char any ZVAL_STRINGL(return_value,$1, $1_dim0, 1); } /* Typemap for in/argout references NOTE: we don't choose to use these for arrays yet, maybe later */ %typemap_inout_ord(bool,convert_to_bool_ex,ZVAL_BOOL) %typemap_inout_ord(int,convert_to_long_ex,ZVAL_LONG) %typemap_inout_ord(unsigned int,convert_to_long_ex,ZVAL_LONG) %typemap_inout_ord(short,convert_to_long_ex,ZVAL_LONG) %typemap_inout_ord(unsigned short,convert_to_long_ex,ZVAL_LONG) %typemap_inout_ord(long,convert_to_long_ex,ZVAL_LONG) %typemap_inout_ord(unsigned long,convert_to_long_ex,ZVAL_LONG) %typemap_inout_ord(signed char,convert_to_long_ex,ZVAL_LONG) %typemap_inout_ord(unsigned char,convert_to_long_ex,ZVAL_LONG) %typemap_inout_ord(enum SWIGTYPE,convert_to_long_ex,ZVAL_LONG) /* Global variables - add the variable to PHP */ %typemap(varinit) char * { zval *z_var; MAKE_STD_ZVAL(z_var); z_var->type = IS_STRING; if($1) { z_var->value.str.val = estrdup($1); z_var->value.str.len = strlen($1); } else { z_var->value.str.val = 0; z_var->value.str.len = 0; } zend_hash_add(&EG(symbol_table), "$1", strlen("$1")+1, (void *)&z_var, sizeof(zval *), NULL); } %typemap(varinit) int, unsigned int, unsigned short, short, unsigned short, long, unsigned long, signed char, unsigned char, bool, enum SWIGTYPE { zval *z_var; MAKE_STD_ZVAL(z_var); z_var->type = IS_LONG; z_var->value.lval = $1; zend_hash_add(&EG(symbol_table), "$1", strlen("$1")+1, (void *)&z_var, sizeof(zval *), NULL); } %typemap(varinit) bool { zval *z_var; MAKE_STD_ZVAL(z_var); z_var->type = IS_BOOL; z_var->value.lval = ($1)?1:0; zend_hash_add(&EG(symbol_table), "$1", strlen("$1")+1, (void *)&z_var, sizeof(zval *), NULL); } %typemap(varinit) float, double { zval *z_var; MAKE_STD_ZVAL(z_var); z_var->type = IS_DOUBLE; z_var->value.dval = $1; zend_hash_add(&EG(symbol_table), "$1", strlen("$1")+1, (void *)&z_var, sizeof(zval *), NULL); } %typemap(varinit) char { zval *z_var; char c[2]; MAKE_STD_ZVAL(z_var); c[0] = $1; c[1] = 0; z_var->type = IS_STRING; z_var->value.str.val = estrdup(c); z_var->value.str.len = 2; zend_hash_add(&EG(symbol_table), "$1", strlen("$1")+1, (void *)&z_var, sizeof(zval *), NULL); } %typemap(varinit) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { zval *z_var; MAKE_STD_ZVAL(z_var); SWIG_SetPointerZval(z_var, (void*)$1, $1_descriptor, $owner); zend_hash_add(&EG(symbol_table), "$1", strlen("$1")+1, (void *)&z_var, sizeof(zval *), NULL); } %typemap(varinit) SWIGTYPE { $&1_ltype argp; zval *z_var; MAKE_STD_ZVAL(z_var); SWIG_SetPointerZval(z_var, (void*)&$1, $&1_descriptor, $owner); zend_hash_add(&EG(symbol_table), "$1", strlen("$1")+1, (void*)&z_var, sizeof(zval *), NULL); } %typemap(varinit) char [ANY] { zval *z_var; MAKE_STD_ZVAL(z_var); z_var->type = IS_STRING; if($1) { // varinit char [ANY] ZVAL_STRINGL(z_var,$1, $1_dim0, 1); } zend_hash_add(&EG(symbol_table), "$1", strlen("$1")+1, (void*)&z_var, sizeof(zval *), NULL); } %typemap(varin) int, unsigned int, unsigned short, short, unsigned short, long, unsigned long, signed char, unsigned char, enum SWIGTYPE { zval **z_var; zend_hash_find(&EG(symbol_table), "$1",strlen("$1")+1, (void**)&z_var); convert_to_long_ex(z_var); if($1 != ($1_ltype)((*z_var)->value.lval)) { $1 = Z_LVAL_PP(z_var); } } %typemap(varin) bool { zval **z_var; zend_hash_find(&EG(symbol_table), "$1",strlen("$1")+1, (void**)&z_var); convert_to_boolean_ex(z_var); if($1 != ($1_ltype)((*z_var)->value.lval)) { $1 = Z_LVAL_PP(z_var); } } %typemap(varin) double,float { zval **z_var; zend_hash_find(&EG(symbol_table), "$1", strlen("$1")+1, (void**)&z_var); convert_to_double_ex(z_var); if($1 != ($1_ltype)((*z_var)->value.dval)) { $1 = Z_DVAL_PP(z_var); } } %typemap(varin) char { zval **z_var; zend_hash_find(&EG(symbol_table), "$1",strlen("$1")+1, (void**)&z_var); convert_to_string_ex(z_var); if($1 != *((*z_var)->value.str.val)) { $1 = *((*z_var)->value.str.val); } } %typemap(varin) char * { zval **z_var; char *s1; zend_hash_find(&EG(symbol_table), "$1", strlen("$1")+1, (void**)&z_var); convert_to_string_ex(z_var); s1 = Z_STRVAL_PP(z_var); if((s1 == NULL) || ($1 == NULL) || zend_binary_strcmp(s1, strlen(s1), $1, strlen($1))) { if(s1) $1 = estrdup(s1); else $1 = NULL; } } %typemap(varin) SWIGTYPE [] { zval **z_var; zend_hash_find(&EG(symbol_table), "$1", strlen("$1")+1, (void**)&z_var); if($1) { SWIG_SetPointerZval(*z_var, (void*)$1, $1_descriptor, $owner); } } %typemap(varin) char [ANY] { zval **z_var; char *s1; zend_hash_find(&EG(symbol_table), "$1", strlen("$1")+1, (void**)&z_var); s1 = Z_STRVAL_PP(z_var); if((s1 == NULL) || ($1 == NULL) || zend_binary_strcmp(s1, strlen(s1), $1, strlen($1))) { if(s1) strncpy($1, s1, $1_dim0); } } %typemap(varin) SWIGTYPE { zval **z_var; $&1_ltype _temp; zend_hash_find(&EG(symbol_table), "$1", strlen("$1")+1, (void**)&z_var); if (SWIG_ConvertPtr(*z_var, (void**)&_temp, $&1_descriptor) < 0) { zend_error(E_ERROR, "Type error in value of $symname. Expected %s", $&1_descriptor->name); } $1 = *($&1_ltype)_temp; } %typemap(varin) SWIGTYPE *, SWIGTYPE & { zval **z_var; $1_ltype _temp; zend_hash_find(&EG(symbol_table), "$1", strlen("$1")+1, (void**)&z_var); if (SWIG_ConvertPtr(*z_var, (void **)&_temp, $1_descriptor) < 0) { zend_error(E_ERROR, "Type error in value of $symname. Expected %s", $1_descriptor->name); } $1 = ($1_ltype)_temp; } %typemap(varout) int, unsigned int, unsigned short, short, unsigned short, long, unsigned long, signed char, unsigned char, enum SWIGTYPE { zval **z_var; zend_hash_find(&EG(symbol_table), "$1", strlen("$1")+1, (void**)&z_var); if($1 != ($1_ltype)((*z_var)->value.lval)) { (*z_var)->value.lval = (long)$1; } } //SAMFIX need to cast zval->type, what if zend-hash_find fails? etc? %typemap(varout) bool { zval **z_var; zend_hash_find(&EG(symbol_table), "$1", strlen("$1")+1, (void**)&z_var); if($1 != ($1_ltype)((*z_var)->value.lval)) { (*z_var)->value.lval = (long)$1; } } %typemap(varout) double, float { zval **z_var; zend_hash_find(&EG(symbol_table), "$1", strlen("$1")+1, (void**)&z_var); if($1 != ($1_ltype)((*z_var)->value.dval)) { (*z_var)->value.dval = (double)$1; } } %typemap(varout) char { zval **z_var; zend_hash_find(&EG(symbol_table), "$1", strlen("$1")+1, (void**)&z_var); if($1 != *((*z_var)->value.str.val)) { char c[2]; efree((*z_var)->value.str.val); c[0] = $1; c[1] = 0; (*z_var)->value.str.val = estrdup(c); } } %typemap(varout) char * { zval **z_var; char *s1; zend_hash_find(&EG(symbol_table), "$1", strlen("$1")+1, (void**)&z_var); s1 = Z_STRVAL_PP(z_var); if((s1 == NULL) || ($1 == NULL) || zend_binary_strcmp(s1, strlen(s1), $1, strlen($1) )) { if(s1) efree(s1); if($1) { (*z_var)->value.str.val = estrdup($1); (*z_var)->value.str.len = strlen($1) +1; } else { (*z_var)->value.str.val = 0; (*z_var)->value.str.len = 0; } } } %typemap(varout) SWIGTYPE { zval **z_var; zend_hash_find(&EG(symbol_table), "$1", strlen("$1")+1, (void**)&z_var); SWIG_SetPointerZval(*z_var, (void*)&$1, $&1_descriptor, $owner); } %typemap(varout) SWIGTYPE [] { zval **z_var; zend_hash_find(&EG(symbol_table), "$1", strlen("$1")+1, (void**)&z_var); if($1) SWIG_SetPointerZval(*z_var, (void*)$1, $1_descriptor, $owner); } %typemap(varout) char [ANY] { zval **z_var; char *s1; deliberate error cos this code looks bogus to me zend_hash_find(&EG(symbol_table), "$1" ,strlen("$1")+1, (void**)&z_var); s1 = Z_STRVAL_PP(z_var); if((s1 == NULL) || zend_binary_strcmp(s1, strlen(s1), $1, strlen($1))) { if($1) { (*z_var)->value.str.val = estrdup($1); (*z_var)->value.str.len = strlen($1)+1; } else { (*z_var)->value.str.val = 0; (*z_var)->value.str.len = 0; } } } %typemap(varout) SWIGTYPE *, SWIGTYPE & { zval **z_var; zend_hash_find(&EG(symbol_table), "$1", strlen("$1")+1, (void**)&z_var); SWIG_SetPointerZval(*z_var, (void*)$1, $1_descriptor, $owner); } /* Typemaps for constants */ %typemap(consttab) int, unsigned int, short, unsigned short, long, unsigned long, unsigned char, signed char, bool, enum SWIGTYPE "REGISTER_LONG_CONSTANT( \"$symname\", $value, CONST_CS | CONST_PERSISTENT);"; %typemap(consttab) float, double "REGISTER_DOUBLE_CONSTANT(\"$symname\", $value, CONST_CS | CONST_PERSISTENT);"; %typemap(consttab) char, char * "REGISTER_STRING_CONSTANT(\"$symname\", \"$value\", CONST_CS | CONST_PERSISTENT);"; %typemap(consttab) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { char *cp; SWIG_SetPointerChar(&cp, (void*)$value, $1_descriptor); REGISTER_STRING_CONSTANT("$symname", cp, CONST_CS | CONST_PERSISTENT); } /* Some ANSI C typemaps */ %apply long { size_t }; /* php kewords */ /* please test and activate */ //%include "phpkw.swg" cableswig-0.1.0+git20150808.orig/SWIG/Lib/php4/php4run.swg0000644000175000000620000001550012561312227021302 0ustar stevestaff/* * php4.swg * * PHP4 runtime library * */ #ifdef __cplusplus extern "C" { #endif #include "zend.h" #include "zend_API.h" #include "php.h" /* These TSRMLS_ stuff should already be defined now, but with older php under redhat are not... */ #ifndef TSRMLS_D #define TSRMLS_D #endif #ifndef TSRMLS_DC #define TSRMLS_DC #endif #ifndef TSRMLS_C #define TSRMLS_C #endif #ifndef TSRMLS_CC #define TSRMLS_CC #endif #ifdef __cplusplus } #endif /* used to wrap returned objects in so we know whether they are newobject and need freeing, or not */ typedef struct _swig_object_wrapper { void * ptr; int newobject; } swig_object_wrapper; /* local scope self_constructors are set to 1 inside function wrappers which are also class constructors, so that the php4.swg output typemaps know whether or not to wrap returned objects in this_ptr or a new object */ int self_constructor=0; /* empty zend destructor for types without one */ static ZEND_RSRC_DTOR_FUNC(SWIG_landfill) {}; /* This one makes old swig style string pointers but the php module doesn't use these any more. This is just left here for old times sake and may go */ SWIGRUNTIME(void) SWIG_MakePtr(char *c, void *ptr, swig_type_info *ty) { static char hex[17] = "0123456789abcdef"; unsigned long p, s; char data[32], *r; r = data; p = (unsigned long) ptr; if (p > 0) { while (p > 0) { s = p & 0xf; *(r++) = hex[s]; p = p >> 4; } *r = '_'; while (r >= data) { *(c++) = *(r--); } strcpy (c, ty->name); } else { strcpy (c, "NULL"); } } SWIGRUNTIME(void) SWIG_SetPointerChar(char **c, void *ptr, swig_type_info *type) { char data[512]; SWIG_MakePtr(data, ptr, type); *c = estrdup(data); } #define SWIG_SetPointerZval(a,b,c,d) SWIG_ZTS_SetPointerZval(a,b,c,d, SWIG_module_entry TSRMLS_CC) SWIGRUNTIME(void) SWIG_ZTS_SetPointerZval(zval *z, void *ptr, swig_type_info *type, int newobject, zend_module_entry* module_entry TSRMLS_DC) { swig_object_wrapper *value=NULL; /* No need to call SWIG_MakePtr here! */ if (type->clientdata) { if (! (*(int *)(type->clientdata))) zend_error(E_ERROR, "Type: %s failed to register with zend",type->name); value=(swig_object_wrapper *)emalloc(sizeof(swig_object_wrapper)); value->ptr=ptr; value->newobject=newobject; ZEND_REGISTER_RESOURCE(z, value, *(int *)(type->clientdata)); return; } else { /* have to deal with old fashioned string pointer? but this should not get this far */ zend_error(E_ERROR, "Type: %s not registered with zend",type->name); } } /* This old-style routine converts an old string-pointer c into a real pointer ptr calling making appropriate casting functions according to ty We don't use this any more */ SWIGRUNTIME(int) SWIG_ConvertPtr_(char *c, void **ptr, swig_type_info *ty) { register int d; unsigned long p; swig_type_info *tc; if(c == NULL) { *ptr = 0; return 0; } p = 0; if (*c != '_') { *ptr = (void *) 0; if (strcmp(c,"NULL") == 0) { return 0; } else { goto type_error; } } c++; /* Extract hex value from pointer */ while ((d = *c)) { if ((d >= '0') && (d <= '9')) p = (p << 4) + (d - '0'); else if ((d >= 'a') && (d <= 'f')) p = (p << 4) + (d - ('a'-10)); else break; c++; } *ptr = (void *) p; if(ty) { tc = SWIG_TypeCheck(c,ty); if(!tc) goto type_error; *ptr = SWIG_TypeCast(tc, (void*)p); } return 0; type_error: return -1; } /* This is a new pointer conversion routine Taking the native pointer p (which would have been converted from the old string pointer) and it's php type id, and it's type name (which also would have come from the old string pointer) it converts it to ptr calling appropriate casting functions according to ty Sadly PHP has no API to find a type name from a type id, only from an instance of a resource of the type id, so we have to pass type_name as well. The two functions which might call this are: SWIG_ZTS_ConvertResourcePtr which gets the type name from the resource and the registered zend destructors for which we have one per type each with the type name hard wired in. */ SWIGRUNTIME(int) SWIG_ZTS_ConvertResourceData(void * p, int type, const char *type_name, void **ptr, swig_type_info *ty TSRMLS_DC) { swig_type_info *tc; if (ty) { if (! type_name) { /* can't convert p to ptr type ty if we don't know what type p is */ return -1; } else { /* convert and cast p from type_name to ptr as ty Need to sort out const-ness, can SWIG_TypeCast really not take a const? */ tc = SWIG_TypeCheck((char *)type_name,ty); if (!tc) return -1; *ptr = SWIG_TypeCast(tc, (void*)p); } } else { /* They don't care about the target type, so just pass on the pointer! */ *ptr = (void *) p; } return 0; } /* This function fills ptr with a pointer of type ty by extracting the pointer and type info from the resource in z. z must be a resource It uses SWIG_ZTS_ConvertResourceData to do the real work. */ SWIGRUNTIME(int) SWIG_ZTS_ConvertResourcePtr(zval *z, void **ptr, swig_type_info *ty TSRMLS_DC) { swig_object_wrapper *value; void *p; int type; char *type_name; value = (swig_object_wrapper *) zend_list_find(z->value.lval,&type); p = value->ptr; if (type==-1) return -1; type_name=zend_rsrc_list_get_rsrc_type(z->value.lval); return SWIG_ZTS_ConvertResourceData(p,type,type_name,ptr,ty TSRMLS_CC); } /* But in fact SWIG_ConvertPtr is the native interface for getting typed pointer values out of zvals. We need the TSRMLS_ macros for when we make PHP type calls later as we handle php resources */ #define SWIG_ConvertPtr(a,b,c) SWIG_ZTS_ConvertPtr(a,b,c TSRMLS_CC) /* We allow passing of a STRING or RESOURCE pointing to the object or an OBJECT whose _cPtr is a string or resource pointing to the object STRING pointers are very depracated */ SWIGRUNTIME(int) SWIG_ZTS_ConvertPtr(zval *z, void **ptr, swig_type_info *ty TSRMLS_DC) { char *c; zval *val; if(z == NULL) { *ptr = 0; return 0; } if (z->type==IS_OBJECT) { zval ** _cPtr; if (zend_hash_find(HASH_OF(z),"_cPtr",sizeof("_cPtr"),(void**)&_cPtr)==SUCCESS) { /* Don't co-erce to string if it isn't */ if ((*_cPtr)->type==IS_STRING) c = Z_STRVAL_PP(_cPtr); else if ((*_cPtr)->type==IS_RESOURCE) { return SWIG_ZTS_ConvertResourcePtr(*_cPtr,ptr,ty TSRMLS_CC); } else goto type_error; /* _cPtr was not string or resource property */ } else goto type_error; /* can't find property _cPtr */ } else if (z->type==IS_RESOURCE) { return SWIG_ZTS_ConvertResourcePtr(z,ptr,ty TSRMLS_CC); } else if (z->type==IS_STRING) { c = Z_STRVAL_P(z); return SWIG_ConvertPtr_(c,ptr,ty); } else goto type_error; type_error: return -1; } cableswig-0.1.0+git20150808.orig/SWIG/Lib/php4/std_common.i0000644000175000000620000000021312561312227021467 0ustar stevestaff// // SWIG typemaps for STL - common utilities // Luigi Ballabio // Aug 17, 2003 // // PHP implementation %apply size_t { std::size_t }; cableswig-0.1.0+git20150808.orig/SWIG/Lib/php4/typemaps.i0000644000175000000620000001202112561312227021167 0ustar stevestaff// // SWIG Typemap library // Richard Palmer // Oct 3, 2001 // // PHP4 implementation // // // This library provides standard typemaps for modifying SWIG's behavior. // With enough entries in this file, I hope that very few people actually // ever need to write a typemap. // %typemap(in) double *INPUT(double temp) { temp = (double) Z_DVAL_PP($input); $1 = &temp; } %typemap(in) float *INPUT(float temp) { temp = (float) Z_DVAL_PP($input); $1 = &temp; } %typemap(in) int *INPUT(int temp) { temp = (int) Z_LVAL_PP($input); $1 = &temp; } %typemap(in) short *INPUT(short temp) { temp = (short) Z_LVAL_PP($input); $1 = &temp; } %typemap(in) long *INPUT(long temp) { temp = (long) Z_LVAL_PP($input); $1 = &temp; } %typemap(in) unsigned int *INPUT(unsigned int temp) { temp = (unsigned int) Z_LVAL_PP($input); $1 = &temp; } %typemap(in) unsigned short *INPUT(unsigned short temp) { temp = (unsigned short) Z_LVAL_PP($input); $1 = &temp; } %typemap(in) unsigned long *INPUT(unsigned long temp) { temp = (unsigned long) Z_LVAL_PP($input); $1 = &temp; } %typemap(in) unsigned char *INPUT(unsigned char temp) { temp = (unsigned char) Z_LVAL_PP($input); $1 = &temp; } %typemap(in,numinputs=0) int *OUTPUT(int temp), short *OUTPUT(short temp), long *OUTPUT(long temp), unsigned int *OUTPUT(unsigned int temp), unsigned short *OUTPUT(unsigned short temp), unsigned long *OUTPUT(unsigned long temp), unsigned char *OUTPUT(unsigned char temp), float *OUTPUT(float temp), double *OUTPUT(double temp) { $1 = &temp; } %typemap(argout) int *OUTPUT, short *OUTPUT, long *OUTPUT, unsigned int *OUTPUT, unsigned short *OUTPUT, unsigned long *OUTPUT, unsigned char *OUTPUT { ZVAL_LONG($result,*($input)); } %typemap(argout) float *OUTPUT, double *OUTPUT { ZVAL_DOUBLE($result,*($input)); } %typemap(in) int *INOUT = int *INPUT; %typemap(in) short *INOUT = short *INPUT; %typemap(in) long *INOUT = long *INPUT; %typemap(in) unsigned *INOUT = unsigned *INPUT; %typemap(in) unsigned short *INOUT = unsigned short *INPUT; %typemap(in) unsigned long *INOUT = unsigned long *INPUT; %typemap(in) unsigned char *INOUT = unsigned char *INPUT; %typemap(in) float *INOUT = float *INPUT; %typemap(in) double *INOUT = double *INPUT; %typemap(argout) int *INOUT = int *OUTPUT; %typemap(argout) short *INOUT = short *OUTPUT; %typemap(argout) long *INOUT= long *OUTPUT; %typemap(argout) unsigned short *INOUT= unsigned short *OUTPUT; %typemap(argout) unsigned long *INOUT = unsigned long *OUTPUT; %typemap(argout) unsigned char *INOUT = unsigned char *OUTPUT; %typemap(argout) float *INOUT = float *OUTPUT; %typemap(argout) double *INOUT= double *OUTPUT; // REFERENCE // Accept Php references as pointers %typemap(in) double *REFERENCE (double dvalue) { if(!ParameterPassedByReference(ht, argvi)) { zend_error(E_WARNING, "Parameter wasn't passed by reference"); RETURN_NULL(); } dvalue = (double) (*$input)->value.dval; $1 = &dvalue; } %typemap(in) float *REFERENCE (float dvalue) { if(!ParameterPassedByReference(ht, argvi)) { zend_error(E_WARNING, "Parameter wasn't passed by reference"); RETURN_NULL(); } dvalue = (float) (*$input)->value.dval; $1 = &dvalue; } %typemap(in) int *REFERENCE (int dvalue) { if(!ParameterPassedByReference(ht, argvi)) { zend_error(E_WARNING, "Parameter wasn't passed by reference"); RETURN_NULL(); } dvalue = (int) (*$input)->value.lval; $1 = &dvalue; } %typemap(in) short *REFERENCE (short dvalue) { if(!ParameterPassedByReference(ht, argvi)) { zend_error(E_WARNING, "Parameter wasn't passed by reference"); RETURN_NULL(); } dvalue = (short) (*$input)->value.lval; $1 = &dvalue; } %typemap(in) long *REFERENCE (long dvalue) { if(!ParameterPassedByReference(ht, argvi)) { zend_error(E_WARNING, "Parameter wasn't passed by reference"); RETURN_NULL(); } dvalue = (long) (*$input)->value.lval; $1 = &dvalue; } %typemap(in) unsigned int *REFERENCE (unsigned int dvalue) { if(!ParameterPassedByReference(ht, argvi)) { zend_error(E_WARNING, "Parameter wasn't passed by reference"); RETURN_NULL(); } dvalue = (unsigned int) (*$input)->value.lval; $1 = &dvalue; } %typemap(in) unsigned short *REFERENCE (unsigned short dvalue) { if(!ParameterPassedByReference(ht, argvi)) { zend_error(E_WARNING, "Parameter wasn't passed by reference"); RETURN_NULL(); } dvalue = (unsigned short) $input->value.lval; $1 = &dvalue; } %typemap(in) unsigned long *REFERENCE (unsigned long dvalue) { if(!ParameterPassedByReference(ht, argvi)) { zend_error(E_WARNING, "Parameter wasn't passed by reference"); RETURN_NULL(); } dvalue = (unsigned long) $input->value.lval; $1 = &dvalue; } %typemap(argout) double *REFERENCE, float *REFERENCE { $1->value.dval = (double)(*$arg); $1->type = IS_DOUBLE; } %typemap(argout) int *REFERENCE, short *REFERENCE, long *REFERENCE, unsigned int *REFERENCE, unsigned short *REFERENCE, unsigned long *REFERENCE { (*$arg)->value.lval = (long)(*$input); (*$arg)->type = IS_LONG; } cableswig-0.1.0+git20150808.orig/SWIG/Lib/php4/std_pair.i0000644000175000000620000000100612561312227021133 0ustar stevestaff// // SWIG typemaps for std::pair // Luigi Ballabio // July 2003 // // Common implementation %include std_common.i %include exception.i // ------------------------------------------------------------------------ // std::pair // ------------------------------------------------------------------------ %{ #include %} // exported class namespace std { template struct pair { // add typemaps here T first; U second; }; // add specializations here } cableswig-0.1.0+git20150808.orig/SWIG/Lib/php4/std_vector.i0000644000175000000620000001110212561312227021500 0ustar stevestaff// // SWIG typemaps for std::vector types // Luigi Ballabio // May 7, 2002 // // PHP implementation %include exception.i // containers // methods which can raise are caused to throw an IndexError %exception std::vector::get { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::vector::set { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::vector::pop { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } // ------------------------------------------------------------------------ // std::vector // // The aim of all that follows would be to integrate std::vector with // PHP as much as possible, namely, to allow the user to pass and // be returned PHP lists. // const declarations are used to guess the intent of the function being // exported; therefore, the following rationale is applied: // // -- f(std::vector), f(const std::vector&), f(const std::vector*): // the parameter being read-only, either a PHP sequence or a // previously wrapped std::vector can be passed. // -- f(std::vector&), f(std::vector*): // the parameter must be modified; therefore, only a wrapped std::vector // can be passed. // -- std::vector f(): // the vector is returned by copy; therefore, a PHP sequence of T:s // is returned which is most easily used in other PHP functions // -- std::vector& f(), std::vector* f(), const std::vector& f(), // const std::vector* f(): // the vector is returned by reference; therefore, a wrapped std::vector // is returned // ------------------------------------------------------------------------ %{ #include #include #include %} // exported class namespace std { template class vector { // add generic typemaps here public: vector(unsigned int size = 0); unsigned int size() const; bool empty() const; void clear(); %rename(push) push_back; void push_back(const T& x); %extend { T pop() { if (self->size() == 0) throw std::out_of_range("pop from empty vector"); T x = self->back(); self->pop_back(); return x; } T& get(int i) { int size = int(self->size()); if (i>=0 && isize()); if (i>=0 && i class vector { // add specialized typemaps here public: vector(unsigned int size = 0); unsigned int size() const; bool empty() const; void clear(); %rename(push) push_back; void push_back(T x); %extend { T pop() { if (self->size() == 0) throw std::out_of_range("pop from empty vector"); T x = self->back(); self->pop_back(); return x; } T get(int i) { int size = int(self->size()); if (i>=0 && isize()); if (i>=0 && itype==IS_STRING || (*$input)->type==IS_LONG || /* Null passed by reference means we want a value back */ (*$input)->type==IS_NULL || (*$input)->type==IS_BOOL || (*$input)->type==IS_DOUBLE) { // Only pass back if we can... if (PZVAL_IS_REF(*$input)) force=1; else force=0; convert_to_string_ex($input); // Init temp buffer strncpy((char *)temp,Z_STRVAL_PP($input),sizeof(BUFFER)); $1=temp; } else { force=0; $1=NULL; zend_error(E_ERROR, "Type error in argument %d of $symname. Expected %s or at least something looking vaguely like a string hopefully passed by reference", $argnum-argbase, $1_descriptor->name); } %enddef // strbufsize_inout defines a typemap which // Example: strbufsize_inout(UCHAR FAR * szErrorMsg, SWORD cbErrorMsgMax,1024) // defines a typeemap for UCHAR FAR * szErrorMsg, SWORD cbErrorMsgMax with a // max buffer size of 1024 %define strbufsize_inout(BUFFER,SIZE,MAXSIZE) %typemap(in) (BUFFER, SIZE) ($*1_ltype temp[MAXSIZE], int force) { _strbuf_in(temp) $2=sizeof(temp); } %typemap(argout) (BUFFER, SIZE) { _strbuf_out((char *)temp,strlen(temp)) } %enddef // char array can be in/out, though the passed string may not be big enough... // so we have to size it // e.g. Do: strarray_inout(char [ANY]) %define strarray_inout(TYPE) %typemap(in) TYPE ($*1_ltype temp[$1_dim0], int force) %{ _strbuf_in(temp) %} %typemap(argout) TYPE %{ _strbuf_out((char *)temp,$1_dim0); %} %enddef %define strarraysize_inout(TYPE,SIZE) %typemap(in) TYPE ($*1_ltype temp[SIZE], int force) %{ _strbuf_in(temp) %} %typemap(argout) TYPE %{ _strbuf_out((char *)temp,SIZE); %} %enddef %define strbuf_inout(BUFFER,MAXSIZE) %typemap(in) (BUFFER) ($*1_ltype temp[MAXSIZE], int force) { _strbuf_in(temp) } %typemap(argout) (BUFFER) { _strbuf_out(temp,strlen(temp)) } %enddef /* Typemap for in/argout references NOTE: we don't choose to use these for arrays yet, maybe later */ %define outLONG(ZVALARG,CARG) ZVAL_LONG(*$arg,intr$argnum); %enddef // Defines an on/argout typemap for ordinal types //Usage: %typemap_inout_ord(bool,convert_to_bool_ex,ZVAL_BOOL) %define %typemap_inout_ord(TYPES,TYPE_IN,TYPE_OUT) %typemap(in) TYPES * ($*1_ltype intr, int force), TYPES & ($*1_ltype intr, int force) %{ /* inout typemap for TYPES using TYPE_IN and TYPE_OUT */ if(SWIG_ConvertPtr(*$input, (void **) &$1, $1_descriptor) < 0) { /* So... we didn't get a ref or ptr, but can it be reasonably co-erced into what we were looking for a ref of or ptr to? */ if (!PZVAL_IS_REF(*$input) && (*$input)->type==IS_NULL) { // null passed not by reference means pass NULL $1 = NULL; force=0; } else if (PZVAL_IS_REF(*$input) && ((*$input)->type==IS_STRING || (*$input)->type==IS_LONG || /* Null passed by reference means we want a value back */ (*$input)->type==IS_NULL || (*$input)->type==IS_BOOL || (*$input)->type==IS_DOUBLE)) { TYPE_IN($input); intr = ($*1_ltype) (*$input)->value.lval; $1 = &intr; /* have to passback arg$arg too */ force=1; } else { /* wasn't a pre/ref/thing, OR anything like an int thing */ force=0; zend_error(E_ERROR, "Type error in argument %d of $symname. Expected %s or at least something looking vaguely like a number hopefully passed by reference", $argnum-argbase, $1_descriptor->name); } } else force=0; %} %typemap(argout) TYPES *, TYPES & %{ if (force$argnum) { /* pass back arg$argnum through params ($arg) if we can */ if(! PZVAL_IS_REF(*$arg)) { zend_error(E_WARNING, "Parameter %d of $symname wasn't passed by reference [argout TYPES *, TYPES &]",$argnum-argbase); } else { TYPE_OUT(*$arg,intr$argnum); } } %} %enddef cableswig-0.1.0+git20150808.orig/SWIG/Lib/php4/php4kw.swg0000644000175000000620000000263512561312227021124 0ustar stevestaff#ifndef __php_phpkw_swg__ #define __php_phpkw_swg__ /* Warnings for Php keywords */ #define PHPKW(x) %namewarn("314:" #x " is a php keyword") #x /* from http://aspn.activestate.com/ASPN/docs/PHP/reserved.html */ PHPKW(and); PHPKW($argc); PHPKW($argv); PHPKW(as); PHPKW(break); PHPKW(case); PHPKW(cfunction); PHPKW(class); PHPKW(continue); PHPKW(declare); PHPKW(default); PHPKW(die); PHPKW(do); PHPKW(E_ALL); PHPKW(echo); PHPKW(E_ERROR); PHPKW(else); PHPKW(elseif); PHPKW(enddeclare); PHPKW(endfor); PHPKW(endforeach); PHPKW(endif); PHPKW(endswitch); PHPKW(endwhile); PHPKW(E_PARSE); PHPKW(eval); PHPKW(E_WARNING); PHPKW(exit); PHPKW(extends); PHPKW(FALSE); PHPKW(__FILE__); PHPKW(for); PHPKW(foreach); PHPKW(function); PHPKW(global); PHPKW($HTTP_COOKIE_VARS); PHPKW($HTTP_ENV_VARS); PHPKW($HTTP_GET_VARS); PHPKW($HTTP_POST_FILES); PHPKW($HTTP_POST_VARS); PHPKW($HTTP_SERVER_VARS); PHPKW(if); PHPKW(include); PHPKW(include_once); PHPKW(__LINE__); PHPKW(list); PHPKW(new); PHPKW(not); PHPKW(NULL); PHPKW(old_function); PHPKW(or); PHPKW(parent); PHPKW(PHP_OS); PHPKW($PHP_SELF); PHPKW(PHP_VERSION); PHPKW(print); PHPKW(require); PHPKW(require_once); PHPKW(return); PHPKW(__sleep); PHPKW(static); PHPKW(stdClass); PHPKW(switch); PHPKW($this); PHPKW(TRUE); PHPKW(var); PHPKW(virtual); PHPKW(__wakeup); PHPKW(while); PHPKW(xor); // This is conflicting with _std_deque.i!. PHPKW(empty); #undef PHPKW #endif //__php_phpkw_swg__ cableswig-0.1.0+git20150808.orig/SWIG/Lib/php4/precommon.swg0000644000175000000620000000135412561312227021703 0ustar stevestaff/*************************************************************** -*- c -*- * php4/precommon.swg * * Rename all exported symbols from common.swg, to avoid symbol * clashes if multiple interpreters are included * ************************************************************************/ #define SWIG_TypeRegister SWIG_PHP4_TypeRegister #define SWIG_TypeCheck SWIG_PHP4_TypeCheck #define SWIG_TypeCast SWIG_PHP4_TypeCast #define SWIG_TypeDynamicCast SWIG_PHP4_TypeDynamicCast #define SWIG_TypeName SWIG_PHP4_TypeName #define SWIG_TypeQuery SWIG_PHP4_TypeQuery #define SWIG_TypeClientData SWIG_PHP4_TypeClientData #define SWIG_PackData SWIG_PHP4_PackData #define SWIG_UnpackData SWIG_PHP4_UnpackData cableswig-0.1.0+git20150808.orig/SWIG/Lib/constraints.i0000644000175000000620000001427512561312227021036 0ustar stevestaff// // SWIG constraint library // Dave Beazley // May 4, 1997 // // This library file contains typemaps for implementing various kinds of // constraints. Depends upon the SWIG exception library for generating // errors in a language-independent manner. #ifdef AUTODOC %text %{ %include constraints.i This library provides support for applying constraints to function arguments. Using a constraint, you can restrict arguments to be positive numbers, non-NULL pointers, and so on. The following constraints are available : Number POSITIVE - Positive number (not zero) Number NEGATIVE - Negative number (not zero) Number NONZERO - Nonzero number Number NONNEGATIVE - Positive number (including zero) Number NONPOSITIVE - Negative number (including zero) Pointer NONNULL - Non-NULL pointer Pointer ALIGN8 - 8-byte aligned pointer Pointer ALIGN4 - 4-byte aligned pointer Pointer ALIGN2 - 2-byte aligned pointer To use the constraints, you need to "apply" them to specific function arguments in your code. This is done using the %apply directive. For example : %apply Number NONNEGATIVE { double nonneg }; double sqrt(double nonneg); // Name of argument must match %apply Pointer NONNULL { void *ptr }; void *malloc(int POSITIVE); // May return a NULL pointer void free(void *ptr); // May not accept a NULL pointer Any function argument of the type you specify with the %apply directive will be checked with the appropriate constraint. Multiple types may be specified as follows : %apply Pointer NONNULL { void *, Vector *, List *, double *}; In this case, all of the types listed would be checked for non-NULL pointers. The common datatypes of int, short, long, unsigned int, unsigned long, unsigned short, unsigned char, signed char, float, and double can be checked without using the %apply directive by simply using the constraint name as the parameter name. For example : double sqrt(double NONNEGATIVE); double log(double POSITIVE); If you have used typedef to change type-names, you can also do this : %apply double { Real }; // Make everything defined for doubles // work for Reals. Real sqrt(Real NONNEGATIVE); Real log(Real POSITIVE); %} #endif %include exception.i // Positive numbers %typemap(check) int POSITIVE, short POSITIVE, long POSITIVE, unsigned int POSITIVE, unsigned short POSITIVE, unsigned long POSITIVE, signed char POSITIVE, unsigned char POSITIVE, float POSITIVE, double POSITIVE, Number POSITIVE { if ($1 <= 0) { SWIG_exception(SWIG_ValueError,"Expected a positive value."); } } // Negative numbers %typemap(check) int NEGATIVE, short NEGATIVE, long NEGATIVE, unsigned int NEGATIVE, unsigned short NEGATIVE, unsigned long NEGATIVE, signed char NEGATIVE, unsigned char NEGATIVE, float NEGATIVE, double NEGATIVE, Number NEGATIVE { if ($1 >= 0) { SWIG_exception(SWIG_ValueError,"Expected a negative value."); } } // Nonzero numbers %typemap(check) int NONZERO, short NONZERO, long NONZERO, unsigned int NONZERO, unsigned short NONZERO, unsigned long NONZERO, signed char NONZERO, unsigned char NONZERO, float NONZERO, double NONZERO, Number NONZERO { if ($1 == 0) { SWIG_exception(SWIG_ValueError,"Expected a nonzero value."); } } // Nonnegative numbers %typemap(check) int NONNEGATIVE, short NONNEGATIVE, long NONNEGATIVE, unsigned int NONNEGATIVE, unsigned short NONNEGATIVE, unsigned long NONNEGATIVE, signed char NONNEGATIVE, unsigned char NONNEGATIVE, float NONNEGATIVE, double NONNEGATIVE, Number NONNEGATIVE { if ($1 < 0) { SWIG_exception(SWIG_ValueError,"Expected a non-negative value."); } } // Nonpositive numbers %typemap(check) int NONPOSITIVE, short NONPOSITIVE, long NONPOSITIVE, unsigned int NONPOSITIVE, unsigned short NONPOSITIVE, unsigned long NONPOSITIVE, signed char NONPOSITIVE, unsigned char NONPOSITIVE, float NONPOSITIVE, double NONPOSITIVE, Number NONPOSITIVE { if ($1 > 0) { SWIG_exception(SWIG_ValueError,"Expected a non-positive value."); } } // Non-NULL pointer %typemap(check) void * NONNULL, Pointer NONNULL { if (!$1) { SWIG_exception(SWIG_ValueError,"Received a NULL pointer."); } } // Aligned pointers %typemap(check) void * ALIGN8, Pointer ALIGN8 { long tmp; tmp = (long) $1; if (tmp & 7) { SWIG_exception(SWIG_ValueError,"Pointer must be 8-byte aligned."); } } %typemap(check) void * ALIGN4, Pointer ALIGN4 { long tmp; tmp = (long) $1; if (tmp & 3) { SWIG_exception(SWIG_ValueError,"Pointer must be 4-byte aligned."); } } %typemap(check) void * ALIGN2, Pointer ALIGN2 { long tmp; tmp = (long) $1; if (tmp & 1) { SWIG_exception(SWIG_ValueError,"Pointer must be 2-byte aligned."); } } cableswig-0.1.0+git20150808.orig/SWIG/Lib/common.swg0000644000175000000620000001632012561312227020320 0ustar stevestaff/*********************************************************************** * 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_TypeRegister(swig_type_info *); SWIGIMPORT(swig_type_info *) SWIG_TypeCheck(char *c, swig_type_info *); SWIGIMPORT(void *) SWIG_TypeCast(swig_type_info *, void *); SWIGIMPORT(swig_type_info *) SWIG_TypeDynamicCast(swig_type_info *, void **); SWIGIMPORT(const char *) SWIG_TypeName(const swig_type_info *); SWIGIMPORT(swig_type_info *) SWIG_TypeQuery(const char *); SWIGIMPORT(void) SWIG_TypeClientData(swig_type_info *, void *); SWIGIMPORT(char *) SWIG_PackData(char *, void *, int); SWIGIMPORT(char *) SWIG_UnpackData(char *, void *, int); #else static swig_type_info *swig_type_list = 0; /* Register a type mapping with the type-checking */ SWIGRUNTIME(swig_type_info *) SWIG_TypeRegister(swig_type_info *ti) { swig_type_info *tc, *head, *ret, *next; /* Check to see if this type has already been registered */ tc = swig_type_list; while (tc) { if (strcmp(tc->name, ti->name) == 0) { /* 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 = swig_type_list; swig_type_list = 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(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); } /* 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 */ 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; } /* Set the clientdata field for a type */ SWIGRUNTIME(void) SWIG_TypeClientData(swig_type_info *ti, void *clientdata) { swig_type_info *tc, *equiv; if (ti->clientdata == clientdata) return; ti->clientdata = clientdata; equiv = ti->next; while (equiv) { if (!equiv->converter) { tc = swig_type_list; while (tc) { if ((strcmp(tc->name, equiv->name) == 0)) SWIG_TypeClientData(tc,clientdata); tc = tc->prev; } } equiv = equiv->next; } } /* 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 cableswig-0.1.0+git20150808.orig/SWIG/Lib/swigrun.i0000644000175000000620000000011212561312227020146 0ustar stevestaff%module swigrun // Empty module (for now). Placeholder for runtime libs cableswig-0.1.0+git20150808.orig/SWIG/Lib/math.i0000644000175000000620000000374612561312227017421 0ustar stevestaff/* * /cvsroot/SWIG/Lib/math.i,v 1.3 2002/11/30 22:10:07 beazley Exp * * math.i * Dave Beazley * March 24, 1996 * SWIG file for floating point operations * */ %module math %{ #include %} extern double cos(double x); /* Cosine of x */ extern double sin(double x); /* Sine of x */ extern double tan(double x); /* Tangent of x */ extern double acos(double x); /* Inverse cosine in range [-PI/2,PI/2], x in [-1,1]. */ extern double asin(double x); /* Inverse sine in range [0,PI], x in [-1,1]. */ extern double atan(double x); /* Inverse tangent in range [-PI/2,PI/2]. */ extern double atan2(double y, double x); /* Inverse tangent of y/x in range [-PI,PI]. */ extern double cosh(double x); /* Hyperbolic cosine of x */ extern double sinh(double x); /* Hyperbolic sine of x */ extern double tanh(double x); /* Hyperbolic tangent of x */ extern double exp(double x); /* Natural exponential function e^x */ extern double log(double x); /* Natural logarithm ln(x), x > 0 */ extern double log10(double x); /* Base 10 logarithm, x > 0 */ extern double pow(double x, double y); /* Power function x^y. */ extern double sqrt(double x); /* Square root. x >= 0 */ extern double fabs(double x); /* Absolute value of x */ extern double ceil(double x); /* Smallest integer not less than x, as a double */ extern double floor(double x); /* Largest integer not greater than x, as a double */ extern double fmod(double x, double y); /* Floating-point remainder of x/y, with the same sign as x. */ #define M_E 2.7182818284590452354 #define M_LOG2E 1.4426950408889634074 #define M_LOG10E 0.43429448190325182765 #define M_LN2 0.69314718055994530942 #define M_LN10 2.30258509299404568402 #define M_PI 3.14159265358979323846 #define M_PI_2 1.57079632679489661923 #define M_PI_4 0.78539816339744830962 #define M_1_PI 0.31830988618379067154 #define M_2_PI 0.63661977236758134308 #define M_2_SQRTPI 1.12837916709551257390 #define M_SQRT2 1.41421356237309504880 #define M_SQRT1_2 0.70710678118654752440 cableswig-0.1.0+git20150808.orig/SWIG/Lib/cstring.i0000644000175000000620000000011612561312227020125 0ustar stevestaff%echo "cstring.i not implemented for this target" #define _CSTRING_UNIMPL cableswig-0.1.0+git20150808.orig/SWIG/Lib/cpointer.i0000644000175000000620000000713412561312227020306 0ustar stevestaff/* ----------------------------------------------------------------------------- * cpointer.i * * Author(s): David Beazley (beazley@cs.uchicago.edu) * * This library file contains macros that can be used to manipulate simple * pointer objects. * * /cvsroot/SWIG/Lib/cpointer.i,v 1.3 2002/11/30 22:10:07 beazley Exp * ----------------------------------------------------------------------------- */ /* ----------------------------------------------------------------------------- * %pointer_class(type,name) * * Places a simple proxy around a simple type like 'int', 'float', or whatever. * The proxy provides this interface: * * class type { * public: * type(); * ~type(); * type value(); * void assign(type value); * }; * * Example: * * %pointer_class(int, intp); * * int add(int *x, int *y) { return *x + *y; } * * In python (with proxies) * * >>> a = intp() * >>> a.assign(10) * >>> a.value() * 10 * >>> b = intp() * >>> b.assign(20) * >>> print add(a,b) * 30 * * As a general rule, this macro should not be used on class/structures that * are already defined in the interface. * ----------------------------------------------------------------------------- */ %define %pointer_class(TYPE, NAME) %{ typedef TYPE NAME; %} typedef struct { } NAME; %extend NAME { #if __cplusplus NAME() { return new TYPE(); } ~NAME() { if (self) delete self; } #else NAME() { return (TYPE *) calloc(1,sizeof(TYPE)); } ~NAME() { if (self) free(self); } #endif } %extend NAME { void assign(TYPE value) { *self = value; } TYPE value() { return *self; } TYPE * cast() { return self; } static NAME * frompointer(TYPE *t) { return (NAME *) t; } } %types(NAME = TYPE); %enddef /* ----------------------------------------------------------------------------- * %pointer_functions(type,name) * * Create functions for allocating/deallocating pointers. This can be used * if you don't want to create a proxy class or if the pointer is complex. * * %pointer_functions(int, intp) * * int add(int *x, int *y) { return *x + *y; } * * In python (with proxies) * * >>> a = copy_intp(10) * >>> intp_value(a) * 10 * >>> b = new_intp() * >>> intp_assign(b,20) * >>> print add(a,b) * 30 * >>> delete_intp(a) * >>> delete_intp(b) * * ----------------------------------------------------------------------------- */ %define %pointer_functions(TYPE,NAME) %{ static TYPE *new_##NAME() { %} #if __cplusplus %{ return new TYPE(); %} #else %{ return (TYPE *) calloc(1,sizeof(TYPE)); %} #endif %{} static TYPE *copy_##NAME(TYPE value) { %} #if __cplusplus %{ return new TYPE(value); %} #else %{ TYPE *self = (TYPE *) calloc(1,sizeof(TYPE)); *self = value; return self; %} #endif %{} static void delete_##NAME(TYPE *self) { %} #if __cplusplus %{ if (self) delete self; %} #else %{ if (self) free(self); %} #endif %{} static void NAME ##_assign(TYPE *self, TYPE value) { *self = value; } static TYPE NAME ##_value(TYPE *self) { return *self; } %} TYPE *new_##NAME(); TYPE *copy_##NAME(TYPE value); void delete_##NAME(TYPE *self); void NAME##_assign(TYPE *self, TYPE value); TYPE NAME##_value(TYPE *self); %enddef /* ----------------------------------------------------------------------------- * %pointer_cast(type1,type2,name) * * Generates a pointer casting function. * ----------------------------------------------------------------------------- */ %define %pointer_cast(TYPE1,TYPE2,NAME) %inline %{ TYPE2 NAME(TYPE1 x) { return (TYPE2) x; } %} %enddef cableswig-0.1.0+git20150808.orig/SWIG/Lib/xml/0002755000175000000620000000000012561312227017106 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Lib/xml/typemaps.i0000644000175000000620000003030612561312227021122 0ustar stevestaff// // SWIG Typemap library // Dave Beazley // May 5, 1997 // // Perl5 implementation // // This library provides standard typemaps for modifying SWIG's behavior. // With enough entries in this file, I hope that very few people actually // ever need to write a typemap. // #ifdef AUTODOC %section "Typemap Library (Perl 5)",info,after,pre,nosort,skip=1,chop_left=3,chop_right=0,chop_top=0,chop_bottom=0 %text %{ %include typemaps.i The SWIG typemap library provides a language independent mechanism for supporting output arguments, input values, and other C function calling mechanisms. The primary use of the library is to provide a better interface to certain C function--especially those involving pointers. %} #endif // ------------------------------------------------------------------------ // Pointer handling // // These mappings provide support for input/output arguments and common // uses for C/C++ pointers. // ------------------------------------------------------------------------ // INPUT typemaps. // These remap a C pointer to be an "INPUT" value which is passed by value // instead of reference. #ifdef AUTODOC %subsection "Input Methods" %text %{ The following methods can be applied to turn a pointer into a simple "input" value. That is, instead of passing a pointer to an object, you would use a real value instead. int *INPUT short *INPUT long *INPUT unsigned int *INPUT unsigned short *INPUT unsigned long *INPUT unsigned char *INPUT float *INPUT double *INPUT To use these, suppose you had a C function like this : double fadd(double *a, double *b) { return *a+*b; } You could wrap it with SWIG as follows : %include typemaps.i double fadd(double *INPUT, double *INPUT); or you can use the %apply directive : %include typemaps.i %apply double *INPUT { double *a, double *b }; double fadd(double *a, double *b); %} #endif %typemap(perl5,in) double *INPUT(double temp) { temp = (double) SvNV($source); $target = &temp; } %typemap(perl5,in) float *INPUT(float temp) { temp = (float) SvNV($source); $target = &temp; } %typemap(perl5,in) int *INPUT(int temp) { temp = (int) SvIV($source); $target = &temp; } %typemap(perl5,in) short *INPUT(short temp) { temp = (short) SvIV($source); $target = &temp; } %typemap(perl5,in) long *INPUT(long temp) { temp = (long) SvIV($source); $target = &temp; } %typemap(perl5,in) unsigned int *INPUT(unsigned int temp) { temp = (unsigned int) SvIV($source); $target = &temp; } %typemap(perl5,in) unsigned short *INPUT(unsigned short temp) { temp = (unsigned short) SvIV($source); $target = &temp; } %typemap(perl5,in) unsigned long *INPUT(unsigned long temp) { temp = (unsigned long) SvIV($source); $target = &temp; } %typemap(perl5,in) unsigned char *INPUT(unsigned char temp) { temp = (unsigned char) SvIV($source); $target = &temp; } // OUTPUT typemaps. These typemaps are used for parameters that // are output only. The output value is appended to the result as // a list element. #ifdef AUTODOC %subsection "Output Methods" %text %{ The following methods can be applied to turn a pointer into an "output" value. When calling a function, no input value would be given for a parameter, but an output value would be returned. In the case of multiple output values, functions will return a Perl array. int *OUTPUT short *OUTPUT long *OUTPUT unsigned int *OUTPUT unsigned short *OUTPUT unsigned long *OUTPUT unsigned char *OUTPUT float *OUTPUT double *OUTPUT For example, suppose you were trying to wrap the modf() function in the C math library which splits x into integral and fractional parts (and returns the integer part in one of its parameters).K: double modf(double x, double *ip); You could wrap it with SWIG as follows : %include typemaps.i double modf(double x, double *OUTPUT); or you can use the %apply directive : %include typemaps.i %apply double *OUTPUT { double *ip }; double modf(double x, double *ip); The Perl output of the function would be an array containing both output values. %} #endif // Force the argument to be ignored. %typemap(perl5,ignore) int *OUTPUT(int temp), short *OUTPUT(short temp), long *OUTPUT(long temp), unsigned int *OUTPUT(unsigned int temp), unsigned short *OUTPUT(unsigned short temp), unsigned long *OUTPUT(unsigned long temp), unsigned char *OUTPUT(unsigned char temp), float *OUTPUT(float temp), double *OUTPUT(double temp) { $target = &temp; } %typemap(perl5,argout) int *OUTPUT, short *OUTPUT, long *OUTPUT, unsigned int *OUTPUT, unsigned short *OUTPUT, unsigned long *OUTPUT, unsigned char *OUTPUT { if (argvi >= items) { EXTEND(sp,1); } $target = sv_newmortal(); sv_setiv($target,(IV) *($source)); argvi++; } %typemap(perl5,argout) float *OUTPUT, double *OUTPUT { if (argvi >= items) { EXTEND(sp,1); } $target = sv_newmortal(); sv_setnv($target,(double) *($source)); argvi++; } // BOTH // Mappings for an argument that is both an input and output // parameter #ifdef AUTODOC %subsection "Input/Output Methods" %text %{ The following methods can be applied to make a function parameter both an input and output value. This combines the behavior of both the "INPUT" and "OUTPUT" methods described earlier. Output values are returned in the form of a Tcl list. int *BOTH short *BOTH long *BOTH unsigned int *BOTH unsigned short *BOTH unsigned long *BOTH unsigned char *BOTH float *BOTH double *BOTH For example, suppose you were trying to wrap the following function : void neg(double *x) { *x = -(*x); } You could wrap it with SWIG as follows : %include typemaps.i void neg(double *BOTH); or you can use the %apply directive : %include typemaps.i %apply double *BOTH { double *x }; void neg(double *x); Unlike C, this mapping does not directly modify the input value. Rather, the modified input value shows up as the return value of the function. Thus, to apply this function to a Perl variable you might do this : $x = neg($x); %} #endif %typemap(perl5,in) int *BOTH = int *INPUT; %typemap(perl5,in) short *BOTH = short *INPUT; %typemap(perl5,in) long *BOTH = long *INPUT; %typemap(perl5,in) unsigned *BOTH = unsigned *INPUT; %typemap(perl5,in) unsigned short *BOTH = unsigned short *INPUT; %typemap(perl5,in) unsigned long *BOTH = unsigned long *INPUT; %typemap(perl5,in) unsigned char *BOTH = unsigned char *INPUT; %typemap(perl5,in) float *BOTH = float *INPUT; %typemap(perl5,in) double *BOTH = double *INPUT; %typemap(perl5,argout) int *BOTH = int *OUTPUT; %typemap(perl5,argout) short *BOTH = short *OUTPUT; %typemap(perl5,argout) long *BOTH = long *OUTPUT; %typemap(perl5,argout) unsigned *BOTH = unsigned *OUTPUT; %typemap(perl5,argout) unsigned short *BOTH = unsigned short *OUTPUT; %typemap(perl5,argout) unsigned long *BOTH = unsigned long *OUTPUT; %typemap(perl5,argout) unsigned char *BOTH = unsigned char *OUTPUT; %typemap(perl5,argout) float *BOTH = float *OUTPUT; %typemap(perl5,argout) double *BOTH = double *OUTPUT; // REFERENCE // Accept Perl references as pointers #ifdef AUTODOC %subsection "Reference Methods" %text %{ The following methods make Perl references work like simple C pointers. References can only be used for simple input/output values, not C arrays however. It should also be noted that REFERENCES are specific to Perl and not supported in other scripting languages at this time. int *REFERENCE short *REFERENCE long *REFERENCE unsigned int *REFERENCE unsigned short *REFERENCE unsigned long *REFERENCE unsigned char *REFERENCE float *REFERENCE double *REFERENCE For example, suppose you were trying to wrap the following function : void neg(double *x) { *x = -(*x); } You could wrap it with SWIG as follows : %include typemaps.i void neg(double *REFERENCE); or you can use the %apply directive : %include typemaps.i %apply double *REFERENCE { double *x }; void neg(double *x); Unlike the BOTH mapping described previous, this approach directly modifies the value of a Perl reference. Thus, you could use it as follows : $x = 3; neg(\$x); print "$x\n"; # Should print out -3. %} #endif %typemap(perl5,in) double *REFERENCE (double dvalue) { SV *tempsv; if (!SvROK($source)) { croak("expected a reference"); } tempsv = SvRV($source); if ((!SvNOK(tempsv)) && (!SvIOK(tempsv))) { printf("Received %d\n", SvTYPE(tempsv)); croak("Expected a double reference."); } dvalue = SvNV(tempsv); $target = &dvalue; } %typemap(perl5,in) float *REFERENCE (float dvalue) { SV *tempsv; if (!SvROK($source)) { croak("expected a reference"); } tempsv = SvRV($source); if ((!SvNOK(tempsv)) && (!SvIOK(tempsv))) { croak("expected a double reference"); } dvalue = (float) SvNV(tempsv); $target = &dvalue; } %typemap(perl5,in) int *REFERENCE (int dvalue) { SV *tempsv; if (!SvROK($source)) { croak("expected a reference"); } tempsv = SvRV($source); if (!SvIOK(tempsv)) { croak("expected a integer reference"); } dvalue = SvIV(tempsv); $target = &dvalue; } %typemap(perl5,in) short *REFERENCE (short dvalue) { SV *tempsv; if (!SvROK($source)) { croak("expected a reference"); } tempsv = SvRV($source); if (!SvIOK(tempsv)) { croak("expected a integer reference"); } dvalue = (short) SvIV(tempsv); $target = &dvalue; } %typemap(perl5,in) long *REFERENCE (long dvalue) { SV *tempsv; if (!SvROK($source)) { croak("expected a reference"); } tempsv = SvRV($source); if (!SvIOK(tempsv)) { croak("expected a integer reference"); } dvalue = (long) SvIV(tempsv); $target = &dvalue; } %typemap(perl5,in) unsigned int *REFERENCE (unsigned int dvalue) { SV *tempsv; if (!SvROK($source)) { croak("expected a reference"); } tempsv = SvRV($source); if (!SvIOK(tempsv)) { croak("expected a integer reference"); } dvalue = (unsigned int) SvIV(tempsv); $target = &dvalue; } %typemap(perl5,in) unsigned short *REFERENCE (unsigned short dvalue) { SV *tempsv; if (!SvROK($source)) { croak("expected a reference"); } tempsv = SvRV($source); if (!SvIOK(tempsv)) { croak("expected a integer reference"); } dvalue = (unsigned short) SvIV(tempsv); $target = &dvalue; } %typemap(perl5,in) unsigned long *REFERENCE (unsigned long dvalue) { SV *tempsv; if (!SvROK($source)) { croak("expected a reference"); } tempsv = SvRV($source); if (!SvIOK(tempsv)) { croak("expected a integer reference"); } dvalue = (unsigned long) SvIV(tempsv); $target = &dvalue; } %typemap(perl5,argout) double *REFERENCE, float *REFERENCE { SV *tempsv; tempsv = SvRV($arg); sv_setnv(tempsv, (double) *$source); } %typemap(perl5,argout) int *REFERENCE, short *REFERENCE, long *REFERENCE, unsigned int *REFERENCE, unsigned short *REFERENCE, unsigned long *REFERENCE { SV *tempsv; tempsv = SvRV($arg); sv_setiv(tempsv, (int) *$source); } // -------------------------------------------------------------------- // Special types // // -------------------------------------------------------------------- cableswig-0.1.0+git20150808.orig/SWIG/Lib/xml/xml.swg0000644000175000000620000000002512561312227020423 0ustar stevestaff/* nothing special */cableswig-0.1.0+git20150808.orig/SWIG/Lib/cmalloc.i0000644000175000000620000000426612561312227020100 0ustar stevestaff/* ----------------------------------------------------------------------------- * cmalloc.i * * Author(s): David Beazley (beazley@cs.uchicago.edu) * * This library file contains macros that can be used to create objects using * the C malloc function. * * /cvsroot/SWIG/Lib/cmalloc.i,v 1.3 2002/11/30 22:10:07 beazley Exp * ----------------------------------------------------------------------------- */ %{ #include %} /* %malloc(TYPE [, NAME = TYPE]) %calloc(TYPE [, NAME = TYPE]) %realloc(TYPE [, NAME = TYPE]) %free(TYPE [, NAME = TYPE]) %allocators(TYPE [,NAME = TYPE]) Creates functions for allocating/reallocating memory. TYPE *malloc_NAME(int nbytes = sizeof(TYPE); TYPE *calloc_NAME(int nobj=1, int size=sizeof(TYPE)); TYPE *realloc_NAME(TYPE *ptr, int nbytes); void free_NAME(TYPE *ptr); */ %define %malloc(TYPE,...) #if #__VA_ARGS__ != "" %name(malloc_##__VA_ARGS__) #else %name(malloc_##TYPE) #endif TYPE *malloc(int nbytes #if #TYPE != "void" = sizeof(TYPE) #endif ); %enddef %define %calloc(TYPE,...) #if #__VA_ARGS__ != "" %name(calloc_##__VA_ARGS__) #else %name(calloc_##TYPE) #endif TYPE *calloc(int nobj = 1, int sz = #if #TYPE != "void" sizeof(TYPE) #else 1 #endif ); %enddef %define %realloc(TYPE,...) %insert("header") { #if #__VA_ARGS__ != "" TYPE *realloc_##__VA_ARGS__(TYPE *ptr, int nitems) #else TYPE *realloc_##TYPE(TYPE *ptr, int nitems) #endif { #if #TYPE != "void" return (TYPE *) realloc(ptr, nitems*sizeof(TYPE)); #else return (TYPE *) realloc(ptr, nitems); #endif } } #if #__VA_ARGS__ != "" TYPE *realloc_##__VA_ARGS__(TYPE *ptr, int nitems); #else TYPE *realloc_##TYPE(TYPE *ptr, int nitems); #endif %enddef %define %free(TYPE,...) #if #__VA_ARGS__ != "" %name(free_##__VA_ARGS__) void free(TYPE *ptr); #else %name(free_##TYPE) void free(TYPE *ptr); #endif %enddef %define %sizeof(TYPE,...) #if #__VA_ARGS__ != "" %constant int sizeof_##__VA_ARGS__ = sizeof(TYPE); #else %constant int sizeof_##TYPE = sizeof(TYPE); #endif %enddef %define %allocators(TYPE,...) %malloc(TYPE,__VA_ARGS__) %calloc(TYPE,__VA_ARGS__) %realloc(TYPE,__VA_ARGS__) %free(TYPE,__VA_ARGS__) #if #TYPE != "void" %sizeof(TYPE,__VA_ARGS__) #endif %enddef cableswig-0.1.0+git20150808.orig/SWIG/Lib/csharp/0002755000175000000620000000000012561312227017566 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Lib/csharp/csharp.swg0000644000175000000620000004247112561312227021576 0ustar stevestaff/* ----------------------------------------------------------------------------- * csharp.swg * * CSharp typemaps * ----------------------------------------------------------------------------- */ %include "csharphead.swg" /* The ctype, imtype and cstype typemaps work together and so there should be one of each. * The ctype typemap contains the PInvoke type used in the PInvoke (C/C++) code. * The imtype typemap contains the C# type used in the intermediary class. * The cstype typemap contains the C# type used in the C# proxy classes, type wrapper classes and module class. */ /* Primitive types */ %typemap(ctype) bool, const bool & "bool" %typemap(ctype) char, const char & "char" %typemap(ctype) signed char, const signed char & "signed char" %typemap(ctype) unsigned char, const unsigned char & "unsigned short" %typemap(ctype) short, const short & "short" %typemap(ctype) unsigned short, const unsigned short & "unsigned short" %typemap(ctype) int, const int & "int" %typemap(ctype) unsigned int, const unsigned int & "unsigned int" %typemap(ctype) long, const long & "long" %typemap(ctype) unsigned long, const unsigned long & "unsigned long" %typemap(ctype) long long, const long long & "long long" %typemap(ctype) unsigned long long, const unsigned long long & "unsigned long long" %typemap(ctype) float, const float & "float" %typemap(ctype) double, const double & "double" %typemap(ctype) char * "char *" %typemap(ctype) void "void" %typemap(imtype) bool, const bool & "bool" %typemap(imtype) char, const char & "char" %typemap(imtype) signed char, const signed char & "sbyte" %typemap(imtype) unsigned char, const unsigned char & "byte" %typemap(imtype) short, const short & "short" %typemap(imtype) unsigned short, const unsigned short & "ushort" %typemap(imtype) int, const int & "int" %typemap(imtype) unsigned int, const unsigned int & "uint" %typemap(imtype) long, const long & "int" %typemap(imtype) unsigned long, const unsigned long & "uint" %typemap(imtype) long long, const long long & "long" %typemap(imtype) unsigned long long, const unsigned long long & "ulong" %typemap(imtype) float, const float & "float" %typemap(imtype) double, const double & "double" %typemap(imtype) char * "string" %typemap(imtype) void "void" %typemap(cstype) bool, const bool & "bool" %typemap(cstype) char, const char & "char" %typemap(cstype) signed char, const signed char & "sbyte" %typemap(cstype) unsigned char, const unsigned char & "byte" %typemap(cstype) short, const short & "short" %typemap(cstype) unsigned short, const unsigned short & "ushort" %typemap(cstype) int, const int & "int" %typemap(cstype) unsigned int, const unsigned int & "uint" %typemap(cstype) long, const long & "int" %typemap(cstype) unsigned long, const unsigned long & "uint" %typemap(cstype) long long, const long long & "long" %typemap(cstype) unsigned long long, const unsigned long long & "ulong" %typemap(cstype) float, const float & "float" %typemap(cstype) double, const double & "double" %typemap(cstype) char * "string" %typemap(cstype) void "void" %typemap(ctype) char[ANY] "char *" %typemap(imtype) char[ANY] "string" %typemap(cstype) char[ANY] "string" /* Non primitive types */ %typemap(ctype) SWIGTYPE "void *" %typemap(imtype) SWIGTYPE "IntPtr" %typemap(cstype) SWIGTYPE "$&csclassname" %typemap(ctype) SWIGTYPE [] "void *" %typemap(imtype) SWIGTYPE [] "IntPtr" %typemap(cstype) SWIGTYPE [] "$csclassname" %typemap(ctype) SWIGTYPE * "void *" %typemap(imtype) SWIGTYPE * "IntPtr" %typemap(cstype) SWIGTYPE * "$csclassname" %typemap(ctype) SWIGTYPE & "void *" %typemap(imtype) SWIGTYPE & "IntPtr" %typemap(cstype) SWIGTYPE & "$csclassname" %typemap(ctype) enum SWIGTYPE "int" %typemap(imtype) enum SWIGTYPE "int" %typemap(cstype) enum SWIGTYPE "int" /* pointer to a class member */ %typemap(ctype) SWIGTYPE (CLASS::*) "int" %typemap(imtype) SWIGTYPE (CLASS::*) "IntPtr" %typemap(cstype) SWIGTYPE (CLASS::*) "$csclassname" /* The following are the in and out typemaps. These are the PInvoke code generating typemaps for converting from C# to C and visa versa. */ /* primitive types */ %typemap(in) bool %{ $1 = $input ? true : false; %} %typemap(in) char, signed char, unsigned char, short, unsigned short, int, unsigned int, long, unsigned long, long long, unsigned long long, float, double, enum SWIGTYPE %{ $1 = ($1_ltype)$input; %} %typemap(out) bool %{ $result = $1; %} %typemap(out) char %{ $result = $1; %} %typemap(out) signed char %{ $result = $1; %} %typemap(out) unsigned char %{ $result = $1; %} %typemap(out) short %{ $result = $1; %} %typemap(out) unsigned short %{ $result = $1; %} %typemap(out) int %{ $result = $1; %} %typemap(out) unsigned int %{ $result = $1; %} %typemap(out) long %{ $result = $1; %} %typemap(out) unsigned long %{ $result = $1; %} %typemap(out) long long %{ $result = $1; %} %typemap(out) unsigned long long %{ $result = $1; %} %typemap(out) float %{ $result = $1; %} %typemap(out) double %{ $result = $1; %} %typemap(out) enum SWIGTYPE %{ $result = $1; %} /* char * - treat as String */ %typemap(in) char * %{ $1 = $input; %} %typemap(out) char * %{ $result = $1; %} %typemap(out) void "" /* primitive types by const reference */ %typemap(in) const bool & (bool temp) %{ temp = $input ? true : false; $1 = &temp; %} %typemap(in) const char & (char temp), const signed char & (signed char temp), const unsigned char & (unsigned char temp), const short & (short temp), const unsigned short & (unsigned short temp), const int & (int temp), const unsigned int & (unsigned int temp), const long & (long temp), const unsigned long & (unsigned long temp), const long long & ($*1_ltype temp), const unsigned long long & ($*1_ltype temp), const float & (float temp), const double & (double temp) %{ temp = ($*1_ltype)$input; $1 = &temp; %} %typemap(out) const bool & %{ $result = *$1; %} %typemap(out) const char & %{ $result = *$1; %} %typemap(out) const signed char & %{ $result = *$1; %} %typemap(out) const unsigned char & %{ $result = *$1; %} %typemap(out) const short & %{ $result = *$1; %} %typemap(out) const unsigned short & %{ $result = *$1; %} %typemap(out) const int & %{ $result = *$1; %} %typemap(out) const unsigned int & %{ $result = *$1; %} %typemap(out) const long & %{ $result = *$1; %} %typemap(out) const unsigned long & %{ $result = *$1; %} %typemap(out) const long long & %{ $result = *$1; %} %typemap(out) const unsigned long long & %{ $result = *$1; %} %typemap(out) const float & %{ $result = *$1; %} %typemap(out) const double & %{ $result = *$1; %} /* Default handling. Object passed by value. Convert to a pointer */ %typemap(in) SWIGTYPE ($&1_type argp) %{ argp = ($&1_ltype)$input; if (!argp) { SWIG_CSharpThrowException(SWIG_CSharpNullReferenceException, "Attempt to dereference null $1_type"); } $1 = *argp; %} %typemap(out) SWIGTYPE #ifdef __cplusplus %{$result = new $1_ltype(($1_ltype &)$1); %} #else { $&1_ltype $1ptr = ($&1_ltype) malloc(sizeof($1_ltype)); memmove($1ptr, &$1, sizeof($1_type)); $result = $1ptr; } #endif /* Generic pointers and references */ %typemap(in) SWIGTYPE * %{ $1 = ($1_ltype)$input; %} %typemap(in) SWIGTYPE (CLASS::*) %{ $1 = *($&1_ltype)&$input; %} %typemap(in) SWIGTYPE & %{ $1 = ($1_ltype)$input; if(!$1) { SWIG_CSharpThrowException(SWIG_CSharpNullReferenceException, "$1_type reference is null"); } %} %typemap(out) SWIGTYPE *, SWIGTYPE & %{ $result = (void *)$1; %} %typemap(out) SWIGTYPE (CLASS::*) %{ *($&1_ltype)&$result = $1; %} /* Default array handling */ %typemap(in) SWIGTYPE [] %{ $1 = ($1_ltype)$input; %} %typemap(out) SWIGTYPE [] %{ $result = $1; %} /* char[ANY] - treat as String */ %typemap(in) char[ANY] %{ $1 = $input; %} %typemap(out) char[ANY] %{ $result = $1; %} /* Typecheck typemaps - The purpose of these is merely to issue a warning for overloaded C++ functions * that cannot be overloaded in C# as more than one C++ type maps to a single C# type */ %typecheck(SWIG_TYPECHECK_BOOL) /* Java boolean */ bool, const bool & "" %typecheck(SWIG_TYPECHECK_CHAR) /* Java char */ char, const char & "" %typecheck(SWIG_TYPECHECK_INT8) /* Java byte */ signed char, const signed char & "" %typecheck(SWIG_TYPECHECK_INT16) /* Java short */ unsigned char, short, const unsigned char &, const short & "" %typecheck(SWIG_TYPECHECK_INT32) /* Java int */ unsigned short, int, long, const unsigned short &, const int &, const long &, enum SWIGTYPE "" %typecheck(SWIG_TYPECHECK_INT64) /* Java long */ unsigned int, unsigned long, long long, const unsigned int &, const unsigned long &, const long long & "" %typecheck(SWIG_TYPECHECK_INT128) /* Java BigInteger */ unsigned long long "" %typecheck(SWIG_TYPECHECK_FLOAT) /* Java float */ float, const float & "" %typecheck(SWIG_TYPECHECK_DOUBLE) /* Java double */ double, const double & "" %typecheck(SWIG_TYPECHECK_STRING) /* Java String */ char *, char[ANY] "" %typecheck(SWIG_TYPECHECK_POINTER) /* Default */ SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "" /* Exception handling */ %typemap(throws) int, long, short, unsigned int, unsigned long, unsigned short { char error_msg[256]; sprintf(error_msg, "C++ $1_type exception thrown, value: %d", $1); SWIG_CSharpThrowException(SWIG_CSharpException, error_msg); } %typemap(throws) SWIGTYPE { SWIG_CSharpThrowException(SWIG_CSharpException, "C++ $1_type exception thrown"); } %typemap(throws) char * { SWIG_CSharpThrowException(SWIG_CSharpException, $1); } /* Typemaps for code generation in proxy classes and C# type wrapper classes */ /* The csin typemap is used for converting function parameter types from the type * used in the proxy, module or type wrapper class to the type used in the PInvoke class. */ %typemap(csin) bool, const bool &, char, const char &, signed char, const signed char &, unsigned char, const unsigned char &, short, const short &, unsigned short, const unsigned short &, int, const int &, unsigned int, const unsigned int &, long, const long &, unsigned long, const unsigned long &, long long, const long long &, unsigned long long, const unsigned long long &, float, const float &, double, const double &, char *, char[ANY], enum SWIGTYPE "$csinput" %typemap(csin) SWIGTYPE "$&csclassname.getCPtr($csinput)" %typemap(csin) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "$csclassname.getCPtr($csinput)" /* The csout typemap is used for converting function return types from the return type * used in the PInvoke class to the type returned by the proxy, module or type wrapper class. */ %typemap(csout) bool, const bool &, char, const char &, signed char, const signed char &, unsigned char, const unsigned char &, short, const short &, unsigned short, const unsigned short &, int, const int &, unsigned int, const unsigned int &, long, const long &, unsigned long, const unsigned long &, long long, const long long &, unsigned long long, const unsigned long long &, float, const float &, double, const double &, char *, char[ANY], enum SWIGTYPE { return $imcall; } %typemap(csout) void { $imcall; } %typemap(csout) SWIGTYPE { return new $&csclassname($imcall, true); } %typemap(csout) SWIGTYPE & { return new $csclassname($imcall, $owner); } %typemap(csout) SWIGTYPE *, SWIGTYPE [], SWIGTYPE (CLASS::*) { IntPtr cPtr = $imcall; return (cPtr == IntPtr.Zero) ? null : new $csclassname(cPtr, $owner); } /* Properties */ %typemap(csvarin) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) %{ set { $imcall; } %} %typemap(csvarout) bool, const bool &, char, const char &, signed char, const signed char &, unsigned char, const unsigned char &, short, const short &, unsigned short, const unsigned short &, int, const int &, unsigned int, const unsigned int &, long, const long &, unsigned long, const unsigned long &, long long, const long long &, unsigned long long, const unsigned long long &, float, const float &, double, const double &, char *, char[ANY], enum SWIGTYPE %{ get { return $imcall; } %} %typemap(csvarout) void %{ get { $imcall; } %} %typemap(csvarout) SWIGTYPE %{ get { return new $&csclassname($imcall, true); } %} %typemap(csvarout) SWIGTYPE & %{ get { return new $csclassname($imcall, $owner); } %} %typemap(csvarout) SWIGTYPE *, SWIGTYPE [], SWIGTYPE (CLASS::*) %{ get { IntPtr cPtr = $imcall; return (cPtr == IntPtr.Zero) ? null : new $csclassname(cPtr, $owner); } %} /* Typemaps used for the generation of proxy and type wrapper class code */ %typemap(csbase) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "" %typemap(csclassmodifiers) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "public" %typemap(cscode) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "" %typemap(csimports) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "using System;" %typemap(csinterfaces) SWIGTYPE "IDisposable" %typemap(csinterfaces_derived) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "" %typemap(csptrconstructormodifiers) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "internal" %typemap(csfinalize) SWIGTYPE %{ ~$csclassname() { Dispose(); } %} %typemap(csdestruct, methodname="Dispose") SWIGTYPE { if(swigCPtr != IntPtr.Zero && swigCMemOwn) { swigCMemOwn = false; $imcall; } swigCPtr = IntPtr.Zero; GC.SuppressFinalize(this); } %typemap(csdestruct_derived, methodname="Dispose") SWIGTYPE { if(swigCPtr != IntPtr.Zero && swigCMemOwn) { swigCMemOwn = false; $imcall; } swigCPtr = IntPtr.Zero; GC.SuppressFinalize(this); base.Dispose(); } %typemap(csgetcptr) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) %{ internal static IntPtr getCPtr($csclassname obj) { return (obj == null) ? IntPtr.Zero : obj.swigCPtr; } %} /* C# specific directives */ #define %csconst(flag) %feature("cs:const","flag") #define %csmethodmodifiers %feature("cs:methodmodifiers") %pragma(csharp) moduleimports=%{ using System; %} %pragma(csharp) imclassimports=%{ using System; using System.Runtime.InteropServices; %} /* Some ANSI C typemaps */ %apply long { size_t }; /* csharp keywords */ /* please test and activate */ //%include "csharpkw.swg" cableswig-0.1.0+git20150808.orig/SWIG/Lib/csharp/std_string.i0000644000175000000620000000310112561312227022111 0ustar stevestaff// // SWIG typemaps for std::string // William Fulton // // C# implementation // /* ------------------------------------------------------------------------ Typemaps for std::string and const std::string& These are mapped to a C# String and are passed around by value. To use non-const std::string references use the following %apply. Note that they are passed by value. %apply const std::string & {std::string &}; ------------------------------------------------------------------------ */ %{ #include %} namespace std { class string; // string %typemap(ctype) string "char *" %typemap(imtype) string "string" %typemap(cstype) string "string" %typemap(in) string %{ if (!$input) SWIG_CSharpThrowException(SWIG_CSharpNullReferenceException, "null string"); $1 = std::string($input); %} %typemap(out) string %{ $result = SWIG_csharp_string_callback($1.c_str()); %} %typemap(csin) string "$csinput" %typemap(csout) string { return $imcall; } %typemap(typecheck) string = char *; // const string & %typemap(ctype) const string & "char *" %typemap(imtype) const string & "string" %typemap(cstype) const string & "string" %typemap(in) const string & %{ if (!$input) SWIG_CSharpThrowException(SWIG_CSharpNullReferenceException, "null string"); $1 = new std::string($input); %} %typemap(out) const string & %{ $result = SWIG_csharp_string_callback($1->c_str()); %} %typemap(freearg) const string & %{ delete $1; %} %typemap(csin) const string & "$csinput" %typemap(csout) const string & { return $imcall; } %typemap(typecheck) const string & = char *; } cableswig-0.1.0+git20150808.orig/SWIG/Lib/csharp/csharpkw.swg0000644000175000000620000000316012561312227022130 0ustar stevestaff#ifndef __csharp_csharpkw_swg__ #define __csharp_csharpkw_swg__ /* Warnings for Csharp keywords */ #define CSHARPKW(x) %namewarn("314:" #x " is a csharp keyword") #x /* from http://www.jaggersoft.com/csharp_grammar.html#1.7%20Keywords */ CSHARPKW(abstract); CSHARPKW(as); CSHARPKW(base); CSHARPKW(bool); CSHARPKW(break); CSHARPKW(byte); CSHARPKW(case); CSHARPKW(catch); CSHARPKW(char); CSHARPKW(checked); CSHARPKW(class); CSHARPKW(const); CSHARPKW(continue); CSHARPKW(decimal); CSHARPKW(default); CSHARPKW(delegate); CSHARPKW(do); CSHARPKW(double); CSHARPKW(else); CSHARPKW(enum); CSHARPKW(event); CSHARPKW(explicit); CSHARPKW(extern); CSHARPKW(false); CSHARPKW(finally); CSHARPKW(fixed); CSHARPKW(float); CSHARPKW(for); CSHARPKW(foreach); CSHARPKW(goto); CSHARPKW(if); CSHARPKW(implicit); CSHARPKW(in); CSHARPKW(int); CSHARPKW(interface); CSHARPKW(internal); CSHARPKW(is); CSHARPKW(lock); CSHARPKW(long); CSHARPKW(namespace); CSHARPKW(new); CSHARPKW(null); CSHARPKW(object); CSHARPKW(operator); CSHARPKW(out); CSHARPKW(override); CSHARPKW(params); CSHARPKW(private); CSHARPKW(protected); CSHARPKW(public); CSHARPKW(readonly); CSHARPKW(ref); CSHARPKW(return); CSHARPKW(sbyte); CSHARPKW(sealed); CSHARPKW(short); CSHARPKW(sizeof); CSHARPKW(stackalloc); CSHARPKW(static); CSHARPKW(struct); CSHARPKW(string); CSHARPKW(switch); CSHARPKW(this); CSHARPKW(throw); CSHARPKW(true); CSHARPKW(try); CSHARPKW(typeof); CSHARPKW(uint); CSHARPKW(ulong); CSHARPKW(unchecked); CSHARPKW(unsafe); CSHARPKW(ushort); CSHARPKW(using); CSHARPKW(virtual); CSHARPKW(void); CSHARPKW(volatile); CSHARPKW(while); #undef CSHARPKW #endif //__csharp_csharpkw_swg__ cableswig-0.1.0+git20150808.orig/SWIG/Lib/csharp/typemaps.i0000644000175000000620000000755612561312227021615 0ustar stevestaff /* These typemaps will eventually probably maybe make their way into named typemaps * OUTPUT * and OUTPUT & as they currently break functions that return a pointer or * reference. */ %typemap(ctype) bool *, bool & "bool *" %typemap(ctype) char & "char *" %typemap(ctype) signed char *, signed char & "signed char *" %typemap(ctype) unsigned char *, unsigned char & "unsigned char *" %typemap(ctype) short *, short & "short *" %typemap(ctype) unsigned short *, unsigned short & "unsigned short *" %typemap(ctype) int *, int & "int *" %typemap(ctype) unsigned int *, unsigned int & "unsigned int *" %typemap(ctype) long *, long & "long *" %typemap(ctype) unsigned long *, unsigned long & "unsigned long *" %typemap(ctype) long long *, long long & "long long *" %typemap(ctype) unsigned long long *, unsigned long long & "unsigned long long *" %typemap(ctype) float *, float & "float *" %typemap(ctype) double *, double & "double *" %typemap(imtype) bool *, bool & "ref bool" %typemap(imtype) char & "ref char" %typemap(imtype) signed char *, signed char & "ref sbyte" %typemap(imtype) unsigned char *, unsigned char & "ref byte" %typemap(imtype) short *, short & "ref short" %typemap(imtype) unsigned short *, unsigned short & "ref ushort" %typemap(imtype) int *, int & "ref int" %typemap(imtype) unsigned int *, unsigned int & "ref uint" %typemap(imtype) long *, long & "ref int" %typemap(imtype) unsigned long *, unsigned long & "ref uint" %typemap(imtype) long long *, long long & "ref long" %typemap(imtype) unsigned long long *, unsigned long long & "ref ulong" %typemap(imtype) float *, float & "ref float" %typemap(imtype) double *, double & "ref double" %typemap(cstype) bool *, bool & "ref bool" %typemap(cstype) char & "ref char" %typemap(cstype) signed char *, signed char & "ref sbyte" %typemap(cstype) unsigned char *, unsigned char & "ref byte" %typemap(cstype) short *, short & "ref short" %typemap(cstype) unsigned short *, unsigned short & "ref ushort" %typemap(cstype) int *, int & "ref int" %typemap(cstype) unsigned int *, unsigned int & "ref uint" %typemap(cstype) long *, long & "ref int" %typemap(cstype) unsigned long *, unsigned long & "ref uint" %typemap(cstype) long long *, long long & "ref long" %typemap(cstype) unsigned long long *, unsigned long long & "ref ulong" %typemap(cstype) float *, float & "ref float" %typemap(cstype) double *, double & "ref double" %typemap(csin) bool *, bool &, char &, signed char *, signed char &, unsigned char *, unsigned char &, short *, short &, unsigned short *, unsigned short &, int *, int &, unsigned int *, unsigned int &, long *, long &, unsigned long *, unsigned long &, long long *, long long &, unsigned long long *, unsigned long long &, float *, float &, double *, double & "ref $csinput" cableswig-0.1.0+git20150808.orig/SWIG/Lib/csharp/csharphead.swg0000644000175000000620000001456612561312227022424 0ustar stevestaff/* ----------------------------------------------------------------------------- * csharphead.swg * * CSharp support code * ----------------------------------------------------------------------------- */ %insert(runtime) %{ #include #include #include #if defined(_WIN32) || defined(__CYGWIN32__) # define DllExport __declspec( dllexport ) # define SWIGSTDCALL __stdcall #else # define DllExport # define SWIGSTDCALL #endif %} %insert(runtime) %{ /* Support for throwing C# exceptions from C/C++ */ typedef enum { SWIG_CSharpException, SWIG_CSharpOutOfMemoryException, SWIG_CSharpIndexOutOfRangeException, SWIG_CSharpDivideByZeroException, SWIG_CSharpArgumentOutOfRangeException, SWIG_CSharpNullReferenceException } SWIG_CSharpExceptionCodes; typedef void (SWIGSTDCALL* SWIG_CSharpExceptionCallback_t)(const char *); typedef struct { SWIG_CSharpExceptionCodes code; SWIG_CSharpExceptionCallback_t callback; } SWIG_CSharpExceptions_t; static SWIG_CSharpExceptions_t SWIG_csharp_exceptions[] = { { SWIG_CSharpException, NULL }, { SWIG_CSharpOutOfMemoryException, NULL }, { SWIG_CSharpIndexOutOfRangeException, NULL }, { SWIG_CSharpDivideByZeroException, NULL }, { SWIG_CSharpArgumentOutOfRangeException, NULL }, { SWIG_CSharpNullReferenceException, NULL } }; static void SWIG_CSharpThrowException(SWIG_CSharpExceptionCodes code, const char *msg) { SWIG_CSharpExceptionCallback_t callback = SWIG_csharp_exceptions[SWIG_CSharpException].callback; if (code >=0 && (size_t)code < sizeof(SWIG_csharp_exceptions)/sizeof(SWIG_CSharpExceptionCodes)) { callback = SWIG_csharp_exceptions[code].callback; } callback(msg); } %} %insert(runtime) %{ #ifdef __cplusplus extern "C" #endif DllExport void SWIGSTDCALL SWIGRegisterExceptionCallbacks_$module(SWIG_CSharpExceptionCallback_t systemException, SWIG_CSharpExceptionCallback_t outOfMemory, SWIG_CSharpExceptionCallback_t indexOutOfRange, SWIG_CSharpExceptionCallback_t divideByZero, SWIG_CSharpExceptionCallback_t argumentOutOfRange, SWIG_CSharpExceptionCallback_t nullReference) { SWIG_csharp_exceptions[SWIG_CSharpException].callback = systemException; SWIG_csharp_exceptions[SWIG_CSharpOutOfMemoryException].callback = outOfMemory; SWIG_csharp_exceptions[SWIG_CSharpIndexOutOfRangeException].callback = indexOutOfRange; SWIG_csharp_exceptions[SWIG_CSharpDivideByZeroException].callback = divideByZero; SWIG_csharp_exceptions[SWIG_CSharpArgumentOutOfRangeException].callback = argumentOutOfRange; SWIG_csharp_exceptions[SWIG_CSharpNullReferenceException].callback = nullReference; } %} %pragma(csharp) imclasscode=%{ class SWIGExceptionHelper { public delegate void SWIGExceptionDelegate(string message); static SWIGExceptionDelegate systemDelegate = new SWIGExceptionDelegate(ThrowSystemException); static SWIGExceptionDelegate outOfMemoryDelegate = new SWIGExceptionDelegate(ThrowOutOfMemoryException); static SWIGExceptionDelegate indexOutOfRangeDelegate = new SWIGExceptionDelegate(ThrowIndexOutOfRangeException); static SWIGExceptionDelegate divideByZeroDelegate = new SWIGExceptionDelegate(ThrowDivideByZeroException); static SWIGExceptionDelegate argumentOutOfRangeDelegate = new SWIGExceptionDelegate(ThrowArgumentOutOfRangeException); static SWIGExceptionDelegate nullReferenceDelegate = new SWIGExceptionDelegate(ThrowNullReferenceException); [DllImport("$module", EntryPoint="SWIGRegisterExceptionCallbacks_$module")] public static extern void SWIGRegisterExceptionCallbacks_$module( SWIGExceptionDelegate systemExceptionDelegate, SWIGExceptionDelegate outOfMemoryDelegate, SWIGExceptionDelegate indexOutOfRangeDelegate, SWIGExceptionDelegate divideByZeroDelegate, SWIGExceptionDelegate argumentOutOfRangeDelegate, SWIGExceptionDelegate nullReferenceDelegate); static void ThrowSystemException(string message) { throw new System.SystemException(message); } static void ThrowOutOfMemoryException(string message) { throw new System.OutOfMemoryException(message); } static void ThrowIndexOutOfRangeException(string message) { throw new System.IndexOutOfRangeException(message); } static void ThrowDivideByZeroException(string message) { throw new System.DivideByZeroException(message); } static void ThrowArgumentOutOfRangeException(string message) { throw new System.ArgumentOutOfRangeException(message); } static void ThrowNullReferenceException(string message) { throw new System.NullReferenceException(message); } static SWIGExceptionHelper() { SWIGRegisterExceptionCallbacks_$module(systemDelegate, outOfMemoryDelegate, indexOutOfRangeDelegate, divideByZeroDelegate, argumentOutOfRangeDelegate, nullReferenceDelegate); } } static SWIGExceptionHelper exceptionHelper = new SWIGExceptionHelper(); %} %insert(runtime) %{ /* Callback for returning strings to C# without leaking memory */ typedef char * (SWIGSTDCALL* SWIG_CSharpStringHelperCallback)(const char *); static SWIG_CSharpStringHelperCallback SWIG_csharp_string_callback = NULL; %} %pragma(csharp) imclasscode=%{ class SWIGStringHelper { public delegate string SWIGStringDelegate(string message); static SWIGStringDelegate stringDelegate = new SWIGStringDelegate(CreateString); [DllImport("$module", EntryPoint="SWIGRegisterStringCallback_$module")] public static extern void SWIGRegisterStringCallback_$module(SWIGStringDelegate stringDelegate); static string CreateString(string cString) { return cString; } static SWIGStringHelper() { SWIGRegisterStringCallback_$module(stringDelegate); } } static SWIGStringHelper stringHelper = new SWIGStringHelper(); %} %insert(runtime) %{ #ifdef __cplusplus extern "C" #endif DllExport void SWIGSTDCALL SWIGRegisterStringCallback_$module(SWIG_CSharpStringHelperCallback callback) { SWIG_csharp_string_callback = callback; } /* Contract support */ #define SWIG_contract_assert(nullreturn, expr, msg) if (!(expr)) {SWIG_CSharpThrowException(SWIG_CSharpArgumentOutOfRangeException, msg); return nullreturn; } else %} cableswig-0.1.0+git20150808.orig/SWIG/Lib/ocaml/0002755000175000000620000000000012561312227017401 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Lib/ocaml/ocamlkw.swg0000644000175000000620000000201212561312227021551 0ustar stevestaff#ifndef __ocaml_ocamlkw_swg__ #define __ocaml_ocamlkw_swg__ /* Warnings for Ocaml keywords */ #define OCAMLKW(x) %namewarn("314:" #x " is a ocaml keyword") #x /* from http://caml.inria.fr/ocaml/htmlman/manual044.html */ OCAMLKW(and); OCAMLKW(as); OCAMLKW(assert); OCAMLKW(begin); OCAMLKW(class); OCAMLKW(constraint); OCAMLKW(do); OCAMLKW(done); OCAMLKW(downto); OCAMLKW(else); OCAMLKW(end); OCAMLKW(exception); OCAMLKW(external); OCAMLKW(false); OCAMLKW(for); OCAMLKW(fun); OCAMLKW(function); OCAMLKW(functor); OCAMLKW(if); OCAMLKW(in); OCAMLKW(include); OCAMLKW(inherit); OCAMLKW(initializer); OCAMLKW(lazy); OCAMLKW(let); OCAMLKW(match); OCAMLKW(method); OCAMLKW(module); OCAMLKW(mutable); OCAMLKW(new); OCAMLKW(object); OCAMLKW(of); OCAMLKW(open); OCAMLKW(or); OCAMLKW(private); OCAMLKW(rec); OCAMLKW(sig); OCAMLKW(struct); OCAMLKW(then); OCAMLKW(to); OCAMLKW(true); OCAMLKW(try); OCAMLKW(type); OCAMLKW(val); OCAMLKW(virtual); OCAMLKW(when); OCAMLKW(while); OCAMLKW(with); #undef OCAMLKW #endif //__ocaml_ocamlkw_swg__ cableswig-0.1.0+git20150808.orig/SWIG/Lib/ocaml/std_list.i0000644000175000000620000001113312561312227021375 0ustar stevestaff// -*- C++ -*- // SWIG typemaps for std::list types // Art Yerkes // Modified from: Jing Cao // Aug 1st, 2002 // // Python implementation %module std_list %{ #include #include %} %include "exception.i" %exception std::list::__getitem__ { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::list::__setitem__ { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::list::__delitem__ { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } namespace std{ template class list { public: typedef T &reference; typedef const T& const_reference; typedef T &iterator; typedef const T& const_iterator; list(); list(unsigned int size, const T& value = T()); list(const list &); ~list(); void assign(unsigned int n, const T& value); void swap(list &x); const_reference front(); const_reference back(); const_iterator begin(); const_iterator end(); void resize(unsigned int n, T c = T()); bool empty() const; void push_front(const T& x); void push_back(const T& x); void pop_front(); void pop_back(); void clear(); unsigned int size() const; unsigned int max_size() const; void resize(unsigned int n, const T& value); void remove(const T& value); void unique(); void reverse(); void sort(); %extend { const_reference __getitem__(int i) { std::list::iterator first = self->begin(); int size = int(self->size()); if (i<0) i += size; if (i>=0 && i::iterator first = self->begin(); int size = int(self->size()); if (i<0) i += size; if (i>=0 && i::iterator first = self->begin(); int size = int(self->size()); if (i<0) i += size; if (i>=0 && ierase(first); } else throw std::out_of_range("list index out of range"); } std::list __getslice__(int i,int j) { std::list::iterator first = self->begin(); std::list::iterator end = self->end(); int size = int(self->size()); if (i<0) i += size; if (j<0) j += size; if (i<0) i = 0; if (j>size) j = size; if (i>=j) i=j; if (i>=0 && i=0) { for (int k=0;k tmp(j-i); if (j>i) std::copy(first,end,tmp.begin()); return tmp; } else throw std::out_of_range("list index out of range"); } void __delslice__(int i,int j) { std::list::iterator first = self->begin(); std::list::iterator end = self->end(); int size = int(self->size()); if (i<0) i += size; if (j<0) j += size; if (i<0) i = 0; if (j>size) j = size; for (int k=0;kerase(first,end); } void __setslice__(int i,int j, const std::list& v) { std::list::iterator first = self->begin(); std::list::iterator end = self->end(); int size = int(self->size()); if (i<0) i += size; if (j<0) j += size; if (i<0) i = 0; if (j>size) j = size; for (int k=0;kerase(first,end); if (i+1 <= int(self->size())) { first = self->begin(); for (int k=0;kinsert(first,v.begin(),v.end()); } else self->insert(self->end(),v.begin(),v.end()); } } unsigned int __len__() { return self->size(); } bool __nonzero__() { return !(self->empty()); } void append(const T& x) { self->push_back(x); } void pop() { self->pop_back(); } }; }; } cableswig-0.1.0+git20150808.orig/SWIG/Lib/ocaml/std_string.i0000644000175000000620000001157012561312227021735 0ustar stevestaff// -*- C++ -*- // SWIG typemaps for std::string // Art Yerkes // Modified from: Luigi Ballabio // Apr 8, 2002 // // Ocaml implementation // ------------------------------------------------------------------------ // std::string is typemapped by value // This can prevent exporting methods which return a string // in order for the user to modify it. // However, I think I'll wait until someone asks for it... // ------------------------------------------------------------------------ %include exception.i %{ #include #include using std::string; using std::vector; %} %include std_vector.i namespace std { template class basic_string { public: typedef charT *pointer; typedef charT &reference; typedef const charT &const_reference; typedef size_t size_type; typedef ptrdiff_t difference_type; basic_string(); basic_string( charT *str ); size_t size(); charT operator []( int pos ) const; charT *c_str() const; basic_string &operator = ( const basic_string &ws ); basic_string &operator = ( const charT *str ); basic_string &append( const basic_string &other ); basic_string &append( const charT *str ); void push_back( charT c ); void clear(); void reserve( size_type t ); void resize( size_type n, charT c = charT() ); int compare( const basic_string &other ) const; int compare( const charT *str ) const; basic_string &insert( size_type pos, const basic_string &str ); size_type find( const basic_string &other, int pos = 0 ) const; size_type find( charT c, int pos = 0 ) const; %extend { bool operator == ( const basic_string &other ) const { return self->compare( other ) == 0; } bool operator != ( const basic_string &other ) const { return self->compare( other ) != 0; } bool operator < ( const basic_string &other ) const { return self->compare( other ) == -1; } bool operator > ( const basic_string &other ) const { return self->compare( other ) == 1; } bool operator <= ( const basic_string &other ) const { return self->compare( other ) != 1; } bool operator >= ( const basic_string &other ) const { return self->compare( other ) != -1; } } }; %template(string) basic_string; %template(wstring) basic_string; typedef basic_string string; typedef basic_string wstring; /* Overloading check */ %typemap(in) string { if (caml_ptr_check($input)) $1 = std::string((char *)caml_ptr_val($input,0), caml_string_len($input)); else SWIG_exception(SWIG_TypeError, "string expected"); } %typemap(in) const string & (std::string temp) { if (caml_ptr_check($input)) { temp = std::string((char *)caml_ptr_val($input,0), caml_string_len($input)); $1 = &temp; } else { SWIG_exception(SWIG_TypeError, "string expected"); } } %typemap(in) string & (std::string temp) { if (caml_ptr_check($input)) { temp = std::string((char *)caml_ptr_val($input,0), caml_string_len($input)); $1 = &temp; } else { SWIG_exception(SWIG_TypeError, "string expected"); } } %typemap(in) string * (std::string *temp) { if (caml_ptr_check($input)) { temp = new std::string((char *)caml_ptr_val($input,0), caml_string_len($input)); $1 = temp; } else { SWIG_exception(SWIG_TypeError, "string expected"); } } %typemap(free) string * (std::string *temp) { delete temp; } %typemap(argout) string & { caml_list_append(swig_result,caml_val_string_len((*$1).c_str(), (*$1).size())); } %typemap(directorout) string { $result = std::string((char *)caml_ptr_val($input,0), caml_string_len($input)); } %typemap(out) string { $result = caml_val_string_len($1.c_str(),$1.size()); } %typemap(out) string * { $result = caml_val_string_len((*$1).c_str(),(*$1).size()); } } #ifdef ENABLE_CHARPTR_ARRAY char **c_charptr_array( const std::vector &str_v ); %{ SWIGEXT char **c_charptr_array( const std::vector &str_v ) { char **out = new char *[str_v.size() + 1]; out[str_v.size()] = 0; for( int i = 0; i < str_v.size(); i++ ) { out[i] = (char *)str_v[i].c_str(); } return out; } %} #endif #ifdef ENABLE_STRING_VECTOR %template (StringVector) std::vector; %insert(ml) %{ (* Some STL convenience items *) let string_array_to_vector sa = let nv = _new_StringVector C_void in array_to_vector nv (fun x -> C_string x) sa ; nv let c_string_array ar = _c_charptr_array (string_array_to_vector ar) %} %insert(mli) %{ val c_string_array: string array -> c_obj %} #endif cableswig-0.1.0+git20150808.orig/SWIG/Lib/ocaml/std_map.i0000644000175000000620000001224512561312227021204 0ustar stevestaff// // SWIG typemaps for std::map // Luigi Ballabio // Jan. 2003 // // Common implementation %include std_common.i %include exception.i %exception std::map::get { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::map::del { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } // ------------------------------------------------------------------------ // std::map // ------------------------------------------------------------------------ %{ #include #include #include %} // exported class namespace std { template class map { // add typemaps here public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T& get(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void set(const K& key, const T& x) { (*self)[key] = x; } void del(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(const K& key) { std::map::iterator i = self->find(key); return i != self->end(); } } }; // specializations for built-ins %define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO) template class map { // add typemaps here public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T& get(K key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void set(K key, const T& x) { (*self)[key] = x; } void del(K key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(K key) { std::map::iterator i = self->find(key); return i != self->end(); } } }; %enddef %define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO) template class map { // add typemaps here public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T get(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void set(const K& key, T x) { (*self)[key] = x; } void del(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(const K& key) { std::map::iterator i = self->find(key); return i != self->end(); } } }; %enddef %define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO) template<> class map { // add typemaps here public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T get(K key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void set(K key, T x) { (*self)[key] = x; } void del(K key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(K key) { std::map::iterator i = self->find(key); return i != self->end(); } } }; %enddef // add specializations here } cableswig-0.1.0+git20150808.orig/SWIG/Lib/ocaml/libswigocaml.h0000644000175000000620000000070612561312227022227 0ustar stevestaff/* Ocaml runtime support */ #ifdef __cplusplus extern "C" { #endif typedef int oc_bool; extern void *nullptr; extern oc_bool isnull( void *v ); extern void *get_char_ptr( char *str ); extern void *make_ptr_array( int size ); extern void *get_ptr( void *arrayptr, int elt ); extern void set_ptr( void *arrayptr, int elt, void *elt_v ); extern void *offset_ptr( void *ptr, int n ); #ifdef __cplusplus }; #endif cableswig-0.1.0+git20150808.orig/SWIG/Lib/ocaml/std_common.i0000644000175000000620000000064712561312227021722 0ustar stevestaff// -*- C++ -*- // SWIG typemaps for STL - common utilities // Art Yerkes // Modified from: Luigi Ballabio // Aug 3, 2002 // // Ocaml implementation %apply size_t { std::size_t }; %{ #include CAML_VALUE SwigString_FromString(const std::string& s) { return caml_val_string((char *)s.c_str()); } std::string SwigString_AsString(CAML_VALUE o) { return std::string((char *)caml_ptr_val(o,0)); } %} cableswig-0.1.0+git20150808.orig/SWIG/Lib/ocaml/class.swg0000644000175000000620000000311112561312227021222 0ustar stevestaff(*Stream:class_ctors*) let create_$classname_from_ptr raw_ptr = C_obj (let rec invoke_inner raw_ptr mth arg = try let method_name,application = List.hd (List.filter (fun (x,y) -> x = mth) method_table) in application (match arg with C_list l -> (C_list (raw_ptr :: l)) | C_void -> (C_list [ raw_ptr ]) | v -> (C_list [ raw_ptr ; v ])) with (Failure "hd") -> (* Try parent classes *) begin let parent_classes = [ $baselist ] in let rec try_parent plist raw_ptr = match plist with p :: tl -> begin try (invoke (p raw_ptr)) mth arg with (BadMethodName (p,m,s)) -> try_parent tl raw_ptr end | [] -> raise (BadMethodName (raw_ptr,mth,"$realname")) in try_parent parent_classes raw_ptr end and method_table = [ "nop", (fun args -> C_void) ; $classbody "&", (fun args -> raw_ptr) ; ":parents", (fun args -> C_list (List.map (fun (x,y) -> C_string (String.sub x 2 ((String.length x) - 2))) (List.filter (fun (x,y) -> ((String.length x) > 2) && x.[0] == ':' && x.[1] == ':') method_table))) ; ":classof", (fun args -> C_string "$realname") ; ":methods", (fun args -> C_list (List.map (fun (x,y) -> C_string x) method_table)) ] in (fun mth arg -> invoke_inner raw_ptr mth arg)) let _ = Callback.register "create_$normalized_from_ptr" create_$classname_from_ptr (*Stream:mli*) val create_$classname_from_ptr : c_obj -> c_obj cableswig-0.1.0+git20150808.orig/SWIG/Lib/ocaml/typemaps.i0000644000175000000620000001751512561312227021424 0ustar stevestaff/* typemaps.i --- ocaml typemaps -*- c -*- Ocaml conversion by Art Yerkes, modified from mzscheme/typemaps.i Copyright 2000, 2001 Matthias Koeppe Based on code written by Oleg Tolmatcev. typemaps.i,v 1.18 2003/09/20 23:52:26 cheetah Exp */ /* The Ocaml module handles all types uniformly via typemaps. Here are the definitions. */ /* Pointers */ %typemap(in) void "" %typemap(out) void "$result = Val_int(0);" %typemap(in) void * { $1 = caml_ptr_val($input,$descriptor); } %typemap(varin) void * { $1 = ($ltype)caml_ptr_val($input,$descriptor); } %typemap(out) void * { $result = caml_val_ptr($1,$descriptor); } %typemap(varout) void * { $result = caml_val_ptr($1,$descriptor); } #ifdef __cplusplus %typemap(in) SWIGTYPE & { /* %typemap(in) SWIGTYPE & */ $1 = ($ltype) caml_ptr_val($input,$1_descriptor); } %typemap(varin) SWIGTYPE & { /* %typemap(varin) SWIGTYPE & */ $1 = *(($ltype) caml_ptr_val($input,$1_descriptor)); } %typemap(out) SWIGTYPE & { /* %typemap(out) SWIGTYPE & */ CAML_VALUE *fromval = caml_named_value("create_$ntype_from_ptr"); if( fromval ) { $result = callback(*fromval,caml_val_ptr((void *) &$1,$1_descriptor)); } else { $result = caml_val_ptr ((void *) &$1,$1_descriptor); } } #if 0 %typemap(argout) SWIGTYPE & { CAML_VALUE *fromval = caml_named_value("create_$ntype_from_ptr"); if( fromval ) { swig_result = caml_list_append(swig_result, callback(*fromval,caml_val_ptr((void *) $1, $1_descriptor))); } else { swig_result = caml_list_append(swig_result, caml_val_ptr ((void *) $1,$1_descriptor)); } } #endif %typemap(argout) const SWIGTYPE & { } %typemap(in) SWIGTYPE { $1 = *(($&1_ltype) caml_ptr_val($input,$&1_descriptor)) ; } %typemap(out) SWIGTYPE { /* %typemap(out) SWIGTYPE */ $&1_ltype temp = new $ltype(($1_ltype &) $1); CAML_VALUE *fromval = caml_named_value("create_$ntype_from_ptr"); if( fromval ) { $result = callback(*fromval,caml_val_ptr((void *)temp,$&1_descriptor)); } else { $result = caml_val_ptr ((void *)temp,$&1_descriptor); } } #else %typemap(in) SWIGTYPE { $1 = *(($&1_ltype) caml_ptr_val($input,$&1_descriptor)) ; } %typemap(out) SWIGTYPE { /* %typemap(out) SWIGTYPE */ void *temp = calloc(1,sizeof($ltype)); CAML_VALUE *fromval = caml_named_value("create_$ntype_from_ptr"); memmove( temp, &$1, sizeof( $1_type ) ); if( fromval ) { $result = callback(*fromval,caml_val_ptr((void *)temp,$&1_descriptor)); } else { $result = caml_val_ptr ((void *)temp,$&1_descriptor); } } %apply SWIGTYPE { const SWIGTYPE & }; #endif /* The SIMPLE_MAP macro below defines the whole set of typemaps needed for simple types. */ %define SIMPLE_MAP(C_NAME, C_TO_MZ, MZ_TO_C) /* In */ %typemap(in) C_NAME { $1 = MZ_TO_C($input); } %typemap(varin) C_NAME { $1 = MZ_TO_C($input); } %typemap(in) C_NAME & ($*1_ltype temp) { temp = ($*1_ltype) MZ_TO_C($input); $1 = &temp; } %typemap(varin) C_NAME & { $1 = MZ_TO_C($input); } %typemap(directorout) C_NAME { $1 = MZ_TO_C($input); } %typemap(in) C_NAME *INPUT ($*1_ltype temp) { temp = ($*1_ltype) MZ_TO_C($input); $1 = &temp; } %typemap(in,numinputs=0) C_NAME *OUTPUT ($*1_ltype temp) { $1 = &temp; } /* Out */ %typemap(out) C_NAME { $result = C_TO_MZ($1); } %typemap(varout) C_NAME { $result = C_TO_MZ($1); } %typemap(varout) C_NAME & { /* %typemap(varout) C_NAME & (generic) */ $result = C_TO_MZ($1); } %typemap(argout) C_NAME *OUTPUT { swig_result = caml_list_append(swig_result,C_TO_MZ((long)*$1)); } %typemap(out) C_NAME & { /* %typemap(out) C_NAME & (generic) */ $result = C_TO_MZ(*$1); } %typemap(argout) C_NAME & { swig_result = caml_list_append(swig_result,C_TO_MZ((long)*$1)); } %typemap(directorin) C_NAME { args = caml_list_append(args,C_TO_MZ($1_name)); } %enddef SIMPLE_MAP(bool, caml_val_bool, caml_long_val); SIMPLE_MAP(oc_bool, caml_val_bool, caml_long_val); SIMPLE_MAP(char, caml_val_char, caml_long_val); SIMPLE_MAP(signed char, caml_val_char, caml_long_val); SIMPLE_MAP(unsigned char, caml_val_uchar, caml_long_val); SIMPLE_MAP(int, caml_val_int, caml_long_val); SIMPLE_MAP(short, caml_val_short, caml_long_val); SIMPLE_MAP(wchar_t, caml_val_short, caml_long_val); SIMPLE_MAP(long, caml_val_long, caml_long_val); SIMPLE_MAP(ptrdiff_t, caml_val_int, caml_long_val); SIMPLE_MAP(unsigned int, caml_val_uint, caml_long_val); SIMPLE_MAP(unsigned short, caml_val_ushort, caml_long_val); SIMPLE_MAP(unsigned long, caml_val_ulong, caml_long_val); SIMPLE_MAP(size_t, caml_val_int, caml_long_val); SIMPLE_MAP(float, caml_val_float, caml_double_val); SIMPLE_MAP(double, caml_val_double, caml_double_val); SIMPLE_MAP(long long,caml_val_ulong,caml_long_val); SIMPLE_MAP(unsigned long long,caml_val_ulong,caml_long_val); /* Void */ %typemap(out) void "$result = Val_unit;"; /* Pass through value */ %typemap (in) value,caml::value,CAML_VALUE "$1=$input;"; %typemap (out) value,caml::value,CAML_VALUE "$result=$1;"; /* Arrays */ %typemap(in) ArrayCarrier * { $1 = ($ltype)caml_ptr_val($input,$1_descriptor); } %typemap(out) ArrayCarrier * { CAML_VALUE *fromval = caml_named_value("create_$ntype_from_ptr"); if( fromval ) { $result = callback(*fromval,caml_val_ptr((void *)$1,$1_descriptor)); } else { $result = caml_val_ptr ((void *)$1,$1_descriptor); } } #if 0 %include "carray.i" #endif /* Handle char arrays as strings */ %define %char_ptr_in(how) %typemap(how) char *, signed char *, unsigned char * { /* %typemap(how) char * ... */ $1 = ($ltype)caml_string_val($input); } %typemap(how) char [ANY], signed char [ANY], unsigned char [ANY] { /* %typemap(how) char [ANY] ... */ char *temp = caml_string_val($input); strncpy((char *)$1,temp,$1_dim0); } %enddef %char_ptr_in(in); %char_ptr_in(varin); %char_ptr_in(directorout); %define %char_ptr_out(how) %typemap(how) char *, signed char *, unsigned char *, const char *, const signed char *, const unsigned char * { $result = caml_val_string((char *)$1); } %typemap(how) char [ANY], signed char [ANY], unsigned char [ANY], const char [ANY], const signed char [ANY], const unsigned char [ANY] { $result = caml_val_string_len((char *)$1,(int)$1_size); } %enddef %char_ptr_out(out); %char_ptr_out(varout); %char_ptr_out(directorin); %define %swigtype_ptr_in(how) %typemap(how) SWIGTYPE * { /* %typemap(how) SWIGTYPE * */ $1 = ($ltype)caml_ptr_val($input,$1_descriptor); } %typemap(how) SWIGTYPE (CLASS::*) { /* %typemap(how) SWIGTYPE (CLASS::*) */ void *v = caml_ptr_val($input,$1_descriptor); memcpy(& $1, &v, sizeof(v)); } %enddef %define %swigtype_ptr_out(how) %typemap(out) SWIGTYPE * { /* %typemap(how) SWIGTYPE *, SWIGTYPE (CLASS::*) */ CAML_VALUE *fromval = caml_named_value("create_$ntype_from_ptr"); if( fromval ) { $result = callback(*fromval,caml_val_ptr((void *)$1,$1_descriptor)); } else { $result = caml_val_ptr ((void *)$1,$1_descriptor); } } %typemap(how) SWIGTYPE (CLASS::*) { /* %typemap(how) SWIGTYPE *, SWIGTYPE (CLASS::*) */ void *v; memcpy(&v,& $1, sizeof(void *)); $result = caml_val_ptr (v,$1_descriptor); } %enddef %swigtype_ptr_in(in); %swigtype_ptr_in(varin); %swigtype_ptr_in(directorout); %swigtype_ptr_out(out); %swigtype_ptr_out(varout); %swigtype_ptr_out(directorin); /* C++ References */ /* Enums */ %typemap(in) enum SWIGTYPE { $1 = ($type)caml_long_val_full($input,"$type_marker"); } %typemap(varin) enum SWIGTYPE { $1 = ($type)caml_long_val_full($input,"$type_marker"); } %typemap(out) enum SWIGTYPE "$result = callback2(*caml_named_value(SWIG_MODULE \"_int_to_enum\"),*caml_named_value(\"$type_marker\"),Val_int($1));" %typemap(varout) enum SWIGTYPE "$result = callback2(*caml_named_value(SWIG_MODULE \"_int_to_enum\"),*caml_named_value(\"$type_marker\"),Val_int($1));" cableswig-0.1.0+git20150808.orig/SWIG/Lib/ocaml/std_pair.i0000644000175000000620000000100612561312227021353 0ustar stevestaff// // SWIG typemaps for std::pair // Luigi Ballabio // July 2003 // // Common implementation %include std_common.i %include exception.i // ------------------------------------------------------------------------ // std::pair // ------------------------------------------------------------------------ %{ #include %} // exported class namespace std { template struct pair { // add typemaps here T first; U second; }; // add specializations here } cableswig-0.1.0+git20150808.orig/SWIG/Lib/ocaml/preamble.swg0000644000175000000620000000103312561312227021705 0ustar stevestaff%insert(mli) %{ type c_obj = c_enum_tag c_obj_t exception BadArgs of string exception BadMethodName of c_obj * string * string exception NotObject of c_obj exception NotEnumType of c_obj exception LabelNotFromThisEnum of c_obj exception InvalidDirectorCall of c_obj %} %insert(ml) %{ type c_obj = c_enum_tag c_obj_t exception BadArgs of string exception BadMethodName of c_obj * string * string exception NotObject of c_obj exception NotEnumType of c_obj exception LabelNotFromThisEnum of c_obj exception InvalidDirectorCall of c_obj %}cableswig-0.1.0+git20150808.orig/SWIG/Lib/ocaml/swig.mli0000644000175000000620000000313212561312227021052 0ustar stevestaff(* -*- tuareg -*- *) type 'a c_obj_t = C_void | C_bool of bool | C_char of char | C_uchar of char | C_short of int | C_ushort of int | C_int of int | C_uint of int32 | C_int32 of int32 | C_int64 of int64 | C_float of float | C_double of float | C_ptr of int64 * int64 | C_array of 'a c_obj_t array | C_list of 'a c_obj_t list | C_obj of (string -> 'a c_obj_t -> 'a c_obj_t) | C_string of string | C_enum of 'a | C_director_core of 'a c_obj_t * 'a c_obj_t option ref type empty_enum = [ `SWIGFake | `Int of int ] exception InvalidDirectorCall of empty_enum c_obj_t val invoke : 'a c_obj_t -> (string -> 'a c_obj_t -> 'a c_obj_t) val convert_c_obj : 'a c_obj_t -> 'b c_obj_t val fnhelper : bool -> ('a c_obj_t list -> 'a c_obj_t list) -> 'a c_obj_t -> 'a c_obj_t val get_int : 'a c_obj_t -> int val get_float : 'a c_obj_t -> float val get_string : 'a c_obj_t -> string val get_char : 'a c_obj_t -> char val get_bool : 'a c_obj_t -> bool val make_float : float -> 'a c_obj_t val make_double : float -> 'a c_obj_t val make_string : string -> 'a c_obj_t val make_bool : bool -> 'a c_obj_t val make_char : char -> 'a c_obj_t val make_char_i : int -> 'a c_obj_t val make_uchar : char -> 'a c_obj_t val make_uchar_i : int -> 'a c_obj_t val make_short : int -> 'a c_obj_t val make_ushort : int -> 'a c_obj_t val make_int : int -> 'a c_obj_t val make_uint : int -> 'a c_obj_t val make_int32 : int -> 'a c_obj_t val make_int64 : int -> 'a c_obj_t val new_derived_object: ('a c_obj_t -> 'a c_obj_t) -> ('a c_obj_t -> string -> 'a c_obj_t -> 'a c_obj_t) -> 'a c_obj_t -> 'a c_obj_t cableswig-0.1.0+git20150808.orig/SWIG/Lib/ocaml/mlheading.swg0000644000175000000620000000004112561312227022044 0ustar stevestaff(* -*- tuareg -*- *) open Swig cableswig-0.1.0+git20150808.orig/SWIG/Lib/ocaml/extra-install.list0000644000175000000620000000013512561312227023062 0ustar stevestaff# see top-level Makefile.in # libswigocaml is not needed anymore. swigp4.ml swig.mli swig.ml cableswig-0.1.0+git20150808.orig/SWIG/Lib/ocaml/ocaml.swg0000644000175000000620000003300112561312227021211 0ustar stevestaff/* -*-c-*- */ /* SWIG pointer structure */ #include #include #ifdef __cplusplus extern "C" { #endif #define C_bool 0 #define C_char 1 #define C_uchar 2 #define C_short 3 #define C_ushort 4 #define C_int 5 #define C_uint 6 #define C_int32 7 #define C_int64 8 #define C_float 9 #define C_double 10 #define C_ptr 11 #define C_array 12 #define C_list 13 #define C_obj 14 #define C_string 15 #define C_enum 16 #define C_director_core 17 /* Cast a pointer if possible; returns 1 if successful */ SWIGSTATIC int SWIG_Cast (void *source, swig_type_info *source_type, void **ptr, swig_type_info *dest_type) { if( !source ) { // Special case for NULL. This is a popular question // for other modules on the list, so I want an easy way out... *ptr = 0; return 0; } #ifdef TYPE_CAST_VERBOSE fprintf( stderr, "Trying to cast %s to %s\n", source_type ? source_type->str : "", dest_type ? dest_type->str : "" ); #endif if (dest_type != source_type) { /* We have a type mismatch. Will have to look through our type mapping table to figure out whether or not we can accept this datatype. -- Ignore typechecks for void *. Allow any conversion. */ if( !dest_type || !source_type || !strcmp(dest_type->name,"_p_void") || !strcmp(source_type->name,"_p_void") ) { *ptr = source; return 0; } else { swig_type_info *tc = SWIG_TypeCheck( (char *)source_type->name, dest_type ); #ifdef TYPE_CAST_VERBOSE fprintf( stderr, "Typecheck -> %s\n", tc ? tc->str : "" ); #endif if( tc ) { *ptr = SWIG_TypeCast( tc, source ); return 0; } else return -1; } } else { *ptr = source; return 0; } } /* Return 0 if successful. */ SWIGSTATIC int SWIG_GetPtr(void *inptr, void **outptr, swig_type_info *intype, swig_type_info *outtype) { if (intype) { return SWIG_Cast(inptr, intype, outptr, outtype) == -1; } else { *outptr = inptr; return 0; } } SWIGSTATIC void caml_print_list( CAML_VALUE v ); SWIGSTATIC void caml_print_val( CAML_VALUE v ) { switch( SWIG_Tag_val(v) ) { case C_bool: if( Bool_val(SWIG_Field(v,0)) ) fprintf( stderr, "true " ); else fprintf( stderr, "false " ); break; case C_char: case C_uchar: fprintf( stderr, "'%c' (\\%03d) ", (Int_val(SWIG_Field(v,0)) >= ' ' && Int_val(SWIG_Field(v,0)) < 127) ? Int_val(SWIG_Field(v,0)) : '.', Int_val(SWIG_Field(v,0)) ); break; case C_short: case C_ushort: case C_int: fprintf( stderr, "%d ", (int)caml_long_val(v) ); break; case C_uint: case C_int32: fprintf( stderr, "%ud ", (unsigned int)caml_long_val(v) ); break; case C_int64: fprintf( stderr, "%ld ", caml_long_val(v) ); break; case C_float: case C_double: fprintf( stderr, "%f ", caml_double_val(v) ); break; case C_ptr: { void *vout = 0; swig_type_info *ty = (swig_type_info *)(long)SWIG_Int64_val(SWIG_Field(v,1)); caml_ptr_val_internal(v,&vout,0); fprintf( stderr, "PTR(%p,%s) ", vout, ty ? ty->name : "(null)" ); } break; case C_array: { unsigned int i; for( i = 0; i < Wosize_val( SWIG_Field(v,0) ); i++ ) caml_print_val( SWIG_Field(SWIG_Field(v,0),i) ); } break; case C_list: caml_print_list( SWIG_Field(v,0) ); break; case C_obj: fprintf( stderr, "OBJ(%p) ", (void *)SWIG_Field(v,0) ); break; case C_string: { void *cout; caml_ptr_val_internal(v,&cout,0); fprintf( stderr, "'%s' ", (char *)cout ); } break; } } SWIGSTATIC void caml_print_list( CAML_VALUE v ) { CAMLparam1(v); while( v && Is_block(v) ) { fprintf( stderr, "[ " ); caml_print_val( SWIG_Field(v,0) ); fprintf( stderr, "]\n" ); v = SWIG_Field(v,1); } CAMLreturn0; } SWIGSTATIC CAML_VALUE caml_list_nth( CAML_VALUE lst, int n ) { CAMLparam1(lst); int i = 0; while( i < n && lst && Is_block(lst) ) { i++; lst = SWIG_Field(lst,1); } if( lst == Val_unit ) CAMLreturn(Val_unit); else CAMLreturn(SWIG_Field(lst,0)); } SWIGSTATIC CAML_VALUE caml_list_append( CAML_VALUE lst, CAML_VALUE elt ) { CAMLparam2(lst,elt); SWIG_CAMLlocal3(v,vt,lh); lh = Val_unit; v = Val_unit; /* Appending C_void should have no effect */ if( !Is_block(elt) ) return lst; while( lst && Is_block(lst) ) { if( v && v != Val_unit ) { vt = alloc_tuple(2); SWIG_Store_field(v,1,vt); v = vt; } else { v = lh = alloc_tuple(2); } SWIG_Store_field(v,0,SWIG_Field(lst,0)); lst = SWIG_Field(lst,1); } if( v && Is_block(v) ) { vt = alloc_tuple(2); SWIG_Store_field(v,1,vt); v = vt; } else { v = lh = alloc_tuple(2); } SWIG_Store_field(v,0,elt); SWIG_Store_field(v,1,Val_unit); CAMLreturn(lh); } SWIGSTATIC int caml_list_length( CAML_VALUE lst ) { CAMLparam1(lst); int i = 0; while( lst && Is_block(lst) ) { i++; lst = SWIG_Field(lst,1); } CAMLreturn(i); } SWIGSTATIC void caml_array_set( CAML_VALUE arr, int n, CAML_VALUE item ) { CAMLparam2(arr,item); SWIG_Store_field(SWIG_Field(arr,0),n,item); CAMLreturn0; } SWIGSTATIC value caml_array_nth( CAML_VALUE arr, int n ) { CAMLparam1(arr); if( SWIG_Tag_val(arr) == C_array ) CAMLreturn(SWIG_Field(SWIG_Field(arr,0),n)); else if( SWIG_Tag_val(arr) == C_list ) CAMLreturn(caml_list_nth(arr,0)); else failwith("Need array or list"); } SWIGSTATIC int caml_array_len( CAML_VALUE arr ) { CAMLparam1(arr); if( SWIG_Tag_val(arr) == C_array ) CAMLreturn(Wosize_val(SWIG_Field(arr,0))); else if( SWIG_Tag_val(arr) == C_list ) CAMLreturn(caml_list_length(arr)); else failwith("Need array or list"); } #ifdef __cplusplus namespace caml { extern "C" #endif CAML_VALUE alloc(int,int); #ifdef __cplusplus }; #endif SWIGSTATIC CAML_VALUE caml_swig_alloc(int x,int y) { #ifdef __cplusplus using namespace caml; #endif return alloc(x,y); } SWIGSTATIC value caml_array_new( int n ) { CAMLparam0(); SWIG_CAMLlocal1(vv); vv = caml_swig_alloc(1,C_array); SWIG_Store_field(vv,0,alloc_tuple(n)); CAMLreturn(vv); } SWIGSTATIC CAML_VALUE caml_val_bool( int b ) { CAMLparam0(); SWIG_CAMLlocal1(bv); bv = caml_swig_alloc(1,C_bool); SWIG_Store_field(bv,0,Val_bool(b)); CAMLreturn(bv); } SWIGSTATIC CAML_VALUE caml_val_char( char c ) { CAMLparam0(); SWIG_CAMLlocal1(cv); cv = caml_swig_alloc(1,C_char); SWIG_Store_field(cv,0,Val_int(c)); CAMLreturn(cv); } SWIGSTATIC CAML_VALUE caml_val_uchar( unsigned char uc ) { CAMLparam0(); SWIG_CAMLlocal1(ucv); ucv = caml_swig_alloc(1,C_uchar); SWIG_Store_field(ucv,0,Val_int(uc)); CAMLreturn(ucv); } SWIGSTATIC CAML_VALUE caml_val_short( short s ) { CAMLparam0(); SWIG_CAMLlocal1(sv); sv = caml_swig_alloc(1,C_short); SWIG_Store_field(sv,0,Val_int(s)); CAMLreturn(sv); } SWIGSTATIC CAML_VALUE caml_val_ushort( unsigned short us ) { CAMLparam0(); SWIG_CAMLlocal1(usv); usv = caml_swig_alloc(1,C_ushort); SWIG_Store_field(usv,0,Val_int(us)); CAMLreturn(usv); } SWIGSTATIC CAML_VALUE caml_val_int( int i ) { CAMLparam0(); SWIG_CAMLlocal1(iv); iv = caml_swig_alloc(1,C_int); SWIG_Store_field(iv,0,Val_int(i)); CAMLreturn(iv); } SWIGSTATIC CAML_VALUE caml_val_uint( unsigned int ui ) { CAMLparam0(); SWIG_CAMLlocal1(uiv); uiv = caml_swig_alloc(1,C_int); SWIG_Store_field(uiv,0,Val_int(ui)); CAMLreturn(uiv); } SWIGSTATIC CAML_VALUE caml_val_long( long l ) { CAMLparam0(); SWIG_CAMLlocal1(lv); lv = caml_swig_alloc(1,C_int64); SWIG_Store_field(lv,0,copy_int64(l)); CAMLreturn(lv); } SWIGSTATIC CAML_VALUE caml_val_ulong( unsigned long ul ) { CAMLparam0(); SWIG_CAMLlocal1(ulv); ulv = caml_swig_alloc(1,C_int64); SWIG_Store_field(ulv,0,copy_int64(ul)); CAMLreturn(ulv); } SWIGSTATIC CAML_VALUE caml_val_float( float f ) { CAMLparam0(); SWIG_CAMLlocal1(fv); fv = caml_swig_alloc(1,C_float); SWIG_Store_field(fv,0,copy_double((double)f)); CAMLreturn(fv); } SWIGSTATIC CAML_VALUE caml_val_double( double d ) { CAMLparam0(); SWIG_CAMLlocal1(fv); fv = caml_swig_alloc(1,C_double); SWIG_Store_field(fv,0,copy_double(d)); CAMLreturn(fv); } SWIGSTATIC CAML_VALUE caml_val_ptr( void *p, swig_type_info *info ) { CAMLparam0(); SWIG_CAMLlocal1(vv); vv = caml_swig_alloc(2,C_ptr); SWIG_Store_field(vv,0,copy_int64((long)p)); SWIG_Store_field(vv,1,copy_int64((long)info)); CAMLreturn(vv); } SWIGSTATIC CAML_VALUE caml_val_string( const char *p ) { CAMLparam0(); SWIG_CAMLlocal1(vv); if( !p ) CAMLreturn(caml_val_ptr( (void *)p, 0 )); vv = caml_swig_alloc(1,C_string); SWIG_Store_field(vv,0,copy_string(p)); CAMLreturn(vv); } SWIGSTATIC CAML_VALUE caml_val_string_len( const char *p, int len ) { CAMLparam0(); SWIG_CAMLlocal1(vv); if( !p || len < 0 ) CAMLreturn(caml_val_ptr( (void *)p, 0 )); vv = caml_swig_alloc(1,C_string); SWIG_Store_field(vv,0,alloc_string(len)); memcpy(String_val(SWIG_Field(vv,0)),p,len); CAMLreturn(vv); } SWIGSTATIC CAML_VALUE caml_val_obj( void *v, char *object_type ) { CAMLparam0(); CAMLreturn(callback2(*caml_named_value("caml_create_object_fn"), caml_val_ptr(v,SWIG_TypeQuery(object_type)), copy_string(object_type))); } SWIGSTATIC long caml_long_val_full( CAML_VALUE v, char *name ) { CAMLparam1(v); if( !Is_block(v) ) return 0; switch( SWIG_Tag_val(v) ) { case C_bool: case C_char: case C_uchar: case C_short: case C_ushort: case C_int: CAMLreturn(Int_val(SWIG_Field(v,0))); case C_uint: case C_int32: CAMLreturn(Int32_val(SWIG_Field(v,0))); case C_int64: CAMLreturn((long)SWIG_Int64_val(SWIG_Field(v,0))); case C_float: case C_double: CAMLreturn((long)Double_val(SWIG_Field(v,0))); case C_string: CAMLreturn((long)String_val(SWIG_Field(v,0))); case C_ptr: CAMLreturn((long)SWIG_Int64_val(SWIG_Field(SWIG_Field(v,0),0))); case C_enum: { SWIG_CAMLlocal1(ret); CAML_VALUE *enum_to_int = caml_named_value(SWIG_MODULE "_enum_to_int"); if( !name ) failwith( "Not an enum conversion" ); ret = callback2(*enum_to_int,*caml_named_value(name),v); CAMLreturn(caml_long_val(ret)); } default: failwith("No conversion to int"); } } SWIGSTATIC long caml_long_val( CAML_VALUE v ) { return caml_long_val_full(v,0); } SWIGSTATIC double caml_double_val( CAML_VALUE v ) { CAMLparam1(v); if( !Is_block(v) ) return 0.0; switch( SWIG_Tag_val(v) ) { case C_bool: case C_char: case C_uchar: case C_short: case C_ushort: case C_int: CAMLreturn(Int_val(SWIG_Field(v,0))); case C_uint: case C_int32: CAMLreturn(Int32_val(SWIG_Field(v,0))); case C_int64: CAMLreturn(SWIG_Int64_val(SWIG_Field(v,0))); case C_float: case C_double: CAMLreturn(Double_val(SWIG_Field(v,0))); default: fprintf( stderr, "Unknown block tag %d\n", SWIG_Tag_val(v) ); failwith("No conversion to double"); } } SWIGSTATIC int caml_ptr_val_internal( CAML_VALUE v, void **out, swig_type_info *descriptor ) { CAMLparam1(v); void *outptr = NULL; swig_type_info *outdescr = NULL; if( v == Val_unit ) { *out = 0; CAMLreturn(0); } if( !Is_block(v) ) return -1; switch( SWIG_Tag_val(v) ) { case C_int: if( !caml_long_val( v ) ) { *out = 0; CAMLreturn(0); } else { *out = 0; CAMLreturn(1); } break; case C_obj: CAMLreturn (caml_ptr_val_internal (callback(*caml_named_value("caml_obj_ptr"),v), out,descriptor)); case C_string: outptr = (void *)String_val(SWIG_Field(v,0)); break; case C_ptr: outptr = (void *)(long)SWIG_Int64_val(SWIG_Field(v,0)); outdescr = (swig_type_info *)(long)SWIG_Int64_val(SWIG_Field(v,1)); break; default: *out = 0; CAMLreturn(1); break; } CAMLreturn(SWIG_GetPtr(outptr,out,outdescr,descriptor)); } SWIGSTATIC void *caml_ptr_val( CAML_VALUE v, swig_type_info *descriptor ) { CAMLparam0(); #ifdef TYPE_CAST_VERBOSE caml_print_val( v ); #endif void *out = NULL; if( !caml_ptr_val_internal( v, &out, descriptor ) ) CAMLreturn(out); else failwith( "No appropriate conversion found." ); } SWIGSTATIC char *caml_string_val( CAML_VALUE v ) { return (char *)caml_ptr_val( v, 0 ); } SWIGSTATIC int caml_string_len( CAML_VALUE v ) { switch( SWIG_Tag_val(v) ) { case C_string: return string_length(SWIG_Field(v,0)); default: return strlen((char *)caml_ptr_val(v,0)); } } SWIGSTATIC int caml_bool_check( CAML_VALUE v ) { CAMLparam1(v); if( !Is_block(v) ) return 0; switch( SWIG_Tag_val(v) ) { case C_bool: case C_ptr: case C_string: CAMLreturn(1); default: CAMLreturn(0); } } SWIGSTATIC int caml_int_check( CAML_VALUE v ) { CAMLparam1(v); if( !Is_block(v) ) return 0; switch( SWIG_Tag_val(v) ) { case C_char: case C_uchar: case C_short: case C_ushort: case C_int: case C_uint: case C_int32: case C_int64: CAMLreturn(1); default: CAMLreturn(0); } } SWIGSTATIC int caml_float_check( CAML_VALUE v ) { CAMLparam1(v); if( !Is_block(v) ) return 0; switch( SWIG_Tag_val(v) ) { case C_float: case C_double: CAMLreturn(1); default: CAMLreturn(0); } } SWIGSTATIC int caml_ptr_check( CAML_VALUE v ) { CAMLparam1(v); if( !Is_block(v) ) return 0; switch( SWIG_Tag_val(v) ) { case C_string: case C_ptr: case C_int64: CAMLreturn(1); default: CAMLreturn(0); } } #ifdef __cplusplus } #endif #undef value /* ocaml keywords */ /* please test and activate */ //%include "ocamlkw.swg" cableswig-0.1.0+git20150808.orig/SWIG/Lib/ocaml/std_deque.i0000644000175000000620000000103112561312227021521 0ustar stevestaff/* Default std_deque wrapper */ %module std_deque %rename(__getitem__) std::deque::getitem; %rename(__setitem__) std::deque::setitem; %rename(__delitem__) std::deque::delitem; %rename(__getslice__) std::deque::getslice; %rename(__setslice__) std::deque::setslice; %rename(__delslice__) std::deque::delslice; %extend std::deque { int __len__() { return (int) self->size(); } int __nonzero__() { return ! self->empty(); } void append(const T &x) { self->push_back(x); } }; %include "_std_deque.i" cableswig-0.1.0+git20150808.orig/SWIG/Lib/ocaml/typeregister.swg0000644000175000000620000000040212561312227022643 0ustar stevestaff/* Code ripped from python implementation */ { static int typeinit = 0; int i; if (!typeinit) { for (i = 0; swig_types_initial[i]; i++) { swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]); } typeinit = 1; } }cableswig-0.1.0+git20150808.orig/SWIG/Lib/ocaml/std_complex.i0000644000175000000620000000301412561312227022070 0ustar stevestaff// -*- C++ -*- #ifndef SWIG_STD_COMPLEX_I_ #define SWIG_STD_COMPLEX_I_ #ifdef SWIG %{ #include %} namespace std { template class complex; %define specialize_std_complex(T) %typemap(in) complex { if (PyComplex_Check($input)) { $1 = std::complex(PyComplex_RealAsDouble($input), PyComplex_ImagAsDouble($input)); } else if (PyFloat_Check($input)) { $1 = std::complex(PyFloat_AsDouble($input), 0); } else if (PyInt_Check($input)) { $1 = std::complex(PyInt_AsLong($input), 0); } else { PyErr_SetString(PyExc_TypeError,"Expected a complex"); SWIG_fail; } } %typemap(in) const complex& (std::complex temp) { if (PyComplex_Check($input)) { temp = std::complex(PyComplex_RealAsDouble($input), PyComplex_ImagAsDouble($input)); $1 = &temp; } else if (PyFloat_Check($input)) { temp = std::complex(PyFloat_AsDouble($input), 0); $1 = &temp; } else if (PyInt_Check($input)) { temp = std::complex(PyInt_AsLong($input), 0); $1 = &temp; } else { PyErr_SetString(PyExc_TypeError,"Expected a complex"); SWIG_fail; } } %typemap(out) complex { $result = PyComplex_FromDoubles($1.real(), $1.imag()); } %typemap(out) const complex & { $result = PyComplex_FromDoubles($1->real(), $1->imag()); } %enddef specialize_std_complex(double); specialize_std_complex(float); } #endif // SWIG #endif //SWIG_STD_COMPLEX_I_ cableswig-0.1.0+git20150808.orig/SWIG/Lib/ocaml/typecheck.i0000644000175000000620000001114712561312227021534 0ustar stevestaff/* -*- C++ -*- */ /* Type checking code adapted from python backend. */ /* ------------------------------------------------------------ * Typechecking rules * ------------------------------------------------------------ */ %typecheck(SWIG_TYPECHECK_INTEGER) char, signed char, const char &, const signed char & { if( !Is_block($input) ) $1 = 0; else { switch( SWIG_Tag_val($input) ) { case C_char: $1 = 1; break; default: $1 = 0; break; } } } %typecheck(SWIG_TYPECHECK_INTEGER) unsigned char, const unsigned char & { if( !Is_block($input) ) $1 = 0; else { switch( SWIG_Tag_val($input) ) { case C_uchar: $1 = 1; break; default: $1 = 0; break; } } } %typecheck(SWIG_TYPECHECK_INTEGER) short, signed short, const short &, const signed short &, wchar_t { if( !Is_block($input) ) $1 = 0; else { switch( SWIG_Tag_val($input) ) { case C_short: $1 = 1; break; default: $1 = 0; break; } } } %typecheck(SWIG_TYPECHECK_INTEGER) unsigned short, const unsigned short & { if( !Is_block($input) ) $1 = 0; else { switch( SWIG_Tag_val($input) ) { case C_ushort: $1 = 1; break; default: $1 = 0; break; } } } // XXX arty // Will move enum SWIGTYPE later when I figure out what to do with it... %typecheck(SWIG_TYPECHECK_INTEGER) int, signed int, const int &, const signed int &, enum SWIGTYPE { if( !Is_block($input) ) $1 = 0; else { switch( SWIG_Tag_val($input) ) { case C_int: $1 = 1; break; default: $1 = 0; break; } } } %typecheck(SWIG_TYPECHECK_INTEGER) unsigned int, const unsigned int & { if( !Is_block($input) ) $1 = 0; else { switch( SWIG_Tag_val($input) ) { case C_uint: $1 = 1; break; case C_int32: $1 = 1; break; default: $1 = 0; break; } } } %typecheck(SWIG_TYPECHECK_INTEGER) long, signed long, unsigned long, long long, signed long long, unsigned long long, const long &, const signed long &, const unsigned long &, const long long &, const signed long long &, const unsigned long long & { if( !Is_block($input) ) $1 = 0; else { switch( SWIG_Tag_val($input) ) { case C_int64: $1 = 1; break; default: $1 = 0; break; } } } %typecheck(SWIG_TYPECHECK_INTEGER) bool, oc_bool, BOOL, const bool &, const oc_bool &, const BOOL & { if( !Is_block($input) ) $1 = 0; else { switch( SWIG_Tag_val($input) ) { case C_bool: $1 = 1; break; default: $1 = 0; break; } } } %typecheck(SWIG_TYPECHECK_DOUBLE) float, const float & { if( !Is_block($input) ) $1 = 0; else { switch( SWIG_Tag_val($input) ) { case C_float: $1 = 1; break; default: $1 = 0; break; } } } %typecheck(SWIG_TYPECHECK_DOUBLE) double, const double & { if( !Is_block($input) ) $1 = 0; else { switch( SWIG_Tag_val($input) ) { case C_double: $1 = 1; break; default: $1 = 0; break; } } } %typecheck(SWIG_TYPECHECK_STRING) char * { if( !Is_block($input) ) $1 = 0; else { switch( SWIG_Tag_val($input) ) { case C_string: $1 = 1; break; case C_ptr: { swig_type_info *typeinfo = (swig_type_info *)(long)SWIG_Int64_val(SWIG_Field($input,1)); $1 = SWIG_TypeCheck("char *",typeinfo) || SWIG_TypeCheck("signed char *",typeinfo) || SWIG_TypeCheck("unsigned char *",typeinfo) || SWIG_TypeCheck("const char *",typeinfo) || SWIG_TypeCheck("const signed char *",typeinfo) || SWIG_TypeCheck("const unsigned char *",typeinfo) || SWIG_TypeCheck("std::string",typeinfo); } break; default: $1 = 0; break; } } } %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { void *ptr; $1 = !caml_ptr_val_internal($input, &ptr,$descriptor); } #if 0 %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE { void *ptr; $1 = !caml_ptr_val_internal($input, &ptr, $&1_descriptor); } #endif %typecheck(SWIG_TYPECHECK_VOIDPTR) void * { void *ptr; $1 = !caml_ptr_val_internal($input, &ptr, 0); } /* ------------------------------------------------------------ * Exception handling * ------------------------------------------------------------ */ %typemap(throws) int, long, short, unsigned int, unsigned long, unsigned short { SWIG_exception($1,"Thrown exception from C++ (int)"); } %typemap(throws) SWIGTYPE CLASS { $&1_ltype temp = new $1_ltype($1); SWIG_exception((int)temp,"Thrown exception from C++ (object)"); } %typemap(throws) SWIGTYPE { SWIG_exception(0,"Thrown exception from C++ (unknown)"); } %typemap(throws) char * { SWIG_exception(0,$1); } cableswig-0.1.0+git20150808.orig/SWIG/Lib/ocaml/director.swg0000644000175000000620000001133112561312227021733 0ustar stevestaff/* -*- C++ -*- */ /*********************************************************************** * director.swg * * This file contains support for director classes that proxy * method calls from C++ to Ocaml extensions. * * Modified for Ocaml by : Art Yerkes * Original Author : Mark Rose (mrose@stm.lbl.gov) ************************************************************************/ #ifdef __cplusplus #include namespace Swig { /* base class for director exceptions */ class DirectorException { protected: std::string swig_msg; public: DirectorException(const char* msg="") { } const char *getMessage() const { return swig_msg.c_str(); } virtual ~DirectorException() {} }; /* type mismatch in the return value from a python method call */ class DirectorTypeMismatchException : public Swig::DirectorException { public: DirectorTypeMismatchException(const char* msg="") { } }; /* any python exception that occurs during a director method call */ class DirectorMethodException : public Swig::DirectorException {}; /* attempt to call a pure virtual method via a director method */ class DirectorPureVirtualException : public Swig::DirectorException {}; /* simple thread abstraction for pthreads on win32 */ #ifdef __THREAD__ #define __PTHREAD__ #if defined(_WIN32) || defined(__WIN32__) #define pthread_mutex_lock EnterCriticalSection #define pthread_mutex_unlock LeaveCriticalSection #define pthread_mutex_t CRITICAL_SECTION #define MUTEX_INIT(var) CRITICAL_SECTION var #else #include #define MUTEX_INIT(var) pthread_mutex_t var = PTHREAD_MUTEX_INITIALIZER #endif #endif /* director base class */ class Director { private: /* pointer to the wrapped ocaml object */ CAML_VALUE swig_self; /* flag indicating whether the object is owned by ocaml or c++ */ mutable bool swig_disown_flag; mutable bool swig_up; #ifdef __PTHREAD__ /* locks for sharing the swig_up flag in a threaded environment */ static pthread_mutex_t swig_mutex_up; static bool swig_mutex_active; static pthread_t swig_mutex_thread; #endif /* reset the swig_up flag once the routing direction has been determined */ #ifdef __PTHREAD__ void swig_clear_up() const { swig_up = false; Swig::Director::swig_mutex_active = false; pthread_mutex_unlock(&swig_mutex_up); } #else void swig_clear_up() const { swig_up = false; } #endif public: /* wrap a ocaml object, optionally taking ownership */ Director(CAML_VALUE self, bool disown = false) : swig_self(self), swig_disown_flag(disown), swig_up( false ) { register_global_root(&swig_self); } /* discard our reference at destruction */ virtual ~Director() { remove_global_root(&swig_self); swig_disown(); // Disown is safe here because we're just divorcing a reference that // points to us. } /* return a pointer to the wrapped ocaml object */ CAML_VALUE swig_get_self() const { return swig_self; } /* get the swig_up flag to determine if the method call should be routed * to the c++ base class or through the wrapped ocaml object */ #ifdef __PTHREAD__ bool swig_get_up( bool clear = true ) const { if (Swig::Director::swig_mutex_active) { if (pthread_equal(Swig::Director::swig_mutex_thread, pthread_self())) { bool up = swig_up; if( clear ) swig_clear_up(); return up; } } return false; } #else bool swig_get_up( bool clear = true ) const { bool up = swig_up; if( clear ) swig_up = false; return up; } #endif /* set the swig_up flag if the next method call should be directed to * the c++ base class rather than the wrapped ocaml object */ #ifdef __PTHREAD__ void swig_set_up() const { pthread_mutex_lock(&Swig::Director::swig_mutex_up); Swig::Director::swig_mutex_thread = pthread_self(); Swig::Director::swig_mutex_active = true; swig_up = true; } #else void swig_set_up() const { swig_up = true; } #endif /* acquire ownership of the wrapped ocaml object (the sense of "disown" * is from ocaml) */ void swig_disown() const { if (!swig_disown_flag) { swig_disown_flag=true; callback(*caml_named_value("caml_obj_disown"),swig_self); } } }; #ifdef __PTHREAD__ MUTEX_INIT(Swig::Director::swig_mutex_up); pthread_t Swig::Director::swig_mutex_thread; bool Swig::Director::swig_mutex_active = false; #endif } #endif /* __cplusplus */ cableswig-0.1.0+git20150808.orig/SWIG/Lib/ocaml/std_vector.i0000644000175000000620000000516012561312227021727 0ustar stevestaff// -*- C++ -*- // SWIG typemaps for std::vector types // Art Yerkes // Modified from: Luigi Ballabio // Apr 8, 2002 // // Ocaml implementation %include std_common.i // ------------------------------------------------------------------------ // std::vector // // The aim of all that follows would be to integrate std::vector with // Python as much as possible, namely, to allow the user to pass and // be returned Python tuples or lists. // const declarations are used to guess the intent of the function being // exported; therefore, the following rationale is applied: // // -- f(std::vector), f(const std::vector&), f(const std::vector*): // the parameter being read-only, either a Python sequence or a // previously wrapped std::vector can be passed. // -- f(std::vector&), f(std::vector*): // the parameter must be modified; therefore, only a wrapped std::vector // can be passed. // -- std::vector f(): // the vector is returned by copy; therefore, a Python sequence of T:s // is returned which is most easily used in other Python functions // -- std::vector& f(), std::vector* f(), const std::vector& f(), // const std::vector* f(): // the vector is returned by reference; therefore, a wrapped std::vector // is returned // ------------------------------------------------------------------------ %{ #include #include #include %} // exported class namespace std { template class vector { public: vector(unsigned int size = 0); vector(unsigned int size, const T& value); vector(const vector&); unsigned int size() const; bool empty() const; void clear(); void push_back(const T& x); T operator [] ( int f ); vector &operator = ( vector &other ); %extend { void set( int i, const T &x ) { self->resize(i+1); (*self)[i] = x; } }; %extend { T *to_array() { T *array = new T[self->size() + 1]; for( int i = 0; i < self->size(); i++ ) array[i] = (*self)[i]; return array; } }; }; }; %insert(ml) %{ let array_to_vector v argcons array = for i = 0 to (Array.length array) - 1 do (invoke v) "set" (C_list [ C_int i ; (argcons array.(i)) ]) done ; v let vector_to_array v argcons array = for i = 0; to (get_int ((invoke v) "size" C_void)) - 1 do array.(i) <- argcons ((invoke v) "[]" (C_int i)) done ; v %} %insert(mli) %{ val array_to_vector : c_obj -> ('a -> c_obj) -> 'a array -> c_obj val vector_to_array : c_obj -> (c_obj -> 'a) -> 'a array -> c_obj %} cableswig-0.1.0+git20150808.orig/SWIG/Lib/ocaml/ocaml.i0000644000175000000620000000140312561312227020642 0ustar stevestaff/* SWIG Configuration File for Ocaml. -*-c-*- Modified from mzscheme.i This file is parsed by SWIG before reading any other interface file. */ /* Insert ML/MLI Common stuff */ %insert(mli) "mliheading.swg" %insert(ml) "mlheading.swg" /* Insert common stuff */ %insert(runtime) "common.swg" /* Include headers */ %insert(runtime) "ocamldec.swg" /* Type registration */ %insert(init) "typeregister.swg" /*#ifndef SWIG_NOINCLUDE*/ %insert(runtime) "ocaml.swg" /*#endif*/ %insert(classtemplate) "class.swg" /* Definitions */ #define SWIG_malloc(size) swig_malloc(size, FUNC_NAME) #define SWIG_free(mem) free(mem) /* Read in standard typemaps. */ %include "swig.swg" %include "typemaps.i" %include "typecheck.i" %include "exception.i" %include "preamble.swg" cableswig-0.1.0+git20150808.orig/SWIG/Lib/ocaml/cstring.i0000644000175000000620000001375712561312227021237 0ustar stevestaff/* -*- C++ -*- * cstring.i * /cvsroot/SWIG/Lib/ocaml/cstring.i,v 1.4 2003/09/23 21:14:35 cheetah Exp * * Author(s): Art Yerkes * Modified from David Beazley (beazley@cs.uchicago.edu) * * This file provides typemaps and macros for dealing with various forms * of C character string handling. The primary use of this module * is in returning character data that has been allocated or changed in * some way. */ %include "fragments.i" /* %cstring_input_binary(TYPEMAP, SIZE) * * Macro makes a function accept binary string data along with * a size. */ %define %cstring_input_binary(TYPEMAP, SIZE) %apply (char *STRING, int LENGTH) { (TYPEMAP, SIZE) }; %enddef /* * %cstring_bounded_output(TYPEMAP, MAX) * * This macro is used to return a NULL-terminated output string of * some maximum length. For example: * * %cstring_bounded_output(char *outx, 512); * void foo(char *outx) { * sprintf(outx,"blah blah\n"); * } * */ %define %cstring_bounded_output(TYPEMAP,MAX) %typemap(ignore) TYPEMAP(char temp[MAX+1]) { $1 = ($1_ltype) temp; } %typemap(argout,fragment="t_output_helper") TYPEMAP { $1[MAX] = 0; $result = caml_list_append($result,caml_val_string(str)); } %enddef /* * %cstring_chunk_output(TYPEMAP, SIZE) * * This macro is used to return a chunk of binary string data. * Embedded NULLs are okay. For example: * * %cstring_chunk_output(char *outx, 512); * void foo(char *outx) { * memmove(outx, somedata, 512); * } * */ %define %cstring_chunk_output(TYPEMAP,SIZE) %typemap(ignore) TYPEMAP(char temp[SIZE]) { $1 = ($1_ltype) temp; } %typemap(argout) TYPEMAP { $result = caml_list_append($result,caml_val_string_len($1,SIZE)); } %enddef /* * %cstring_bounded_mutable(TYPEMAP, SIZE) * * This macro is used to wrap a string that's going to mutate. * * %cstring_bounded_mutable(char *in, 512); * void foo(in *x) { * while (*x) { * *x = toupper(*x); * x++; * } * } * */ %define %cstring_bounded_mutable(TYPEMAP,MAX) %typemap(in) TYPEMAP(char temp[MAX+1]) { char *t = (char *)caml_ptr_val($input); strncpy(temp,t,MAX); $1 = ($1_ltype) temp; } %typemap(argout) TYPEMAP { $result = caml_list_append($result,caml_val_string_len($1,MAX)); } %enddef /* * %cstring_mutable(TYPEMAP [, expansion]) * * This macro is used to wrap a string that will mutate in place. * It may change size up to a user-defined expansion. * * %cstring_mutable(char *in); * void foo(in *x) { * while (*x) { * *x = toupper(*x); * x++; * } * } * */ %define %cstring_mutable(TYPEMAP,...) %typemap(in) TYPEMAP { char *t = String_val($input); int n = string_length($input); $1 = ($1_ltype) t; #if #__VA_ARGS__ == "" #if __cplusplus $1 = ($1_ltype) new char[n+1]; #else $1 = ($1_ltype) malloc(n+1); #endif #else #if __cplusplus $1 = ($1_ltype) new char[n+1+__VA_ARGS__]; #else $1 = ($1_ltype) malloc(n+1+__VA_ARGS__); #endif #endif memmove($1,t,n); $1[n] = 0; } %typemap(argout) TYPEMAP { $result = caml_list_append($result,caml_val_string($1)); #if __cplusplus delete[] $1; #else free($1); #endif } %enddef /* * %cstring_output_maxsize(TYPEMAP, SIZE) * * This macro returns data in a string of some user-defined size. * * %cstring_output_maxsize(char *outx, int max) { * void foo(char *outx, int max) { * sprintf(outx,"blah blah\n"); * } */ %define %cstring_output_maxsize(TYPEMAP, SIZE) %typemap(in) (TYPEMAP, SIZE) { $2 = caml_val_long($input); #ifdef __cplusplus $1 = ($1_ltype) new char[$2+1]; #else $1 = ($1_ltype) malloc($2+1); #endif } %typemap(argout) (TYPEMAP,SIZE) { $result = caml_list_append($result,caml_val_string($1)); #ifdef __cplusplus delete [] $1; #else free($1); #endif } %enddef /* * %cstring_output_withsize(TYPEMAP, SIZE) * * This macro is used to return character data along with a size * parameter. * * %cstring_output_maxsize(char *outx, int *max) { * void foo(char *outx, int *max) { * sprintf(outx,"blah blah\n"); * *max = strlen(outx); * } */ %define %cstring_output_withsize(TYPEMAP, SIZE) %typemap(in) (TYPEMAP, SIZE) { int n = caml_val_long($input); #ifdef __cplusplus $1 = ($1_ltype) new char[n+1]; $2 = ($2_ltype) new $*1_ltype; #else $1 = ($1_ltype) malloc(n+1); $2 = ($2_ltype) malloc(sizeof($*1_ltype)); #endif *$2 = n; } %typemap(argout) (TYPEMAP,SIZE) { $result = caml_list_append($result,caml_val_string_len($1,$2)); #ifdef __cplusplus delete [] $1; delete $2; #else free($1); free($2); #endif } %enddef /* * %cstring_output_allocate(TYPEMAP, RELEASE) * * This macro is used to return character data that was * allocated with new or malloc. * * %cstring_output_allocated(char **outx, free($1)); * void foo(char **outx) { * *outx = (char *) malloc(512); * sprintf(outx,"blah blah\n"); * } */ %define %cstring_output_allocate(TYPEMAP, RELEASE) %typemap(ignore) TYPEMAP($*1_ltype temp = 0) { $1 = &temp; } %typemap(argout) TYPEMAP { if (*$1) { $result = caml_list_append($result,caml_val_string($1)); RELEASE; } else { $result = caml_list_append($result,caml_val_ptr($1)); } } %enddef /* * %cstring_output_allocate_size(TYPEMAP, SIZE, RELEASE) * * This macro is used to return character data that was * allocated with new or malloc. * * %cstring_output_allocated(char **outx, int *sz, free($1)); * void foo(char **outx, int *sz) { * *outx = (char *) malloc(512); * sprintf(outx,"blah blah\n"); * *sz = strlen(outx); * } */ %define %cstring_output_allocate_size(TYPEMAP, SIZE, RELEASE) %typemap(ignore) (TYPEMAP, SIZE) ($*1_ltype temp = 0, $*2_ltype tempn) { $1 = &temp; $2 = &tempn; } %typemap(argout)(TYPEMAP,SIZE) { if (*$1) { $result = caml_list_append($result,caml_val_string_len($1,$2)); RELEASE; } else $result = caml_list_append($result,caml_val_ptr($1)); } %enddef cableswig-0.1.0+git20150808.orig/SWIG/Lib/ocaml/carray.i0000644000175000000620000000626412561312227021042 0ustar stevestaff%insert(mli) %{ type _value = c_obj %} %insert(ml) %{ type _value = c_obj %} %define %array_tmap_out(type,what,out_f) %typemap(type) what [ANY] { int i; /* $*1_type */ $result = caml_array_new($1_dim0); for( i = 0; i < $1_dim0; i++ ) { caml_array_set($result,i,out_f($1[i])); } } %enddef %define %array_tmap_in(type,what,in_f) %typemap(type) what [ANY] { int i; /* $*1_type */ $1 = ($*1_type *)malloc( $1_size ); for( i = 0; i < $1_dim0 && i < caml_array_len($input); i++ ) { $1[i] = in_f(caml_array_nth($input,i)); } } %typemap(free) what [ANY] { free( (void *)$1 ); } %enddef %define %make_simple_array_typemap(type,out_f,in_f) %array_tmap_out(out,type,out_f); %array_tmap_out(varout,type,out_f); %array_tmap_out(directorin,type,out_f); %array_tmap_in(in,type,in_f); %array_tmap_in(varin,type,in_f); %array_tmap_in(directorout,type,in_f); %enddef %make_simple_array_typemap(bool,caml_val_bool,caml_long_val); %make_simple_array_typemap(short,caml_val_short,caml_long_val); %make_simple_array_typemap(unsigned short,caml_val_ushort,caml_long_val); %make_simple_array_typemap(int,caml_val_int,caml_long_val); %make_simple_array_typemap(unsigned int,caml_val_uint,caml_long_val); %make_simple_array_typemap(long,caml_val_long,caml_long_val); %make_simple_array_typemap(unsigned long,caml_val_ulong,caml_long_val); %make_simple_array_typemap(size_t,caml_val_int,caml_long_val); %make_simple_array_typemap(float,caml_val_float,caml_double_val); %make_simple_array_typemap(double,caml_val_double,caml_double_val); #ifdef __cplusplus %typemap(in) SWIGTYPE [] { int i; /* $*1_type */ $1 = new $*1_type [$1_dim0]; for( i = 0; i < $1_dim0 && i < caml_array_len($input); i++ ) { $1[i] = *(($*1_ltype *) caml_ptr_val(caml_array_nth($input,i), $*1_descriptor)) ; } } #else %typemap(in) SWIGTYPE [] { int i; /* $*1_type */ $1 = ($*1_type *)malloc( $1_size ); for( i = 0; i < $1_dim0 && i < caml_array_len($input); i++ ) { $1[i] = *(($*1_ltype) caml_ptr_val(caml_array_nth($input), $*1_descriptor)); } } #endif %typemap(out) SWIGTYPE [] { int i; CAML_VALUE *fromval = caml_named_value("create_$ntype_from_ptr"); $result = caml_array_new($1_dim0); for( i = 0; i < $1_dim0; i++ ) { if( fromval ) { caml_array_set ($result, i, callback(*fromval,caml_val_ptr((void *)&$1[i],$*1_descriptor))); } else { caml_array_set ($result, i, caml_val_ptr ((void *)&$1[i],$&1_descriptor)); } } } %typemap(in) enum SWIGTYPE [] { int i; /* $*1_type */ $1 = ($*1_type *)malloc( $1_size ); for( i = 0; i < $1_dim0 && i < caml_array_len($input); i++ ) { $1[i] = ($type) caml_long_val_full(caml_array_nth($input), "$type_marker"); } } %typemap(out) enum SWIGTYPE [] { int i; $result = caml_array_new($1_dim0); for( i = 0; i < $1_dim0; i++ ) { caml_array_set ($result, i, callback2(*caml_named_value(SWIG_MODULE "_int_to_enum"), *caml_named_value("$type_marker"), Val_int($1[i]))); } } #ifdef __cplusplus %typemap(freearg) SWIGTYPE [ANY] { delete [] $1; } #else %typemap(freearg) SWIGTYPE [ANY] { free( (void *)$1 ); } #endif cableswig-0.1.0+git20150808.orig/SWIG/Lib/ocaml/mliheading.swg0000644000175000000620000000004012561312227022214 0ustar stevestaff(* -*- tuareg -*- *) open Swig cableswig-0.1.0+git20150808.orig/SWIG/Lib/ocaml/swig.ml0000644000175000000620000001024012561312227020677 0ustar stevestaff(* -*- tuareg -*- *) open Int32 open Int64 type 'a c_obj_t = C_void | C_bool of bool | C_char of char | C_uchar of char | C_short of int | C_ushort of int | C_int of int | C_uint of int32 | C_int32 of int32 | C_int64 of int64 | C_float of float | C_double of float | C_ptr of int64 * int64 | C_array of 'a c_obj_t array | C_list of 'a c_obj_t list | C_obj of (string -> 'a c_obj_t -> 'a c_obj_t) | C_string of string | C_enum of 'a | C_director_core of 'a c_obj_t * 'a c_obj_t option ref type empty_enum = [ `SWIGFake | `Int of int ] exception BadArgs of string exception BadMethodName of string * string exception NotObject of empty_enum c_obj_t exception NotEnumType of empty_enum c_obj_t exception LabelNotFromThisEnum of empty_enum c_obj_t exception InvalidDirectorCall of empty_enum c_obj_t let rec invoke obj = match obj with C_obj o -> o | C_director_core (o,r) -> invoke o | _ -> raise (NotObject (Obj.magic obj)) let _ = Callback.register "swig_runmethod" invoke let fnhelper fin f arg = let args = match arg with C_list l -> l | C_void -> [] | _ -> [ arg ] in match f args with [] -> C_void | [ x ] -> (if fin then Gc.finalise (fun x -> ignore ((invoke x) "~" C_void)) x) ; x | lst -> C_list lst let rec get_int x = match x with C_bool b -> if b then 1 else 0 | C_char c | C_uchar c -> (int_of_char c) | C_short s | C_ushort s | C_int s -> s | C_uint u | C_int32 u -> (Int32.to_int u) | C_int64 u -> (Int64.to_int u) | C_float f -> (int_of_float f) | C_double d -> (int_of_float d) | C_ptr (p,q) -> (Int64.to_int p) | C_obj o -> (try (get_int (o "int" C_void)) with _ -> (get_int (o "&" C_void))) | _ -> raise (Failure "Can't convert to int") let rec get_float x = match x with C_char c | C_uchar c -> (float_of_int (int_of_char c)) | C_short s -> (float_of_int s) | C_ushort s -> (float_of_int s) | C_int s -> (float_of_int s) | C_uint u | C_int32 u -> (float_of_int (Int32.to_int u)) | C_int64 u -> (float_of_int (Int64.to_int u)) | C_float f -> f | C_double d -> d | C_obj o -> (try (get_float (o "float" C_void)) with _ -> (get_float (o "double" C_void))) | _ -> raise (Failure "Can't convert to float") let rec get_char x = (char_of_int (get_int x)) let rec get_string x = match x with C_string str -> str | _ -> raise (Failure "Can't convert to string") let rec get_bool x = match x with C_bool b -> b | _ -> (try if get_int x != 0 then true else false with _ -> raise (Failure "Can't convert to bool")) let disown_object obj = match obj with C_director_core (o,r) -> r := None | _ -> raise (Failure "Not a director core object") let _ = Callback.register "caml_obj_disown" disown_object let addr_of obj = match obj with C_obj _ -> (invoke obj) "&" C_void | C_director_core (self,r) -> (invoke self) "&" C_void | C_ptr _ -> obj | _ -> raise (Failure "Not a pointer.") let _ = Callback.register "caml_obj_ptr" addr_of let convert_c_obj a = Obj.magic a let make_float f = C_float f let make_double f = C_double f let make_string s = C_string s let make_bool b = C_bool b let make_char c = C_char c let make_char_i c = C_char (char_of_int c) let make_uchar c = C_uchar c let make_uchar_i c = C_uchar (char_of_int c) let make_short i = C_short i let make_ushort i = C_ushort i let make_int i = C_int i let make_uint i = C_uint (Int32.of_int i) let make_int32 i = C_int32 (Int32.of_int i) let make_int64 i = C_int64 (Int64.of_int i) let new_derived_object cfun x_class args = begin let get_object ob = match !ob with None -> raise (NotObject C_void) | Some o -> o in let ob_ref = ref None in let class_fun class_f ob_r = (fun meth args -> class_f (get_object ob_r) meth args) in let new_class = class_fun x_class ob_ref in let dircore = C_director_core (C_obj new_class,ob_ref) in let obj = cfun (match args with C_list argl -> (C_list ((dircore :: argl))) | C_void -> (C_list [ dircore ]) | a -> (C_list [ dircore ; a ])) in ob_ref := Some obj ; obj end cableswig-0.1.0+git20150808.orig/SWIG/Lib/ocaml/swigp4.ml0000644000175000000620000001346612561312227021160 0ustar stevestaffopen Pcaml ;; let lap x y = x :: y let c_ify e loc = match e with <:expr< $int:_$ >> -> <:expr< (C_int $e$) >> | <:expr< $str:_$ >> -> <:expr< (C_string $e$) >> | <:expr< $chr:_$ >> -> <:expr< (C_char $e$) >> | <:expr< $flo:_$ >> -> <:expr< (C_double $e$) >> | <:expr< True >> -> <:expr< (C_bool $e$) >> | <:expr< False >> -> <:expr< (C_bool $e$) >> | _ -> <:expr< $e$ >> let mk_list args loc f = let rec mk_list_inner args loc f = match args with [] -> <:expr< [] >> | x :: xs -> (let loc = MLast.loc_of_expr x in <:expr< [ ($f x loc$) ] @ ($mk_list_inner xs loc f$) >>) in match args with [] -> <:expr< (Obj.magic C_void) >> | [ a ] -> <:expr< (Obj.magic $f a loc$) >> | _ -> <:expr< (Obj.magic (C_list ($mk_list_inner args loc f$))) >> EXTEND expr: [ [ e1 = expr ; "'" ; "[" ; e2 = expr ; "]" -> <:expr< (invoke $e1$) "[]" (C_list [ $c_ify e2 loc$ ]) >> | e1 = expr ; "->" ; l = LIDENT ; "(" ; args = LIST0 (expr LEVEL "simple") SEP "," ; ")" -> <:expr< (invoke $e1$) $str:l$ ($mk_list args loc c_ify$) >> | e1 = expr ; "->" ; u = UIDENT ; "(" ; args = LIST0 (expr LEVEL "simple") SEP "," ; ")" -> <:expr< (invoke $e1$) $str:u$ ($mk_list args loc c_ify$) >> | e1 = expr ; "->" ; s = expr LEVEL "simple" ; "(" ; args = LIST0 (expr LEVEL "simple") SEP "," ; ")" -> <:expr< (invoke $e1$) $s$ ($mk_list args loc c_ify$) >> | e1 = expr ; "'" ; "." ; "(" ; args = LIST0 (expr LEVEL "simple") SEP "," ; ")" -> <:expr< (invoke $e1$) "()" ($mk_list args loc c_ify$) >> | e1 = expr ; "'" ; "->" ; l = LIDENT ; "(" ; args = LIST0 (expr LEVEL "simple") SEP "," ; ")" -> <:expr< (invoke ((invoke $e1$) "->" C_void)) $str:l$ ($mk_list args loc c_ify$) >> | e1 = expr ; "'" ; "->" ; u = UIDENT ; "(" ; args = LIST0 (expr LEVEL "simple") SEP "," ; ")" -> <:expr< (invoke ((invoke $e1$) "->" C_void)) $str:u$ ($mk_list args loc c_ify$) >> | e1 = expr ; "'" ; "->" ; s = expr LEVEL "simple" ; "(" ; args = LIST0 (expr LEVEL "simple") SEP "," ; ")" -> <:expr< (invoke ((invoke $e1$) "->" C_void)) $s$ ($mk_list args loc c_ify$) >> | e1 = expr ; "'" ; "++" -> <:expr< (invoke $e1$) "++" C_void >> | e1 = expr ; "'" ; "--" -> <:expr< (invoke $e1$) "--" C_void >> | e1 = expr ; "'" ; "-" ; e2 = expr -> <:expr< (invoke $e1$) "-" (C_list [ $c_ify e2 loc$ ]) >> | e1 = expr ; "'" ; "+" ; e2 = expr -> <:expr< (invoke $e1$) "+" (C_list [ $c_ify e2 loc$ ]) >> | e1 = expr ; "'" ; "*" ; e2 = expr -> <:expr< (invoke $e1$) "*" (C_list [ $c_ify e2 loc$ ]) >> | "'" ; "&" ; e1 = expr -> <:expr< (invoke $e1$) "&" C_void >> | "'" ; "!" ; e1 = expr -> <:expr< (invoke $e1$) "!" C_void >> | "'" ; "~" ; e1 = expr -> <:expr< (invoke $e1$) "~" C_void >> | e1 = expr ; "'" ; "/" ; e2 = expr -> <:expr< (invoke $e1$) "/" (C_list [ $c_ify e2 loc$ ]) >> | e1 = expr ; "'" ; "%" ; e2 = expr -> <:expr< (invoke $e1$) "%" (C_list [ $c_ify e2 loc$ ]) >> | e1 = expr ; "'" ; "lsl" ; e2 = expr -> <:expr< (invoke $e1$) ("<" ^ "<") (C_list [ $c_ify e2 loc$ ]) >> | e1 = expr ; "'" ; "lsr" ; e2 = expr -> <:expr< (invoke $e1$) (">" ^ ">") (C_list [ $c_ify e2 loc$ ]) >> | e1 = expr ; "'" ; "<" ; e2 = expr -> <:expr< (invoke $e1$) "<" (C_list [ $c_ify e2 loc$ ]) >> | e1 = expr ; "'" ; "<=" ; e2 = expr -> <:expr< (invoke $e1$) "<=" (C_list [ $c_ify e2 loc$ ]) >> | e1 = expr ; "'" ; ">" ; e2 = expr -> <:expr< (invoke $e1$) ">" (C_list [ $c_ify e2 loc$ ]) >> | e1 = expr ; "'" ; ">=" ; e2 = expr -> <:expr< (invoke $e1$) ">=" (C_list [ $c_ify e2 loc$ ]) >> | e1 = expr ; "'" ; "==" ; e2 = expr -> <:expr< (invoke $e1$) "==" (C_list [ $c_ify e2 loc$ ]) >> | e1 = expr ; "'" ; "!=" ; e2 = expr -> <:expr< (invoke $e1$) "!=" (C_list [ $c_ify e2 loc$ ]) >> | e1 = expr ; "'" ; "&" ; e2 = expr -> <:expr< (invoke $e1$) "&" (C_list [ $c_ify e2 loc$ ]) >> | e1 = expr ; "'" ; "^" ; e2 = expr -> <:expr< (invoke $e1$) "^" (C_list [ $c_ify e2 loc$ ]) >> | e1 = expr ; "'" ; "|" ; e2 = expr -> <:expr< (invoke $e1$) "|" (C_list [ $c_ify e2 loc$ ]) >> | e1 = expr ; "'" ; "&&" ; e2 = expr -> <:expr< (invoke $e1$) "&&" (C_list [ $c_ify e2 loc$ ]) >> | e1 = expr ; "'" ; "||" ; e2 = expr -> <:expr< (invoke $e1$) "||" (C_list [ $c_ify e2 loc$ ]) >> | e1 = expr ; "'" ; "=" ; e2 = expr -> <:expr< (invoke $e1$) "=" (C_list [ $c_ify e2 loc$ ]) >> | e1 = expr ; "'" ; "+=" ; e2 = expr -> <:expr< (invoke $e1$) "+=" (C_list [ $c_ify e2 loc$ ]) >> | e1 = expr ; "'" ; "-=" ; e2 = expr -> <:expr< (invoke $e1$) "-=" (C_list [ $c_ify e2 loc$ ]) >> | e1 = expr ; "'" ; "*=" ; e2 = expr -> <:expr< (invoke $e1$) "*=" (C_list [ $c_ify e2 loc$ ]) >> | e1 = expr ; "'" ; "/=" ; e2 = expr -> <:expr< (invoke $e1$) "/=" (C_list [ $c_ify e2 loc$ ]) >> | e1 = expr ; "'" ; "%=" ; e2 = expr -> <:expr< (invoke $e1$) "%=" (C_list [ $c_ify e2 loc$ ]) >> | e1 = expr ; "'" ; "lsl" ; "=" ; e2 = expr -> <:expr< (invoke $e1$) ("<" ^ "<=") (C_list [ $c_ify e2 loc$ ]) >> | e1 = expr ; "'" ; "lsr" ; "=" ; e2 = expr -> <:expr< (invoke $e1$) (">" ^ ">=") (C_list [ $c_ify e2 loc$ ]) >> | e1 = expr ; "'" ; "&=" ; e2 = expr -> <:expr< (invoke $e1$) "&=" (C_list [ $c_ify e2 loc$ ]) >> | e1 = expr ; "'" ; "^=" ; e2 = expr -> <:expr< (invoke $e1$) "^=" (C_list [ $c_ify e2 loc$ ]) >> | e1 = expr ; "'" ; "|=" ; e2 = expr -> <:expr< (invoke $e1$) "|=" (C_list [ $c_ify e2 loc$ ]) >> | "'" ; e = expr -> c_ify e loc | c = expr ; "as" ; id = LIDENT -> <:expr< $lid:"get_" ^ id$ $c$ >> | c = expr ; "to" ; id = LIDENT -> <:expr< $uid:"C_" ^ id$ $c$ >> | "`" ; "`" ; l = LIDENT -> <:expr< C_enum `$lid:l$ >> | "`" ; "`" ; u = UIDENT -> <:expr< C_enum `$uid:u$ >> | f = expr ; "'" ; "(" ; args = LIST0 (expr LEVEL "simple") SEP "," ; ")" -> <:expr< $f$ ($mk_list args loc c_ify$) >> ] ] ; END ;; cableswig-0.1.0+git20150808.orig/SWIG/Lib/ocaml/ocamldec.swg0000644000175000000620000001117312561312227021673 0ustar stevestaff/* -*-c-*- * ----------------------------------------------------------------------- * ocaml/ocamldec.swg * Copyright (C) 2000, 2001 Matthias Koeppe * * Ocaml runtime code -- declarations * ----------------------------------------------------------------------- */ #include #include #include #ifdef __cplusplus #define SWIGEXT extern "C" SWIGEXT { #else #define SWIGEXT #endif #define value caml_value_t #define CAML_VALUE caml_value_t #define alloc caml_alloc #include #include #include #include #include #include #include #undef alloc // Adapted from memory.h and mlvalues.h #define SWIG_CAMLlocal1(x) \ caml_value_t x = 0; \ CAMLxparam1 (x) #define SWIG_CAMLlocal2(x, y) \ caml_value_t x = 0, y = 0; \ CAMLxparam2 (x, y) #define SWIG_CAMLlocal3(x, y, z) \ caml_value_t x = 0, y = 0, z = 0; \ CAMLxparam3 (x, y, z) #define SWIG_CAMLlocal4(x, y, z, t) \ caml_value_t x = 0, y = 0, z = 0, t = 0; \ CAMLxparam4 (x, y, z, t) #define SWIG_CAMLlocal5(x, y, z, t, u) \ caml_value_t x = 0, y = 0, z = 0, t = 0, u = 0; \ CAMLxparam5 (x, y, z, t, u) #define SWIG_CAMLlocalN(x, size) \ caml_value_t x [(size)] = { 0, /* 0, 0, ... */ }; \ CAMLxparamN (x, (size)) #define SWIG_Field(x, i) (((caml_value_t *)(x)) [i]) /* Also an l-value. */ #define SWIG_Store_field(block, offset, val) do{ \ mlsize_t caml__temp_offset = (offset); \ caml_value_t caml__temp_val = (val); \ modify (&SWIG_Field ((block), caml__temp_offset), caml__temp_val); \ }while(0) #define SWIG_Data_custom_val(v) ((void *) &SWIG_Field((v), 1)) #ifdef ARCH_BIG_ENDIAN #define SWIG_Tag_val(val) (((unsigned char *) (val)) [-1]) /* Also an l-value. */ #define SWIG_Tag_hp(hp) (((unsigned char *) (hp)) [sizeof(caml_value_t)-1]) /* Also an l-value. */ #else #define SWIG_Tag_val(val) (((unsigned char *) (val)) [-sizeof(caml_value_t)]) /* Also an l-value. */ #define SWIG_Tag_hp(hp) (((unsigned char *) (hp)) [0]) /* Also an l-value. */ #endif #ifndef ARCH_ALIGN_INT64 #define SWIG_Int64_val(v) (*((int64 *) SWIG_Data_custom_val(v))) #else CAMLextern int64 Int64_val(caml_value_t v); #define SWIG_Int64_val(v) Int64_val(v) #endif #if defined(SWIG_NOINCLUDE) # define SWIGSTATIC #elif defined(SWIG_GLOBAL) # define SWIGSTATIC #else # define SWIGSTATIC static #endif #define SWIG_NewPointerObj(p,type,flags) caml_val_ptr(p,type) #define SWIG_contract_assert(expr, msg) if(!(expr)) {failwith(msg);} else SWIGSTATIC int SWIG_GetPtr(void *source, void **result, swig_type_info *type, swig_type_info *result_type); SWIGSTATIC void * SWIG_MustGetPtr (CAML_VALUE v, swig_type_info *type); static CAML_VALUE _wrap_delete_void( CAML_VALUE ); static int enum_to_int( char *name, CAML_VALUE v ); static CAML_VALUE int_to_enum( char *name, int v ); static CAML_VALUE caml_list_nth( CAML_VALUE lst, int n ); static CAML_VALUE caml_list_append( CAML_VALUE lst, CAML_VALUE elt ); static int caml_list_length( CAML_VALUE lst ); static CAML_VALUE caml_array_new( int n ); static void caml_array_set( CAML_VALUE arr, int n, CAML_VALUE item ); static CAML_VALUE caml_array_nth( CAML_VALUE arr, int n ); static int caml_array_length( CAML_VALUE arr ); static CAML_VALUE caml_val_char( char c ); static CAML_VALUE caml_val_uchar( unsigned char c ); static CAML_VALUE caml_val_short( short s ); static CAML_VALUE caml_val_ushort( unsigned short s ); static CAML_VALUE caml_val_int( int x ); static CAML_VALUE caml_val_uint( unsigned int x ); static CAML_VALUE caml_val_long( long x ); static CAML_VALUE caml_val_ulong( unsigned long x ); static CAML_VALUE caml_val_float( float f ); static CAML_VALUE caml_val_double( double d ); static CAML_VALUE caml_val_ptr( void *p, swig_type_info *descriptor ); static CAML_VALUE caml_val_string( const char *str ); static CAML_VALUE caml_val_string_len( const char *str, int len ); static long caml_long_val( CAML_VALUE v ); static double caml_double_val( CAML_VALUE v ); static int caml_ptr_val_internal( CAML_VALUE v, void **out, swig_type_info *descriptor ); static void *caml_ptr_val( CAML_VALUE v, swig_type_info *descriptor ); static char *caml_string_val( CAML_VALUE v ); static int caml_string_len( CAML_VALUE v ); #ifdef __cplusplus } #endif /* mzschemedec.swg ends here */ cableswig-0.1.0+git20150808.orig/SWIG/Lib/perl5/0002755000175000000620000000000012561312227017335 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Lib/perl5/std_string.i0000644000175000000620000000352512561312227021672 0ustar stevestaff// // SWIG typemaps for std::string // Roy M. LeCates // October 23, 2002 // // Perl implementation // ------------------------------------------------------------------------ // std::string is typemapped by value // This can prevent exporting methods which return a string // in order for the user to modify it. // However, I think I'll wait until someone asks for it... // ------------------------------------------------------------------------ %include exception.i %{ #include %} namespace std { class string; /* Overloading check */ %typemap(typecheck) string = char *; %typemap(typecheck) const string & = char *; %typemap(in) string { if (!SvPOK((SV*) $input)) { SWIG_croak("Type error in argument $argnum of $symname. " "Expected a string"); } else { STRLEN len; const char *ptr = SvPV($input, len); $1.assign(ptr, len); } } %typemap(in) string *INPUT(std::string temp), const string & (std::string temp) { if (!SvPOK((SV*) $input)) { SWIG_croak("Type error in argument $argnum of $symname. " "Expected a string"); } else { STRLEN len; const char *ptr = SvPV($input, len); temp.assign(ptr, len); $1 = &temp; } } %typemap(out) string { if (argvi >= items) EXTEND(sp, 1); // bump stack ptr, if needed char *data = const_cast($1.data()); sv_setpvn($result = sv_newmortal(), data, $1.size()); ++argvi; } %typemap(out) const string & { if (argvi >= items) EXTEND(sp, 1); // bump stack ptr, if needed char *data = const_cast($1->data()); sv_setpvn($result = sv_newmortal(), data, $1->size()); ++argvi; } } cableswig-0.1.0+git20150808.orig/SWIG/Lib/perl5/std_map.i0000644000175000000620000001224712561312227021142 0ustar stevestaff// // SWIG typemaps for std::map // Luigi Ballabio // Jan. 2003 // // Common implementation %include std_common.i %include exception.i %exception std::map::get { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::map::del { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } // ------------------------------------------------------------------------ // std::map // ------------------------------------------------------------------------ %{ #include #include #include %} // exported class namespace std { template class map { // add typemaps here public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T& get(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void set(const K& key, const T& x) { (*self)[key] = x; } void del(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(const K& key) { std::map::iterator i = self->find(key); return i != self->end(); } } }; // specializations for built-ins %define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO) template class map { // add typemaps here public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T& get(K key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void set(K key, const T& x) { (*self)[key] = x; } void del(K key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(K key) { std::map::iterator i = self->find(key); return i != self->end(); } } }; %enddef %define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO) template class map { // add typemaps here public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T get(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void set(const K& key, T x) { (*self)[key] = x; } void del(const K& key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(const K& key) { std::map::iterator i = self->find(key); return i != self->end(); } } }; %enddef %define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO) template<> class map { // add typemaps here public: map(); map(const map &); unsigned int size() const; bool empty() const; void clear(); %extend { T get(K key) { std::map::iterator i = self->find(key); if (i != self->end()) return i->second; else throw std::out_of_range("key not found"); } void set(K key, T x) { (*self)[key] = x; } void del(K key) { std::map::iterator i = self->find(key); if (i != self->end()) self->erase(i); else throw std::out_of_range("key not found"); } bool has_key(K key) { std::map::iterator i = self->find(key); return i != self->end(); } } }; %enddef // add specializations here } cableswig-0.1.0+git20150808.orig/SWIG/Lib/perl5/Makefile.in0000644000175000000620000000756612561312227021416 0ustar stevestaff# --------------------------------------------------------------- # /cvsroot/SWIG/Lib/perl5/Makefile.in,v 1.3 2002/11/30 22:10:08 beazley Exp # SWIG Perl5 Makefile # # This file can be used to build various Perl5 extensions with SWIG. # By default this file is set up for dynamic loading, but it can # be easily customized for static extensions by modifying various # portions of the file. # # SRCS = C source files # CXXSRCS = C++ source files # OBJCSRCS = Objective-C source files # OBJS = Additional .o files (compiled previously) # INTERFACE = SWIG interface file # TARGET = Name of target module or executable # # Many portions of this file were created by the SWIG configure # script and should already reflect your machine. #---------------------------------------------------------------- SRCS = CXXSRCS = OBJCSRCS = OBJS = INTERFACE = WRAPFILE = $(INTERFACE:.i=_wrap.c) WRAPOBJ = $(INTERFACE:.i=_wrap.o) TARGET = module@SO@ # Use this kind of target for dynamic loading #TARGET = myperl # Use this target for static linking prefix = @prefix@ exec_prefix = @exec_prefix@ CC = @CC@ CXX = @CXX@ OBJC = @CC@ -Wno-import # -Wno-import needed for gcc CFLAGS = INCLUDES = LIBS = # SWIG Options # SWIG = location of the SWIG executable # SWIGOPT = SWIG compiler options # SWIGCC = Compiler used to compile the wrapper file SWIG = $(exec_prefix)/bin/swig SWIGOPT = -perl5 SWIGCC = $(CC) # SWIG Library files. Uncomment this to staticly rebuild Perl #SWIGLIB = -static -lperlmain.i # Rules for creating .o files from source. COBJS = $(SRCS:.c=.o) CXXOBJS = $(CXXSRCS:.cxx=.o) OBJCOBJS = $(OBJCSRCS:.m=.o) ALLOBJS = $(COBJS) $(CXXOBJS) $(OBJCOBJS) $(OBJS) # Command that will be used to build the final extension. BUILD = $(SWIGCC) # Uncomment the following if you are using dynamic loading CCSHARED = @CCSHARED@ BUILD = @LDSHARED@ # Uncomment the following if you are using dynamic loading with C++ and # need to provide additional link libraries (this is not always required). #DLL_LIBS = -L/usr/local/lib/gcc-lib/sparc-sun-solaris2.5.1/2.7.2 \ -L/usr/local/lib -lg++ -lstdc++ -lgcc # X11 installation (possibly needed if using Perl-Tk) XLIB = @XLIBSW@ XINCLUDE = @XINCLUDES@ # Perl installation PERL_INCLUDE = -I@PERL5EXT@ PERL_LIB = -L@PERL5EXT@ -lperl PERL_FLAGS = -Dbool=char -Dexplicit= # Tcl installation. If using Tk you might need this TCL_INCLUDE = @TCLINCLUDE@ TCL_LIB = @TCLLIB@ # Build libraries (needed for static builds) LIBM = @LIBM@ LIBC = @LIBC@ SYSLIBS = $(LIBM) $(LIBC) @LIBS@ # Build options (uncomment only one these) #TK_LIB = $(TCL_LIB) -ltcl -ltk $(XLIB) BUILD_LIBS = $(LIBS) # Dynamic loading #BUILD_LIBS = $(PERL_LIB) $(TK_LIB) $(LIBS) $(SYSLIBS) # Static linking # Compilation rules for non-SWIG components .SUFFIXES: .c .cxx .m .c.o: $(CC) $(CCSHARED) $(CFLAGS) $(INCLUDES) -c $< .cxx.o: $(CXX) $(CCSHARED) $(CXXFLAGS) $(INCLUDES) -c $< .m.o: $(OBJC) $(CCSHARED) $(CFLAGS) $(INCLUDES) -c $< # ---------------------------------------------------------------------- # Rules for building the extension # ---------------------------------------------------------------------- all: $(TARGET) # Convert the wrapper file into an object file $(WRAPOBJ) : $(WRAPFILE) $(SWIGCC) -c $(CCSHARED) $(CFLAGS) $(INCLUDES) $(PERL_INCLUDE) $(PERL_FLAGS) $(WRAPFILE) $(WRAPFILE) : $(INTERFACE) $(SWIG) $(SWIGOPT) -o $(WRAPFILE) $(SWIGLIB) $(INTERFACE) $(TARGET): $(WRAPOBJ) $(ALLOBJS) $(BUILD) $(WRAPOBJ) $(ALLOBJS) $(BUILD_LIBS) -o $(TARGET) clean: rm -f $(COBJS) $(CXXOBJS) $(OBJCOBJS) $(WRAPOBJ) $(WRAPFILE) $(TARGET) cableswig-0.1.0+git20150808.orig/SWIG/Lib/perl5/std_common.i0000644000175000000620000000064212561312227021651 0ustar stevestaff// // SWIG typemaps for STL - common utilities // Luigi Ballabio // May 16, 2003 // // Perl implementation %apply size_t { std::size_t }; %{ #include double SwigSvToNumber(SV* sv) { return SvIOK(sv) ? double(SvIVX(sv)) : SvNVX(sv); } std::string SwigSvToString(SV* sv) { STRLEN len; return SvPV(sv,len); } void SwigSvFromString(SV* sv, const std::string& s) { sv_setpv(sv,s.c_str()); } %} cableswig-0.1.0+git20150808.orig/SWIG/Lib/perl5/typemaps.i0000644000175000000620000004365012561312227021357 0ustar stevestaff// // SWIG Typemap library // Dave Beazley // May 5, 1997 // // Perl5 implementation // // This library provides standard typemaps for modifying SWIG's behavior. // With enough entries in this file, I hope that very few people actually // ever need to write a typemap. // /* The SWIG typemap library provides a language independent mechanism for supporting output arguments, input values, and other C function calling mechanisms. The primary use of the library is to provide a better interface to certain C function--especially those involving pointers. */ // INPUT typemaps. // These remap a C pointer to be an "INPUT" value which is passed by value // instead of reference. /* The following methods can be applied to turn a pointer into a simple "input" value. That is, instead of passing a pointer to an object, you would use a real value instead. int *INPUT short *INPUT long *INPUT long long *INPUT unsigned int *INPUT unsigned short *INPUT unsigned long *INPUT unsigned long long *INPUT unsigned char *INPUT bool *INPUT float *INPUT double *INPUT To use these, suppose you had a C function like this : double fadd(double *a, double *b) { return *a+*b; } You could wrap it with SWIG as follows : %include typemaps.i double fadd(double *INPUT, double *INPUT); or you can use the %apply directive : %include typemaps.i %apply double *INPUT { double *a, double *b }; double fadd(double *a, double *b); */ %define INPUT_TYPEMAP(type, converter) %typemap(in) type *INPUT(type temp), type &INPUT(type temp) { temp = (type) converter($input); $1 = &temp; } %typemap(typecheck) type *INPUT = type; %typemap(typecheck) type &INPUT = type; %enddef INPUT_TYPEMAP(float, SvNV); INPUT_TYPEMAP(double, SvNV); INPUT_TYPEMAP(int, SvIV); INPUT_TYPEMAP(long, SvIV); INPUT_TYPEMAP(short, SvIV); INPUT_TYPEMAP(signed char, SvIV); INPUT_TYPEMAP(unsigned int, SvUV); INPUT_TYPEMAP(unsigned long, SvUV); INPUT_TYPEMAP(unsigned short, SvUV); INPUT_TYPEMAP(unsigned char, SvUV); INPUT_TYPEMAP(bool, SvIV); %typemap(in) long long *INPUT($*1_ltype temp), long long &INPUT($*1_ltype temp) { temp = strtoll(SvPV($input,PL_na), 0, 0); $1 = &temp; } %typemap(typecheck) long long *INPUT = long long; %typemap(typecheck) long long &INPUT = long long; %typemap(in) unsigned long long *INPUT($*1_ltype temp), unsigned long long &INPUT($*1_ltype temp) { temp = strtoull(SvPV($input,PL_na), 0, 0); $1 = &temp; } %typemap(typecheck) unsigned long long *INPUT = unsigned long long; %typemap(typecheck) unsigned long long &INPUT = unsigned long long; #undef INPUT_TYPEMAP // OUTPUT typemaps. These typemaps are used for parameters that // are output only. The output value is appended to the result as // a list element. /* The following methods can be applied to turn a pointer into an "output" value. When calling a function, no input value would be given for a parameter, but an output value would be returned. In the case of multiple output values, functions will return a Perl array. int *OUTPUT short *OUTPUT long *OUTPUT long long *OUTPUT unsigned int *OUTPUT unsigned short *OUTPUT unsigned long *OUTPUT unsigned long long *OUTPUT unsigned char *OUTPUT bool *OUTPUT float *OUTPUT double *OUTPUT For example, suppose you were trying to wrap the modf() function in the C math library which splits x into integral and fractional parts (and returns the integer part in one of its parameters).: double modf(double x, double *ip); You could wrap it with SWIG as follows : %include typemaps.i double modf(double x, double *OUTPUT); or you can use the %apply directive : %include typemaps.i %apply double *OUTPUT { double *ip }; double modf(double x, double *ip); The Perl output of the function would be an array containing both output values. */ // Force the argument to be ignored. %typemap(in,numinputs=0) int *OUTPUT(int temp), int &OUTPUT(int temp), short *OUTPUT(short temp), short &OUTPUT(short temp), long *OUTPUT(long temp), long &OUTPUT(long temp), unsigned int *OUTPUT(unsigned int temp), unsigned int &OUTPUT(unsigned int temp), unsigned short *OUTPUT(unsigned short temp), unsigned short &OUTPUT(unsigned short temp), unsigned long *OUTPUT(unsigned long temp), unsigned long &OUTPUT(unsigned long temp), unsigned char *OUTPUT(unsigned char temp), unsigned char &OUTPUT(unsigned char temp), signed char *OUTPUT(signed char temp), signed char &OUTPUT(signed char temp), bool *OUTPUT(bool temp), bool &OUTPUT(bool temp), float *OUTPUT(float temp), float &OUTPUT(float temp), double *OUTPUT(double temp), double &OUTPUT(double temp), long long *OUTPUT($*1_ltype temp), long long &OUTPUT($*1_ltype temp), unsigned long long *OUTPUT($*1_ltype temp), unsigned long long &OUTPUT($*1_ltype temp) "$1 = &temp;"; %typemap(argout) int *OUTPUT, int &OUTPUT, short *OUTPUT, short &OUTPUT, long *OUTPUT, long &OUTPUT, signed char *OUTPUT, signed char &OUTPUT, bool *OUTPUT, bool &OUTPUT { if (argvi >= items) { EXTEND(sp,1); } $result = sv_newmortal(); sv_setiv($result,(IV) *($1)); argvi++; } %typemap(argout) unsigned int *OUTPUT, unsigned int &OUTPUT, unsigned short *OUTPUT, unsigned short &OUTPUT, unsigned long *OUTPUT, unsigned long &OUTPUT, unsigned char *OUTPUT, unsigned char &OUTPUT { if (argvi >= items) { EXTEND(sp,1); } $result = sv_newmortal(); sv_setuv($result,(UV) *($1)); argvi++; } %typemap(argout) float *OUTPUT, float &OUTPUT, double *OUTPUT, double &OUTPUT { if (argvi >= items) { EXTEND(sp,1); } $result = sv_newmortal(); sv_setnv($result,(double) *($1)); argvi++; } %typemap(argout) long long *OUTPUT, long long &OUTPUT { char temp[256]; if (argvi >= items) { EXTEND(sp,1); } sprintf(temp,"%lld", $1); $result = sv_newmortal(); sv_setpv($result,temp); argvi++; } %typemap(argout) unsigned long long *OUTPUT, unsigned long long &OUTPUT { char temp[256]; if (argvi >= items) { EXTEND(sp,1); } sprintf(temp,"%llu", $1); $result = sv_newmortal(); sv_setpv($result,temp); argvi++; } // INOUT // Mappings for an argument that is both an input and output // parameter /* The following methods can be applied to make a function parameter both an input and output value. This combines the behavior of both the "INPUT" and "OUTPUT" methods described earlier. Output values are returned in the form of a Perl array. int *INOUT short *INOUT long *INOUT long long *INOUT unsigned int *INOUT unsigned short *INOUT unsigned long *INOUT unsigned long long *INOUT unsigned char *INOUT bool *INOUT float *INOUT double *INOUT For example, suppose you were trying to wrap the following function : void neg(double *x) { *x = -(*x); } You could wrap it with SWIG as follows : %include typemaps.i void neg(double *INOUT); or you can use the %apply directive : %include typemaps.i %apply double *INOUT { double *x }; void neg(double *x); Unlike C, this mapping does not directly modify the input value. Rather, the modified input value shows up as the return value of the function. Thus, to apply this function to a Perl variable you might do this : $x = neg($x); */ %typemap(in) int *INOUT = int *INPUT; %typemap(in) short *INOUT = short *INPUT; %typemap(in) long *INOUT = long *INPUT; %typemap(in) unsigned *INOUT = unsigned *INPUT; %typemap(in) unsigned short *INOUT = unsigned short *INPUT; %typemap(in) unsigned long *INOUT = unsigned long *INPUT; %typemap(in) unsigned char *INOUT = unsigned char *INPUT; %typemap(in) signed char *INOUT = signed char *INPUT; %typemap(in) bool *INOUT = bool *INPUT; %typemap(in) float *INOUT = float *INPUT; %typemap(in) double *INOUT = double *INPUT; %typemap(in) long long *INOUT = long long *INPUT; %typemap(in) unsigned long long *INOUT = unsigned long long *INPUT; %typemap(in) int &INOUT = int &INPUT; %typemap(in) short &INOUT = short &INPUT; %typemap(in) long &INOUT = long &INPUT; %typemap(in) unsigned &INOUT = unsigned &INPUT; %typemap(in) unsigned short &INOUT = unsigned short &INPUT; %typemap(in) unsigned long &INOUT = unsigned long &INPUT; %typemap(in) unsigned char &INOUT = unsigned char &INPUT; %typemap(in) signed char &INOUT = signed char &INPUT; %typemap(in) bool &INOUT = bool &INPUT; %typemap(in) float &INOUT = float &INPUT; %typemap(in) double &INOUT = double &INPUT; %typemap(in) long long &INOUT = long long &INPUT; %typemap(in) unsigned long long &INOUT = unsigned long long &INPUT; %typemap(argout) int *INOUT = int *OUTPUT; %typemap(argout) short *INOUT = short *OUTPUT; %typemap(argout) long *INOUT = long *OUTPUT; %typemap(argout) unsigned *INOUT = unsigned *OUTPUT; %typemap(argout) unsigned short *INOUT = unsigned short *OUTPUT; %typemap(argout) unsigned long *INOUT = unsigned long *OUTPUT; %typemap(argout) unsigned char *INOUT = unsigned char *OUTPUT; %typemap(argout) signed char *INOUT = signed char *OUTPUT; %typemap(argout) bool *INOUT = bool *OUTPUT; %typemap(argout) float *INOUT = float *OUTPUT; %typemap(argout) double *INOUT = double *OUTPUT; %typemap(argout) long long *INOUT = long long *OUTPUT; %typemap(argout) unsigned long long *INOUT = unsigned long long *OUTPUT; %typemap(argout) int &INOUT = int &OUTPUT; %typemap(argout) short &INOUT = short &OUTPUT; %typemap(argout) long &INOUT = long &OUTPUT; %typemap(argout) unsigned &INOUT = unsigned &OUTPUT; %typemap(argout) unsigned short &INOUT = unsigned short &OUTPUT; %typemap(argout) unsigned long &INOUT = unsigned long &OUTPUT; %typemap(argout) unsigned char &INOUT = unsigned char &OUTPUT; %typemap(argout) signed char &INOUT = signed char &OUTPUT; %typemap(argout) bool &INOUT = bool &OUTPUT; %typemap(argout) float &INOUT = float &OUTPUT; %typemap(argout) double &INOUT = double &OUTPUT; %typemap(argout) long long &INOUT = long long &OUTPUT; %typemap(argout) unsigned long long &INOUT = unsigned long long &OUTPUT; // REFERENCE // Accept Perl references as pointers /* The following methods make Perl references work like simple C pointers. References can only be used for simple input/output values, not C arrays however. It should also be noted that REFERENCES are specific to Perl and not supported in other scripting languages at this time. int *REFERENCE short *REFERENCE long *REFERENCE unsigned int *REFERENCE unsigned short *REFERENCE unsigned long *REFERENCE unsigned char *REFERENCE float *REFERENCE double *REFERENCE For example, suppose you were trying to wrap the following function : void neg(double *x) { *x = -(*x); } You could wrap it with SWIG as follows : %include typemaps.i void neg(double *REFERENCE); or you can use the %apply directive : %include typemaps.i %apply double *REFERENCE { double *x }; void neg(double *x); Unlike the INOUT mapping described previous, this approach directly modifies the value of a Perl reference. Thus, you could use it as follows : $x = 3; neg(\$x); print "$x\n"; # Should print out -3. */ %typemap(in) double *REFERENCE (double dvalue), double &REFERENCE(double dvalue) { SV *tempsv; if (!SvROK($input)) { SWIG_croak("expected a reference"); } tempsv = SvRV($input); if ((!SvNOK(tempsv)) && (!SvIOK(tempsv))) { printf("Received %d\n", SvTYPE(tempsv)); SWIG_croak("Expected a double reference."); } dvalue = SvNV(tempsv); $1 = &dvalue; } %typemap(in) float *REFERENCE (float dvalue), float &REFERENCE(float dvalue) { SV *tempsv; if (!SvROK($input)) { SWIG_croak("expected a reference"); } tempsv = SvRV($input); if ((!SvNOK(tempsv)) && (!SvIOK(tempsv))) { SWIG_croak("expected a double reference"); } dvalue = (float) SvNV(tempsv); $1 = &dvalue; } %typemap(in) int *REFERENCE (int dvalue), int &REFERENCE (int dvalue) { SV *tempsv; if (!SvROK($input)) { SWIG_croak("expected a reference"); } tempsv = SvRV($input); if (!SvIOK(tempsv)) { SWIG_croak("expected a integer reference"); } dvalue = SvIV(tempsv); $1 = &dvalue; } %typemap(in) short *REFERENCE (short dvalue), short &REFERENCE(short dvalue) { SV *tempsv; if (!SvROK($input)) { SWIG_croak("expected a reference"); } tempsv = SvRV($input); if (!SvIOK(tempsv)) { SWIG_croak("expected a integer reference"); } dvalue = (short) SvIV(tempsv); $1 = &dvalue; } %typemap(in) long *REFERENCE (long dvalue), long &REFERENCE(long dvalue) { SV *tempsv; if (!SvROK($input)) { SWIG_croak("expected a reference"); } tempsv = SvRV($input); if (!SvIOK(tempsv)) { SWIG_croak("expected a integer reference"); } dvalue = (long) SvIV(tempsv); $1 = &dvalue; } %typemap(in) unsigned int *REFERENCE (unsigned int dvalue), unsigned int &REFERENCE(unsigned int dvalue) { SV *tempsv; if (!SvROK($input)) { SWIG_croak("expected a reference"); } tempsv = SvRV($input); if (!SvIOK(tempsv)) { SWIG_croak("expected a integer reference"); } dvalue = (unsigned int) SvUV(tempsv); $1 = &dvalue; } %typemap(in) unsigned short *REFERENCE (unsigned short dvalue), unsigned short &REFERENCE(unsigned short dvalue) { SV *tempsv; if (!SvROK($input)) { SWIG_croak("expected a reference"); } tempsv = SvRV($input); if (!SvIOK(tempsv)) { SWIG_croak("expected a integer reference"); } dvalue = (unsigned short) SvUV(tempsv); $1 = &dvalue; } %typemap(in) unsigned long *REFERENCE (unsigned long dvalue), unsigned long &REFERENCE(unsigned long dvalue) { SV *tempsv; if (!SvROK($input)) { SWIG_croak("expected a reference"); } tempsv = SvRV($input); if (!SvIOK(tempsv)) { SWIG_croak("expected a integer reference"); } dvalue = (unsigned long) SvUV(tempsv); $1 = &dvalue; } %typemap(in) unsigned char *REFERENCE (unsigned char dvalue), unsigned char &REFERENCE(unsigned char dvalue) { SV *tempsv; if (!SvROK($input)) { SWIG_croak("expected a reference"); } tempsv = SvRV($input); if (!SvIOK(tempsv)) { SWIG_croak("expected a integer reference"); } dvalue = (unsigned char) SvUV(tempsv); $1 = &dvalue; } %typemap(in) signed char *REFERENCE (signed char dvalue), signed char &REFERENCE(signed char dvalue) { SV *tempsv; if (!SvROK($input)) { SWIG_croak("expected a reference"); } tempsv = SvRV($input); if (!SvIOK(tempsv)) { SWIG_croak("expected a integer reference"); } dvalue = (signed char) SvIV(tempsv); $1 = &dvalue; } %typemap(in) bool *REFERENCE (bool dvalue), bool &REFERENCE(bool dvalue) { SV *tempsv; if (!SvROK($input)) { SWIG_croak("expected a reference"); } tempsv = SvRV($input); if (!SvIOK(tempsv)) { SWIG_croak("expected a integer reference"); } dvalue = (bool) SvIV(tempsv); $1 = &dvalue; } %typemap(argout) double *REFERENCE, double &REFERENCE, float *REFERENCE, float &REFERENCE { SV *tempsv; tempsv = SvRV($arg); sv_setnv(tempsv, (double) *$1); } %typemap(argout) int *REFERENCE, int &REFERENCE, short *REFERENCE, short &REFERENCE, long *REFERENCE, long &REFERENCE, signed char *REFERENCE, unsigned char &REFERENCE, bool *REFERENCE, bool &REFERENCE { SV *tempsv; tempsv = SvRV($input); sv_setiv(tempsv, (IV) *$1); } %typemap(argout) unsigned int *REFERENCE, unsigned int &REFERENCE, unsigned short *REFERENCE, unsigned short &REFERENCE, unsigned long *REFERENCE, unsigned long &REFERENCE, unsigned char *REFERENCE, unsigned char &REFERENCE { SV *tempsv; tempsv = SvRV($input); sv_setuv(tempsv, (UV) *$1); } /* Overloading information */ %typemap(typecheck) double *INOUT = double; %typemap(typecheck) bool *INOUT = bool; %typemap(typecheck) signed char *INOUT = signed char; %typemap(typecheck) unsigned char *INOUT = unsigned char; %typemap(typecheck) unsigned long *INOUT = unsigned long; %typemap(typecheck) unsigned short *INOUT = unsigned short; %typemap(typecheck) unsigned int *INOUT = unsigned int; %typemap(typecheck) long *INOUT = long; %typemap(typecheck) short *INOUT = short; %typemap(typecheck) int *INOUT = int; %typemap(typecheck) float *INOUT = float; %typemap(typecheck) long long *INOUT = long long; %typemap(typecheck) unsigned long long *INOUT = unsigned long long; %typemap(typecheck) double &INOUT = double; %typemap(typecheck) bool &INOUT = bool; %typemap(typecheck) signed char &INOUT = signed char; %typemap(typecheck) unsigned char &INOUT = unsigned char; %typemap(typecheck) unsigned long &INOUT = unsigned long; %typemap(typecheck) unsigned short &INOUT = unsigned short; %typemap(typecheck) unsigned int &INOUT = unsigned int; %typemap(typecheck) long &INOUT = long; %typemap(typecheck) short &INOUT = short; %typemap(typecheck) int &INOUT = int; %typemap(typecheck) float &INOUT = float; %typemap(typecheck) long long &INOUT = long long; %typemap(typecheck) unsigned long long &INOUT = unsigned long long; cableswig-0.1.0+git20150808.orig/SWIG/Lib/perl5/std_pair.i0000644000175000000620000000100612561312227021307 0ustar stevestaff// // SWIG typemaps for std::pair // Luigi Ballabio // July 2003 // // Common implementation %include std_common.i %include exception.i // ------------------------------------------------------------------------ // std::pair // ------------------------------------------------------------------------ %{ #include %} // exported class namespace std { template struct pair { // add typemaps here T first; U second; }; // add specializations here } cableswig-0.1.0+git20150808.orig/SWIG/Lib/perl5/perl5.swg0000644000175000000620000004205112561312227021106 0ustar stevestaff/* ----------------------------------------------------------------------------- * perl5.swg * * Perl 5 configuration file * ----------------------------------------------------------------------------- */ %runtime "precommon.swg" %runtime "common.swg" // common type checking code %runtime "perlrun.swg" // Perl runtime functions %runtime "noembed.h" // undefine Perl5 macros /* Typemaps for input parameters */ %typemap(in) int, short, long, signed char, bool, enum SWIGTYPE "$1 = ($1_ltype) SvIV($input);"; %typemap(in) unsigned int, unsigned short, unsigned long, unsigned char "$1 = ($1_ltype) SvUV($input);"; %typemap(in) char "$1 = ($1_ltype) *SvPV($input,PL_na);"; %typemap(in) float, double "$1 = ($1_ltype) SvNV($input);\n"; %typemap(in) long long "$1 = ($1_ltype) strtoll(SvPV($input, PL_na), 0, 0);"; %typemap(in) unsigned long long "$1 = ($1_ltype) strtoull(SvPV($input, PL_na), 0, 0);"; %typemap(in) char * "if (!SvOK((SV*) $input)) $1 = 0; else $1 = ($1_ltype) SvPV($input, PL_na);"; %typemap(in) char [ANY] "$1 = SvPV($input,PL_na);\n"; %typemap(in) SWIGTYPE *, SWIGTYPE [], SWIGTYPE & { if (SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor,0) < 0) { SWIG_croak("Type error in argument $argnum of $symname. Expected $1_mangle"); } } %typemap(in) void * { if (SWIG_ConvertPtr($input, (void **) &$1, 0,0) < 0) { SWIG_croak("Type error in argument $argnum of $symname. Expected $1_mangle"); } } /* Object passed by value. Convert to a pointer */ %typemap(in) SWIGTYPE { $&1_ltype argp; if (SWIG_ConvertPtr($input,(void **) &argp, $&1_descriptor,0) < 0) { SWIG_croak("Type error in argument $argnum of $symname. Expected $&1_mangle"); } $1 = *argp; } /* Pointer to a class member */ %typemap(in) SWIGTYPE (CLASS::*) { if ((SWIG_ConvertPacked($input, (void *) &$1, sizeof($1_type), $1_descriptor,0)) < 0) { SWIG_croak("Type error in argument $argnum of $symname. Expected $&1_mangle"); } } /* Const primitive references. Passed by value */ %typemap(in) const int & (int temp), const short & (short temp), const long & (long temp), const signed char & (signed char temp), const bool & (bool temp) "temp = ($*1_ltype) SvIV($input); $1 = &temp;"; %typemap(in) const unsigned int & (unsigned int temp), const unsigned short & (unsigned short temp), const unsigned long & (unsigned long temp), const unsigned char & (unsigned char temp) "temp = ($*1_ltype) SvUV($input); $1 = &temp;"; %typemap(in) const float & (float temp), const double & (double temp) "temp = ($*1_ltype) SvNV($input); $1 = &temp;"; %typemap(in) const long long & ($*1_ltype temp) "temp = ($*1_ltype) strtoll(SvPV($input,PL_na),0,0); $1 = &temp;"; %typemap(in) const unsigned long long & ($*1_ltype temp) "temp = ($*1_ltype) strtoull(SvPV($input, PL_na),0,0); $1 = &temp;"; %typemap(in) const char &(char temp) { temp = *SvPV($input,PL_na); $1 = &temp; } /* Typemap for output values */ %typemap(out) int, short, long, signed char, bool, enum SWIGTYPE "ST(argvi) = sv_newmortal(); sv_setiv(ST(argvi++), (IV) $1);"; %typemap(out) unsigned int, unsigned short, unsigned long, unsigned char "ST(argvi) = sv_newmortal(); sv_setuv(ST(argvi++), (UV) $1);"; %typemap(out) float, double "ST(argvi) = sv_newmortal(); sv_setnv(ST(argvi++), (double) $1);"; %typemap(out) char "ST(argvi) = sv_newmortal(); sv_setpvn((SV*)ST(argvi++), &$1, 1);"; %typemap(out) char * "ST(argvi) = sv_newmortal(); if ($1) { sv_setpv((SV*)ST(argvi++), (char *) $1); } else { sv_setsv((SV*)ST(argvi++), &PL_sv_undef); }"; %typemap(out) long long { char temp[256]; sprintf(temp,"%lld", $1); ST(argvi) = sv_newmortal(); sv_setpv((SV*)ST(argvi++), temp); } %typemap(out) unsigned long long { char temp[256]; sprintf(temp,"%llu", $1); ST(argvi) = sv_newmortal(); sv_setpv((SV*)ST(argvi++), temp); } %typemap(out) SWIGTYPE *, SWIGTYPE [], SWIGTYPE & "ST(argvi) = sv_newmortal(); SWIG_MakePtr(ST(argvi++), (void *) $1, $1_descriptor, $shadow|$owner);"; %typemap(out) SWIGTYPE #ifdef __cplusplus { $&1_ltype resultobj = new $1_ltype(($1_ltype &)$1); ST(argvi) = sv_newmortal(); SWIG_MakePtr(ST(argvi++), (void *) resultobj, $&1_descriptor, $shadow|$owner); } #else { $&1_ltype resultobj = ($&1_ltype) malloc(sizeof($1_type)); memmove(resultobj, &$1, sizeof($1_type)); ST(argvi) = sv_newmortal(); SWIG_MakePtr(ST(argvi++), (void *) resultobj, $&1_descriptor, $shadow|$owner); } #endif /* Dynamic casts */ %typemap(out) SWIGTYPE *DYNAMIC, SWIGTYPE &DYNAMIC { swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor, (void **) &$1); ST(argvi) = sv_newmortal(); SWIG_MakePtr(ST(argvi++), (void *) $1, ty, $shadow|$owner); } /* Member pointer */ %typemap(out) SWIGTYPE (CLASS::*) { ST(argvi) = sv_newmortal(); SWIG_MakePackedObj(ST(argvi), (void *) &$1, sizeof($1_type), $1_descriptor); argvi++; } %typemap(out) void ""; /* Typemap for character array returns */ %typemap(out) char [ANY] "ST(argvi) = sv_newmortal(); sv_setpv((SV*)ST(argvi++),(char *) $1);"; /* References to primitive types. Return by value */ %typemap(out) const int &, const short &, const long &, const signed char &, const bool & "ST(argvi) = sv_newmortal(); sv_setiv(ST(argvi++), (IV) *($1));"; %typemap(out) const unsigned int &, const unsigned short &, const unsigned long &, const unsigned char & "ST(argvi) = sv_newmortal(); sv_setuv(ST(argvi++), (UV) *($1));"; %typemap(out) const float &, const double & "ST(argvi) = sv_newmortal(); sv_setnv(ST(argvi++), (double) *($1));"; %typemap(out) const long long & { char temp[256]; sprintf(temp,"%lld", *($1)); ST(argvi) = sv_newmortal(); sv_setpv((SV*)ST(argvi++), temp); } %typemap(out) const unsigned long long & { char temp[256]; sprintf(temp,"%llu", *($1)); ST(argvi) = sv_newmortal(); sv_setpv((SV*)ST(argvi++), temp); } %typemap(out) const char & "ST(argvi) = sv_newmortal(); sv_setpvn((SV*)ST(argvi++), $1, 1);"; /* Variable input */ %typemap(varin) int, short, long, signed char, bool, enum SWIGTYPE "$1 = ($1_ltype) SvIV($input);"; %typemap(varin) unsigned int, unsigned short, unsigned long, unsigned char "$1 = ($1_ltype) SvUV($input);"; %typemap(varin) char "$1 = ($1_ltype) *SvPV($input,PL_na);"; %typemap(varin) float, double "$1 = ($1_ltype) SvNV($input);\n"; %typemap(varin) long long "$1 = ($1_ltype) strtoll(SvPV($input, PL_na), 0, 0);"; %typemap(varin) unsigned long long "$1 = ($1_ltype) strtoull(SvPV($input, PL_na), 0, 0);"; %typemap(varin) SWIGTYPE * { if (SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor,0) < 0) { croak("Type error in argument $argnum of $symname. Expected $1_mangle"); } } %typemap(varin) SWIGTYPE [ANY] { int i; $1_basetype *temp; $1_basetype *b = ($1_basetype *) $1; if (SWIG_ConvertPtr($input, (void **) &temp, $1_descriptor,0) < 0) { croak("Type error in argument $argnum of $symname. Expected $1_mangle"); } for (i = 0; i < $1_size; i++) b[i] = temp[i]; } %typemap(varin) SWIGTYPE & { void *temp; if (SWIG_ConvertPtr($input, (void **) &temp, $1_descriptor,0) < 0) { croak("Type error in argument $argnum of $symname. Expected $1_mangle"); } $1 = *($1_ltype) temp; } %typemap(varin) void * { if (SWIG_ConvertPtr($input, (void **) &$1, 0,0) < 0) { croak("Type error in argument $argnum of $symname. Expected $1_mangle"); } } /* Object passed by value. Convert to a pointer */ %typemap(varin) SWIGTYPE { $&1_ltype argp; if (SWIG_ConvertPtr($input,(void **) &argp, $&1_descriptor,0) < 0) { croak("Type error in argument $argnum of $symname. Expected $&1_mangle"); } $1 = *argp; } /* Member pointer */ %typemap(varin) SWIGTYPE (CLASS::*) { char temp[sizeof($1_type)]; if (SWIG_ConvertPacked($input, (void *) temp, sizeof($1_type), $1_descriptor, 0) < 0) { croak("Type error in argument $argnum of $symname. Expected $&1_mangle"); } memmove((void *) &$1, temp, sizeof($1_type)); } /* Const primitive references. Passed by value */ %typemap(varin) const int & (int temp), const short & (short temp), const long & (long temp), const signed char & (signed char temp), const bool & (bool temp) "temp = ($*1_ltype) SvIV($input); $1 = &temp;"; %typemap(varin) const unsigned int & (unsigned int temp), const unsigned short & (unsigned short temp), const unsigned long & (unsigned long temp), const unsigned char & (unsigned char temp) "temp = ($*1_ltype) SvUV($input); $1 = &temp;"; %typemap(varin) const float & (float temp), const double & (double temp) "temp = ($*1_ltype) SvNV($input); $1 = &temp;"; %typemap(varin) const long long & ($*1_ltype temp) "temp = ($1_ltype) strtoll(SvPV($input,PL_na),0,0); $1 = &temp;"; %typemap(varin) const unsigned long long & ($*1_ltype temp) "temp = ($1_ltype) strtoull(SvPV($input, PL_na),0,0); $1 = &temp;"; %typemap(varin) const char &(char temp) { temp = *SvPV($input,PL_na); $1 = &temp; } %typemap(varin) char * #ifdef __cplusplus { char *_a = (char *) SvPV(sv,PL_na); if ($1) delete [] $1; $1 = new char[strlen(_a)+1]; strcpy((char *)$1,_a); } #else { char *_a = (char *) SvPV(sv,PL_na); if ($1) free((char *) $1); $1 = (char *) malloc(strlen(_a)+1); strcpy((char *)$1,_a); } #endif %typemap(varin,warning="451:Setting const char * variable may leak memory") const char * #ifdef __cplusplus { char *_a = (char *) SvPV(sv,PL_na); $1 = new char[strlen(_a)+1]; strcpy((char *)$1,_a); } #else { char *_a = (char *) SvPV(sv,PL_na); $1 = (char *) malloc(strlen(_a)+1); strcpy((char *)$1,_a); } #endif %typemap(varin) char [ANY] "strncpy($1, (char *) SvPV(sv,PL_na), $1_dim0);"; %typemap(varin,warning="462: Unable to set variable of type char []") char [] { croak("Variable $symname is read-only."); } %typemap(varin) enum SWIGTYPE "$1 = ($1_type) SvIV($input);"; /* --- Typemaps for variable output --- */ %typemap(varout) int, short, long, signed char, bool, enum SWIGTYPE "sv_setiv($result, (IV) $1);"; %typemap(varout) unsigned int, unsigned short, unsigned long, unsigned char "sv_setuv($result, (UV) $1);"; %typemap(varout) float, double "sv_setnv($result, (double) $1);"; %typemap(varout) char "sv_setpvn((SV *) $result, &$1, 1);"; %typemap(varout) long long { char temp[256]; sprintf(temp,"%lld",$1); sv_setpv((SV *) $result, temp); } %typemap(varout) unsigned long long { char temp[256]; sprintf(temp,"%llu",$1); sv_setpv((SV *) $result, temp); } %typemap(varout) char *, char [ANY] "if ($1) { sv_setpv((SV*)$result, (char *) $1); } else { sv_setsv((SV*)$result, &PL_sv_undef); }"; //%typemap(varout) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] // "SWIG_MakePtr($result, (void *) $1, $1_descriptor);"; %typemap(varout,type="$1_descriptor") SWIGTYPE *, SWIGTYPE [] "sv_setiv(SvRV($result),(IV) $1);"; %typemap(varout,type="$1_descriptor") SWIGTYPE & "sv_setiv(SvRV($result),(IV) &$1);"; //%typemap(varout) SWIGTYPE // "SWIG_MakePtr($result, (void *) &$1, $&1_descriptor);"; %typemap(varout,type="$&1_descriptor") SWIGTYPE "sv_setiv(SvRV($result), (IV) &$1);"; %typemap(varout,type="$1_descriptor") SWIGTYPE (CLASS::*) { SWIG_MakePackedObj($result, (void *) &$1, sizeof($1_type), $1_descriptor); } /* --- Typemaps for constants --- * /* --- Constants --- */ %typemap(consttab) int, unsigned int, short, unsigned short, long, unsigned long, unsigned char, signed char, bool, enum SWIGTYPE { SWIG_INT, (char *) SWIG_prefix "$symname", (long) $value, 0, 0, 0} %typemap(consttab) float, double { SWIG_FLOAT, (char *) SWIG_prefix "$symname", 0, (double) $value, 0, 0} %typemap(consttab) char, char * { SWIG_STRING, (char *) SWIG_prefix "$symname", 0, 0, (void *)"$value", 0} %typemap(consttab) long long, unsigned long long { SWIG_STRING, (char *) SWIG_prefix "$symname", 0, 0, (void *) "$value", 0} %typemap(consttab) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { SWIG_POINTER, (char *) SWIG_prefix "$symname", 0, 0, (void *)$value, &$1_descriptor} %typemap(consttab) SWIGTYPE (CLASS::*) { SWIG_BINARY, (char *) SWIG_prefix "$symname", sizeof($type), 0, (void *)&$value, &$1_descriptor} /* ------------------------------------------------------------ * String & length * ------------------------------------------------------------ */ %typemap(in) (char *STRING, int LENGTH) { STRLEN temp; $1 = ($1_ltype) SvPV($input,temp); $2 = ($2_ltype) temp; } /* ------------------------------------------------------------ * ANSI C typemaps * ------------------------------------------------------------ */ %apply unsigned long { size_t }; /* ------------------------------------------------------------ * Typechecking rules * ------------------------------------------------------------ */ %typecheck(SWIG_TYPECHECK_INTEGER) int, short, long, unsigned int, unsigned short, unsigned long, signed char, unsigned char, long long, unsigned long long, const int &, const short &, const long &, const unsigned int &, const unsigned short &, const unsigned long &, const long long &, const unsigned long long &, enum SWIGTYPE, bool, const bool & { $1 = SvIOK($input) ? 1 : 0; } %typecheck(SWIG_TYPECHECK_DOUBLE) float, double, const float &, const double & { $1 = SvNIOK($input) ? 1 : 0; } %typecheck(SWIG_TYPECHECK_CHAR) char { $1 = SvPOK($input) ? 1 : 0; } %typecheck(SWIG_TYPECHECK_STRING) char * { $1 = SvPOK($input) ? 1 : 0; } %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { void *tmp; if (SWIG_ConvertPtr($input, (void **) &tmp, $1_descriptor, 0) == -1) { $1 = 0; } else { $1 = 1; } } %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE { void *tmp; if (SWIG_ConvertPtr($input, (void **) &tmp, $&1_descriptor, 0) == -1) { $1 = 0; } else { $1 = 1; } } %typecheck(SWIG_TYPECHECK_VOIDPTR) void * { void *tmp; if (SWIG_ConvertPtr($input, (void **) &tmp, 0, 0) == -1) { $1 = 0; } else { $1 = 1; } } /* ------------------------------------------------------------ * Exception handling * ------------------------------------------------------------ */ %typemap(throws) int, long, short, unsigned int, unsigned long, unsigned short { SWIG_SetErrorf("%d", $1); SWIG_fail; } /* throws real objects */ %typemap(throws) SWIGTYPE { SV *esv=sv_newmortal(); $&1_ltype copy = new $1_ltype(($1_ltype &)$1); SWIG_MakePtr(esv, (void *) copy, $&1_descriptor, SWIG_OWNER); SWIG_croakSV(esv); } %typemap(throws) char * { SWIG_croak($1); } /* Export the SWIG initialization function */ %header %{ #ifdef __cplusplus extern "C" #endif #ifndef PERL_OBJECT #ifndef MULTIPLICITY SWIGEXPORT(void) SWIG_init (CV* cv); #else SWIGEXPORT(void) SWIG_init (pTHXo_ CV* cv); #endif #else SWIGEXPORT(void) SWIG_init (CV *cv, CPerlObj *); #endif %} /* Module initialization function */ %init %{ #ifdef __cplusplus extern "C" #endif XS(SWIG_init) { dXSARGS; int i; static int _init = 0; if (!_init) { for (i = 0; swig_types_initial[i]; i++) { swig_types[i] = SWIG_TypeRegister(swig_types_initial[i]); } _init = 1; } /* Install commands */ for (i = 0; swig_commands[i].name; i++) { newXS((char*) swig_commands[i].name,swig_commands[i].wrapper, (char*)__FILE__); } /* Install variables */ for (i = 0; swig_variables[i].name; i++) { SV *sv; sv = perl_get_sv((char*) swig_variables[i].name, TRUE | 0x2); if (swig_variables[i].type) { SWIG_MakePtr(sv,(void *)1, *swig_variables[i].type,0); } else { sv_setiv(sv,(IV) 0); } swig_create_magic(sv, (char *) swig_variables[i].name, swig_variables[i].set, swig_variables[i].get); } /* Install constant */ for (i = 0; swig_constants[i].type; i++) { SV *sv; sv = perl_get_sv((char*)swig_constants[i].name, TRUE | 0x2); switch(swig_constants[i].type) { case SWIG_INT: sv_setiv(sv, (IV) swig_constants[i].lvalue); break; case SWIG_FLOAT: sv_setnv(sv, (double) swig_constants[i].dvalue); break; case SWIG_STRING: sv_setpv(sv, (char *) swig_constants[i].pvalue); break; case SWIG_POINTER: SWIG_MakePtr(sv, swig_constants[i].pvalue, *(swig_constants[i].ptype),0); break; case SWIG_BINARY: SWIG_MakePackedObj(sv, swig_constants[i].pvalue, swig_constants[i].lvalue, *(swig_constants[i].ptype)); break; default: break; } SvREADONLY_on(sv); } %} cableswig-0.1.0+git20150808.orig/SWIG/Lib/perl5/extra-install.list0000644000175000000620000000006212561312227023015 0ustar stevestaff# see top-level Makefile.in Makefile.pl noembed.h cableswig-0.1.0+git20150808.orig/SWIG/Lib/perl5/perlrun.swg0000644000175000000620000002676612561312227021565 0ustar stevestaff/* ---------------------------------------------------------------------- -*- c -*- * perl5.swg * * Perl5 runtime library * /cvsroot/SWIG/Lib/perl5/perlrun.swg,v 1.14 2003/12/04 19:14:14 beazley Exp * ----------------------------------------------------------------------------- */ #define SWIGPERL #define SWIGPERL5 #ifdef __cplusplus /* Needed on some windows machines---since MS plays funny games with the header files under C++ */ #include #include extern "C" { #endif #include "EXTERN.h" #include "perl.h" #include "XSUB.h" /* Get rid of free and malloc defined by perl */ #undef free #undef malloc /* get rid of some more junk that perl defines */ #undef eof #undef write #undef read #undef bool #undef close #ifndef pTHX_ #define pTHX_ #endif #include #ifdef __cplusplus } #endif /* Macro to call an XS function */ #ifdef PERL_OBJECT # define SWIG_CALLXS(_name) _name(cv,pPerl) #else # ifndef MULTIPLICITY # define SWIG_CALLXS(_name) _name(cv) # else # define SWIG_CALLXS(_name) _name(PERL_GET_THX, cv) # endif #endif /* Contract support */ #define SWIG_contract_assert(expr,msg) if (!(expr)) { SWIG_croak(msg); } else /* Note: SwigMagicFuncHack is a typedef used to get the C++ compiler to just shut up already */ #ifdef PERL_OBJECT #define MAGIC_PPERL CPerlObj *pPerl = (CPerlObj *) this; typedef int (CPerlObj::*SwigMagicFunc)(SV *, MAGIC *); #ifdef __cplusplus extern "C" { #endif typedef int (CPerlObj::*SwigMagicFuncHack)(SV *, MAGIC *); #ifdef __cplusplus } #endif #define SWIG_MAGIC(a,b) (SV *a, MAGIC *b) #define SWIGCLASS_STATIC #else #define MAGIC_PPERL #define SWIGCLASS_STATIC static #ifndef MULTIPLICITY #define SWIG_MAGIC(a,b) (SV *a, MAGIC *b) typedef int (*SwigMagicFunc)(SV *, MAGIC *); #ifdef __cplusplus extern "C" { #endif typedef int (*SwigMagicFuncHack)(SV *, MAGIC *); #ifdef __cplusplus } #endif #else #define SWIG_MAGIC(a,b) (struct interpreter *interp, SV *a, MAGIC *b) typedef int (*SwigMagicFunc)(struct interpreter *, SV *, MAGIC *); #ifdef __cplusplus extern "C" { #endif typedef int (*SwigMagicFuncHack)(struct interpreter *, SV *, MAGIC *); #ifdef __cplusplus } #endif #endif #endif #if defined(WIN32) && defined(PERL_OBJECT) && !defined(PerlIO_exportFILE) #define PerlIO_exportFILE(fh,fl) (FILE*)(fh) #endif /* Modifications for newer Perl 5.005 releases */ #if !defined(PERL_REVISION) || ((PERL_REVISION >= 5) && ((PERL_VERSION < 5) || ((PERL_VERSION == 5) && (PERL_SUBVERSION < 50)))) # ifndef PL_sv_yes # define PL_sv_yes sv_yes # endif # ifndef PL_sv_undef # define PL_sv_undef sv_undef # endif # ifndef PL_na # define PL_na na # endif #endif #include #ifdef __cplusplus extern "C" { #endif #define SWIG_OWNER 1 #define SWIG_SHADOW 2 /* Common SWIG API */ #ifdef PERL_OBJECT # define SWIG_ConvertPtr(obj, pp, type, flags) \ SWIG_Perl_ConvertPtr(pPerl, obj, pp, type, flags) # define SWIG_NewPointerObj(p, type, flags) \ SWIG_Perl_NewPointerObj(pPerl, p, type, flags) # define SWIG_MakePackedObj(sv, p, s, type) \ SWIG_Perl_MakePackedObj(pPerl, sv, p, s, type) # define SWIG_ConvertPacked(obj, p, s, type, flags) \ SWIG_Perl_ConvertPacked(pPerl, obj, p, s, type, flags) #else # define SWIG_ConvertPtr(obj, pp, type, flags) \ SWIG_Perl_ConvertPtr(obj, pp, type, flags) # define SWIG_NewPointerObj(p, type, flags) \ SWIG_Perl_NewPointerObj(p, type, flags) # define SWIG_MakePackedObj(sv, p, s, type) \ SWIG_Perl_MakePackedObj(sv, p, s, type ) # define SWIG_ConvertPacked(obj, p, s, type, flags) \ SWIG_Perl_ConvertPacked(obj, p, s, type, flags) #endif /* Perl-specific API */ #ifdef PERL_OBJECT # define SWIG_MakePtr(sv, ptr, type, flags) \ SWIG_Perl_MakePtr(pPerl, sv, ptr, type, flags) # define SWIG_TypeCheckRV(rv, ty) \ SWIG_Perl_TypeCheckRV(pPerl, rv, ty) # define SWIG_SetError(str) \ SWIG_Perl_SetError(pPerl, str) #else # define SWIG_MakePtr(sv, ptr, type, flags) \ SWIG_Perl_MakePtr(sv, ptr, type, flags) # define SWIG_TypeCheckRV(rv, ty) \ SWIG_Perl_TypeCheckRV(rv, ty) # define SWIG_SetError(str) \ SWIG_Perl_SetError(str) # define SWIG_SetErrorSV(str) \ SWIG_Perl_SetErrorSV(str) #endif #define SWIG_SetErrorf SWIG_Perl_SetErrorf #ifdef PERL_OBJECT # define SWIG_MAYBE_PERL_OBJECT CPerlObj *pPerl, #else # define SWIG_MAYBE_PERL_OBJECT #endif #ifdef SWIG_NOINCLUDE SWIGIMPORT(int) SWIG_Perl_ConvertPtr(SWIG_MAYBE_PERL_OBJECT SV *, void **, swig_type_info *, int flags); SWIGIMPORT(void) SWIG_Perl_MakePtr(SWIG_MAYBE_PERL_OBJECT SV *, void *, swig_type_info *, int flags); SWIGIMPORT(SV *) SWIG_Perl_NewPointerObj(SWIG_MAYBE_PERL_OBJECT void *, swig_type_info *, int flags); SWIGIMPORT(void) SWIG_Perl_MakePackedObj(SWIG_MAYBE_PERL_OBJECT SV *, void *, int, swig_type_info *); SWIGIMPORT(int) SWIG_Perl_ConvertPacked(SWIG_MAYBE_PERL_OBJECT SV *, void *, int, swig_type_info *, int flags); SWIGIMPORT(swig_type_info *) SWIG_Perl_TypeCheckRV(SWIG_MAYBE_PERL_OBJECT SV *rv, swig_type_info *ty); SWIGIMPORT(SV *) SWIG_Perl_SetError(SWIG_MAYBE_PERL_OBJECT char *); #else SWIGRUNTIME(swig_type_info *) SWIG_Perl_TypeCheckRV(SWIG_MAYBE_PERL_OBJECT SV *rv, 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 (sv_derived_from(rv, (char *) s->name)) { 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; } /* Function for getting a pointer value */ SWIGRUNTIME(int) SWIG_Perl_ConvertPtr(SWIG_MAYBE_PERL_OBJECT SV *sv, void **ptr, swig_type_info *_t, int flags) { swig_type_info *tc; void *voidptr = (void *)0; /* If magical, apply more magic */ if (SvGMAGICAL(sv)) mg_get(sv); /* Check to see if this is an object */ if (sv_isobject(sv)) { SV *tsv = (SV*) SvRV(sv); IV tmp = 0; if ((SvTYPE(tsv) == SVt_PVHV)) { MAGIC *mg; if (SvMAGICAL(tsv)) { mg = mg_find(tsv,'P'); if (mg) { SV *rsv = mg->mg_obj; if (sv_isobject(rsv)) { tmp = SvIV((SV*)SvRV(rsv)); } } } else { return -1; } } else { tmp = SvIV((SV*)SvRV(sv)); } voidptr = (void *)tmp; if (!_t) { *(ptr) = voidptr; return 0; } } else if (! SvOK(sv)) { /* Check for undef */ *(ptr) = (void *) 0; return 0; } else if (SvTYPE(sv) == SVt_RV) { /* Check for NULL pointer */ *(ptr) = (void *) 0; if (!SvROK(sv)) return 0; else return -1; } else { /* Don't know what it is */ *(ptr) = (void *) 0; return -1; } if (_t) { /* Now see if the types match */ tc = SWIG_TypeCheckRV(sv,_t); if (!tc) { *ptr = voidptr; return -1; } *ptr = SWIG_TypeCast(tc,voidptr); return 0; } *ptr = voidptr; return 0; } SWIGRUNTIME(void) SWIG_Perl_MakePtr(SWIG_MAYBE_PERL_OBJECT SV *sv, void *ptr, swig_type_info *t, int flags) { if (ptr && (flags & SWIG_SHADOW)) { SV *self; SV *obj=newSV(0); HV *hash=newHV(); HV *stash; sv_setref_pv(obj, (char *) t->name, ptr); stash=SvSTASH(SvRV(obj)); if (flags & SWIG_OWNER) { HV *hv; GV *gv=*(GV**)hv_fetch(stash, "OWNER", 5, TRUE); if (!isGV(gv)) gv_init(gv, stash, "OWNER", 5, FALSE); hv=GvHVn(gv); hv_store_ent(hv, obj, newSViv(1), 0); } sv_magic((SV *)hash, (SV *)obj, 'P', Nullch, 0); SvREFCNT_dec(obj); self=newRV_noinc((SV *)hash); sv_setsv(sv, self); SvREFCNT_dec((SV *)self); sv_bless(sv, stash); } else { sv_setref_pv(sv, (char *) t->name, ptr); } } SWIGRUNTIME(SV *) SWIG_Perl_NewPointerObj(SWIG_MAYBE_PERL_OBJECT void *ptr, swig_type_info *t, int flags) { SV *result = sv_newmortal(); SWIG_MakePtr(result, ptr, t, flags); return result; } SWIGRUNTIME(void) SWIG_Perl_MakePackedObj(SWIG_MAYBE_PERL_OBJECT SV *sv, void *ptr, int sz, swig_type_info *type) { char result[1024]; char *r = result; if ((2*sz + 1 + strlen(type->name)) > 1000) return; *(r++) = '_'; r = SWIG_PackData(r,ptr,sz); strcpy(r,type->name); sv_setpv(sv, result); } /* Convert a packed value value */ SWIGRUNTIME(int) SWIG_Perl_ConvertPacked(SWIG_MAYBE_PERL_OBJECT SV *obj, void *ptr, int sz, swig_type_info *ty, int flags) { swig_type_info *tc; char *c = 0; if ((!obj) || (!SvOK(obj))) return -1; c = SvPV(obj, PL_na); /* Pointer values must start with leading underscore */ if (*c != '_') return -1; c++; c = SWIG_UnpackData(c,ptr,sz); if (ty) { tc = SWIG_TypeCheck(c,ty); if (!tc) return -1; } return 0; } SWIGRUNTIME(void) SWIG_Perl_SetError(SWIG_MAYBE_PERL_OBJECT const char *error) { if (error) sv_setpv(perl_get_sv("@", TRUE), error); } SWIGRUNTIME(void) SWIG_Perl_SetErrorSV(SWIG_MAYBE_PERL_OBJECT SV *error) { if (error) sv_setsv(perl_get_sv("@", TRUE), error); } SWIGRUNTIME(void) SWIG_Perl_SetErrorf(const char *fmt, ...) { va_list args; va_start(args, fmt); sv_vsetpvfn(perl_get_sv("@", TRUE), fmt, strlen(fmt), &args, Null(SV**), 0, Null(bool*)); va_end(args); } #endif /* Macros for low-level exception handling */ #define SWIG_fail goto fail #define SWIG_croak(x) { SWIG_SetError(x); goto fail; } #define SWIG_croakSV(x) { SWIG_SetErrorSV(x); goto fail; } /* most preprocessors do not support vararg macros :-( */ /* #define SWIG_croakf(x...) { SWIG_SetErrorf(x); goto fail; } */ typedef XS(SwigPerlWrapper); typedef SwigPerlWrapper *SwigPerlWrapperPtr; /* Structure for command table */ typedef struct { const char *name; SwigPerlWrapperPtr wrapper; } swig_command_info; /* Information for constant table */ #define SWIG_INT 1 #define SWIG_FLOAT 2 #define SWIG_STRING 3 #define SWIG_POINTER 4 #define SWIG_BINARY 5 /* Constant information structure */ typedef struct swig_constant_info { int type; const char *name; long lvalue; double dvalue; void *pvalue; swig_type_info **ptype; } swig_constant_info; #ifdef __cplusplus } #endif /* Structure for variable table */ typedef struct { const char *name; SwigMagicFunc set; SwigMagicFunc get; swig_type_info **type; } swig_variable_info; /* Magic variable code */ #ifndef PERL_OBJECT #define swig_create_magic(s,a,b,c) _swig_create_magic(s,a,b,c) #ifndef MULTIPLICITY static void _swig_create_magic(SV *sv, char *name, int (*set)(SV *, MAGIC *), int (*get)(SV *,MAGIC *)) { #else static void _swig_create_magic(SV *sv, char *name, int (*set)(struct interpreter*, SV *, MAGIC *), int (*get)(struct interpreter*, SV *,MAGIC *)) { #endif #else # define swig_create_magic(s,a,b,c) _swig_create_magic(pPerl,s,a,b,c) static void _swig_create_magic(CPerlObj *pPerl, SV *sv, const char *name, int (CPerlObj::*set)(SV *, MAGIC *), int (CPerlObj::*get)(SV *, MAGIC *)) { #endif MAGIC *mg; sv_magic(sv,sv,'U',(char *) name,strlen(name)); mg = mg_find(sv,'U'); mg->mg_virtual = (MGVTBL *) malloc(sizeof(MGVTBL)); mg->mg_virtual->svt_get = (SwigMagicFuncHack) get; mg->mg_virtual->svt_set = (SwigMagicFuncHack) set; mg->mg_virtual->svt_len = 0; mg->mg_virtual->svt_clear = 0; mg->mg_virtual->svt_free = 0; } cableswig-0.1.0+git20150808.orig/SWIG/Lib/perl5/std_vector.i0000644000175000000620000003774212561312227021676 0ustar stevestaff// // SWIG typemaps for std::vector types // Luigi Ballabio // May 7, 2002 // Chris Seatory // August 5, 2002 // Igor Bely // May 16, 2003 // // Perl implementation %include std_common.i %include exception.i // containers // methods which can raise are caused to throw an IndexError %exception std::vector::get { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::vector::set { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } %exception std::vector::pop { try { $action } catch (std::out_of_range& e) { SWIG_exception(SWIG_IndexError,const_cast(e.what())); } } // ------------------------------------------------------------------------ // std::vector // // The aim of all that follows would be to integrate std::vector with // Perl as much as possible, namely, to allow the user to pass and // be returned Perl arrays. // const declarations are used to guess the intent of the function being // exported; therefore, the following rationale is applied: // // -- f(std::vector), f(const std::vector&), f(const std::vector*): // the parameter being read-only, either a Perl sequence or a // previously wrapped std::vector can be passed. // -- f(std::vector&), f(std::vector*): // the parameter must be modified; therefore, only a wrapped std::vector // can be passed. // -- std::vector f(): // the vector is returned by copy; therefore, a Perl sequence of T:s // is returned which is most easily used in other Perl functions // -- std::vector& f(), std::vector* f(), const std::vector& f(), // const std::vector* f(): // the vector is returned by reference; therefore, a wrapped std::vector // is returned // ------------------------------------------------------------------------ %{ #include #include #include %} // exported class namespace std { template class vector { %typemap(in) vector (std::vector* v) { if (SWIG_ConvertPtr($input,(void **) &v, $&1_descriptor,1) != -1) { $1 = *v; } else if (SvROK($input)) { AV *av = (AV *)SvRV($input); if (SvTYPE(av) != SVt_PVAV) SWIG_croak("Type error in argument $argnum of $symname. " "Expected an array of " #T); SV **tv; I32 len = av_len(av) + 1; T* obj; for (int i=0; i& (std::vector temp, std::vector* v), const vector* (std::vector temp, std::vector* v) { if (SWIG_ConvertPtr($input,(void **) &v, $1_descriptor,1) != -1) { $1 = v; } else if (SvROK($input)) { AV *av = (AV *)SvRV($input); if (SvTYPE(av) != SVt_PVAV) SWIG_croak("Type error in argument $argnum of $symname. " "Expected an array of " #T); SV **tv; I32 len = av_len(av) + 1; T* obj; for (int i=0; i { int len = $1.size(); SV **svs = new SV*[len]; for (unsigned int i=0; i { { /* wrapped vector? */ std::vector* v; if (SWIG_ConvertPtr($input,(void **) &v, $1_&descriptor,0) != -1) { $1 = 1; } else if (SvROK($input)) { /* native sequence? */ AV *av = (AV *)SvRV($input); if (SvTYPE(av) == SVt_PVAV) { SV **tv; I32 len = av_len(av) + 1; if (len == 0) { /* an empty sequence can be of any type */ $1 = 1; } else { /* check the first element only */ T* obj; tv = av_fetch(av, 0, 0); if (SWIG_ConvertPtr(*tv, (void **)&obj, $descriptor(T *),0) != -1) $1 = 1; else $1 = 0; } } } else { $1 = 0; } } } %typecheck(SWIG_TYPECHECK_VECTOR) const vector&, const vector* { { /* wrapped vector? */ std::vector* v; if (SWIG_ConvertPtr($input,(void **) &v, $1_descriptor,0) != -1) { $1 = 1; } else if (SvROK($input)) { /* native sequence? */ AV *av = (AV *)SvRV($input); if (SvTYPE(av) == SVt_PVAV) { SV **tv; I32 len = av_len(av) + 1; if (len == 0) { /* an empty sequence can be of any type */ $1 = 1; } else { /* check the first element only */ T* obj; tv = av_fetch(av, 0, 0); if (SWIG_ConvertPtr(*tv, (void **)&obj, $descriptor(T *),0) != -1) $1 = 1; else $1 = 0; } } } else { $1 = 0; } } } public: vector(unsigned int size = 0); vector(unsigned int size, const T& value); vector(const vector &); unsigned int size() const; bool empty() const; void clear(); %rename(push) push_back; void push_back(const T& x); %extend { T pop() { if (self->size() == 0) throw std::out_of_range("pop from empty vector"); T x = self->back(); self->pop_back(); return x; } T& get(int i) { int size = int(self->size()); if (i>=0 && isize()); if (i>=0 && i class vector { %typemap(in) vector (std::vector* v) { if (SWIG_ConvertPtr($input,(void **) &v, $&1_descriptor,1) != -1){ $1 = *v; } else if (SvROK($input)) { AV *av = (AV *)SvRV($input); if (SvTYPE(av) != SVt_PVAV) SWIG_croak("Type error in argument $argnum of $symname. " "Expected an array of " #T); SV **tv; I32 len = av_len(av) + 1; for (int i=0; i& (std::vector temp, std::vector* v), const vector* (std::vector temp, std::vector* v) { if (SWIG_ConvertPtr($input,(void **) &v, $1_descriptor,1) != -1) { $1 = v; } else if (SvROK($input)) { AV *av = (AV *)SvRV($input); if (SvTYPE(av) != SVt_PVAV) SWIG_croak("Type error in argument $argnum of $symname. " "Expected an array of " #T); SV **tv; I32 len = av_len(av) + 1; T* obj; for (int i=0; i { int len = $1.size(); SV **svs = new SV*[len]; for (unsigned int i=0; i { { /* wrapped vector? */ std::vector* v; if (SWIG_ConvertPtr($input,(void **) &v, $1_&descriptor,0) != -1) { $1 = 1; } else if (SvROK($input)) { /* native sequence? */ AV *av = (AV *)SvRV($input); if (SvTYPE(av) == SVt_PVAV) { SV **tv; I32 len = av_len(av) + 1; if (len == 0) { /* an empty sequence can be of any type */ $1 = 1; } else { /* check the first element only */ tv = av_fetch(av, 0, 0); if (CHECK_T(*tv)) $1 = 1; else $1 = 0; } } } else { $1 = 0; } } } %typecheck(SWIG_TYPECHECK_VECTOR) const vector&, const vector* { { /* wrapped vector? */ std::vector* v; if (SWIG_ConvertPtr($input,(void **) &v, $1_descriptor,0) != -1) { $1 = 1; } else if (SvROK($input)) { /* native sequence? */ AV *av = (AV *)SvRV($input); if (SvTYPE(av) == SVt_PVAV) { SV **tv; I32 len = av_len(av) + 1; if (len == 0) { /* an empty sequence can be of any type */ $1 = 1; } else { /* check the first element only */ tv = av_fetch(av, 0, 0); if (CHECK_T(*tv)) $1 = 1; else $1 = 0; } } } else { $1 = 0; } } } public: vector(unsigned int size = 0); vector(unsigned int size, T value); vector(const vector &); unsigned int size() const; bool empty() const; void clear(); %rename(push) push_back; void push_back(T x); %extend { T pop() { if (self->size() == 0) throw std::out_of_range("pop from empty vector"); T x = self->back(); self->pop_back(); return x; } T get(int i) { int size = int(self->size()); if (i>=0 && isize()); if (i>=0 && i '$module', # Name of your module 'LIBS' => [''], # Custom libraries (if any) 'OBJECT' => '$module_wrap.o' # Object files ); cableswig-0.1.0+git20150808.orig/SWIG/Lib/perl5/perlmain.i0000644000175000000620000000353312561312227021320 0ustar stevestaff// /cvsroot/SWIG/Lib/perl5/perlmain.i,v 1.2 2003/09/01 18:13:33 beazley Exp // Code to statically rebuild perl5. // #ifdef AUTODOC %subsection "perlmain.i" %text %{ This module provides support for building a new version of the Perl executable. This will be necessary on systems that do not support shared libraries and may be necessary with C++ extensions. This module may only build a stripped down version of the Perl executable. Thus, it may be necessary (or desirable) to hand-edit this file for your particular application. To do this, simply copy this file from swig_lib/perl5/perlmain.i to your working directory and make the appropriate modifications. This library file works with Perl 5.003. It may work with earlier versions, but it hasn't been tested. As far as I know, this library is C++ safe. %} #endif %{ static void xs_init _((pTHX)); static PerlInterpreter *my_perl; int perl_eval(char *string) { char *argv[2]; argv[0] = string; argv[1] = (char *) 0; return perl_call_argv("eval",0,argv); } int main(int argc, char **argv, char **env) { int exitstatus; my_perl = perl_alloc(); if (!my_perl) exit(1); perl_construct( my_perl ); exitstatus = perl_parse( my_perl, xs_init, argc, argv, (char **) NULL ); if (exitstatus) exit( exitstatus ); /* Initialize all of the module variables */ exitstatus = perl_run( my_perl ); perl_destruct( my_perl ); perl_free( my_perl ); exit( exitstatus ); } /* Register any extra external extensions */ /* Do not delete this line--writemain depends on it */ /* EXTERN_C void boot_DynaLoader _((CV* cv)); */ static void xs_init(pTHX) { /* dXSUB_SYS; */ char *file = __FILE__; { /* newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file); */ newXS(SWIG_name, SWIG_init, file); #ifdef SWIGMODINIT SWIGMODINIT #endif } } %} cableswig-0.1.0+git20150808.orig/SWIG/Lib/perl5/precommon.swg0000644000175000000620000000135512561312227022060 0ustar stevestaff/*************************************************************** -*- c -*- * perl5/precommon.swg * * Rename all exported symbols from common.swg, to avoid symbol * clashes if multiple interpreters are included * ************************************************************************/ #define SWIG_TypeRegister SWIG_Perl_TypeRegister #define SWIG_TypeCheck SWIG_Perl_TypeCheck #define SWIG_TypeCast SWIG_Perl_TypeCast #define SWIG_TypeDynamicCast SWIG_Perl_TypeDynamicCast #define SWIG_TypeName SWIG_Perl_TypeName #define SWIG_TypeQuery SWIG_Perl_TypeQuery #define SWIG_TypeClientData SWIG_Perl_TypeClientData #define SWIG_PackData SWIG_Perl_PackData #define SWIG_UnpackData SWIG_Perl_UnpackData cableswig-0.1.0+git20150808.orig/SWIG/SWIG-NEW0000644000175000000620000002122012561312227016716 0ustar stevestaffNew Features and Important Changes, v1.3 Author(s) : David Beazley March 21, 2003 1. Introduction --------------- This document briefly explains some of the most important changes made since the release of SWIG1.1. The goal is to provide information for people who want to upgrade an older SWIG interface to the new version. Most changes pertain to the internal implementation of SWIG and the organization of the core, parser, and language modules. As a SWIG user, almost all of these changes are hidden from view except for a few important cases where changes to the core have dramatically altered SWIG's old behavior. 2. Types and typemaps --------------------- 2.1 Variables of the form 'const type *' are no longer wrapped as constants, but as C global variables. The earlier SWIG behavior was incorrect due to Dave's misinterpretation of 'const' in the C language specification. If you have written an interface that expects to create constants using 'const type *' you will need to rewrite those specifications using a new %constant directive like this: %constant(type *) name = value; 2.2 SWIG generally has better support for pointers, 'const', arrays, and pointers to functions. 2.3 Typemaps are now applied to a more precisely defined set of datatypes. For example, consider the following typemap: %typemap(in) foo * { ... get a foo ... } In SWIG1.1, this typemap would get applied to 'foo *', 'foo &', 'foo []', 'foo[][]', and so forth. In SWIG1.3, this typemap *only* gets applied to 'foo *' and 'const foo *'. It does *NOT* get mapped to the other variants listed above. 2.4 Bug fix. SWIG now correctly handles typemaps of the form %typemap(in) Object { ... get an object ... } 2.5 The memberout typemap is no longer available and is withdrawn. The old implementation was essentially useless because of the way in which code was generated. 2.6 The memberin typemap is now inserted inline in the generated wrapper code. This provides access to scripting-specific variables in the wrapper function. 2.7 SWIG-1.3.10 features a total rewrite of the typemap system. Typemaps now use a different variable naming scheme. Typemaps for arguments look like this: %typemap(in) sometype { $1 = convert value ($input); } The variable $1 replaces $target and the variable $input replaces $source. For output values, typemaps look like this: %typemap(out) sometype { $result = create result ($1); } The variable $1 replaces $source and the variable $result replaces $target. See Doc/Manual/Typemaps.html for a full description of the new typemap system. 2.8 Multi-argument typemaps are now supported. This solves a common problem that occurs with functions like this void foo(char *buffer, int len); where you would like to make the two arguments operate as a single object in the target language. 2.9 Types such as 'const int &', 'const double &', are passed as values instead of pointers. 2.10 C++ namespaces are now supported. 3. Type checking ---------------- SWIG no longer uses the functions SWIG_GetPtr() and SWIG_MakePtr() to parse datatypes in wrapper code. This is because the type of a pointer is no longer associated with a string, but with a special "swig_type_info *" object. If you are not using typemaps, this change should cause no noticable effects. However, if you have written typemaps to handle pointers, here are the essential details: 3.1 Type name mangling is different in SWIG1.3. For a type of "int **", SWIG1.1 used to produce a name of the form "_int_pp". SWIG1.3 on the other hand, produces a name of the form "_p_p_int". There are a number of reasons for changing the format, but I'd rather not go into it here. You'll just have to learn to live with it :-). 3.2 Types are described by a special "swig_type_info *" object. Everywhere a string was used before, an object of this type will be used. The "swig_type_info *" for a given type can always be obtained using macros involving the mangled typename in 3.1. For example, the type object of of 'int **' is 'SWIGTYPE_p_p_int'. 3.3 Instead of SWIG_GetPtr, a function of the following form is used: int SWIG_ConvertPtr(ScriptObj *o, void **ptr, swig_type_info *ty, int flags); Note: the function name may differ in certain implementations (read the source). For example: int SWIG_ConvertPtr(ScriptObj *o, void **ptr, SWIGTYPE_p_p_int,0); Passing a value of '0' for the type will accept any pointer. This works kind of like 'void *'. The flags argument is reserved for future expansion. 3.4. To create a pointer object, one uses a function similar to ScriptObj *SWIG_NewPointer(void *ptr, swig_type_info *ty, int flags); It works in a similar manner: p = SWIG_NewPointer(ptr, SWIGTYPE_p_p_int, 0); You will have to read the source to get the exact function name used. The flags argument is implementation specific and reserved for future expansion. 3.5. If, for whatever reason, you need to obtain the 'swig_type_info *' outside the context of a wrapper file, you can use the SWIG_TypeQuery() function. For example: swig_type_info *ty = SWIG_TypeQuery("int **"); this function returns an appropriate type_info structure or NULL if no such type is registered. 3.6 SWIG does not generate swig_type_info structures for types that are not actually used in an interface file. As a result, the type checking tables for SWIG1.3 tend to be much smaller than for SWIG1.1. *** Note: The old string-based type checking scheme is not going to return to SWIG so do not ask for backwards compatibility. The new scheme is substantially faster, it is less error-prone, it requires no dynamic memory allocation, it works better with the runtime libraries, and it is simpler to implement than the old string based approach. 4. Deprecated Features (incomplete list) ---------------------------------------- 4.1 Documentation system. The old documentation system has been removed entirely. I expect it to return someday, but it will have a much different form (probably influenced by XML). 4.2 The %val and %out directives. These directives used to attach properties to function parameters such as void foo(%val int *ptr); The same effect can now be achieved with typemaps: void foo(int *INPUT); 4.3 Extensions to the %module and %init directive are no longer supported. For example: %module example, foo, bar This used to perform a special kind of multi-module initialization for static linking. If you really need to do this, you will have to manually insert code into the module initialization function. 4.4 %ifdef, %ifndef, %endif, %if, %elif, %else directives are withdrawn. SWIG now has a real preprocessor. 4.5 %checkout directive removed. 4.6 %except and %new are deprecated. 4.7 %readonly and %readwrite are deprecated. Use %immutable instead. 4.8 The %addmethods directive has been renamed to %extend. 5. Language specific changes ---------------------------- 5.1 Python shadow classes are much more efficient and pass the shadow objects directly to the C wrappers. 5.2 Tcl code generation is substantially improved--especially for C++. 5.3 Tcl module can now link to global variables of any type. 5.4 Perl shadow classes improved and optimized somewhat. 5.5 The Guile module represents pointers as smobs. (They used to be mangled into strings.) Memory leaks and type conversion bugs have been fixed. The Guile module system, including dynamic loading, and exceptions are supported. A typemap-driven procedure-documentation system has been added (requires Guile 1.4). Procedures-with-setters can be generated. 5.6 The Python module now automatically creates shadow class objects from the C wrappers. This fixes a bunch of hard problems related to typemaps, exception handling, and more. 6. New Features --------------- 6.1 Java module added 6.2 Ruby module added 6.3 Mzscheme module added. 6.4 Integrated preprocessor. You can now use C macros in SWIG interface files. 6.5 PHP module added. 6.6 %rename directive is greatly enhanced to deal with overloaded functions. 6.7 Support for simple templates 6.8 Support for overloaded operators. 6.9 %feature directive. 6.10 Ocaml module added. 6.11 XML module added. 6.12 CHICKEN module added. 6.13 C# module added. cableswig-0.1.0+git20150808.orig/SWIG/ANNOUNCE0000644000175000000620000000520512561312226016730 0ustar stevestaff*** ANNOUNCE: SWIG 1.3.20 *** http://www.swig.org December 17, 2003 We're pleased to announce SWIG 1.3.20, the latest installment in the SWIG development effort. SWIG-1.3.20 includes a number of bug fixes and large number of enhancements throughout. 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 from other languages including Perl, Python, Tcl, Ruby, PHP, Java, Guile, Mzscheme, Ocaml, Chicken Scheme, and C#. Major applications of SWIG include generation of scripting language extension modules, rapid prototyping, testing, and user interface development for large C/C++ systems. Availability: ------------- The release is available for download on Sourceforge at http://prdownloads.sourceforge.net/swig/swig-1.3.20.tar.gz Within the next day, a Windows version will also be made available at http://prdownloads.sourceforge.net/swig/swigwin-1.3.20.zip Release numbers --------------- With SWIG1.3, we are adopting an odd/even version numbering scheme for SWIG. Odd version numbers (1.3, 1.5, 1.7, etc...) are considered to be development releases. Even numbers (1.4,1.6,1.8) are stable releases. The current 1.3 effort is working to produce a stable 2.0 release. A stable 2.0 release will not be made until it can accompanied by fully updated documentation. In the meantime, we will continue to make periodic 1.3.x releases. We need your help! ------------------ Even if you are perfectly happy with SWIG1.1, we can still use your feedback. First, we like to know about compilation problems and other issues concerning the building of SWIG. Second, if SWIG1.3 is unable to compile your old interface files, we would like to get information about the features you are using. This information will help us find bugs in the SWIG1.3 release, develop techniques for supporting backwards compatibility, and write documentation that addresses specific issues related to migrating from SWIG1.1 to SWIG1.3. We are also looking for volunteers who would like to work on various aspects of SWIG development. SWIG is an unfunded project that would not exist without volunteers. We are also looking for the developers of other SWIG language modules. If you have developed a SWIG module and would like to see it incorporated into the new release, please contact us to obtain SWIG-CVS access. We are also more than willing to help port your module from SWIG1.1 to SWIG1.3. Please send email to beazley@cs.uchicago.edu for further information. Please report problems with this release to swig-dev@cs.uchicago.edu. --- The SWIG Developers cableswig-0.1.0+git20150808.orig/SWIG/Doc/0002755000175000000620000000000012561312226016304 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Doc/Devel/0002755000175000000620000000000012561312226017343 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Doc/Devel/migrate.txt0000644000175000000620000001122712561312226021535 0ustar stevestaffSWIG1.3 Migration Guide (The not entirely complete guide to updating language modules to work with SWIG1.3). Dave Beazley August 15, 2000 1. Introduction --------------- Virtually all of SWIG's internal data structures have now been rewritten. Take everything you thought you knew about SWIG1.1 and throw it out. 2. DataTypes ------------ The old 'DataType' data structure is gone. Therefore, direct manipulation of 'is_pointer', 'implicit_ptr', and 'arraystr' attributes no longer applies. Sorry. Datatypes are now represented by the type 'SwigType' which has no public attributes. Actually, if you look at it closely, 'SwigType' is really just an alias for 'void' and if you look at it even closer than that you will realize that it's nothing more than a string! The string encoding of types is described in more detail in the file Source/Swig/stype.c and is not so important here. What is important is the functions used to produce various types of output: SwigType_str(type,name = 0); This produces an exact C representation of the datatype with all qualifiers, arrays, references, and so forth. name is an optional name that is given if you wanted to associate the type with a parameter name or something. SwigType_lstr(type,name = 0); This function takes a type and produces a C string containing a type suitable for assignment (appearing as an lvalue in an expression). To do this, certain things such as 'const', arrays, and references are stripped away or converted into pointers. SwigType_ltype(type); Returns a SwigType object corresponding to the type created by SwigType_lstr(). SwigType_lcaststr(type,name); Produces a string casting a value 'name' from the real datatype to the assignable type created by SwigType_lstr(). SwigType_rcaststr(type,name) Produces a string that casts a value 'name' from the type created by SwigType_lstr() to the real datatype. SwigType_manglestr(type) Produces the 'mangled' version of a datatype. Getting the 'type' code. Most language modules still operate by looking at special integer type codes. This interface is a little ragged and will probably go away at some point. However, for now the following function can be used to get the type code: int SwigType_type(type) The codes are the same as the before, except that there are a few special codes: T_STRING - The 'char *' type and variations. T_POINTER - Any pointer type (not char * though) T_REFERENCE - Any C++ reference T_ARRAY - Any array T_FUNCTION - A function (this is usually an error). Because of the special codes, it is no longer necessary to have code like this: if ((t->is_pointer == 1) and (t->type == T_CHAR)) { ... get a string ... } Instead, just use the type code above like this: switch(SwigType_type(type)) { case T_STRING: ... get a string ... break; case T_POINTER: ... get a pointer ... break; } There are about 2-dozen type manipulation functions that could also be useful. See Source/Swig/swig.h and Source/Swig/stype.c. 3. Parameter Lists ------------------ The ParmList data structure is gone. In reality, parameter lists are nothing more than a linked list of parameters. The proper way to iterate over this list and get parameter values is as follows: ParmList *l; Parm *p; for (p = l; p; p = Getnext(p)) { SwigType *pt = Gettype(p); /* Get parameter type */ String *pn = Getname(p); /* Get parameter name */ String *value = Getvalue(p); /* Get parameter value */ ... do whatever ... } 4. Typemaps ----------- Typemaps more or less work. However, the interface has changed slightly. Instead of typemap_lookup("in","python",type,pname,"$source","$target",wrapper); the function is Swig_typemap_lookup("in",type,pname,"$source","$target",wrapper); There are a variety of other changes to typemaps (see CHANGES). 5. Use of new types ------------------- When possible, language modules should try to use the built in String, List, and Hash objects instead of C arrays or 'char *'. This will probably require a detailed pass through the code with an eye towards cleanup. 6. Miscellaneous ---------------- Language modules no longer need to concern themselves with formatting the wrapper code they produce (provided you are using the special Wrapper object). The function Wrapper_print() passes everything through a pretty-printer that automatically performs indentation and tries to clean things up. This especially works well when there are lots of typemaps. cableswig-0.1.0+git20150808.orig/SWIG/Doc/Devel/engineering.html0000644000175000000620000003615612561312226022534 0ustar stevestaff SWIG Engineering Manual

SWIG Engineering Manual

David Beazley
Department of Computer Science
University of Chicago
Chicago, IL 60637
beazley@cs.uchicago.edu

/cvsroot/SWIG/Doc/Devel/engineering.html,v 1.3 2002/11/30 22:10:01 beazley Exp

(Note : This is a work in progress.)

Table of Contents

1. Introduction

The purpose of this document is to describe various coding conventions and organizational aspects for SWIG developers. The idea for this document is largely borrowed from John Ousterhout's Tcl/Tk Engineering Manual. It is not my intent to overly managerial about matters--rather I'm hoping to make life a little less chaotic for everyone.

First a little background: SWIG was started in 1995 as a one-person project and continued in this mode of operation until about 1998. Most of this development was driven by ideas submitted by early SWIG users as opposed to being motivated by a grand design. As a result, the code ended up being a pretty horrible C++ coding disaster. A mostly working disaster perhaps, but a disaster nonetheless.

With that said, the primary goal of future SWIG development is to reengineer the original system, fix most of its inherent design flaws, and to produce what I hope will become a highly extensible and modular interface compiler framework. To this do this, there are a few critical areas of work. First, I want to restructure SWIG as a collection of loosely coupled modules written in either ANSI C or an scripting language. Second, I want the system to be minimalistic in its use of data structures and interconnections. The primary reason for this is that the fewer data structures there are, the less users will have to remember. This will also make the system more accessible to non-experts. Finally, I want to reevaluate the whole idea of a SWIG module is and expand the definition to include just about anything from parsers, preprocessors, optimizers, interface editors, and code generators.

The rest of this document outlines a few general rules of how code should be developed within the SWIG project. These rules are primarily drawn from my own experience developing software and observing the practices of other successful projects.

2. Programming Languages and Libraries

All SWIG modules must be written in either ANSI C or one of the scripting languages for which SWIG can generate an interface (e.g., Perl, Python, or Tcl). C++ is currently being used to write SWIG modules, but it is only being utilized to avoid working with a lot of pointers to functions. Advanced C++ features like namespaces, templates, and overloading should not be used..

Module writers should make every attempt to use only those functions described in the POSIX.1 standard. This includes most of the functions contained the Kernighan and Ritchie C programming book. Use of operating system dependent functionality such as socket libraries should always be included inside a conditional compilation block so that it can be omitted on problematic platforms. If you are unsure about a library call, check the man page or contact Dave.

3. The Source Directory and Module Names

All SWIG modules are contained within the "Source" directory. Within this directory, each module is placed into its own subdirectory. The name of this subdirectory should exactly match the name of the module. For example, if you are creating a module called "Tcl", all of your files should be placed in a directory "Tcl".

When choosing a module name, please pick a name that is not currently in use. As a general convention, the first letter of a module name is capitalized such as "Perl". Alternatives such as "perl" or "PERL" should be avoided. In certain instances, the first two letters may be capitalized as in "CParse." The exact usage of this is somewhat inconsistent and isn't terribly important--just make sure the first letter is capitalized. Also, module names should not start with numbers, include underscores or any other special non-alphanumeric characters.

4. Include Files

All modules should include a header file that defines the public interface. The name of this header file should be of the form "swigmodule.h" where "module" is the name of your module. For example, if you created a module "Perl", the header file should be named "swigperl.h". This scheme should prevent header-file naming conflicts both within SWIG and when linking parts of SWIG to the outside world.

All header files should include a short description, author information, copyright message, CVS version, include guards, and be C++ aware. For example:

/* -------------------------------------------------------------------------
 * swigperl.h
 *
 *     All of the externally visible functions in the Perl module.
 * 
 * Author(s) : David Beazley (beazley@cs.uchicago.edu)
 *
 * Copyright (C) 1999-2000, The University of Chicago.
 * See the file LICENSE for information on usage and redistribution. 
 *
 * /cvsroot/SWIG/Doc/Devel/engineering.html,v 1.3 2002/11/30 22:10:01 beazley Exp
 * ------------------------------------------------------------------------- */

#ifndef _SWIGPERL_H
#define _SWIGPERL_H   1

#ifdef __cplusplus
extern "C" {
#endif

/* Your declarations here */
...

#ifdef __cplusplus
}
#endif

#endif  /* _SWIGPERL_H */

To minimize compilation time, please include as few other header files as possible.

5. File Structure

Each file in a module should be given a filename that is all lowercase letters such as "parser.c", not "Parser.c" or "PARSER.c". Please note that filenames are case-insensitive on Windows so this convention will prevent you from inadvertantly creating two files that differ in case-only.

Each file should include a short abstract, author information, copyright information, and a CVS revision tag like this:

/* -----------------------------------------------------------------------------
 * include.c
 *
 *     This file implements the functions used to locate and include files in
 *     the SWIG library.  Functions for maintaining the library search path are
 *     also located here.
 * 
 * Author(s) : David Beazley (beazley@cs.uchicago.edu)
 *
 * Copyright (C) 1999-2000, The University of Chicago.
 * See the file LICENSE for information on usage and redistribution. 
 * ----------------------------------------------------------------------------- */

static char cvsroot[] = "/cvsroot/SWIG/Doc/Devel/engineering.html,v 1.3 2002/11/30 22:10:01 beazley Exp";

#include "swig.h"

/* Declarations */
typedef struct {
   int x, y;
} Foo;

...

/* Private Declarations (used only in this file) */
static int  avariable;

...

/* Functions */
... 

The CVS revision tag should be placed into a static string as shown above. This adds the revision information to the SWIG executable and makes it possible to extract version information from a raw binary (sometimes useful in debugging).

As a general rule, files start to get unmanagable once they exceed about 2000 lines. Files larger than this should be broken up into multiple files. Similarly, you should avoid the temptation to create many small files as this increases compilation time and makes the directory structure too complicated.

6. Bottom-Up Design

Within each source file, the preferred organization is to use what is known as "bottom-up" design. Under this scheme, lower-level functions appear first and the highest level function appears last. The easy way to remember is that the "main" function of your module should always appear last in the source file. For example:
/* Simple bottom-up program */
#include <stdio.h>

int foo(int x, int y) {
    /* Implement foo */
    ...
}

int bar() {
    ...
    foo(i,j);
    ...
}

...
int main(int argc, char **argv) {
    ...
    bar();   
    ...
}
This choice of design is somewhat arbitrary however it has a number of benefits particular to C. In particular, a bottom-up design generally eliminates the need to include forward references--resulting in cleaner code and fewer compilation errors.

7. Functions

All functions should have a function header that gives the function name and a short description like this:
/* -------------------------------------------------------------------------
 * Swig_add_directory()
 *
 * Adds a directory to the SWIG search path.
 * ------------------------------------------------------------------------- */

void 
Swig_add_directory(DOH *dirname) {
...

}
In the function declaration, the return type and any specifiers (extern or static) should appear on a separate line followed by the function name and arguments as shown above. The left curly brace should appear on the same line as the function name.

Function declarations should NOT use the pre-ANSI function declaration syntax. The ANSI standard has been around long enough for this to be a non-issue.

8. Naming Conventions

The following conventions are used to name various objects throughout SWIG.

Functions

Functions should consist of the module name and the function name separated by an underscore like this:
Preprocessor_define()
Swig_add_directory()
In general, the module name should match the name of the module subdirectory and the function name should be in all lowercase with words separated by underscores.

Structures and Types

If your module defines new structures, the structure name should include the name of the module and the name of the structure appended together like this:
typedef struct SwigScanner {
   ...
} SwigScanner;

typedef struct LParseType {
   ...
} LParseType;
In this case, both the name of the module and the type should be capitalized. Also, whenever possible, you should use the "typedef struct Name { ... } Name" form when defining new data structures.

Global Variables

Global variables should be avoided if at all possible. However, if you must use a global variable, please prepend the module name and use the same naming scheme as for functions.

Constants

Constants should be created using #define and should be in all caps like this:
#define   SWIG_TOKEN_LPAREN  1
Separate words in a constant should be separated by underscores as with functions.

Structure members

Structure members should be in all lower-case and follow the same word-separation convention as for function names. However, the module name does not have to be included. For example:
typedef struct SwigScanner {
  DOH           *text;           /* Current token value */
  DOH           *scanobjs;       /* Objects being scanned */
  DOH           *str;            /* Current object being scanned */
  char          *idstart;        /* Optional identifier start characters */
  int            next_token;     /* Next token to be returned */
  int            start_line;     /* Starting line of certain declarations */
  int            yylen;          /* Length of text pushed into text */
  DOH           *file;           /* Current file name */
} SwigScanner;

Static Functions and Variables

Static declarations are free to use any naming convention that is appropriate. However, most existing parts of SWIG use lower-case names and follow the same convention as described for functions.

9. Visibility

Modules should keep the following rules in mind when exposing their internals:
  • Only publicly accessible functions should be included in the module header file.
  • All non-static declarations must be prepended with some form of the module name to avoid potential linker namespace conflicts with other modules.
  • Modules should not expose global variables or use global variables in their public interface.
  • Similarly, modules should discourage the direct manipulation of data contained within data structures in favor of using function calls instead. For example, instead of providing a user with a structure like this:
    typedef struct Foo {
       int line;
    } Foo;
    
    It is better to hide the implementation of Foo and provide an function-call interface like this:
    typedef struct Foo Foo;
    extern int  Foo_getline(Foo *f);
    extern void Foo_setline(Foo *f, int line);
    
    Although this results in worse performance, there are many practical reasons for doing this. The most important reason is that it allows you to change the internal representation of Foo without breaking all of the other modules or having to recompile the entire universe after making your changes.

10. Miscellaneous Coding Guidelines

  • Do not use the ternary ?: operator. It is unnecessarily error prone, hard for people to read, and hard to maintain code that uses it. [I don't agree w/ this guideline. ?: operator can be abused just like everything else, but it can also be used cleanly. In some styles of programming, it is the best tool for the job. --ttn]

11. CVS Tagging Conventions

Use cvs tag to declare some set of file revisions as related in some symbolic way. This eases reference, retrieval and manipulation of these files later. At the moment (2001/01/16 14:02:53), the conventions are very simple; let's hope they stay that way!

There are two types of tags, internal (aka personal) and external. Internal tags are used by SWIG developers primarily, whereas external tags are used when communicating with people w/ anonymous cvs access.

  • Internal tags should start with the developer name and a hyphen.
  • External tags should start with "v-".
That's all there is to it. Some example tags:
  • ttn-pre-xml-patch
  • ttn-post-xml-patch
  • ttn-going-on-vacation-so-dutifully-tagging-now
  • v-1-3-a37-fixes-bug-2432
  • v-1-3-a37-fixes-bug-2433
  • v-1-3-a37-fixes-bug-2432-again
  • v-1-3-a37-release

Copyright (C) 1999-2001 SWIG Development Team cableswig-0.1.0+git20150808.orig/SWIG/Doc/Devel/internals.html0000644000175000000620000007755512561312226022251 0ustar stevestaff SWIG Internals

SWIG Internals Manual

Thien-Thi Nguyen
ttn@glug.org

David M. Beazley
beazley@cs.uchicago.edu

/cvsroot/SWIG/Doc/Devel/internals.html,v 1.4 2003/09/23 21:38:32 cheetah Exp

(Note : This is a work in progress.)

Table of Contents

1. Introduction

This document details SWIG internals: architecture and sometimes implementation. The first few sections concentrate on data structures, interfaces, conventions and code shared by all language targets. Subsequent sections focus on a particular language.

The audience is assumed to be SWIG developers (who should also read the SWIG Engineering Manual before starting to code).

1.1 Directory Guide

Doc HTML documentation. If you find a documentation bug, please let us know.
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 for more info. [FIXME: Ref SWIG user manual.]
Lib These are the .i (interface) files that form the SWIG installed library. Language-specific files are in subdirectories (for example, guile/typemaps.i). Each language also has a .swg file implementing runtime type support for that language. The SWIG library is not versioned.
Misc Currently this subdir only contains file fileheader. See the Engineering Manual for more info.
Runtime This subdir contains scripts and a makefile for creating runtime shared-object libraries used by various languages. Runtime/make.sh says: "The runtime libraries are only needed if you are building multiple extension modules that need to share information."
Source SWIG source code is in this subdir tree. Directories marked w/ "(*)" are used in building the swig executable.
DOH (*) C library providing memory allocation, file access and generic containers. Result: libdoh.a
Experiment [TODO]
Include (*) Configuration .h files
LParse Parser (lex / yacc) files and support [why not (*)?!]
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
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 and contains generic functions related to types, file handling, scanning, and so forth.
Tools Libtool support and the mkdist.py script.
Win This improperly-named (spit spit) subdir only has README.txt.

1.2 Overall Program Flow

Here is the general control flow and where under subdir Source to look for code:
  • Modules1.1/swigmain.cxx:main() is the program entry point. It parses the language-specifying command-line option (for example, -java), creating a new language-specific wrapping object (each language is a C++ class derived from base class Language). This object and the command-line is passed to SWIG_main(), whose return value is the program exit value.
  • SWIG1.1/main.cxx:SWIG_main() is the "real" main. It initializes the preprocessor and typemap machinery, defines some preprocessor symbols, locates the SWIG library, processes common command-line options, and then calls the language-specific command-line parser. From here there are three paths: "help", "checkout" and everything else.
    • In "help" mode, clean up open files and exit.
    • In "checkout" mode, copy specified files from the SWIG library to the current directory. Errors cause error messages but no non-lcoal exits.
    • Otherwise, do wrapping: determine output file name(s), define some preprocessor symbols and run the preprocessor, initialize the interface-definition parser, set up the typemap for handling new return strings, and finally do the language-specific parse (by calling the language object's parse() method), which creates output files by side-effect.
    Afterwards, remove temporary files, and clean up. If the command-line included -freeze, go into an infinite loop; otherwise return the error count.
  • The language-specific parse() (and all other language-specific code) lives in Modules1.1/foo.{h,cxx} for language Foo. Typically, FOO::parse() calls FOO::headers() and then the global function yyparse(), which uses the callbacks registered by SWIG_main() above.

2. DOH

DOH is a collection of low-level objects such as strings, lists, and hash tables upon which the rest of SWIG is built. The name 'DOH' unofficially stands for "Dave's Object Hack", but it's also a good expletive to use when things don't work (as in "SWIG core dumped---DOH!").

2.1 Motivation and Background

The development of DOH is influenced heavily by the problems encountered during earlier attempts to create a C++ based version of SWIG2.0. In each of these attempts (over a 3 year period), the resulting system always ended up growing into a collossal nightmare of large inheritance hierarchies and dozens of specialized classes for different types of objects (functions, variables, constants, etc.). The end result was that the system was tremendously complicated, difficult to understand, difficult to maintain, and fairly inflexible in the grand scheme of things.

DOH takes a different approach to tackling the complexity problem. First, rather than going overboard with dozens of types and class definitions, DOH only defines a handful of simple yet very useful objects that are easy to remember. Second, DOH uses dynamic typing---one of the features that make scripting languages so useful and which make it possible to accomplish things with much less code. Finally, DOH utilizes a few coding tricks that allow it to perform a limited form of function overloading for certain C datatypes (more on that a little later).

The key point to using DOH is that instead of thinking about code in terms of highly specialized C data structures, just about everything ends up being represented in terms of a just a few datatypes. For example, structures are replaced by DOH hash tables whereas arrays are replaced by DOH lists. At first, this is probably a little strange to most C/C++ programmers, but in the long run in makes the system extremely flexible and highly extensible. Also, in terms of coding, many of the newly DOH-based subsystems are less than half the size (in lines of code) of the earlier C++ implementation.

2.2 Basic Types

The following built-in types are currently provided by DOH:
  • String. A string of characters with automatic memory management and high-level operations such as string replacement. In addition, strings support file I/O operations that make it possible to use them just about anyplace a file can be used.

  • List. A list of arbitrary DOH objects (of possibly mixed types).

  • Hash. A hash table that maps a set of string keys to a set of arbitrary DOH objects. The DOH version of an associative array for all of you Perl fans.

  • File. A DOH wrapper around the C FILE * structure. This is provided since other objects sometimes want to behave like files (strings for instance).

  • Void. A DOH wrapper around an arbitrary C pointer. This can be used if you want to place arbitrary C data structures in DOH lists and hash tables.
Due to dynamic typing, all of the objects in DOH are represented by pointers of type DOH *. Furthermore, all objects are completely opaque--that means that the only way to access the internals of an object is through a well-defined public API. For convenience, the following symbolic names are sometimes used to improve readability:
  • DOHString *. A String object.
  • DOHList *. A list object.
  • DOHHash *. A hash object.
  • DOHFile *. A file object.
  • DOHVoid *. A void object.
  • DOHString_or_char *. A DOH String object or a raw C "char *".
It should be stressed that all of these names are merely symbolic aliases to the type DOH * and that no compile-time type checking is performed (of course, a runtime error may occur if you screw up).

2.3 Creating, Copying, and Destroying Objects

The following functions can be used to create new DOH objects
  • NewString(DOHString_or_char *value)
    Create a new string object with contents initially set to value. value can be either a C string or a DOH string object.

  • NewStringf(char *fmt, ...)
    Create a new string object with contents initially set to a formatted string. Think of this as being sprintf() combined with an object constructor.

  • NewList()
    Create a new list object that is initially empty.

  • NewHash()
    Create a new hash object that is initially empty.

  • NewFile(DOHString_or_char *filename, char *mode)
    Open a file and return a file object. This is a wrapper around the C fopen() library call.

  • NewFileFromFile(FILE *f)
    Create a new file object given an already opened FILE * object.

  • NewVoid(void *obj, void (*del)(void *))
    Create a new DOH object that is a wrapper around an arbitrary C pointer. del is an optional destructor function that will be called when the object is destroyed.
Any object can be copied using the Copy() function. For example:
DOH *a, *b, *c, *d;
a = NewString("Hello World");
b = NewList();
c = Copy(a);         /* Copy the string a */
d = Copy(b);         /* Copy the list b */
Copies of lists and hash tables are shallow. That is, their contents are only copied by reference.

Objects can be deleted using the Delete() function. For example:

DOH *a = NewString("Hello World");
...
Delete(a);              /* Destroy a */
All objects are referenced counted and given a reference count of 1 when initially created. The Delete() function only destroys an object when the reference count reaches zero. When an object is placed in a list or hash table, it's reference count is automatically increased. For example:
DOH *a, *b;
a = NewString("Hello World");
b = NewList();
Append(b,a);         /* Increases refcnt of a to 2 */
Delete(a);           /* Decreases refcnt of a to 1 */
Delete(b);           /* Destroys b, and destroys a */
Should it ever be necessary to manually increase the reference count of an object, the DohIncref() function can be used:
DOH *a = NewString("Hello");
DohIncref(a);

2.4 A Word About Mutability and Copying

All DOH objects are mutable regardless of their current reference count. For example, if you create a string and then create a 1000 references to it (in lists and hash tables), changes to the string will be reflected in all of the references. Therefore, if you need to make any kind of local change, you should first make a copy using the Copy() function. Caveat: when copying lists and hash tables, elements are copied by reference.

2.5 Strings

The DOH String type is perhaps the most flexible object. First, it supports a variety of string-oriented operations. Second, it supports many of the same operations as lists. Finally, strings provide file I/O operations that allow them to be used interchangably with DOH file objects. [ TODO ]

2.6 Lists

[ TODO ]

2.7 Hash tables

[ TODO ]

2.8 Files

[ TODO ]

2.9 Void objects

[ TODO ]

2.10 Utility functions

[ TODO ]

3. Types and Typemaps

Revised: Dave Beazley (8/14/00)

The representation and manipulation of types is currently in the process of being reorganized and (hopefully) simplified. The following list describes the current set of functions that are used to manipulate datatypes. These functions are different than in SWIG1.1 and may change names in the final SWIG1.3 release.

  • SwigType_str(SwigType *t, char *name).
    This function produces the exact string representation of the datatype t. name is an optional parameter that specifies a declaration name. This is used when dealing with more complicated datatypes such as arrays and pointers to functions where the output might look something like "int (*name)(int, double)".

  • SwigType_lstr(SwigType *t, char *name).
    This function produces a string representation of a datatype that can be safely be assigned a value (i.e., can be used as the "lvalue" of an expression). To do this, qualifiers such as "const", arrays, and references are stripped away or converted into pointers. For example:
    Original Datatype              lstr()
    ------------------             --------
    const char *a                  char *a
    double a[20]                   double *a
    double a[20][30]               double *a
    double &a                      double *a
    
    The intent of the lstr() function is to produce local variables inside wrapper functions--all of which must be reassignable types since they are the targets of conversions from a scripting representation.

  • SwigType_rcaststr(SwigType *t, char *name).
    This function produces a string that casts a type produced by the lstr() function to the type produced by the str() function. You might view it as the inverse of lstr(). This function only produces output when it needs to (when str() and lstr() produce different results). Furthermore, an optional name can be supplied when the cast is to be applied to a specific name. Examples:
    Original Datatype             rcaststr()
    ------------------            ---------
    char *a                       
    const char *a                 (const char *) name
    double a[20]                  (double *) name
    double a[20][30]              (double (*)[30]) name
    double &a                     (double &) *name
    

  • SwigType_lcaststr(SwigType *t, char *name).
    This function produces a string that casts a type produced by the str() function to the type produced by the lstr() function. This function only produces output when it needs to (when str() and lstr() produce different results). Furthermore, an optional name can be supplied when the cast is to be applied to a specific name.
    Original Datatype             lcaststr()
    ------------------            ---------
    char *a                       
    const char *a                 (char *) name
    double a[20]                  (double *) name
    double a[20][30]              (double *) name
    double &a                     (double *) &name
    

  • SwigType_manglestr(SwigType *t).
    Produces a type-string that is used to identify this datatype in the target scripting language. Usually this string looks something like "_p_p_double" although the target language may redefine the output for its own purposes. Normally this function strips all qualifiers, references, and arrays---producing a mangled version of the type produced by the lstr() function.
The following example illustrates the intended use of the above functions when creating wrapper functions using shorthand pseudocode. Suppose you had a function like this:
int foo(int a, double b[20][30], const char *c, double &d);
Here's how a wrapper function would be generated using the type generation functions above:
wrapper_foo() {
   lstr("int","result")
   lstr("int","arg0")
   lstr("double [20][30]", "arg1")
   lstr("const char *", "arg2")
   lstr("double &", "arg3")
   ...
   get arguments
   ...
   result = (lcaststr("int"))  foo(rcaststr("int","arg0"),
                               rcaststr("double [20][30]","arg1"),
                               rcaststr("const char *", "arg2"),
                               rcaststr("double &", "arg3"))
   ...
}
Here's how it would look with the corresponding output filled in:
wrapper_foo() {
   int      result;
   int      arg0;
   double  *arg1;
   char    *arg2;
   double  *arg3;
   ...
   get arguments
   ...
   result = (int) foo(arg0,
                      (double (*)[30]) arg1,
                      (const char *) arg2,
                      (double &) *arg3);
   ...
}
Notes:
  • For convenience, the string generation functions return a "char *" that points to statically allocated memory living inside the type library. Therefore, it is never necessary (and it's an error) to free the pointer returned by the functions. Also, if you need to save the result, you should make a copy of it. However, with that said, it is probably worth nothing that these functions do cache the last 8 results. Therefore, it's fairly safe to make a handful of repeated calls without making any copies.
[TODO]

4. Parsing

[TODO]

5. Difference Between SWIG 1.1 and SWIG 1.3

[TODO]

6. Plans for SWIG 2.0

[TODO]

7. The C/C++ Wrapping Layer

Added: Dave Beazley (July 22, 2000)

When SWIG generates wrappers, it tries to provide a mostly seamless integration with the original code. However, there are a number of problematic features of C/C++ programs that complicate this interface.

  • Passing and returning structures by value. When used, SWIG converts all pass-by-value functions into wrappers that pass by reference. For example:
    double dot_product(Vector a, Vector b);
    
    gets turned into a wrapper like this:
    double wrap_dot_product(Vector *a, Vector *b) {
         return dot_product(*a,*b);
    }
    
    Functions that return by value require a memory allocation to store the result. For example:
    Vector cross_product(Vector *a, Vector *b);
    
    become
    Vector *wrap_cross_product(Vector *a, Vector *b) {
       Vector *result = (Vector *) malloc(sizeof(Vector));
       *result = cross_product(a,b);
       return result;
    }
    
    Note: If C++ is being wrapped, the default copy constructor is used instead of malloc() to create a copy of the return result.

  • C++ references. C++ references are handled exactly the same as pass/return by value except that a memory allocation is not made for functions that return a reference.

  • Qualifiers such as "const" and "volatile". SWIG strips all qualifiers from the interface presented to the target language. Besides, what in the heck is "const" in Perl anyways?

  • Instance Methods. Method invocations are handled as a function call in which a pointer to the object (the "this" pointer) appears as the first argument. For example, in the following class:
    class Foo {
    public:
        double bar(double);
    };
    
    The "bar" method is wrapped by a function like this:
    double Foo_bar(Foo *self, double arg0) {
       return self->bar(arg0);
    }
    

  • Structure/class data members. Data members are handled by creating a pair of wrapper functions that set and get the value respectively. For example:
    struct Foo {
        int x;
    };
    
    gets wrapped as follows:
    int Foo_x_get(Foo *self) {
        return self->x;
    }
    int Foo_x_set(Foo *self, int value) {
        return (self->x = value);
    }
    

  • Constructors. Constructors for C/C++ data structures are wrapped by a function like this:
    Foo *new_Foo() {
        return new Foo;
    }
    
    Note: For C, new objects are created using the calloc() function.

  • Destructors. Destructors for C/C++ data structures are wrapper like this:
    void delete_Foo(Foo *self) {
        delete self;
    }
    
    Note: For C, objects are destroyed using free().
The creation of wrappers and various type transformations are handled by a collection of functions found in the file Source/Swig/cwrap.c.
  • char *Swig_clocal(DataType *t, char *name, char *value)
    This function creates a string containing the declaration of a local variable with type t, name name, and default value value. This local variable is stripped of all qualifiers and will be a pointer if the type is a reference or user defined type.

  • DataType *Swig_clocal_type(DataType *t)
    Returns a type object corresponding to the type string produced by the Swig_clocal() function.

  • char *Swig_clocal_deref(DataType *t, char *name)
    This function is the inverse of the clocal() function. Given a type and a name, it produces a string containing the code needed to cast/convert the type produced by Swig_clocal() back into it's original type.

  • char *Swig_clocal_assign(DataType *t, char *name)
    Given a type and name, this produces a string containing the code (and an optional cast) needed to make an assignment from the real datatype to the local datatype produced by Swig_clocal(). Kind of the opposite of deref().

  • int Swig_cargs(Wrapper *w, ParmList *l)
    Given a wrapper function object and a list of parameters, this function declares a set of local variables for holding all of the parameter values (using Swig_clocal()). Returns the number of parameters. In addition, this function sets the local name of each parameter which can be retrieved using the Parm_Getlname() function.

  • void Swig_cresult(Wrapper *w, DataType *t, char *resultname, char *decl)
    Generates the code needed to set the result of a wrapper function and performs all of the needed memory allocations for ANSI C (if necessary). t is the type of the result, resultname is the name of the result variable, and decl is a string that contains the C code which produces the result.

  • void Swig_cppresult(Wrapper *w, DataType *t, char *resultname, char *decl)
    Generates the code needed to set the result of a wrapper function and performs all of the needed memory allocations for C++ (if necessary). t is the type of the result, resultname is the name of the result variable, and decl is a string that contains the C code which produces the result.

  • Wrapper *Swig_cfunction_wrapper(char *fname, DataType *rtype, ParmList *parms, char *code)
    Create a wrapper around a normal function declaration. fname is the name of the wrapper, rtype is the return type, parms are the function parameters, and code is a string containing the code in the function body.

  • Wrapper *Swig_cmethod_wrapper(char *classname, char *methodname, DataType *rtype, DataType *parms, char *code)

  • char *Swig_cfunction_call(char *name, ParmList *parms) This function produces a string containing the code needed to call a C function. The string that is produced contains all of the transformations needed to convert pass-by-value into pass-by-reference as well as handle C++ references. Produces a string like "name(arg0, arg1, ..., argn)".
Here is a short example showing how these functions could be used. Suppose you had a C function like this:
double dot_product(Vector a, Vector b);
Here's how you might write a really simple wrapper function
ParmList *l = ... parameter list of the function ...
DataType *t = ... return type of the function ...
char     *name = ... name of the function ...
Wrapper *w = NewWrapper();
Printf(w->def,"void wrap_%s() {\n", name);

/* Declare all of the local variables */
Swig_cargs(w, l);

/* Convert all of the arguments */
...

/* Make the function call and declare the result variable */
Swig_cresult(w,t,"result",Swig_cfunction(name,l));

/* Convert the result into whatever */
...

Printf(w->code,"}\n");
Wrapper_print(w,out);
The output of this would appear as follows:
void wrap_dot_product() {
    Vector *arg0;
    Vector *arg1;
    double  result;

    ...
    result = dot_product(*arg0, *arg1);
    ...
}
Notice that the Swig_cargs(), Swig_cresult(), and Swig_cfunction() functions have taken care of the type conversions for the Vector type automatically.

Notes:

  • The intent of these functions is to provide consistent handling of function parameters and return values so that language module writers don't have to worry about it too much.

  • These functions may be superceded by features in the new typemap system which provide hooks for specifying local variable declarations and argument conversions.

8. Symbol Naming Guidelines for Generated C/C++ Code

The C++ standard (ISO/IEC 14882:1998(E)) states:

17.4.3.1.2 Global names [lib.global.names]

1 Certain sets of names and function signatures are always reserved to the implementation:

    * Each name that contains a double underscore (__) or begins with an underscore followed 
      by an upper case letter (2.11) is reserved to the implementation for any use.
    * Each name that begins with an underscore is reserved to the implementation for use as 
      a name in the global namespace.165)

    165) Such names are also reserved in namespace ::std (17.4.3.1). [back to text] 

When generating code it is important not to generate symbols that might clash with the code being wrapped. It is tempting to flout the standard or just use a symbol which starts with a single underscore followed by a lowercase letter in order to avoid name clashes. However even these legal symbols can also clash with symbols being wrapped. The following guidelines should be used when generating code in order to meet the standard and make it highly unlikely that symbol clashes will occur:

For C++ code that doesn't attempt to mangle a symbol being wrapped (for example SWIG convenience functions):

  • Put symbols in the Swig namespace, for example class Swig::Director. Qualify using the Swig namespace whenever the symbol is referenced, even within the Swig namespace, for example new Swig::Director() not new Director().
  • Use swig_ as a prefix for all member variables and member functions that are involved in an inheritance chain with wrapped classes, for example Swig::Director::swig_get_up() and bool Swig::Director::swig_up.
  • Alternatively class names can be prefixed with Swig in the global namespace for example template<class T> class SwigValueWrapper.

For code compiled as C or C++ that doesn't attempt to mangle a symbol being wrapped (for example SWIG convenience functions):

  • Use SWIG_ as a prefix for structures for example SWIG_JavaExceptions_t.
  • Use SWIG_ as a prefix for global functions for example SWIG_TypeRegister.
  • Use SWIG_ as a prefix for macros for example #define SWIG_PY_INT 1
For code compiled as C or C++ that attempts to mangle a wrapped symbol:
  • Use SWIGxxx or Swigxxx as a prefix where xxx is chosen which would make SWIGxxx/Swigxxx a unique symbol in the global namespace, for example class SwigDirectorFoo when wrapping class Foo. Don't use a trailing underscore for the prefix as this may generate a double underscore when wrapping a symbol which starts with a single underscore.
In the past SWIG has generated many symbols which flout the standard especially double underscores. In fact they may not all be rooted out yet, so please fix them when you see them.

9. Reserved

10. Guile Support

The information that used to live here has moved to the user documentation, file Guile.html.

11. Python Support

[TODO]

12. Perl Support

[TODO]

13. Java Support

[TODO]
Copyright (C) 1999-2001 SWIG Development Team cableswig-0.1.0+git20150808.orig/SWIG/Doc/Devel/index.html0000644000175000000620000000061112561312226021334 0ustar stevestaff SWIG Documentation This directory contains SWIG documentation:
Copyright (C) 1999-2001 SWIG Development Team cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/0002755000175000000620000000000012561312226017521 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/Java.html0000644000175000000620000047343712561312226021310 0ustar stevestaff SWIG and Java

17 SWIG and Java

This chapter describes SWIG's support of Java. It covers most SWIG features, but certain low-level details are covered in less depth than in earlier chapters.

17.1 Overview

The 100% Pure Java effort is a commendable concept, however in the real world programmers often either need to re-use their existing code or in some situations want to take advantage of Java but are forced into using some native (C/C++) code. The Java extension to SWIG makes it very easy to plumb in existing C/C++ code for access from Java, as SWIG writes the Java Native Interface (JNI) code for you. It is different to using the 'javah' tool as SWIG will wrap existing C/C++ code, whereas javah takes 'native' Java function declarations and creates C/C++ function prototypes. SWIG wraps C/C++ code using Java proxy classes and is very useful if you want to have access to large amounts of C/C++ code from Java. If only one or two JNI functions are needed then using SWIG may be overkill. SWIG enables a Java program to easily call into C/C++ code from Java. Historically, SWIG was not able to generate any code to call into Java code from C++. However, SWIG now supports full cross language polymorphism and code is generated to call up from C++ to Java when wrapping C++ virtual methods.

Java is one of the few non-scripting language modules in SWIG. As SWIG utilizes the type safety that the Java language offers, it takes a somewhat different approach to that used for scripting languages. In particular runtime type checking and the runtime library are not used by Java. This should be borne in mind when reading the rest of the SWIG documentation. This chapter on Java is relatively self contained and will provide you with nearly everything you need for using SWIG and Java. However, the "SWIG Basics" chapter will be a useful read in conjunction with this one.

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

17.2 Preliminaries

SWIG 1.1 works with JDKs from JDK 1.1 to JDK1.4 (Java 2 SDK1.4) and should also work with any later versions. Given the choice, you should probably use the latest version of Sun's JDK. The SWIG Java module is known to work using Sun's JVM on Solaris, Linux and the various flavours of Microsoft Windows including Cygwin. The Kaffe JVM is known to give a few problems and at the time of writing was not a fully fledged JVM with full JNI support. The generated code is also known to work on vxWorks using WindRiver's PJava 3.1. The best way to determine whether your combination of operating system and JDK will work is to test the examples and test-suite that comes with SWIG. Run make -k check from the SWIG root directory after installing SWIG on Unix systems.

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.

17.2.1 Running SWIG

Suppose that you defined a SWIG module such as the following:
%module example
%{
#include "header.h"
%}
int fact(int n);
To build a Java module, run SWIG using the -java option :

%swig -java example.i

If building C++, add the -c++ option:

$ swig -c++ -java example.i
This creates two different files; a C/C++ source file example_wrap.c or example_wrap.cxx and numerous Java files. The generated C/C++ source file contains the JNI wrapper code that needs to be compiled and linked with the 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.

17.2.2 Additional Commandline Options

The following table list the additional commandline options available for the Java module. They can also be seen by using:
swig -java -help 
Java specific options
-package <name> set name of the Java package to <name>
-noproxy generate the low-level functional interface instead of proxy classes

Their use will become clearer by the time you have finished reading this section on SWIG and Java.

17.2.3 Getting the right header files

In order to compile the C/C++ wrappers, the compiler needs the jni.h and jni_md.h header files which are part of the JDK. They are usually in directories like this:

/usr/java/include
/usr/java/include/<operating_system>

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

17.2.4 Compiling a dynamic module

The JNI code exists in a dynamic module or shared library (DLL on Windows) and gets loaded by the JVM. To build a shared library file, you need to compile your module in a manner similar to the following (shown for Solaris):

$ swig -java example.i
$ gcc -c example_wrap.c  -I/usr/java/include -I/usr/java/include/solaris
$ ld -G example_wrap.o  -o libexample.so

The exact commands for doing this vary from platform to platform. However, SWIG tries to guess the right options when it is installed. Therefore, you may want to start with one of the examples in the Examples/java directory. If that doesn't work, you will need to read the man-pages for your compiler and linker to get the right set of options. You might also check the SWIG Wiki for additional information.

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). The name of the module is specified using the %module directive or -module command line option.

17.2.5 Using your module

To load your shared native library module in Java, simply use Java's System.loadLibrary method in a Java class:

// main.java

public class main {
  static {
    System.loadLibrary("example");
  }

  public static void main(String argv[]) {
    System.out.println(example.fact(4));
  }
}
Compile all the Java files and run:
$ javac *.java
$ java main
24
$
If it doesn't work have a look at the following section which discusses problems loading the shared library.

17.2.6 Dynamic linking problems

As shown in the previous section the code to load a native library (shared library) is System.loadLibrary("name"). This can fail with an UnsatisfiedLinkError exception and can be due to a number of reasons.

You may get an exception similar to this:

$ java main
Exception in thread "main" java.lang.UnsatisfiedLinkError: no example in java.library.path
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1312)
        at java.lang.Runtime.loadLibrary0(Runtime.java:749)
        at java.lang.System.loadLibrary(System.java:820)
        at main.(main.java:5)
The most common cause for this is an incorrect naming of the native library for the name passed to the loadLibrary function. The string passed to the loadLibrary function must not include the file extension name in the string, that is .dll or .so. The string must be name and not libname for all platforms. On Windows the native library must then be called name.dll and on most Unix systems it must be called libname.so. If you are debugging using java -debug, then the native library must be called name_g.dll on Windows and libname_g.so on Unix.

Another common reason for the native library not loading is because it is not in your path. On Windows make sure the path environment variable contains the path to the native library. On Unix make sure that your LD_LIBRARY_PATH contains the path to the native library. Adding paths to LD_LIBRARY_PATH can slow down other programs on your system so you may want to consider alternative approaches. For example you could recompile your native library with extra path information using -rpath if you're using GNU, see the GNU linker documentation (ld man page). You could use a command such as ldconfig (Linux) or crle (Solaris) to add additional search paths to the default system configuration (this requires root access and you will need to read the man pages).

The native library will also not load if there are any unresolved symbols in the compiled C/C++ code. The following exception is indicative of this:

$ java main
Exception in thread "main" java.lang.UnsatisfiedLinkError: libexample.so: undefined symbol: fact
        at java.lang.ClassLoader$NativeLibrary.load(Native Method)
        at java.lang.ClassLoader.loadLibrary0(ClassLoader.java, Compiled Code)
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java, Compiled Code)
        at java.lang.Runtime.loadLibrary0(Runtime.java, Compiled Code)
        at java.lang.System.loadLibrary(System.java, Compiled Code)
        at main.(main.java:5)
$
This error usually indicates that you forgot to include some object files or libraries in the linking of the native library file. Make sure you compile both the SWIG wrapper file and the code you are wrapping into the native library file. Also make sure you pass all of the required libraries to the linker. The java -verbose:jni commandline switch is also a great way to get more information on unresolved symbols. One last piece of advice is to beware of the common faux pas of having more than one native library version in your path.

In summary, ensure that you are using the correct C/C++ compiler and linker combination and options for successful native library loading. If you are using the examples that ship with SWIG, then the Examples/Makefile must have these set up correctly for your system. The SWIG installation package makes a best attempt at getting these correct but does not get it right 100% of the time. The SWIG Wiki also has some settings for commonly used compiler and operating system combinations. The following section also contains some C++ specific linking problems and solutions.

17.2.7 Compilation problems and compiling with C++

On most machines, shared library files should be linked using the C++ compiler. For example:

% swig -c++ -java example.i
% g++ -c -fpic example.cxx
% g++ -c -fpic example_wrap.cxx -I/usr/java/j2sdk1.4.1/include -I/usr/java/j2sdk1.4.1/include/linux
% g++ -shared example.o example_wrap.o -o libexample.so
In addition to this, you may need to include additional library files to make it work. For example, if you are using the Sun C++ compiler on Solaris, you often need to add an extra library -lCrun like this:

% swig -c++ -java example.i
% CC -c example.cxx
% CC -c example_wrap.cxx -I/usr/java/include -I/usr/java/include/solaris
% CC -G example.o example_wrap.o -L/opt/SUNWspro/lib -o libexample.so -lCrun
If you aren't entirely sure about the linking for C++, you might look at an existing C++ program. On many Unix machines, the ldd command will list library dependencies. This should give you some clues about what you might have to include when you link your shared library. For example:
$ ldd swig
        libstdc++-libc6.1-1.so.2 => /usr/lib/libstdc++-libc6.1-1.so.2 (0x40019000)
        libm.so.6 => /lib/libm.so.6 (0x4005b000)
        libc.so.6 => /lib/libc.so.6 (0x40077000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
$
Finally make sure the version of JDK header files matches the version of Java that you are running as incompatibilities could lead to compilation problems or unpredictable behaviour.

17.2.8 Building on Windows

Building on Windows is roughly similar to the process used with Unix. 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.

17.2.8.1 Running SWIG from Visual Studio

If you are developing your application within Microsoft Visual studio, SWIG can be invoked as a custom build option. The Examples\java directory has a few Windows Examples containing Visual Studio project (.dsp) files. The process to re-create the project files for a C project are roughly:

  • Open up a new workspace and use the AppWizard to select a DLL project.
  • Add both the SWIG interface file (the .i file), any supporting C files, and the name of the wrapper file that will be created by SWIG (ie. example_wrap.c). Don't worry if the wrapper file doesn't exist yet--Visual Studio will keep a reference to it.
  • Select the SWIG interface file and go to the settings menu. Under settings, select the "Custom Build" option.
  • Enter "SWIG" in the description field.
  • Enter "swig -java -o $(ProjDir)\$(InputName)_wrap.c $(InputPath)" in the "Build command(s) field"
  • Enter "$(ProjDir)\$(InputName)_wrap.c" in the "Output files(s) field".
  • Next, select the settings for the entire project and go to C/C++ tab and select the Preprocessor category . Add the include directories to the JNI header files under "Additional include directories", eg "C:\jdk1.3\include,C:\jdk1.3\include\win32".
  • Next, select the settings for the entire project and go to Link tab and select the General category. Set the name of the output file to match the name of your Java module (ie. example.dll).
  • Next, select the example.c and example_wrap.c files and go to the C/C++ tab and select the Precompiled Headers tab in the project settings. Disabling precompiled headers for these files will overcome any precompiled header errors while building.
  • Finally, add the java compilation as a post build rule in the Post-build step tab in project settings, eg, "c:\jdk1.3\bin\javac *.java"
  • Build your project.

Note: If using C++, choose a C++ suffix for the wrapper file, for example example_wrap.cxx. Use _wrap.cxx instead of _wrap.c in the instructions above and add -c++ when invoking swig.

Now, assuming all went well, SWIG will be automatically invoked when you build your project. When doing a build, any changes made to the interface file will result in SWIG being automatically invoked to produce a new version of the wrapper file. 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.

17.2.8.2 Using NMAKE

Alternatively, a Makefile for use by NMAKE can be written. Make sure the environment variables for MSVC++ are available and the MSVC++ tools are in your path. Now, just write a short Makefile like this :

# Makefile for using SWIG and Java for C code

SRCS          = example.c
IFILE         = example
INTERFACE     = $(IFILE).i
WRAPFILE      = $(IFILE)_wrap.c

# Location of the Visual C++ tools (32 bit assumed)

TOOLS         = c:\msdev
TARGET        = example.dll
CC            = $(TOOLS)\bin\cl.exe
LINK          = $(TOOLS)\bin\link.exe
INCLUDE32     = -I$(TOOLS)\include
MACHINE       = IX86

# C Library needed to build a DLL

DLLIBC        = msvcrt.lib oldnames.lib  

# Windows libraries that are apparently needed
WINLIB        = kernel32.lib advapi32.lib user32.lib gdi32.lib comdlg32.lib winspool.lib

# Libraries common to all DLLs
LIBS          = $(DLLIBC) $(WINLIB) 

# Linker options
LOPT      = -debug:full -debugtype:cv /NODEFAULTLIB /RELEASE /NOLOGO \
             /MACHINE:$(MACHINE) -entry:_DllMainCRTStartup@12 -dll

# C compiler flags

CFLAGS        = /Z7 /Od /c /nologo
JAVA_INCLUDE    = -ID:\jdk1.3\include -ID:\jdk1.3\include\win32

java::
	swig -java -o $(WRAPFILE) $(INTERFACE)
	$(CC) $(CFLAGS) $(JAVA_INCLUDE) $(SRCS) $(WRAPFILE)
	set LIB=$(TOOLS)\lib
	$(LINK) $(LOPT) -out:example.dll $(LIBS) example.obj example_wrap.obj
	javac *.java

To build the DLL and compile the java code, run NMAKE (you may need to run vcvars32 first). This is a pretty simplistic Makefile, but hopefully its enough to get you started. Of course you may want to make changes for it to work for C++ by adding in the -c++ command line switch for swig and replacing .c with .cxx.

17.3 A tour of basic C/C++ wrapping

By default, SWIG attempts to build a natural Java interface to your C/C++ code. Functions are wrapped as functions, classes are wrapped as classes, variables are wrapped with JavaBean type getters and setters and so forth. This section briefly covers the essential aspects of this wrapping.

17.3.1 Modules, packages and generated Java classes

The SWIG %module directive specifies the name of the Java module. When you specify `%module example', the module name determines the name of some of the generated files in the module. The generated code consists of a module class file example.java, an intermediary JNI class file, exampleJNI.java as well as numerous other Java proxy class files. Each proxy class is named after the structs, unions and classes you are wrapping. You may also get a constants interface file if you are wrapping any enumerations or constants, for example exampleConstants.java. When choosing a module name, make sure you don't use the same name as one of the generated proxy class files nor a Java keyword. Sometimes a C/C++ type cannot be wrapped by a proxy class, for example a pointer to a primitive type. In these situations a type wrapper class is generated. Details of all these generated classes will unfold as you read this section.

The JNI (C/C++) code is generated into a file which also contains the module name, for example example_wrap.cxx or example_wrap.c. These C or C++ files complete the contents of the module.

The generated Java classes can be placed into a Java package by using the -package commandline option. This is often combined with the -outdir to specify a package directory for generating the Java files.

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

17.3.2 Functions

There is no such thing as a global Java function so global C functions are wrapped as static methods in the module class. For example,

%module example
int fact(int n);

creates a static function that works exactly like you think it might:

public class example {
  public static int fact(int n) {
    // makes call using JNI to the C function
  }
}

The Java class example is the module class. The function can be used as follows from Java:

System.out.println(example.fact(4));

17.3.3 Global variables

C/C++ global variables are fully supported by SWIG. Java does not allow the overriding of the dot operator so all variables are accessed through getters and setters. Again because there is no such thing as a Java global variable, access to C/C++ global variables is done through static getter and setter functions in the module class.
// SWIG interface file with global variables
%module example
...
extern int My_variable;
extern double density;
...

Now in Java :

// Print out value of a C global variable
System.out.println("My_variable = " + example.getMy_variable());
// Set the value of a C global variable
example.setDensity(0.8442);
The value returned by the getter will always be up to date even if the value is changed in C. Note that the getters and setters produced follow the JavaBean property design pattern. That is the first letter of the variable name is capitalized and preceded with set or get. If you have the misfortune of wrapping two variables that differ only in the capitalization of their first letters, use %rename to change one of the variable names. For example:
%rename Clash RenamedClash;
float Clash;
int clash;

If a variable is declared as const, it is wrapped as a read-only variable. That is only a getter is produced.

To make ordinary variables read-only, you can use the %immutable directive. For example:

%immutable;
extern char *path;
%mutable;
The %immutable directive stays in effect until it is explicitly disabled using %mutable.

If you just want to make a specific variable immutable, supply a declaration name. For example:

%immutable path;
...
extern char *path;      // Read-only (due to %immutable)

17.3.4 Constants

C/C++ constants are wrapped as Java static final variables. To create a constant, use #define or the %constant directive. For example:
#define PI 3.14159
#define VERSION "1.0"
%constant int FOO = 42;
%constant const char *path = "/usr/local";
By default the generated static final variables are initialised by making a JNI call to get their value. The constants are generated into the constants interface and look like this:
public interface exampleConstants {
  // enums and constants
  public final static double PI = exampleJNI.get_PI();
  public final static String VERSION = exampleJNI.get_VERSION();
  public final static int FOO = exampleJNI.get_FOO();
  public final static String path = exampleJNI.get_path();
}
These are 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). 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:
%javaconst(1);
%javaconst(0) BIG;
#define BIG 1000LL
#define EXPRESSION (0x100+5)
generates:
public interface exampleConstants {
  // enums and constants
  public final static long BIG = exampleJNI.get_BIG();
  public final static int EXPRESSION = (0x100+5);
}
Be careful using the %javaconst(1) directive as not all C code will compile as Java code. For example the 1000LL value for the BIG constant above would not generate valid Java code. The example demonstrates how you can target particular constants (BIG) with %javaconst.

Note: declarations declared as const are wrapped as read-only variables and will be accessed using a getter as described in the previous section. They are not wrapped as constants.

Compatibility Note: In SWIG-1.3.19 and earlier releases, the constants were generated into the module class and the constants interface didn't exist. Backwards compatibility is maintained as the module class implements the constants interface (even though some consider this type of interface implementation to be bad practice):

public class example implements exampleConstants {
}
You thus have the choice of accessing these constants from either the module class or the constants interface, for example, example.EXPRESSION or exampleConstants.EXPRESSION.

17.3.5 Enumerations

Enumerations are wrapped as final static integers in Java and are also initialised using a JNI call. For example:
enum Beverage { ALE, LAGER=10, STOUT, PILSNER };
is wrapped into the constants interface, in a similar manner as constants (see previous section):
public interface exampleConstants {
  // enums and constants
  public final static int ALE = exampleJNI.get_ALE();
  public final static int LAGER = exampleJNI.get_LAGER();
  public final static int STOUT = exampleJNI.get_STOUT();
  public final static int PILSNER = exampleJNI.get_PILSNER();
}
The %javaconst(flag) directive introduced in the previous section on constants can also be used with enums, thereby also allowing enum values to be used in Java switch statements. As is the case for constants, the default is %javaconst(0) as not all C values will compile as Java code. However, it is recommended to add in a %javaconst(1) directive at the top of your interface file as it is only on very rare occasions that this will produce code that won't compile under Java. Example usage:
%javaconst(1);
%javaconst(0) PILSNER;
enum Beverage { ALE, LAGER=10, STOUT, PILSNER };
generates:
public interface exampleConstants {
  // enums and constants
  public final static int ALE = 0;
  public final static int LAGER = 10;
  public final static int STOUT = LAGER+1;
  public final static int PILSNER = exampleJNI.get_PILSNER();
}
As in the case of constants, you can access them through either the module class or the constants interface, for example, example.ALE or exampleConstants.ALE.

For enums, make sure that the definition of the enumeration actually appears in a header file or in the wrapper file somehow---if you just have an enum in a SWIG interface without also telling the C compiler about it, the wrapper code won't compile.

17.3.6 Pointers

C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with incomplete type information. Here is a rather simple interface:
%module example

FILE *fopen(const char *filename, const char *mode);
int fputs(const char *, FILE *);
int fclose(FILE *);
When wrapped, you will be able to use the functions in a natural way from Java. For example:
SWIGTYPE_p_FILE f = example.fopen("junk","w");
example.fputs("Hello World\n", f);
example.fclose(f);
C pointers in the Java module are stored in a Java long and cross the JNI boundary held within this 64 bit number. Many other SWIG language modules use an encoding of the pointer in a string. These scripting languages use the SWIG runtime type checker for dynamic type checking as they do not support static type checking by a compiler. In order to implement static type checking of pointers within Java, they are wrapped by a simple Java class. In the example above the FILE * pointer is wrapped with a type wrapper class called SWIGTYPE_p_FILE.

Once obtained, a type wrapper object can be freely passed around to different C functions that expect to receive an object of that type. The only thing you can't do is dereference the pointer from Java. Of course, that isn't much of a concern in this example.

As much as you might be inclined to modify a pointer value directly from Java, don't. The value is not necessarily the same as the logical memory address of the underlying object. The value will vary depending on the native byte-ordering of the platform (i.e., big-endian vs. little-endian). Most JVMs are 32 bit applications so any JNI code must also be compiled as 32 bit. The net result is pointers in JNI code are also 32 bits and are stored in the high order 4 bytes on big-endian machines and in the low order 4 bytes on little-endian machines. By design it is also not possible to manually cast a pointer to a new type by using Java casts as it is particularly dangerous especially when casting C++ objects. If you need to cast a pointer or change its value, consider writing some helper functions instead. For example:

%inline %{
/* C-style cast */
Bar *FooToBar(Foo *f) {
   return (Bar *) f;
}

/* C++-style cast */
Foo *BarToFoo(Bar *b) {
   return dynamic_cast<Foo*>(b);
}

Foo *IncrFoo(Foo *f, int i) {
    return f+i;
}
%}
Also, if working with C++, you should always try to use the new C++ style casts. For example, in the above code, the 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.

17.3.7 Structures

If you wrap a C structure, it is wrapped by a Java class with getters and setters for access to the member variables. For example,

struct Vector {
	double x,y,z;
};

is used as follows:
Vector v = new Vector();
v.setX(3.5);
v.setY(7.2);
double x = v.getX();
double y = v.getY();
The variable setters and getters are also based on the JavaBean design pattern already covered under the Global variables section. Similar access is provided for unions and the public data members of C++ classes.

This object is actually an instance of a Java class that has been wrapped around a pointer to the C structure. This instance doesn't actually do anything--it just serves as a proxy. The pointer to the C object is held in the Java proxy class in much the same way as pointers are held by type wrapper classes. Further details about Java proxy classes are covered a little later.

const members of a structure are read-only. Data members can also be forced to be read-only using the %immutable directive. For example:

struct Foo {
   ...
   %immutable;
   int x;        /* Read-only members */
   char *name;
   %mutable;
   ...
};

When char * members of a structure are wrapped, the contents are assumed to be dynamically allocated using malloc or new (depending on whether or not SWIG is run with the -c++ option). When the structure member is set, the old contents will be released and a new value created. If this is not the behavior you want, you will have to use a typemap (described later).

If a structure contains arrays, access to those arrays is managed through pointers. For example, consider this:

struct Bar {
    int  x[16];
};
If accessed in Java, you will see behavior like this:
Bar b = new Bar();
SWIGTYPE_p_int x = b.getX();
This pointer can be passed around to functions that expect to receive an int * (just like C). You can also set the value of an array member using another pointer. For example:
Bar b = new Bar();
SWIGTYPE_p_int x = b.getX();
Bar c = new Bar();
c.setX(x);                    // Copy contents of b.x to c.x
For array assignment (setters not getters), SWIG copies the entire contents of the array starting with the data pointed to by b.x. In this example, 16 integers would be copied. Like C, SWIG makes no assumptions about bounds checking---if you pass a bad pointer, you may get a segmentation fault or access violation. Array access can be changed from this default to use Java arrays and this is covered later.

When a member of a structure is itself a structure, it is handled as a pointer. For example, suppose you have two structures like this:

struct Foo {
   int a;
};

struct Bar {
   Foo f;
};
Now, suppose that you access the f member of Bar like this:
Bar b = new Bar();
Foo x = b.getF();
In this case, x is a pointer that points to the Foo that is inside b. This is the same value as generated by this C code:
Bar b;
Foo *x = &b->f;       /* Points inside b */
Because the pointer points inside the structure, you can modify the contents and everything works just like you would expect. For example:
Bar b = new Bar();
b.getF().setA(3);   // Modify b.f.a
Foo x = b.getF();                   
x.setA(3);          // Modify x.a - this is the same as b.f.a

17.3.8 C++ classes

C++ classes are wrapped by Java classes as well. For example, if you have this class,

class List {
public:
  List();
  ~List();
  int  search(char *item);
  void insert(char *item);
  void remove(char *item);
  char *get(int n);
  int  length;
};
you can use it in Java like this:
List l = new List();
l.insert("Ale");
l.insert("Stout");
l.insert("Lager");
String item = l.get(2);
int length = l.getLength();
Class data members are accessed in the same manner as C structures.

Static class members are unsurprisingly wrapped as static members of the Java class:

class Spam {
public:
   static void foo();
   static int bar;
};
The static members work like any other Java static member:
Spam.foo();
int bar = Spam.getBar();

17.3.9 C++ inheritance

SWIG is fully aware of issues related to C++ inheritance. Therefore, if you have classes like this
class Foo {
...
};

class Bar : public Foo {
...
};
those classes are wrapped into a hierarchy of Java classes that reflect the same inheritance structure:
Bar b = new Bar();
Class c = b.getClass();
System.out.println(c.getSuperclass().getName());
will of course display:
Foo
Furthermore, if you have functions like this
void spam(Foo *f);
then the Java function spam() accepts instances of Foo or instances of any other proxy classes derived from Foo.

Note that Java does not support multiple inheritance so any multiple inheritance in the C++ code is not going to work. A warning is given when multiple inheritance is detected and only the first base class is used.

17.3.10 Pointers, references, arrays and pass by value

In C++, there are many different ways a function might receive and manipulate objects. For example:
void spam1(Foo *x);      // Pass by pointer
void spam2(Foo &x);      // Pass by reference
void spam3(Foo x);       // Pass by value
void spam4(Foo x[]);     // Array of objects
In Java, there is no detailed distinction like this--specifically, there are only instances of classes. There are no pointers nor references. Because of this, SWIG unifies all of these types together in the wrapper code. For instance, if you actually had the above functions, it is perfectly legal to do this from Java:
Foo f = new Foo();  // Create a Foo
example.spam1(f);   // Ok. Pointer
example.spam2(f);   // Ok. Reference
example.spam3(f);   // Ok. Value.
example.spam4(f);   // Ok. Array (1 element)
Similar behavior occurs for return values. For example, if you had functions like this,
Foo *spam5();
Foo &spam6();
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 (Java will release this memory when the returned object's finalizer is run by the garbage collector).

17.3.10.1 Null pointers

Working with null pointers is easy. A Java null can be used whenever a method expects a proxy class or typewrapper class. However, it is not possible to pass null to C/C++ functions that take parameters by value or by reference. If you try you will get a NullPointerException.
example.spam1(null);   // Pointer - ok
example.spam2(null);   // Reference - NullPointerException
example.spam3(null);   // Value - NullPointerException
example.spam4(null);   // Array - ok
For spam1 and spam4 above the Java null gets translated into a NULL pointer for passing to the C/C++ function. The converse also occurs, that is, NULL pointers are translated into null Java objects when returned from a C/C++ function.

17.3.11 C++ overloaded functions

C++ overloaded functions, methods, and constructors are mostly supported by SWIG. For example, if you have two functions like this:
void foo(int);
void foo(char *c);
You can use them in Java in a straightforward manner:
foo(3);           // foo(int)
foo("Hello");     // foo(char *c)
Similarly, if you have a class like this,
class Foo {
public:
    Foo();
    Foo(const Foo &);
    ...
};
you can write Java code like this:
Foo f = new Foo();        // Create a Foo
Foo g = new Foo(f);       // Copy f
Overloading support is not quite as flexible as in C++. Sometimes there are methods that SWIG cannot disambiguate as there can be more than one C++ type mapping onto a single Java type. For example:
void spam(int);
void spam(unsigned short);
Here both int and unsigned short map onto a Java int. Here is another example:
void foo(Bar *b);
void foo(Bar &b);
If declarations such as these appear, you will get a warning message like this:
example.i:12: Warning(515): Overloaded method spam(unsigned short) ignored. Method spam(int) at example.i:11 used.
To fix this, you either need to ignore or rename one of the methods. For example:
%rename(spam_short) spam(short);
...
void spam(int);    
void spam(short);   // Accessed as spam_short
or
%ignore spam(short);
...
void spam(int);    
void spam(short);   // Ignored

17.3.12 C++ namespaces

SWIG is aware of C++ namespaces, but 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,
%module example

namespace foo {
   int fact(int n);
   struct Vector {
       double x,y,z;
   };
};
it works in Java as follows:
int f = example.fact(3);
Vector v = new Vector();
v.setX(3.4);
double y = v.getY();
If your program has more than one namespace, name conflicts (if any) can be resolved using %rename For example:
%rename(Bar_spam) Bar::spam;

namespace Foo {
    int spam();
}

namespace Bar {
    int spam();
}
If you have more than one namespace and your want to keep their symbols separate, consider wrapping them as separate SWIG modules. Each SWIG module can be placed into a separate package.

17.3.13 C++ templates

C++ templates don't present a huge problem for SWIG. However, in order to create wrappers, you have to tell SWIG to create wrappers for a particular template instantiation. To do this, you use the %template directive. For example:
%module example
%{
#include "pair.h"
%}

template<class T1, class T2>
struct pair {
   typedef T1 first_type;
   typedef T2 second_type;
   T1 first;
   T2 second;
   pair();
   pair(const T1&, const T2&);
  ~pair();
};

%template(pairii) pair<int,int>;
In Java:
pairii p = new pairii(3,4);
int first = p.getFirst();
int second = p.getSecond();
Obviously, there is more to template wrapping than shown in this example. More details can be found in the SWIG and C++ chapter.

17.3.14 C++ Smart Pointers

In certain C++ programs, it is common to use classes that have been wrapped by so-called "smart pointers." Generally, this involves the use of a template class that implements operator->() like this:
template<class T> class SmartPtr {
   ...
   T *operator->();
   ...
}
Then, if you have a class like this,
class Foo {
public:
     int x;
     int bar();
};
A smart pointer would be used in C++ as follows:
SmartPtr<Foo> p = CreateFoo();   // Created somehow (not shown)
...
p->x = 3;                        // Foo::x
int y = p->bar();                // Foo::bar
To wrap this in Java, simply tell SWIG about the SmartPtr class and the low-level Foo object. Make sure you instantiate SmartPtr using %template if necessary. For example:
%module example
...
%template(SmartPtrFoo) SmartPtr<Foo>;
...
Now, in Java, everything should just "work":
SmartPtrFoo p = example.CreateFoo(); // Create a smart-pointer somehow
p.setX(3);                           // Foo::x
int y = p.bar();                     // Foo::bar
If you ever need to access the underlying pointer returned by operator->() itself, simply use the __deref__() method. For example:
Foo f = p.__deref__();               // Returns underlying Foo *

17.4 Further details on the generated Java classes

In the previous section, a high-level view of Java wrapping was presented. A key component of this wrapping is that structures and classes are wrapped by Java proxy classes and type wrapper classes are used in situations where no proxies are generated. This provides a very natural, type safe Java interface to the C/C++ code and fits in with the Java programing paradigm. However, a number of low-level details were omitted. This section provides a brief overview of how the proxy classes work and then covers the type wrapper classes. First, the crucial intermediary JNI class is considered.

17.4.1 The intermediary JNI class

In the "SWIG basics" and "SWIG and C++" chapters, details of low-level structure and class wrapping are described. To summarize those chapters, if you have a global function and class like this
class Foo {
public:
     int x;
     int spam(int num, Foo* foo);
};
void egg(Foo* chips);
then SWIG transforms the class into a set of low-level procedural wrappers. These procedural wrappers essentially perform the equivalent of this C++ code:
Foo *new_Foo() {
    return new Foo();
}
void delete_Foo(Foo *f) {
    delete f;
}
int Foo_x_get(Foo *f) {
    return f->x;
}
void Foo_x_set(Foo *f, int value) {
    f->x = value;
}
int Foo_spam(Foo *f, int num, Foo* foo) {
    return f->spam(num, foo);
}
These procedural function names don't actually exist, but their functionality appears inside the generated JNI functions. The JNI functions have to follow a particular naming convention so the function names are actually:
JNIEXPORT jlong JNICALL Java_exampleJNI_new_1Foo(JNIEnv *jenv, jclass jcls);
JNIEXPORT void JNICALL Java_exampleJNI_delete_1Foo(JNIEnv *jenv, jclass jcls, jlong jarg1);
JNIEXPORT void JNICALL Java_exampleJNI_set_1Foo_1x(JNIEnv *jenv, jclass jcls, jlong jarg1, jint jarg2);
JNIEXPORT jint JNICALL Java_exampleJNI_get_1Foo_1x(JNIEnv *jenv, jclass jcls, jlong jarg1);
JNIEXPORT jint JNICALL Java_exampleJNI_Foo_1spam(JNIEnv *jenv, jclass jcls, jlong jarg1, jint jarg2, jlong jarg3);
JNIEXPORT void JNICALL Java_exampleJNI_egg(JNIEnv *jenv, jclass jcls, jlong jarg1);
For every JNI C function there has to be a static native Java function. These appear in the intermediary JNI class:
class exampleJNI {
  public final static native long new_Foo();
  public final static native void delete_Foo(long jarg1);
  public final static native void set_Foo_x(long jarg1, int jarg2);
  public final static native int get_Foo_x(long jarg1);
  public final static native int Foo_spam(long jarg1, int jarg2, long jarg3);
  public final static native void egg(long jarg1);
}
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.

You may notice that SWIG uses a Java long wherever a pointer or class object needs traversing the Java-C/C++ boundary. This approach leads to minimal JNI code which makes for better performance as JNI code involves a lot of string manipulation. SWIG uses Java code wherever possible as it is compiled into byte code which requires fewer string operations.

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:

%module (jniclassname="name") modulename
If name is the same as modulename then the module class name gets changed from modulename to modulenameModule.

17.4.1.1 The intermediary JNI class pragmas

The intermediary JNI class can be tailored through the use of pragmas, but is not commonly done. The pragmas for this class are:

Pragma Description
jniclassbase Base class for the intermediary JNI class
jniclassclassmodifiers Class modifiers for the intermediary JNI class
jniclasscode Java code is copied verbatim into the intermediary JNI class
jniclassimports Java code, usually one or more import statements, placed before the intermediary JNI class definition
jniclassinterfaces Comma separated interface classes for the intermediary JNI class

The pragma code appears in the generated intermediary JNI class where you would expect:

[ jniclassimports pragma ]
[ jniclassmodifiers pragma ] class jniclassname extends [ jniclassbase pragma ] implements [ jniclassinterfaces pragma ] {
[ jniclasscode pragma ]
... SWIG generated native methods ...
}
The jniclasscode pragma is quite useful for adding in a static block for loading the shared library / dynamic link library and demonstrates how pragmas work:
%pragma(java) jniclasscode=%{
  static {
    try {
        System.loadLibrary("example");
    } catch (UnsatisfiedLinkError e) {
      System.err.println("Native code library failed to load. \n" + e);
      System.exit(1);
    }
  }
%}
Pragmas will take either "" or %{ %} as delimeters. For example, let's change the intermediary JNI class access attribute to public.
%pragma(java) jniclassclassmodifiers="public"
All the methods in the intermediary JNI class will then be callable outside of the package as the method modifiers are public by default.

17.4.2 The Java module class

All global functions and variable getters/setters appear in the module class. For our example, there is just one function:
public class example {
  public static void egg(Foo chips) {
    exampleJNI.egg(Foo.getCPtr(chips));
  }
}
The module class is necessary as there is no such thing as a global in Java so all the C globals are put into this class. They are generated as static functions and so must be accessed as such by using the module name in the static function call:
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.

17.4.2.1 The Java module class pragmas

The module class can be tailored through the use of pragmas, in the same manner as the intermediary JNI class. The pragmas are similarly named and are used in the same way. The complete list follows:

Pragma Description
modulebase Base class for the module class
moduleclassmodifiers Class modifiers for the module class
modulecode Java code is copied verbatim into the module class
moduleimports Java code, usually one or more import statements, placed before the module class definition
moduleinterfaces Comma separated interface classes for the module class

The pragma code appears in the generated module class like this:

[ moduleimports pragma ]
[ modulemodifiers pragma ] class modulename extends [ modulebase pragma ] implements [ moduleinterfaces pragma ] {
[ modulecode pragma ]
... SWIG generated wrapper functions ...
}
See The intermediary JNI class pragmas section for further details on using pragmas.

17.4.3 Java proxy classes

A Java proxy class is generated for each structure, union or C++ class that is wrapped. The default proxy class for our previous example looks like this:
public class Foo {
  private long swigCPtr;
  protected boolean swigCMemOwn;

  protected Foo(long cPtr, boolean cMemoryOwn) {
    swigCMemOwn = cMemoryOwn;
    swigCPtr = cPtr;
  }

  protected void finalize() {
    delete();
  }

  public void delete() {
    if(swigCPtr != 0 && swigCMemOwn) {
      exampleJNI.delete_Foo(swigCPtr);
      swigCMemOwn = false;
    }
    swigCPtr = 0;
  }

  protected static long getCPtr(Foo obj) {
    return obj.swigCPtr;
  }

  public void setX(int x) {
    exampleJNI.set_Foo_x(swigCPtr, x);
  }

  public int getX() {
    return exampleJNI.get_Foo_x(swigCPtr);
  }

  public int spam(int num, Foo foo) {
    return exampleJNI.Foo_spam(swigCPtr, num, Foo.getCPtr(foo));
  }

  public Foo() {
    this(exampleJNI.new_Foo(), true);
  }
}
This class merely holds a pointer to the underlying C++ object (swigCPtr). It also contains all the methods in the C++ class it is proxying plus getters and setters for public member variables. These functions call the native methods in the intermediary JNI class. The advantage of having this extra layer is the type safety that the proxy class functions offer. It adds static type checking which leads to fewer surprises at runtime. For example, you can see that if you attempt to use the spam() function it will only compile when the parameters passed are an int and a Foo. From a user's point of view, it makes the class work as if it were a Java class:
Foo f = new Foo();
f.setX(3);
int y = f.spam(5, new Foo());

17.4.3.1 Memory management

Each proxy class has an ownership flag swigCMemOwn. The value of this flag determines who is responsible for deleting the underlying C++ object. If set to true, the proxy class's finalizer will destroy the C++ object when the proxy class is garbage collected. If set to false, then the destruction of the proxy class has no effect on the C++ object.

When an object is created by a constructor or returned by value, Java automatically takes ownership of the result. On the other hand, when pointers or references are returned to Java, there is often no way to know where they came from. Therefore, the ownership is set to false. For example:

class Foo {
public:
    Foo();
    Foo bar1();
    Foo &bar2();
    Foo *bar2();
};
In Java:
Foo f = new Foo();   //  f.swigCMemOwn = true
Foo f1 = f.bar1();   // f1.swigCMemOwn = true
Foo f2 = f.bar2();   // f2.swigCMemOwn = false
Foo f3 = f.bar3();   // f3.swigCMemOwn = false
This behavior for pointers and references is especially important for classes that act as containers. For example, if a method returns a pointer to an object that is contained inside another object, you definitely don't want Java to assume ownership and destroy it!

For the most part, memory management issues remain hidden. However, there are situations where you might have to manually change the ownership of an object. For instance, consider code like this:

class Obj {};
class Node {
   Obj *value;
public:
   void set_value(Obj *v) { value = v; }
};
Now, consider the following Java code:
Node n = new Node();    // Create a node
{
  Obj o = new Obj();    // Create an object
  n.set_value(o);       // Set value
}                       // o goes out of scope
In this case, the Node n is holding a reference to o internally. However, SWIG has no way to know that this has occurred. The Java proxy class still thinks that it has ownership of o. As o has gone out of scope, it could be garbage collected in which case the C++ destructor will be invoked and n will then be holding a stale-pointer to o. If 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 is achieved using a typemap to add pure Java code to the proxy class and is detailed later in the section on typemaps.

Sometimes a function will create memory and return a pointer to a newly allocated object. SWIG has no way of knowing this so by default the proxy class does not manage the returned object. However, you can tell the proxy class to manage the memory if you specify the %newobject directive. Consider:

class Obj {...};
class Factory {
public:
    static Obj *createObj() { return new Obj(); }
};
If we call the factory function, then we have to manually delete the memory:
Obj obj = Factory.createObj();   // obj.swigCMemOwn = false
...
obj.delete();
Now add in the %newobject directive:
%newobject Factory::createObj();

class Obj {...};
class Factory {
public:
    static Obj *createObj() { return new Obj(); }
};
A call to delete() is no longer necessary as the garbage collector will make the C++ destructor call because swigCMemOwn is now true.
Obj obj = Factory.createObj();   // obj.swigCMemOwn = true;
...

17.4.3.2 Inheritance

Java proxy classes will mirror C++ inheritance chains. For example, given the base class Base and its derived class Derived:
class Base {
public:
  virtual double foo();
};

class Derived : public Base {
public:
  virtual double foo();
};
The base class is generated much like any other proxy class seen so far:
public class Base {
  private long swigCPtr;
  protected boolean swigCMemOwn;

  protected Base(long cPtr, boolean cMemoryOwn) {
    swigCMemOwn = cMemoryOwn;
    swigCPtr = cPtr;
  }

  protected void finalize() {
    delete();
  }

  public void delete() {
    if(swigCPtr != 0 && swigCMemOwn) {
      exampleJNI.delete_Base(swigCPtr);
      swigCMemOwn = false;
    }
    swigCPtr = 0;
  }

  protected static long getCPtr(Base obj) {
    return obj.swigCPtr;
  }

  public double foo() {
    return exampleJNI.Base_foo(swigCPtr);
  }

  public Base() {
    this(exampleJNI.new_Base(), true);
  }
}
The Derived class extends Base mirroring the C++ class inheritance hierarchy.
public class Derived extends Base {
  private long swigCPtr;

  protected Derived(long cPtr, boolean cMemoryOwn) {
    super(exampleJNI.SWIGDerivedToBase(cPtr), cMemoryOwn);
    swigCPtr = cPtr;
  }

  protected void finalize() {
    delete();
  }

  public void delete() {
    if(swigCPtr != 0 && swigCMemOwn) {
      exampleJNI.delete_Derived(swigCPtr);
      swigCMemOwn = false;
    }
    swigCPtr = 0;
    super.delete();
  }

  protected static long getCPtr(Derived obj) {
    return obj.swigCPtr;
  }

  public double foo() {
    return exampleJNI.Derived_foo(swigCPtr);
  }

  public Derived() {
    this(exampleJNI.new_Derived(), true);
  }
}
Note the memory ownership is controlled by the base class. However each class in the inheritance hierarchy has its own pointer value which is obtained during construction. The SWIGDerivedToBase() call converts the pointer from a Derived * to a Base * as C++ compilers are free to implement pointers in the inheritance hierarchy with different values.

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.

17.4.3.3 Proxy classes and garbage collection

By default each proxy class has a delete() and a finalize() method. The finalize() method calls delete() which frees any malloc'd memory for wrapped C structs or calls the C++ class destructors. The idea is for delete() to be called when you have finished with the C/C++ object. Ideally you need not call delete(), but rather leave it to the garbage collector to call it from the finalizer. The unfortunate thing is that Sun, in their wisdom, do not guarantee that the finalizers will be called. When a program exits, the garbage collector does not always call the finalizers. Depending on what the finalizers do and which operating system you use, this may or may not be a problem.

If the delete() call into JNI code is just for memory handling, there is not a problem when run on most operating systems, for example Windows and Unix. Say your JNI code creates memory on the heap which your finalizers should clean up, the finalizers may or may not be called before the program exits. In Windows and Unix all memory that a process uses is returned to the system on exit, so this isn't a problem. This is not the case in some operating systems like vxWorks. If however, your finalizer calls into JNI code invoking the C++ destructor which in turn releases a TCP/IP socket for example, there is no guarantee that it will be released. Note that with long running programs the garbage collector will eventually run, thereby calling any unreferenced object's finalizers.

Some not so ideal solutions are:

  1. Call the System.runFinalizersOnExit(true) or Runtime.getRuntime().runFinalizersOnExit(true) to ensure the finalizers are called before the program exits. The catch is that this is a deprecated function call as the documenation says:
    This method is inherently unsafe. It may result in finalizers being called on live objects while other threads are concurrently manipulating those objects, resulting in erratic behavior or deadlock.
    In many cases you will be lucky and find that it works, but it is not to be advocated. Have a look at Sun's Java web site and search for runFinalizersOnExit.
  2. From jdk1.3 onwards a new function, addShutdownHook(), was introduced which is guaranteed to be called when your program exits. You can encourage the garbage collector to call the finalizers, for example, add this static block to the class that has the main() function:
      static {
        Runtime.getRuntime().addShutdownHook( 
          new Thread() {
            public void run() { System.gc(); System.runFinalization(); }
          }
        );
      }
    
    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.
  3. Call the delete() function manually which will immediately invoke the C++ destructor. As a suggestion it may be a good idea to set the object to null so that should the object be inadvertantly used again a Java null pointer exception is thrown, the alternative would crash the JVM by using a null C pointer. For example given a SWIG generated class A:
    A myA = new A();
    // use myA ...
    myA.delete();
    // any use of myA here would crash the JVM 
    myA=null;
    // any use of myA here would cause a Java null pointer exception to be thrown
    
    The SWIG generated code ensures that the memory is not deleted twice, in the event the finalizers get called in addition to the manual delete() call.
  4. 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.

17.4.4 Type wrapper classes

The generated type wrapper class, for say an int *, looks like this:
public class SWIGTYPE_p_int {
  private long swigCPtr;

  protected SWIGTYPE_p_int(long cPtr, boolean bFutureUse) {
    swigCPtr = cPtr;
  }

  protected SWIGTYPE_p_int() {
    swigCPtr = 0;
  }

  protected static long getCPtr(SWIGTYPE_p_int obj) {
    return obj.swigCPtr;
  }
}
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.

Note that if you use a pointer or reference to a proxy class in a function then no type wrapper class is generated because the proxy class can be used as the function parameter. If however, you need anything more complicated like a pointer to a pointer to a proxy class then a typewrapper class is generated for your use.

Note that SWIG generates a type wrapper class and not a proxy class when it has not parsed the definition of a type that gets used. For example, say SWIG has not parsed the definition of class Snazzy because it is in a header file that you may have forgotten to use the %include directive on. Should SWIG parse Snazzy * being used in a function parameter, it will then generates a type wrapper class around a Snazzy pointer. Also recall from earlier that SWIG will use a pointer when a class is passed by value or by reference:

void spam(Snazzy *x, Snazzy &y, Snazzy z);
Should SWIG not know anything about Snazzy then a SWIGTYPE_p_Snazzy must be used for all 3 parameters in the spam function. The Java function generated is:
public static void spam(SWIGTYPE_p_Snazzy x, SWIGTYPE_p_Snazzy y, SWIGTYPE_p_Snazzy z) { ... }

Note that typedefs are tracked by SWIG and the typedef name is used to construct the type wrapper class name. For example, consider the case where Snazzy is a typedef to an int which SWIG does parse:

typedef int Snazzy;
void spam(Snazzy *x, Snazzy &y, Snazzy z);
Because the typedefs have been tracked the Java function generated is:
public static void spam(SWIGTYPE_p_int x, SWIGTYPE_p_int y, int z) { ... }

17.5 Cross language polymorphism using directors (experimental)

Proxy classes provide a natural, object-oriented way to wrap C++ classes. As described earlier, each proxy instance has an associated C++ instance, and method calls from Java to the proxy are passed to the C++ instance transparently via C wrapper functions.

This arrangement is asymmetric in the sense that no corresponding mechanism exists to pass method calls down the inheritance chain from C++ to Java. In particular, if a C++ class has been extended in Java (by deriving from the proxy class), these classes will not be visible from C++ code. Virtual method calls from C++ are thus not able to access the lowest implementation in the inheritance chain.

SWIG can address this problem and make the relationship between C++ classes and proxy classes more symmetric. To achieve this goal, new classes called directors are introduced at the bottom of the C++ inheritance chain. The job of the directors is to route method calls correctly, either to C++ implementations higher in the inheritance chain or to Java implementations lower in the inheritance chain. The upshot is that C++ classes can be extended in Java and from C++ these extensions look exactly like native C++ classes. 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.

17.5.1 Enabling directors

The director feature is disabled by default. To use directors you must make two changes to the interface file. First, add the "directors" option to the %module directive, like this:
%module(directors="1") modulename
Without this option no director code will be generated. Second, you must use the %feature("director") directive to tell SWIG which classes and methods should get directors. The %feature directive can be applied globally, to specific classes, and to specific methods, like this:
 
// generate directors for all classes that have virtual methods
%feature("director");         

// genarate directors for all virtual methods in class Foo
%feature("director") Foo;      

// generate a director for just Foo::bar()
%feature("director") Foo::bar; 
You can use the %feature("nodirector") directive to turn off directors for specific classes or methods. So for example,
%feature("director") Foo;
%feature("nodirector") Foo::bar;
will generate directors for all virtual methods of class Foo except bar().

Directors can also be generated implicitly through inheritance. In the following, class Bar will get a director class that handles the methods one() and two() (but not three()):

%feature("director") Foo;
class Foo {
public:
    virtual void one();
    virtual void two();
};

class Bar: public Foo {
public:
    virtual void three();
};

17.5.2 Director classes

For each class that has directors enabled, SWIG generates a new class that derives from both the class in question and a special Swig::Director class. These new classes, referred to as director classes, can be loosely thought of as the C++ equivalent of the Java proxy classes. The director classes store a pointer to their underlying Java proxy classes.

For simplicity let's ignore the Swig::Director class and refer to the original C++ class as the director's base class. By default, a director class extends all virtual methods in the inheritance chain of its base class (see the preceding section for how to modify this behavior). Thus all virtual method calls, whether they originate in C++ or in Java via proxy classes, eventually end up in at the implementation in the director class. The job of the director methods is to route these method calls to the appropriate place in the inheritance chain. By "appropriate place" we mean the method that would have been called if the C++ base class and its Java derived classes were seamlessly integrated. That seamless integration is exactly what the director classes provide, transparently skipping over all the messy JNI glue code that binds the two languages together.

In reality, the "appropriate place" is one of only two possibilities: C++ or Java. Once this decision is made, the rest is fairly easy. If the correct implementation is in C++, then the lowest implementation of the method in the C++ inheritance chain is called explicitly. If the correct implementation is in Java, the Java API is used to call the method of the underlying Java object (after which the usual virtual method resolution in Java automatically finds the right implementation).

17.5.3 Overhead and code bloat

Enabling directors for a class will generate a new director method for every virtual method in the class' inheritance chain. This alone can generate a lot of code bloat for large hierarchies. Method arguments that require complex conversions to and from Java types can result in large director methods. For this reason it is recommended that directors are selectively enabled only for specific classes that are likely to be extended in Java and used in C++.

Although directors make it natural to mix native C++ objects with Java objects (as director objects), one should be aware of the obvious fact that method calls to Java objects from C++ will be much slower than calls to C++ objects. Additionally, compared to classes that do not use directors, the call routing in the director methods adds a small overhead. This situation can be optimized by selectively enabling director methods (using the %feature directive) for only those methods that are likely to be extended in Java.

17.5.4 Simple directors example

Consider the following SWIG interface file:

%module(directors="1") example;

%feature("director") DirectorBase;

class DirectorBase {
public:
  virtual ~DirectorBase() {}
  virtual void upcall_method() {}
};

void callup(DirectorBase *director) {
  director->upcall_method();
}
The following directorDerived Java class is derived from the Java proxy class DirectorBase and overrides upcall_method(). When C++ code invokes upcall_method(), the SWIG-generated C++ code redirects the call via JNI to the Java directorDerived subclass. Naturally, the SWIG generated C++ code and the generated Java intermediate class marshall and convert arguments between C++ and Java when needed.

public class directorDerived extends DirectorBase {
  public directorDerived() {
  }

  public void upcall_method() {
    System.out.println("directorDerived::upcall_method() invoked.");
  }
}
Running the following Java code
directorDerived director = new directorDerived();
example.callup(director);
will result in the following being output:
directorDerived::upcall_method() invoked.

17.6 Common customization features

An earlier section presented the absolute basics of C/C++ wrapping. If you do nothing but feed SWIG a header file, you will get an interface that mimics the behavior described. However, sometimes this isn't enough to produce a nice module. Certain types of functionality might be missing or the interface to certain functions might be awkward. This section describes some common SWIG features that are used to improve the interface to existing C/C++ code.

17.6.1 C/C++ helper functions

Sometimes when you create a module, it is missing certain bits of functionality. For example, if you had a function like this
typedef struct Image {...};
void set_transform(Image *im, double m[4][4]);
it would be accessible from Java, but there may be no easy way to call it. The problem here is that a type wrapper class is generated for the two dimensional array parameter so there is no easy way to construct and manipulate a suitable double [4][4] value. To fix this, you can write some extra C helper functions. Just use the %inline directive. For example:
%inline %{
/* Note: double[4][4] is equivalent to a pointer to an array double (*)[4] */
double (*new_mat44())[4] {
   return (double (*)[4]) malloc(16*sizeof(double));
}
void free_mat44(double (*x)[4]) {
   free(x);
}
void mat44_set(double x[4][4], int i, int j, double v) {
   x[i][j] = v;
}
double mat44_get(double x[4][4], int i, int j) {
   return x[i][j];
}
%}
From Java, you could then write code like this:
Image im = new Image();
SWIGTYPE_p_a_4__double a = example.new_mat44();
example.mat44_set(a,0,0,1.0);
example.mat44_set(a,1,1,1.0);
example.mat44_set(a,2,2,1.0);
...
example.set_transform(im,a);
example.free_mat44(a);
Admittedly, this is not the most elegant looking approach. However, it works and it wasn't too hard to implement. It is possible to improve on this using Java code, typemaps, and other customization features as covered in later sections, but sometimes helper functions are a quick and easy solution to difficult cases.

17.6.2 Class extension with %extend

One of the more interesting features of SWIG is that it can extend structures and classes with new methods or constructors. Here is a simple example:
%module example
%{
#include "someheader.h"
%}

struct Vector {
   double x,y,z;
};

%extend Vector {
   char *toString() {
       static char tmp[1024];
       sprintf(tmp,"Vector(%g,%g,%g)", self->x,self->y,self->z);
       return tmp;
   }
   Vector(double x, double y, double z) {
       Vector *v = (Vector *) malloc(sizeof(Vector));
       v->x = x;
       v->y = y;
       v->z = z;
       return v;
   }
};
Now, in Java
Vector v = new Vector(2,3,4);
System.out.println(v);
will display
Vector(2,3,4)
%extend works with both C and C++ code. It does not modify the underlying object in any way---the extensions only show up in the Java interface.

17.6.3 Exception handling with %exception

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.

In C, a function often indicates an error by returning a status code (a negative number or a NULL pointer perhaps). Here is a simple example of how you might handle that:

%exception malloc {
  $action
  if (!result) {
    jclass clazz = (*jenv)->FindClass(jenv, "java/lang/OutOfMemoryError");
    (*jenv)->ThrowNew(jenv, clazz, "Not enough memory");
    return $null;
  }
}
void *malloc(size_t nbytes);
In Java,
SWIGTYPE_p_void a = example.malloc(2000000000);
will produce a familiar looking Java exception:
Exception in thread "main" java.lang.OutOfMemoryError: Not enough memory
        at exampleJNI.malloc(Native Method)
        at example.malloc(example.java:16)
        at main.main(main.java:112)
If a library provides some kind of general error handling framework, you can also use that. For example:
%exception malloc {
  $action
  if (err_occurred()) {
    jclass clazz = (*jenv)->FindClass(jenv, "java/lang/OutOfMemoryError");
    (*jenv)->ThrowNew(jenv, clazz, "Not enough memory");
    return $null;
  }
}
void *malloc(size_t nbytes);
No declaration name is given to %exception, it is applied to all wrapper functions. The $action is a SWIG special variable and is replaced by the C/C++ function call being wrapped. 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.

C++ exceptions are also easy to handle. We can catch the C++ exception and rethrow it as a Java exception like this:

%exception getitem {
  try {
     $action
  } catch (std::out_of_range &e) {
    jclass clazz = jenv->FindClass("java/lang/Exception");
    jenv->ThrowNew(clazz, "Range error");
    return $null;
   }
}

class Base {
public:
     Foo *getitem(int index);      // Exception handler added
     ...
};
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 visa 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.

The language-independent exception.i library file can also be used to raise exceptions. See the SWIG Library chapter.

17.6.4 Method access with %javamethodmodifiers

A Java feature called %javamethodmodifiers can be used to change the method modifiers from the default public. It applies to both module class methods and proxy class methods. For example:
%javamethodmodifiers protect_me() "protected";
void protect_me();
Will produce the method in the module class with protected access.
protected static void protect_me() {
  exampleJNI.protect_me();
}

17.7 Tips and techniques

Although SWIG is largely automatic, there are certain types of wrapping problems that require additional user input. Examples include dealing with output parameters, strings and arrays. This chapter discusses the common techniques for solving these problems.

17.7.1 Input and output parameters using primitive pointers and references

A common problem in some C programs is handling parameters passed as simple pointers or references. For example:
void add(int x, int y, int *result) {
   *result = x + y;
}
or perhaps
int sub(int *x, int *y) {
   return *x-*y;
}
The typemaps.i library file will help in these situations. For example:
%module example
%include "typemaps.i"

void add(int, int, int *OUTPUT);
int  sub(int *INPUT, int *INPUT);
In Java, this allows you to pass simple values. For example:
int result = example.sub(7,4);
System.out.println("7 - 4 = " + result);
int[] sum = {0};
example.add(3,4,sum);
System.out.println("3 + 4 = " + sum[0]);
Which will display:
7 - 4 = 3
3 + 4 = 7
Notice how the INPUT parameters allow integer values to be passed instead of pointers and how the OUTPUT parameter will return the result in the first element of the integer array.

If you don't want to use the names INPUT or OUTPUT, use the %apply directive. For example:

%module example
%include "typemaps.i"

%apply int *OUTPUT { int *result };
%apply int *INPUT  { int *x, int *y};

void add(int x, int y, int *result);
int  sub(int *x, int *y);

If a function mutates one of its parameters like this,

void negate(int *x) {
   *x = -(*x);
}
you can use INOUT like this:
%include "typemaps.i"
...
void negate(int *INOUT);
In Java, the input parameter is the first element in a 1 element array and is replaced by the output of the function. For example:
int[] neg = {3};
example.negate(neg);
System.out.println("Negative of 3 = " + neg[0]);
And no prizes for guessing the output:
Negative of 3 = -3
These typemaps can also be applied to C++ references. The above examples would work the same if they had been defined using references instead of pointers. For example, the Java code to use the negate function would be the same if it were defined either as it is above:
void negate(int *INOUT);
or using a reference:
void negate(int &INOUT);

Note: Since most Java primitive types are immutable and are passed by value, it is not possible to perform in-place modification of a type passed as a parameter.

Be aware that the primary purpose of the typemaps.i file is to support primitive datatypes. Writing a function like this

void foo(Bar *OUTPUT);
will not have the intended effect since typemaps.i does not define an OUTPUT rule for Bar.

17.7.2 Simple pointers

If you must work with simple pointers such as int * or double * another approach to using typemaps.i is to use the cpointer.i pointer library file. For example:
%module example
%include "cpointer.i"

extern void add(int x, int y, int *result);
%pointer_functions(int, intp);
The %pointer_functions(type,name) macro generates five helper functions that can be used to create, destroy, copy, assign, and dereference a pointer. In this case, the functions are as follows:
int  *new_intp();
int  *copy_intp(int *x);
void  delete_intp(int *x);
void  intp_assign(int *x, int value);
int   intp_value(int *x);
In Java, you would use the functions like this:
SWIGTYPE_p_int intPtr = example.new_intp();
example.add(3,4,intPtr);
int result = example.intp_value(intPtr);
System.out.println("3 + 4 = " + result);
If you replace %pointer_functions(int,intp) by %pointer_class(int,intp), the interface is more class-like.
intp intPtr = new intp();
example.add(3,4,intPtr.cast());
int result = intPtr.value();
System.out.println("3 + 4 = " + result);
See the SWIG Library chapter for further details.

17.7.3 Wrapping C arrays with Java arrays

SWIG can wrap arrays in a more natural Java manner than the default by using the arrays_java.i library file. Let's consider an example:
%include "arrays_java.i";
int array[4];
void populate(int x[]) {
    int i;
    for (i=0; i<4; i++)
        x[i] = 100 + i;
}
These one dimensional arrays can then be used as if they were Java arrays:
int[] array = new int[4];
example.populate(array);

System.out.print("array: ");
for (int i=0; i<array.length; i++)
    System.out.print(array[i] + " ");

example.setArray(array);

int[] global_array = example.getArray();

System.out.print("\nglobal_array: ");
for (int i=0; i<array.length; i++)
    System.out.print(global_array[i] + " ");
Java arrays are always passed by reference, so any changes a function makes to the array will be seen by the calling function. Here is the output after running this code:
array: 100 101 102 103
global_array: 100 101 102 103
Note that for assigning array variables the length of the C variable is used, so it is possible to use a Java array that is bigger than the C code will cope with. Only the number of elements in the C array will be used. However, if the Java array is not large enough then you are likely to get a segmentation fault or access violation, just like you would in C. When arrays are used in functions like populate, the size of the C array passed to the function is determined by the size of the Java array.

Please be aware that the typemaps in this library are not efficient as all the elements are copied from the Java array to a C array whenever the array is passed to and from JNI code. There is an alternative approach using the SWIG array library and this is covered in the next.

17.7.4 Unbounded C Arrays

Sometimes a C function expects an array to be passed as a pointer. For example,
int sumitems(int *first, int nitems) {
    int i, sum = 0;
    for (i = 0; i < nitems; i++) {
        sum += first[i];
    }
    return sum;
}
One of the ways to wrap this is to apply the Java array typemaps that come in the arrays_java.i library file:
%include "arrays_java.i"
%apply int[ANY] {int *};
The ANY size will ensure the typemap is applied to arrays of all sizes. You could narrow the typemap matching rules by specifying a particular array size. Now you can use a pure Java array and pass it to the C code:
int[] array = new int[10000000];          // Array of 10-million integers
for (int i=0; i<array.length; i++) {      // Set some values
  array[i] = i;
}
int sum = example.sumitems(array,10000);
System.out.println("Sum = " + sum);
and the sum would be displayed:
Sum = 49995000
This approach is probably the most natural way to use arrays. However, it suffers from performance problems when using large arrays as a lot of copying of the elements occurs in transferring the array from the Java world to the C++ world. An alternative approach to using Java arrays for C arrays is to use an alternative SWIG library file carrays.i. This approach can be more efficient for large arrays as the array is accessed one element at a time. For example:
%include "carrays.i"
%array_functions(int, intArray);
The %array_functions(type,name) macro generates four helper functions that can be used to create and destroy arrays and operate on elements. In this case, the functions are as follows:
int *new_intArray(int nelements);
void delete_intArray(int *x);
int intArray_getitem(int *x, int index);
void intArray_setitem(int *x, int index, int value);
In Java, you would use the functions like this:
SWIGTYPE_p_int array = example.new_intArray(10000000);  // Array of 10-million integers
for (int i=0; i<10000; i++) {                           // Set some values
    example.intArray_setitem(array,i,i);
}
int sum = example.sumitems(array,10000);
System.out.println("Sum = " + sum);
If you replace %array_functions(int,intp) by %array_class(int,intp), the interface is more class-like and a couple more helper functions are available for casting between the array and the type wrapper class.
%include "carrays.i"
%array_class(int, intArray);
The %array_class(type, name) macro creates wrappers for an unbounded array object that can be passed around as a simple pointer like int * or double *. For instance, you will be able to do this in Java:
intArray array = new intArray(10000000);  // Array of 10-million integers
for (int i=0; i<10000; i++) {             // Set some values
    array.setitem(i,i);
}
int sum = example.sumitems(array.cast(),10000);
System.out.println("Sum = " + sum);
The array "object" created by %array_class() does not encapsulate pointers inside a special array object. In fact, there is no bounds checking or safety of any kind (just like in C). Because of this, the arrays created by this library are extremely low-level indeed. You can't iterate over them nor can you even query their length. In fact, any valid memory address can be accessed if you want (negative indices, indices beyond the end of the array, etc.). Needless to say, this approach is not going to suit all applications. On the other hand, this low-level approach is extremely efficient and well suited for applications in which you need to create buffers, package binary data, etc.

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

  • Title: 'Essential JNI: Java Native Interface.' Author: Rob Gordon. Publisher: Prentice Hall. ISBN: 0-13-679895-0.
  • Title: 'The Java Native Interface: Programmer's Guide and Specification.' Author: Sheng Liang. Publisher: Addison-Wesley. ISBN: 0-201-32577-2.

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.

17.8.1 Default primitive type mappings

The following table lists the default type mapping from Java to C/C++.

C/C++ type Java type JNI type
bool
const bool &
boolean jboolean
char
const char &
char jchar
signed char
const signed char &
byte jbyte
unsigned char
const unsigned char &
short jshort
short
const short &
short jshort
unsigned short
const unsigned short &
int jint
int
const int &
int jint
unsigned int
const unsigned int &
long jlong
long
const long &
int jint
unsigned long
const unsigned long &
long jlong
long long
const long long &
long jlong
unsigned long long
const unsigned long long &
java.math.BigInteger jobject
float
const float &
float jfloat
double
const double &
double jdouble
char *
char []
String jstring

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.

Given the following C function:

void func(unsigned short a, char *b, const long &c, unsigned long long d);
The module class method would be:
public static void func(int a, String b, int c, java.math.BigInteger d) {...}
The intermediary JNI class would use the same types:
public final static native void func(int jarg1, String jarg2, int jarg3, java.math.BigInteger jarg4);
and the JNI function would look like this:
JNIEXPORT void JNICALL Java_exampleJNI_func(JNIEnv *jenv, jclass jcls, jint jarg1, jstring jarg2, jint jarg3, jobject jarg4) {...}

The mappings for C int and C long are appropriate for 32 bit applications which are used in the 32 bit JVMs. There is no perfect mapping between Java and C as Java doesn't support all the unsigned C data types. However, the mappings allow the full range of values for each C type from Java.

17.8.2 Sixty four bit JVMs

If you are using a 64 bit JVM you may have to override the C long, but probably not C int default mappings. Mappings will be system dependent, for example long will need remapping on Unix LP64 systems (long, pointer 64 bits, int 32 bits), but not on Microsoft 64 bit Windows which will be using a P64 IL32 (pointer 64 bits and int, long 32 bits) model. This may be automated in a future version of SWIG. Note that the Java write once run anywhere philosophy holds true for all pure Java code when moving to a 64 bit JVM. Unfortunately it won't of course hold true for JNI code.

17.8.3 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 Java to C, you might define a typemap like this:

%module example

%typemap(in) int {
  $1 = $input;
  printf("Received an integer : %d\n",  $1);
}
extern int fact(int nonnegative);

Typemaps are always associated with some specific aspect of code generation. In this case, the "in" method refers to the conversion of input arguments to C/C++. The datatype int is the datatype to which the typemap will be applied. The supplied C code is used to convert values. In this code a number of special variables prefaced by a $ are used. The $1 variable is a placeholder for a local variable of type int. The $input variable contains the Java data, the JNI jint in this case.

When this example is compiled into a Java module, it can be used as follows:

System.out.println(example.fact(6));
and the output will be:
Received an integer : 6
720
In this example, the typemap is applied to all occurrences of the int datatype. You can refine this by supplying an optional parameter name. For example:
%module example

%typemap(in) int nonnegative {
  $1 = $input;
  printf("Received an integer : %d\n",  $1);
}

extern int fact(int nonnegative);
In this case, the typemap code is only attached to arguments that exactly match int nonnegative.

The application of a typemap to specific datatypes and argument names involves more than simple text-matching--typemaps are fully integrated into the SWIG C++ type-system. When you define a typemap for int, that typemap applies to int and qualified variations such as const int. In addition, the typemap system follows typedef declarations. For example:

%typemap(in) int nonnegative {
  $1 = $input;
  printf("Received an integer : %d\n",  $1);
}
typedef int Integer;
extern int fact(Integer nonnegative);    // Above typemap is applied
However, the matching of typedef only occurs in one direction. If you defined a typemap for Integer, it is not applied to arguments of type int.

Typemaps can also be defined for groups of consecutive arguments. For example:

%typemap(in) (char *str, int len) {
...
};

int count(char c, char *str, int len);
When a multi-argument typemap is defined, the arguments are always handled as a single Java parameter. This allows the function to be used like this (notice how the length parameter is omitted):
int c = example.count('e',"Hello World");

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

The typemaps available to the Java module include the common typemaps listed in the main typemaps section. There are a number of additional typemaps which are necessary for using SWIG with Java. The most important of these implement the mapping of C/C++ types to Java types:
 
Typemap Description
jni JNI C types. These provide the default mapping of types from C/C++ to JNI for use in the JNI (C/C++) code.
jtype Java intermediary types. These provide the default mapping of types from C/C++ to Java for use in the native functions in the intermediary JNI class. The type must be the equivalent Java type for the JNI C type specified in the "jni" typemap.
jstype Java types. These provide the default mapping of types from C/C++ to Java for use in the Java module class, proxy classes and type wrapper classes.
javain Conversion from jstype to jtype. 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). In other words the typemap provides the conversion to the native method call parameter types.
javaout Conversion from jtype to jstype. 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). In other words the typemap provides the conversion from the native method call return type.
javadirectorin Conversion from jtype to jstype for director methods. 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.
javadirectorout Conversion from jstype to jtype for director methods. 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.
directorin Conversion from C++ type to jni type for director methods. These are C++ typemaps which converts 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.

If you are writing your own typemaps to handle a particular type, you will normally have to write a collection of them. The default typemaps are in java.swg and so might be a good place for finding typemaps to base any new ones on.

The "jni", "jtype" and "jstype" typemaps are usually defined together to handle the Java to C/C++ type mapping. An "in" typemap should be accompanied by a "javain" typemap and likewise an "out" typemap by a "javaout" typemap. If an "in" typemap is written, a "freearg" and "argout" typemap may also need to be written as some types have a default "freearg" and/or "argout" typemap which may need overriding. The "freearg" typemap sometimes releases memory allocated by the "in" typemap. The "argout" typemap sometimes sets values in function parameters which are passed by reference in Java.

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 covered earlier. There are other type mapping typemaps in the Java library. These are listed below:
 
C Type Typemap File Kind Java Type Function
primitive pointers and references INPUT typemaps.i input Java basic types Allows values to be used for C functions taking pointers for data input.
primitive pointers and references OUTPUT typemaps.i output Java basic type arrays Allows values held within an array to be used for C functions taking pointers for data output.
primitive pointers and references INOUT typemaps.i input
output
Java basic type arrays Allows values held within an array to be used for C functions taking pointers for data input and output.
string
wstring
[unnamed] std_string.i input
output
String Use for std::string mapping to Java String.
arrays of primitive types [unnamed] arrays_java.i input
output
arrays of primitive Java types Use for mapping C arrays to Java arrays.
arrays of classes/structs/unions JAVA_ARRAYSOFCLASSES macro arrays_java.i input
output
arrays of proxy classes Use for mapping C arrays to Java arrays.
arrays of enums ARRAYSOFENUMS arrays_java.i input
output
int[] Use for mapping C arrays to Java arrays.
char * BYTE various.i input byte[] Java byte array is converted to char array
char ** STRING_ARRAY various.i input
output
String[] Use for mapping NULL terminated arrays of C strings to Java String arrays

17.8.5 Java special variables

The standard SWIG special variables are available for use within typemaps as described in the Typemaps documentation, for example $1, $input,$result etc.

The Java module uses a few additional special variables:

$javaclassname
$javaclassname is similar to $1_type. It expands to the class name for use in Java. When wrapping a union, struct or class, it expands to the Java proxy class name. Otherwise it expands to the type wrapper class name. For example, $javaclassname is replaced by Foo when the wrapping a struct Foo or struct Foo * and SWIGTYPE_p_unsigned_short is used for unsigned short *.

$null
Used in input typemaps to return early from JNI functions that have either void or a non-void return type. Example:

%typemap(check) int * %{ 
  if (error) {
    SWIG_exception(SWIG_IndexError, "Array element error");
    return $null;
  }
%}
If the typemap gets put into a function with void as return, $null will expand to nothing:
JNIEXPORT void JNICALL Java_jnifn(...) {
    if (error) {
      SWIG_exception(SWIG_IndexError, "Array element error");
      return ;
    }
  ...
}
otherwise $null expands to NULL
JNIEXPORT jobject JNICALL Java_jnifn(...) {
    if (error) {
      SWIG_exception(SWIG_IndexError, "Array element error");
      return NULL;
    }
  ...
}
$javainput, $jnicall and $owner
The $javainput special variable is used in "javain" typemaps and $jnicall and $owner are used in "javaout" typemaps. $jnicall is analogous to $action in %exception. It is replaced by the call to the native method in the intermediary JNI class. $owner is replaced by either true if %newobject has been used, otherwise false. $javainput is analogous to the $input special variable. It is replaced by the parameter name.

Here is an example:

%typemap(javain) Class "Class.getCPtr($javainput)"
%typemap(javain) unsigned short "$javainput"
%typemap(javaout) Class * {
    return new Class($jnicall, $owner);
  }

%inline %{
    class Class {...};
    Class * bar(Class cls, unsigned short ush) { return new Class(); };
%}
The generated proxy code is then:
public static Class bar(Class cls, int ush) {
  return new Class(exampleJNI.bar(Class.getCPtr(cls), ush), false);
}
Here $javainput has been replaced by cls and ush. $jnicall has been replaced by the native method call, exampleJNI.bar(...) and $owner has been replaced by false. If %newobject is used by adding the following at the beginning of our example:
%newobject bar(Class cls, unsigned short ush);
The generated code constructs the return type using true indicating the proxy class Class is responsible for destroying the C++ memory allocated for it in bar:
public static Class bar(Class cls, int ush) {
  return new Class(exampleJNI.bar(Class.getCPtr(cls), ush), true);
}
$jniinput, $javacall and $packagepath
These special variables used in the directors typemaps. See Director specific typemaps for details.

17.8.6 Typemaps for both C and C++ compilation

JNI calls must be written differently depending on whether the code is being compiled as C or C++. For example C compilation requires the pointer to a function pointer struct member syntax like
const jclass clazz = (*jenv)->FindClass(jenv, "java/lang/String");
whereas C++ code compilation of the same function call is a member function call using a class pointer like
const jclass clazz = jenv->FindClass("java/lang/String");
To enable typemaps to be used for either C or C++ compilation, a set of JCALLx macros have been defined in Lib/java/javahead.swg, where x is the number of arguments in the C++ version of the JNI call. The above JNI calls would be written in a typemap like this
const jclass clazz = JCALL1(FindClass, jenv, "java/lang/String");
Note that the SWIG preprocessor expands these into the appropriate C or C++ JNI calling convention. The C calling convention is emitted by default and the C++ calling convention is emitted when using the -c++ SWIG commandline option. If you do not intend your code to be targeting both C and C++ then your typemaps can use the appropriate JNI calling convention and need not use the JCALLx macros.

17.8.7 Java code typemaps

Most of SWIG's typemaps are used for the generation of C/C++ code. The typemaps in this section are used solely for the generation of Java code. Elements of proxy classes and type wrapper classes come from the following typemaps (the defaults).

%typemap(javabase)

base (extends) for Java class: empty default
%typemap(javaclassmodifiers)
class modifiers for the Java class: default is "public"
%typemap(javacode)
Java code is copied verbatim to the Java class: empty default
%typemap(javadestruct, methodname="delete")
destructor wrapper - the delete() method (proxy classes only), used for all classes except those which have a base class : default calls C++ destructor (or frees C memory) and resets swigCPtr and swigCMemOwn flags

Note that the delete() method name is configurable and is specified by the methodname attribute.
%typemap(javadestruct_derived, methodname="delete")
destructor wrapper - the delete() method (proxy classes only), same as "javadestruct" but only used for derived classes : default calls C++ destructor (or frees C memory) and resets swigCPtr and swigCMemOwn flags

Note that the delete() method name is configurable and is specified by the methodname attribute.
%typemap(javaimports)
import statements for Java class: empty default
%typemap(javainterfaces)
interfaces (extends) for Java class: empty default
%typemap(javafinalize)
the finalize() method (proxy classes only): default calls the delete() method
%typemap(javagetcptr)
the getCPtr() method: default returns the swigCPtr member variable
%typemap(javaptrconstructormodifiers)
method modifier for the constructors taking a C pointer and the memory ownership flag: default is "protected"
In summary the contents of the typemaps make up a proxy class like this:
[ javaimports typemap ]
[ javamodifiers typemap ] class proxyclassname extends [ javabase typemap ] implements [ javainterfaces typemap ] {
[ javafinalize typemap ]
[ javaptrconstructormodifiers typemap ] proxyclassname(long cPtr, boolean cMemoryOwn) {...}
... Other SWIG generated constructors ...
public void delete() [ javadestruct OR javadestruct_derived typemap ]
[ javagetcptr typemap ]
[ javacode typemap ]
... proxy functions ...
}
Note the delete() methodname is configurable, see "javadestruct" and "javadestruct_derived" typemaps above.

The type wrapper class is similar in construction:

[ javaimports typemap ]
[ javamodifiers typemap ] class typewrappername extends [ javabase typemap ] implements [ javainterfaces typemap ] {
[ javaptrconstructormodifiers typemap ] proxyclassname(long cPtr, boolean bFutureUse) {...}
... Other SWIG generated constructors ...
[ javagetcptr typemap ]
[ javacode typemap ]
}
The defaults can be overridden to tailor these classes and are often used to hide or expose the C/C++ pointer. Here is an example which will change the getCPtr() method from the default protected access to public access.
%typemap(javagetcptr) SWIGTYPE %{
  public static long getCPtr($javaclassname obj) {
    return (obj == null) ? 0 : obj.swigCPtr;
  }
%}
Note that SWIGTYPE will target all proxy classes, but not all type wrapper classes. 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:
%typemap(javagetcptr) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) %{
  public static long getCPtr($javaclassname obj) {
    return obj.swigCPtr;
  }
%}

17.8.8 Director specific typemaps

The Java directors feature requires the "javadirectorin", "javadirectorout" and the "directorin" typemaps in order to work properly. The "javapackage" typemap is an optional typemap used to identify the Java package path for individual SWIG generated proxy classes.

%typemap(directorin)

The "directorin" typemap is used for converting arguments in the C++ director class to the appropriate JNI type before the upcall to Java. This typemap also specifies the JNI field descriptor for the type in the "descriptor" attribute. For example, integers are converted as follows:
%typemap(directorin,descriptor="I") int "$input = (jint) $1;"
$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. A typemap for C character strings is:
%typemap(directorin,descriptor="Ljava/lang/String;") char *
  %{ $input = jenv->NewStringUTF($1); %}
User-defined types have the default "descriptor" attribute "L$packagepath/$javaclassname;" where $packagepath is the package name passed from the SWIG command line and $javaclassname is the Java proxy class' name. If the -package commandline option is not used to specify the package, then '$packagepath/' will be removed from the resulting output JNI field descriptor. Do not forget the terminating ';' for JNI field descriptors starting with 'L'. If the ';' is left out, Java will generate a "method not found" runtime error.
%typemap(javadirectorin)
Conversion from jtype to jstype for director methods. 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. For primitive types, this typemap is usually specified as:
%typemap(javadirectorin) int "$jniinput"
The $jniinput special variable is analogous to $javainput special variable. It is replaced by the input parameter name.
%typemap(javadirectorout)
Conversion from jstype to jtype for director methods. 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. For primitive types, this typemap is usually specified as:
%typemap(javadirectorout) int "$javacall"
The $javacall special variable is analogous to the $jnicall special variable. It is replaced by the call to the target Java method. The target method is the method in the Java proxy class which overrides the virtual C++ method in the C++ base class.
%typemap(javapackage)
The "javapackage" typemap is optional; it serves to identify a class's Java package. This typemap should be used in conjunction with classes that are defined outside of the current SWIG interface file. For example:
// class Foo is handled in a different interface file:
%import "Foo.i"

%feature("director") Example;

%inline {
  class Bar { };

  class Example {
  public:
    virtual ~Example();
    void     ping(Foo *arg1, Bar *arg2);
  };
}
Assume that the Foo class is part of the Java package wombat.foo but the above interface file is part of the Java package wombat.example. Without the "javapackage" typemap, SWIG will assume that the Foo class belongs to wombat.example class. The corrected interface file looks like:
// class Foo is handled in a different interface file:
%import "Foo.i"
%typemap("javapackage") Foo "wombat.foo";
%feature("director") Example;

%inline {
  class Bar { };

  class Example {
  public:
    virtual ~Example();
    void     ping(Foo *arg1, Bar *arg2);
  };
}

Practically speaking, you should create a separate SWIG interface file, which is %import-ed into each SWIG interface file, when you have multiple Java packages:

%typemap("javapackage") SWIGTYPE, SWIGTYPE *, SWIGTYPE & "package.for.most.classes";

%typemap("javapackage") Package_2_class_one "package.for.other.classes";
%typemap("javapackage") Package_3_class_two "package.for.another.set";
/* etc */
The basic strategy here is to provide a default package typemap for the majority of the classes, only providing "javapackage" typemaps for the exceptions.

17.9 Typemap Examples

This section includes a few examples of typemaps. For more examples, you might look at the files "java.swg" and "typemaps.i" in the SWIG library.

17.9.1 Converting Java String arrays to char **

A common problem in many C programs is the processing of command line arguments, which are usually passed in an array of NULL terminated strings. The following SWIG interface file allows a Java String array to be used as a char ** object.

%module example

/* This tells SWIG to treat char ** as a special case when used as a parameter in a function call */
%typemap(in) char ** (jint size) {
    int i = 0;
    size = (*jenv)->GetArrayLength(jenv, $input);
    $1 = (char **) malloc((size+1)*sizeof(char *));
    /* make a copy of each string */
    for (i = 0; i<size; i++) {
        jstring j_string = (jstring)(*jenv)->GetObjectArrayElement(jenv, $input, i);
        const char * c_string = (*jenv)->GetStringUTFChars(jenv, j_string, 0);
        $1[i] = malloc(strlen((c_string)+1)*sizeof(const char *));
        strcpy($1[i], c_string);
        (*jenv)->ReleaseStringUTFChars(jenv, j_string, c_string);
        (*jenv)->DeleteLocalRef(jenv, j_string);
    }
    $1[i] = 0;
}

/* This cleans up the memory we malloc'd before the function call */
%typemap(freearg) char ** {
    int i;
    for (i=0; i<size$argnum-1; i++)
      free($1[i]);
    free($1);
}

/* This allows a C function to return a char ** as a Java String array */
%typemap(out) char ** {
    int i;
    int len=0;
    jstring temp_string;
    const jclass clazz = (*jenv)->FindClass(jenv, "java/lang/String");

    while ($1[len]) len++;    
    jresult = (*jenv)->NewObjectArray(jenv, len, clazz, NULL);
    /* exception checking omitted */

    for (i=0; i<len; i++) {
      temp_string = (*jenv)->NewStringUTF(jenv, *result++);
      (*jenv)->SetObjectArrayElement(jenv, jresult, i, temp_string);
      (*jenv)->DeleteLocalRef(jenv, temp_string);
    }
}

/* These 3 typemaps tell SWIG what JNI and Java types to use */
%typemap(jni) char ** "jobjectArray"
%typemap(jtype) char ** "String[]"
%typemap(jstype) char ** "String[]"

/* These 2 typemaps handle the conversion of the jtype to jstype typemap type and visa versa */
%typemap(javain) char ** "$javainput"
%typemap(javaout) char ** {
    return $jnicall;
  }

/* Now a few test functions */
%inline %{

int print_args(char **argv) {
    int i = 0;
    while (argv[i]) {
         printf("argv[%d] = %s\n", i, argv[i]);
         i++;
    }
    return i;
}

char **get_args() {
  static char *values[] = { "Dave", "Mike", "Susan", "John", "Michelle", 0};
  return &values[0];
}

%}
Note that the 'C' JNI calling convention is used. Checking for any thrown exceptions after JNI function calls has been omitted. When this module is compiled, our wrapped C functions can be used by the following Java program:

// File main.java

public class main {

  static {
    try {
     System.loadLibrary("example");
    } catch (UnsatisfiedLinkError e) {
      System.err.println("Native code library failed to load. " + e);
      System.exit(1);
    }
  }

  public static void main(String argv[]) {
    String animals[] = {"Cat","Dog","Cow","Goat"};
    example.print_args(animals);
    String args[] = example.get_args();
    for (int i=0; i<args.length; i++)
        System.out.println(i + ":" + args[i]);
  }
}
When compiled and run we get:
$ java main
argv[0] = Cat
argv[1] = Dog
argv[2] = Cow
argv[3] = Goat
0:Dave
1:Mike
2:Susan
3:John
4:Michelle
In the example, a few different typemaps are used. The "in" typemap is used to receive an input argument and convert it to a C array. Since dynamic memory allocation is used to allocate memory for the array, the "freearg" typemap is used to later release this memory after the execution of the C function. The "out" typemap is used for function return values. Lastly the "jni", "jtype" and "jstype" typemaps are also required to specify what Java types to use.

17.9.2 Expanding a Java object to multiple arguments

Suppose that you had a collection of C functions with arguments such as the following:
int foo(int argc, char **argv);
In the previous example, a typemap was written to pass a Java String array as the char **argv. This allows the function to be used from Java as follows:
example.foo(4, new String[]{"red", "green", "blue", "white"});
Although this works, it's a little awkward to specify the argument count. To fix this, a multi-argument typemap can be defined. This is not very difficult--you only have to make slight modifications to the previous example's typemaps:
%typemap(in) (int argc, char **argv) {
    int i = 0;
    $1 = (*jenv)->GetArrayLength(jenv, $input);
    $2 = (char **) malloc(($1+1)*sizeof(char *));
    /* make a copy of each string */
    for (i = 0; i<$1; i++) {
        jstring j_string = (jstring)(*jenv)->GetObjectArrayElement(jenv, $input, i);
        const char * c_string = (*jenv)->GetStringUTFChars(jenv, j_string, 0);
        $2[i] = malloc(strlen((c_string)+1)*sizeof(const char *));
        strcpy($2[i], c_string);
        (*jenv)->ReleaseStringUTFChars(jenv, j_string, c_string);
        (*jenv)->DeleteLocalRef(jenv, j_string);
    }
    $2[i] = 0;
}

%typemap(freearg) (int argc, char **argv) {
    int i;
    for (i=0; i<$1-1; i++)
      free($2[i]);
    free($2);
}

%typemap(jni) (int argc, char **argv) "jobjectArray"
%typemap(jtype) (int argc, char **argv) "String[]"
%typemap(jstype) (int argc, char **argv) "String[]"

%typemap(javain) (int argc, char **argv) "$javainput"
When writing a multiple-argument typemap, each of the types is referenced by a variable such as $1 or $2. The typemap code simply fills in the appropriate values from the supplied Java parameter.

With the above typemap in place, you will find it no longer necessary to supply the argument count. This is automatically set by the typemap code. For example:

example.foo(new String[]{"red", "green", "blue", "white"});

17.9.3 Using typemaps to return arguments

A common problem in some C programs is that values may be returned in function parameters rather than in the return value of a function. The typemaps.i file defines INPUT, OUTPUT and INOUT typemaps which can be used to solve some instances of this problem. This library file uses an array as a means of moving data to and from Java when wrapping a C function that takes non const pointers or non const references as parameters.

Now we are going to outline an alternative approach to using arrays for C pointers. The INOUT typemap uses a double[] array for receiving and returning the double* parameters. In this approach we are able to use a Java class myDouble instead of double[] arrays where the C pointer double* is required. Here is our example function:

/* Returns a status value and two values in out1 and out2 */
int spam(double a, double b, double *out1, double *out2);
If we define a structure MyDouble containing a double member variable and use some typemaps we can solve this problem. For example we could put the following through SWIG:
%module example

/* Define a new structure to use instead of double * */
%inline %{
typedef struct {
    double value;
} MyDouble;
%}


%{
/* Returns a status value and two values in out1 and out2 */
int spam(double a, double b, double *out1, double *out2) {
  int status = 1;
  *out1 = a*10.0;
  *out2 = b*100.0;
  return status;
};
%}

/* 
This typemap will make any double * function parameters with name OUTVALUE take an
argument of MyDouble instead of double *. This will 
allow the calling function to read the double * value after returning from the function.
*/
%typemap(in) double *OUTVALUE {
    jclass clazz = jenv->FindClass("MyDouble");
    jfieldID fid = jenv->GetFieldID(clazz, "swigCPtr", "J");
    jlong cPtr = jenv->GetLongField($input, fid);
    MyDouble *pMyDouble = NULL;
    *(MyDouble **)&pMyDouble = *(MyDouble **)&cPtr;
    $1 = &pMyDouble->value;
}

%typemap(jtype) double *OUTVALUE "MyDouble"
%typemap(jstype) double *OUTVALUE "MyDouble"
%typemap(jni) double *OUTVALUE "jobject"

%typemap(javain) double *OUTVALUE "$javainput"

/* Now we apply the typemap to the named variables */
%apply double *OUTVALUE { double *out1, double *out2 };
int spam(double a, double b, double *out1, double *out2);
Note that the C++ JNI calling convention has been used this time and so must be compiled as C++ and the -c++ commandline must be passed to SWIG. JNI error checking has been omitted for clarity.

What the typemaps do are make the named double* function parameters use our new MyDouble wrapper structure. The "in" typemap takes this structure, gets the C++ pointer to it, takes the double value member variable and passes it to the C++ spam function. In Java, when the function returns, we use the SWIG created getValue() function to get the output value. The following Java program demonstrates this:

// File: main.java

public class main {

  static {
    try {
      System.loadLibrary("example");
    } catch (UnsatisfiedLinkError e) {
      System.err.println("Native code library failed to load. " + e);
      System.exit(1);
    }
  }

  public static void main(String argv[]) {
    MyDouble out1 = new MyDouble();
    MyDouble out2 = new MyDouble();
    int ret = example.spam(1.2, 3.4, out1, out2);
    System.out.println(ret + "  " + out1.getValue() + "  " + out2.getValue());
  }
}
When compiled and run we get:
$ java main
1 12.0  340.0

17.9.4 Adding Java downcasts to polymorphic return types

SWIG support for polymorphism works in that the appropriate virtual function is called. However, the default generated code does not allow for downcasting. Let's examine this with the follow code:
%include "std_string.i"

#include <iostream>
using namespace std;
class Vehicle {
public:
    virtual void start() = 0;
...
};

class Ambulance : public Vehicle {
    string vol;
public:
    Ambulance(string volume) : vol(volume) {}
    virtual void start() {
        cout << "Ambulance started" << endl;
    }
    void sound_siren() {
        cout << vol << " siren sounded!" << endl;
    }
...
};

Vehicle *vehicle_factory() {
    return new Ambulance("Very loud");
}
If we execute the following Java code:
Vehicle vehicle = example.vehicle_factory();
vehicle.start();

Ambulance ambulance = (Ambulance)vehicle;
ambulance.sound_siren();
We get:
Ambulance started
java.lang.ClassCastException
        at main.main(main.java:16)
Even though we know from examination of the C++ code that vehicle_factory returns an object of type Ambulance, we are not able to use this knowledge to perform the downcast in Java. This occurs because the runtime type information is not completely passed from C++ to Java when returning the type from vehicle_factory(). Usually this is not a problem as virtual functions do work by default, such as in the case of start(). There are a few solutions to getting downcasts to work.

The first is not to use a Java cast but a call to C++ to make the cast. Add this to your code:

%exception Ambulance::dynamic_cast(Vehicle *vehicle) {
    $action
    if (!result) {
        jclass excep = jenv->FindClass("java/lang/ClassCastException");
        if (excep) {
            jenv->ThrowNew(excep, "dynamic_cast exception");
        }
    }
}
%extend Ambulance {
    static Ambulance *dynamic_cast(Vehicle *vehicle) {
        return dynamic_cast<Ambulance *>(vehicle);
    }
};
It would then be used from Java like this
Ambulance ambulance = Ambulance.dynamic_cast(vehicle);
ambulance.sound_siren();
Should vehicle not be of type ambulance then a Java ClassCastException is thrown. The next solution is a purer solution in that Java downcasts can be performed on the types. Add the following before the definition of vehicle_factory:
%typemap(out) Vehicle * {
    Ambulance *downcast = dynamic_cast<Ambulance *>($1);
    *(Ambulance **)&$result = downcast;
}

%typemap(javaout) Vehicle * {
    return new Ambulance($jnicall, $owner);
  }
Here we are using our knowledge that vehicle_factory always returns type Ambulance so that the Java proxy is created as a type Ambulance. If vehicle_factory can manufacture any type of Vehicle and we want to be able to downcast using Java casts for any of these types, then a different approach is needed. Consider expanding our example with a new Vehicle type and a more flexible factory function:
class FireEngine : public Vehicle {
public:
    FireEngine() {}
    virtual void start() {
        cout << "FireEngine started" << endl;
    }
    void roll_out_hose() {
        cout << "Hose rolled out" << endl;
    }
 ...
};
Vehicle *vehicle_factory(int vehicle_number) {
    if (vehicle_number == 0)
        return new Ambulance("Very loud");
    else
        return new FireEngine();
}
To be able to downcast with this sort of Java code:
FireEngine fireengine = (FireEngine)example.vehicle_factory(1);
fireengine.roll_out_hose();
Ambulance ambulance = (Ambulance)example.vehicle_factory(0);
ambulance.sound_siren();
the following typemaps targeted at the vehicle_factory function will achieve this. Note that in this case, the Java class is constructed using JNI code rather than passing a pointer across the JNI boundary in a Java long for construction in Java code.
%typemap(jni) Vehicle *vehicle_factory "jobject"
%typemap(jtype) Vehicle *vehicle_factory "Vehicle"
%typemap(jstype) Vehicle *vehicle_factory "Vehicle"
%typemap(javaout) Vehicle *vehicle_factory {
    return $jnicall;
  }

%typemap(out) Vehicle *vehicle_factory {
    Ambulance *ambulance = dynamic_cast<Ambulance *>($1);
    FireEngine *fireengine = dynamic_cast<FireEngine *>($1);
    if (ambulance) {
        // call the Ambulance(long cPtr, boolean cMemoryOwn) constructor
        jclass clazz = jenv->FindClass("Ambulance");
        if (clazz) {
            jmethodID mid = jenv->GetMethodID(clazz, "", "(JZ)V");
            if (mid) {
                jlong cptr = 0;
                *(Ambulance **)&cptr = ambulance; 
                $result = jenv->NewObject(clazz, mid, cptr, false);
            }
        }
    } else if (fireengine) {
        // call the FireEngine(long cPtr, boolean cMemoryOwn) constructor
        jclass clazz = jenv->FindClass("FireEngine");
        if (clazz) {
            jmethodID mid = jenv->GetMethodID(clazz, "", "(JZ)V");
            if (mid) {
                jlong cptr = 0;
                *(FireEngine **)&cptr = fireengine; 
                $result = jenv->NewObject(clazz, mid, cptr, false);
            }
        }
    }
    else {
        cout << "Unexpected type " << endl;
    }

    if (!$result)
        cout << "Failed to create new java object" << endl;
}
Better error handling would need to be added into this code. There are other solutions to this problem, but this last example demonstrates some more involved JNI code. SWIG usually generates code which constructs the proxy classes using Java code as it is easier to handle error conditions and is faster. 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.

17.9.5 Adding an equals method to the Java classes

When a pointer is returned from a JNI function, it is wrapped using a new Java proxy class or type wrapper class. Even when the pointers are the same, it will not be possible to know that the two Java classes containing those pointers are actually the same object. It is common in Java to use the equals() method to check whether two objects are equivalent. An equals method is easily added to all proxy classes. For example:
%typemap(javacode) SWIGTYPE %{
  public boolean equals(Object obj) {
    boolean equal = false;
    if (obj instanceof $javaclassname)
      equal = ((($javaclassname)obj).swigCPtr == this.swigCPtr);
    return equal;
  }
%}

class Foo { };
Foo* returnFoo(Foo *foo) { return foo; }
The following would display false without the javacode typemap above. With the typemap defining the equals method the result is true.
Foo foo1 = new Foo();
Foo foo2 = example.returnFoo(foo1);
System.out.println("foo1? " + foo1.equals(foo2));

17.9.6 Void pointers and a common Java base class

One might wonder why the common code that SWIG emits for the proxy and type wrapper classes is not pushed into a base class. The reason is that although swigCPtr could be put into a common base class for all classes wrapping C structures, it would not work for C++ classes involved in an inheritance chain. Each class derived from a base needs a separate swigCPtr because C++ compilers sometimes use a different pointer value when casting a derived class to a base. Additionally as Java only supports single inheritance, it would not be possible to derive wrapped classes from your own pure Java classes if the base class has been 'used up' by SWIG. However, you may want to move some of the common code into a base class. Here is an example which uses a common base class for all proxy classes and type wrapper classes:
%typemap(javabase) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) "SWIG"

%typemap(javacode) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [], SWIGTYPE (CLASS::*) %{
  protected long getPointer() {
    return swigCPtr;
  }
%}

Define new base class called SWIG:

public abstract class SWIG {
  protected abstract long getPointer();

  public boolean equals(Object obj) {
    boolean equal = false;
    if (obj instanceof SWIG)
      equal = (((SWIG)obj).getPointer() == this.getPointer());
    return equal;
  }
  
  SWIGTYPE_p_void getVoidPointer() {
    return new SWIGTYPE_p_void(getPointer(), false);
  }
}
This example contains some useful functionality which you may want in your code.
  • It has an equals() method. Unlike the previous example, the method code isn't replicated in all classes.
  • 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.

17.10 Living with Java Directors

This section is intended to address frequently asked questions and frequently encountered problems when using Java directors.

  1. When my program starts up, it complains that method_foo cannot be found in a Java method called swig_module_init. How do I fix this?
  2. Open up the C++ wrapper source code file and look for "method_foo" (include the double quotes, they are important!) Look at the JNI field descriptor and make sure that each class that occurs in the descriptor has the correct package name in front of it. If the package name is incorrect, put a "javapackage" typemap in your SWIG interface file.

  3. I'm compiling my code and I'm using templates. I provided a javapackage typemap, but SWIG doesn't generate the right JNI field descriptor.
  4. Use the template's renamed name as the argument to the "javapackage" typemap:

    %typemap(javapackage)  std::vector  "your.package.here"
    %template(VectorOfInt) std::vector;
    

  5. When I pass class pointers or references through a C++ upcall and I try to type cast them, Java complains with a ClassCastException. What am I doing wrong?
  6. Normally, a non-director generated Java proxy class creates temporary Java objects as follows:

    public static void MyClass_method_upcall(MyClass self, long jarg1)
    {
      Foo darg1 = new Foo(jarg1, false);
    
      self.method_upcall(darg1);
    }
    

    Unfortunately, this loses the Java type information that is part of the underlying Foo director proxy class's java object pointer causing the type cast to fail. The SWIG Java module's director code attempts to correct the problem, but only for director-enabled classes, since the director class retains a global reference to its Java object. Thus, for director-enabled classes and only for director-enabled classes, the generated proxy Java code looks somthing like:
    public static void MyClass_method_upcall(MyClass self, long jarg1, Foo jarg1_object)
    {
      Foo darg1 = (jarg1_object != null ? jarg1_object : new Foo(jarg1, false));
    
      self.method_upcall(darg1);
    }
    
    When you import a SWIG interface file containing class definitions, the classes you want to be director-enabled must be have the feature("director") enabled for type symmetry to work. This applies even when the class being wrapped isn't a director-enabled class but takes parameters that are director-enabled classes.

    The current "type symmetry" design will work for simple C++ inheritance, but will most likely fail for anything more compicated such as tree or diamond C++ inheritance hierarchies. Those who are interested in challenging problems are more than welcome to hack the Java::Java_director_declaration method in Source/Modules/java.cxx.

    If all else fails, you can use the downcastXXXXX() method to attempt to recover the director class's Java object pointer. For the Java Foo proxy class, the Foo director class's java object pointer can be accessed through the javaObjectFoo() method. The generated method's signature is:

      public static Foo javaObjectFoo(Foo obj);
    
    From your code, this method is invoked as follows:
    public class MyClassDerived {
      public void method_upcall(Foo foo_object)
      {
        FooDerived    derived = (foo_object != null ? (FooDerived) Foo.downcastFoo(foo_object) : null);
        /* rest of your code here */
      }
    }
    
    An good approach for managing downcasting is placing a static method in each derived class that performs the downcast from the superclass, e.g.,
    public class FooDerived extends Foo {
      /* ... */
      public static FooDerived downcastFooDerived(Foo foo_object)
      {
        try {
         return (foo_object != null ? (FooDerived) Foo.downcastFoo(foo_object);
        }
    
        catch (ClassCastException exc) {
          // Wasn't a FooDerived object, some other sublcass of Foo
          return null;
        }
      }
    }
    
    Then change the code in MyClassDerived as follows:
    public class MyClassDerived extends MyClass {
      /* ... */
      public void method_upcall(Foo foo_object)
      {
        FooDerived    derived = FooDerived.downcastFooDerived(foo_object) : null);
        /* rest of your code here */
      }
    }
    

  7. Why isn't the proxy class declared abstract? Why aren't the director upcall methods in the proxy class declared abstract?
  8. Declaring the proxy class and its methods abstract would break the JNI argument marshalling and SWIG's downcall functionality (going from Java to C++.) Create an abstract Java subclass that inherits from the director-enabled class instead. Using the previous Foo class example:

    public abstract class UserVisibleFoo extends Foo {
      /** Make sure user overrides this method, it's where the upcall
       * happens.
       */
      public abstract void method_upcall(Foo foo_object);
    
      /// Downcast from Foo to UserVisibleFoo
      public static UserVisibleFoo downcastUserVisibleFoo(Foo foo_object)
      {
        try {
         return (foo_object != null ? (FooDerived) Foo.downcastFoo(foo_object) : null);
        }
    
        catch (ClassCastException exc) {
          // Wasn't a FooDerived object, some other sublcass of Foo
          return null;
        }
      }
    }
    
    This doesn't prevent the user from creating subclasses derived from Foo, however, UserVisibleFoo provides the safety net that reminds the user to override the method_upcall() method.

17.11 Odds and ends

17.11.1 JavaDoc comments

The SWIG documentation system is currently deprecated. When it is resurrected JavaDoc comments will be fully supported. If you can't wait for the full documentation system a couple of workarounds are available. The %javamethodmodifiers feature can be used for adding proxy class method comments and module class method comments. The "javaimports" typemap can be hijacked for adding in proxy class JavaDoc comments. The jniclassimports or jniclassclassmodifiers pragmas can also be used for adding intermediary JNI class comments and likewise the moduleimports or moduleclassmodifiers pragmas for the module class. Here is an example adding in a proxy class and method comment:
%javamethodmodifiers Barmy::lose_marbles() "
  /**
    * Calling this method will make you mad.
    * Use with <b>utmost</b> caution. 
    */
  public";

%typemap(javaimports) Barmy "
/** The crazy class. Use as a last resort. */"

class Barmy {
public:
  void lose_marbles() {}
};
Note the "public" added at the end of the %javamethodmodifiers as this is the default for this feature. The generated proxy class with JavaDoc comments is then as follows:
/** The crazy class. Use as a last resort. */
public class Barmy {
...
  /**
    * Calling this method will make you mad.
    * Use with <b>utmost</b> caution. 
    */
  public void lose_marbles() {
    ...
  }
...
}

17.11.2 Functional interface without proxy classes

It is possible to run SWIG in a mode that does not produce proxy classes by using the -noproxy commandline option. The interface is rather primitive when wrapping structures or classes and is accessed through function calls to the module class. All the functions in the module class are wrapped by functions with identical names as those in the intermediary JNI class.

Consider the example we looked at when examining proxy classes:

class Foo {
public:
     int x;
     int spam(int num, Foo* foo);
};
When using -noproxy, type wrapper classes are generated instead of proxy classes. Access to all the functions and variables is through a C like set of functions where the first parameter passed is the pointer to the class, that is an instance of a type wrapper class. Here is what the module class looks like:
public class example {
  public static void set_Foo_x(SWIGTYPE_p_Foo self, int x) {...}
  public static int get_Foo_x(SWIGTYPE_p_Foo self) {...}
  public static int Foo_spam(SWIGTYPE_p_Foo self, int num, SWIGTYPE_p_Foo foo) {...}
  public static SWIGTYPE_p_Foo new_Foo() {...}
  public static void delete_Foo(SWIGTYPE_p_Foo self) {...}
}
This approach is not nearly as natural as using proxy classes as the functions need to be used like this:
SWIGTYPE_p_Foo foo = example.new_Foo();
example.set_Foo_x(foo, 10);
int var = example.get_Foo_x(foo);
example.Foo_spam(foo, 20, foo);
example.delete_Foo(foo);
Unlike proxy classes, there is no attempt at tracking memory. All destructors have to be called manually for example the delete_Foo(foo) call above.

17.11.3 Using your own JNI functions

You may have some hand written JNI functions that you want to use in addition to the SWIG generated JNI functions. Adding these to your SWIG generated package is possible using the %native directive. If you don't want SWIG to wrap your JNI function then of course you can simply use the %ignore directive. However, if you want SWIG to generate just the Java code for a JNI function then use the %native directive. The C types for the parameters and return type must be specified in place of the JNI types and the function name must be the native method name. For example:
%native (HandRolled) void HandRolled(int, char *);
%{
JNIEXPORT void JNICALL Java_packageName_moduleName_HandRolled(JNIEnv *, jclass, jlong, jstring);
%}
No C JNI function will be generated and the Java_packageName_moduleName_HandRolled function will be accessible using the SWIG generated Java native method call in the intermediary JNI class which will look like this:
  public final static native void HandRolled(int jarg1, String jarg2);
and as usual this function is wrapped by another which for a global C function would appear in the module class:
  public static void HandRolled(int arg0, String arg1) {
    exampleJNI.HandRolled(arg0, arg1);
  }
The packageName and moduleName must of course be correct else you will get linker errors when the JVM dynamically loads the JNI function. You may have to add in some "jtype", "jstype", "javain" and "javaout" typemaps when wrapping some JNI types. Here the default typemaps work for for int and char *.

In summary the %native directive is telling SWIG to generate the Java code to access the JNI C code, but not the JNI C function itself. This directive is only really useful if you want to mix your own hand crafted JNI code and the SWIG generated code into one Java class or package.

17.11.4 Performance concerns and hints

If you're directly manipulating huge arrays of complex objects from Java, performance may suffer greatly when using the array functions in arrays_java.i. Try and minimise the expensive JNI calls to C/C++ functions, perhaps by using temporary Java variables instead of accessing the information directly from the C/C++ object.

Java classes without any finalizers generally speed up code execution as there is less for the garbage collector to do. Finalizer generation can be stopped by using an empty javafinalize typemap:

%typemap(javafinalize) SWIGTYPE ""
However, you will have to be careful about memory management and make sure that you code in a call to the delete() member function. This method calls the C++ destructor or free() for C code.

17.12 Examples

The directory Examples/java has a number of further examples. Take a look at these if you want to see some of the techniques described in action. The Examples/index.html file in the parent directory contains the SWIG Examples Documentation and is a useful starting point. If your SWIG installation went well Unix users should be able to type make in each example directory, then java main to see them running. For the benefit of Windows users, there are also Visual C++ project files in a couple of the Windows Examples. cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/Copyright.html0000644000175000000620000000501312561312226022354 0ustar stevestaff SWIG Documentation Copyright

SWIG Users Manual

Version 1.1
June, 1997

Copyright(C) 1996, 1997
All Rights Reserved

David M. Beazley
Department of Computer Science
University of Utah
Salt Lake City, Utah 84112
beazley@cs.utah.edu

This document may be freely distributed in whole or part provided this copyright notice is retained. Commercial distribution of this document is prohibited without the express written consent of the author.


SWIG 1.1 is Copyright (C) 1995-1997 by the University of Utah and the Univerity of California and distributed under the following license.

This software is copyrighted by the University of Utah and the Regents of the University of California. The following terms apply to all files associated with the software unless explicitly disclaimed in individual files.

Permission is hereby granted, without written agreement and without license or royalty fees, to use, copy, modify, and distribute this software and its documentation for any purpose, provided that (1) The above copyright notice and the following two paragraphs appear in all copies of the source code and (2) redistributions including binaries reproduces these notices in the supporting documentation. Substantial modifications to this software may be copyrighted by their authors and need not follow the licensing terms described here, provided that the new terms are clearly indicated in all files where they apply.

IN NO EVENT SHALL THE AUTHOR, THE UNIVERSITY OF CALIFORNIA, THE UNIVERSITY OF UTAH OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHOR, THE UNIVERSITY OF CALIFORNIA, AND THE UNIVERSITY OF UTAH SPECIFICALLY DISCLAIM ANY WARRANTIES,INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.


beazley@cs.utah.edu
Last Modified, August 3, 1997
cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/Advanced.html0000644000175000000620000004701012561312226022114 0ustar stevestaff Advanced Topics

15 Advanced Topics

Caution: This chapter is under repair!

15.1 Creating multi-module packages

SWIG can be used to create packages consisting of many different modules. However, there are some technical aspects of doing this and techniques for managing the problem.

This chapter doesn't apply to those languages that use static type checking, rather than runtime type checking, such as Java and C#.

15.1.1 Runtime support (and potential problems)

Most SWIG generated modules rely upon a small collection of functions that are used during run-time. These functions are primarily used for pointer type-checking, exception handling, and so on. When you run SWIG, these functions are included in the wrapper file (and declared as static). If you create a system consisting of many modules, each one will have an identical copy of these runtime libraries :

This duplication of runtime libraries is usually harmless since there are no namespace conflicts and memory overhead is minimal. However, there is serious problem related to the fact that modules do not share type-information. This is particularly a problem when working with C++ (as described next).

15.1.2 Why doesn't C++ inheritance work between modules?

Consider for a moment the following two interface files :

// File : a.i
%module a

// Here is a base class
class a {
public:
	a();
	~a();
	void foo(double);
};


// File : b.i
%module b

// Here is a derived class
%import a.i                 // Gets definition of base class

class b : public a {
public:
	bar();
};

When compiled into two separate modules, the code does not work properly. In fact, you get a type error such as the following:

[beazley@guinness shadow]$ python
Python 1.4 (Jan 16 1997)  [GCC 2.7.2]
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> from a import *
>>> from b import *
>>> # Create a new "b"
>>> b = new_b()
>>> # Call a function in the base class
...
>>> a_foo(b,3)
Traceback (innermost last):
  File "<stdin>", line 1, in ?
TypeError: Type error in argument 1 of a_foo. Expected _a_p.
>>>

However, from our class definitions we know that "b" is an "a" by inheritance and there should be no type-error. This problem is directly due to the lack of type-sharing between modules. If we look closely at the module modules created here, they look like this :

The type information listed shows the acceptable values for various C datatypes. In the "a" module, we see that "a" can only accept instances of itself. In the "b" module, we see that "a" can accept both "a" and "b" instances--which is correct given that a "b" is an "a" by inheritance.

Unfortunately, this problem is inherent in the method by which SWIG makes modules. When we made the "a" module, we had no idea what derived classes might be used at a later time. However, it's impossible to produce the proper type information until after we know all of the derived classes. A nice problem to be sure, but one that can be fixed by making all modules share a single copy of the SWIG run-time library.

15.1.3 The SWIG runtime library

To reduce overhead and to fix type-handling problems, it is possible to share the SWIG run-time functions between multiple modules. This requires the use of the SWIG runtime library which is optionally built during SWIG installation. To use the runtime libraries, follow these steps:

1. Build the SWIG run-time libraries. The SWIG/Runtime directory contains a makefile for doing this for Unix users. Some of the runtime libraries can also be built under Windows by following the instructions in the Windows documentation. If successfully built, you will end up with a number of files that are usually installed in /usr/local/lib. The Perl, Python, Tcl and Ruby library files are listed below:

libswigpl.a                  # Perl library (static)
libswigpl.so                 # Perl library (shared)
libswigpy.a                  # Python library (static)
libswigpy.so                 # Python library (shared)
libswigtcl8.a                # Tcl 8.x library (static)
libswigtcl8.so               # Tcl 8.x library (shared)
libswigrb.a                  # Ruby library (static)
libswigrb.so                 # Ruby library (shared)

Note that certain libraries may be missing due to missing packages or unsupported features (like dynamic loading) on your machine. Also some languages don't use the runtime libraries at all as they implement static type checking rather than dynamic type checking, for example, Java and C#.

2. Compile all SWIG modules using the -c option. For example :

% swig -c -python a.i
% swig -c -python b.i
The -c option tells SWIG to omit runtime support. It's now up to you to provide it separately--which we will do using our libraries.

3. Build SWIG modules by linking against the appropriate runtime libraries.

% swig -c -python a.i
% swig -c -python b.i
% gcc -c a_wrap.c b_wrap.c -I/usr/local/include
% ld -shared a_wrap.o b_wrap.o -lswigpy  -o a.so

or if building a new executable (static linking)

% swig -c -tcl -ltclsh.i a.i
% gcc a_wrap.c -I/usr/local/include -L/usr/local/lib -ltcl -lswigtcl8 -lm -o mytclsh

When completed you should now end up with a collection of modules like this:

In this configuration, the runtime library manages all datatypes and other information between modules. This management process is dynamic in nature--when new modules are loaded, they contribute information to the run-time system. In the C++ world, one could incrementally load classes as needed. As this process occurs, type information is updated and base-classes learn about derived classes as needed.

15.1.4 A few dynamic loading gotchas

When working with dynamic loading, it is critical to check that only one copy of the run-time library is being loaded into the system. When working with .a library files, problems can sometimes occur so there are a few approaches to the problem.

1. Rebuild the scripting language executable with the SWIG runtime library attached to it. This is actually, fairly easy to do using SWIG. For example :

%module mytclsh
%{

static void *__embedfunc(void *a) { return a};
%}

void *__embedfunc(void *);
%include tclsh.i

Now, run SWIG and compile as follows:

% swig -c -tcl mytclsh.i
% gcc mytclsh_wrap.c -I/usr/local/include -L/usr/local/lib -ltcl -lswigtcl8 -ldl -lm \
      -o tclsh
This produces a new executable "tclsh" that contains a copy of the SWIG runtime library. The weird __embedfunc() function is needed to force the functions in the runtime library to be included in the final executable.

To make new dynamically loadable SWIG modules, simply compile as follows :

% swig -c -tcl example.i
% gcc -c example_wrap.c -I/usr/local/include
% ld -shared example_wrap.o -o example.so
Linking against the swigtcl8 library is no longer necessary as all of the functions are now included in the tclsh executable and will be resolved when your module is loaded. However, some operating systems, like Windows, will still require linking with the libraries so that there are no unresolved symbols.

2. Using shared library versions of the runtime library

If supported on your machine, the runtime libraries will be built as shared libraries (for example a .so, .sl, or .dll suffix). To compile using the runtime libraries, your link process should look something like this:

% ld -shared example_wrap.o -o libexample.so             # Irix
% gcc -shared example_wrap.o -o libexample.so            # Linux
% ld -G example_wrap.o -o libexample.so                  # Solaris
> cl /LD example_wrap.obj /o example.dll swigtcl8.lib tcl83.lib /link /LIBPATH:c:\SWIG\Runtime /LIBPATH:c:\Tcl\lib # Windows VC++
In order for the libexample.so library to work, it needs to be placed in a location where the dynamic loader can find it. Typically this is a system library directory (eg. /usr/local/lib or /usr/lib).

When running with the shared libary version, you may get error messages such as the following:

Unable to locate libexample.so
This indicates that the loader was unable to find the shared libary at run-time. To find shared libaries, the loader looks through a collection of predetermined paths. If the shared library file is not in any of these directories, it results in an error. On most machines, you can change the loader search path by changing the path (Windows) or environment variable LD_LIBRARY_PATH (Unix), e.g.

% setenv LD_LIBRARY_PATH .:/home/beazley/packages/lib
A somewhat better approach is to link your module with the proper path encoded. This is typically done using the `-rpath' or `-R' option to your linker (see the man page). For example:

% ld -shared example_wrap.o example.o -rpath /home/beazley/packages/lib \
       -L/home/beazley/packages/lib -lswigtcl8.so -o example.so
The -rpath option encodes the location of shared libraries into your modules and gets around having to set the LD_LIBRARY_PATH variable.

If all else fails, pull up the man pages for your linker and start playing around.

15.2 Dynamic Loading of C++ modules

Dynamic loading of C++ modules presents a special problem for many systems. This is because C++ modules often need additional supporting code for proper initialization and operation. Static constructors are also a bit of a problem.

While the process of building C++ modules is, by no means, and exact science, here are a few rules of thumb to follow :

  • Don't use static constructors if at all possible (not always avoidable).
  • Try linking your module with the C++ compiler using a command like `c++ -shared'. This often solves alot of problems.
  • Sometimes it is necessary to link against special libraries. For example, modules compiled with g++ often need to be linked against the libgcc.a, libg++.a, and libstdc++.a libraries.
  • Read the compiler and linker man pages over and over until you have them memorized (this may not help in some cases however).
  • Search articles on Usenet, particularly in comp.lang.tcl, comp.lang.perl, comp.lang.python and comp.lang.ruby. Building C++ modules is a common problem.

The SWIG distribution contains some additional documentation about C++ modules in the Doc directory as well.

15.3 Inside the SWIG type-checker

The SWIG runtime type-checker plays a critical role in the correct operation of SWIG modules. It not only checks the validity of pointer types, but also manages C++ inheritance, and performs proper type-casting of pointers when necessary. This section provides some insight into what it does, how it works, and why it is the way it is.

15.3.1 Type equivalence

SWIG uses a name-based approach to managing pointer datatypes. For example, if you are using a pointer like "double *", the type-checker will look for a particular string representation of that datatype such as "_double_p". If no match is found, a type-error is reported.

However, the matching process is complicated by the fact that datatypes may use a variety of different names. For example, the following declarations

typedef double   Real;
typedef Real *   RealPtr;
typedef double   Float;

define two sets of equivalent types :

{double, Real, Float}
{RealPtr, Real *}

All of the types in each set are freely interchangable and the type-checker knows about the relationships by managing a table of equivalences such as the following :

double    => { Real, Float }
Real      => { double, Float }
Float     => { double, Real }
RealPtr   => { Real * }
Real *    => { RealPtr }

When you declare a function such as the following :

void foo(Real *a);

SWIG first checks to see if the argument passed is a "Real *". If not, it checks to see if it is any of the other equivalent types (double *, RealPtr, Float *). If so, the value is accepted and no error occurs.

Derived versions of the various datatypes are also legal. For example, if you had a function like this,

void bar(Float ***a);

The type-checker will accept pointers of type double *** and Real ***. However, the type-checker does not always capture the full-range of possibilities. For example, a datatype of `RealPtr **' is equivalent to a `Float ***' but would be flagged as a type error. If you encounter this kind of problem, you can manually force SWIG to make an equivalence as follows:

// Tell the type checker that `Float_ppp' and `RealPtr_pp' are equivalent.
%init %{
	SWIG_RegisterMapping("Float_ppp","RealPtr_pp",0);
%}

Doing this should hardly ever be necessary (I have never encountered a case where this was necessary), but if all else fails, you can force the run-time type checker into doing what you want.

Type-equivalence of C++ classes is handled in a similar manner, but is encoded in a manner to support inheritance. For example, consider the following classes hierarchy :

class A { };
class B : public A { };
class C : public B { };
class D {};
class E : public C, public D {};

The type-checker encodes this into the following sets :

A => { B, C, E }              "B isa A, C isa A, E isa A"
B => { C, E }                 "C isa B, E isa B"
C => { E }                    "E isa C"
D => { E }                    "E isa D"
E => { }

The encoding reflects the class hierarchy. For example, any object of type "A" will also accept objects of type B,C, and E because these are all derived from A. However, it is not legal to go the other way. For example, a function operating on a object from class E will not accept an object from class A.

15.3.2 Type casting

When working with C++ classes, SWIG needs to perform proper typecasting between derived and base classes. This is particularly important when working with multiple inheritance. To do this, conversion functions are created such as the following :

void *EtoA(void *ptr) {
	E *in = (E *) ptr;
	A *out = (A *) in;       // Cast using C++
	return (void *) out;
}

All pointers are internally represented as void *, but conversion functions are always invoked when pointer values are converted between base and derived classes in a C++ class hierarchy.

15.3.3 Why a name based approach?

SWIG uses a name-based approach to type-checking for a number of reasons :

  • One of SWIG's main uses is code development and debugging. In this environment, the type name of an object turns out to be a useful piece of information in tracking down problems.
  • In languages like Perl, the name of a datatype is used to determine things like packages and classes. By using datatype names we get a natural mapping between C and Perl.
  • I believe using the original names of datatypes is more intuitive than munging them into something completely different.

An alternative to a name based scheme would be to generate type-signatures based on the structure of a datatype. Such a scheme would result in perfect type-checking, but I think it would also result in a very confusing scripting language module. For this reason, I see SWIG sticking with the name-based approach--at least for the foreseeable future.

15.3.4 Performance of the type-checker

The type-checker performs the following steps when matching a datatype :

1. Check a pointer against the type supplied in the original C declaration. If there is a perfect match, we're done.
2. Check the supplied pointer against a cache of recently used datatypes.
3. Search for a match against the full list of equivalent datatypes.
4. If not found, report an error.

Most well-structured C codes will find an exact match on the first attempt, providing the best possible performance. For C++ codes, it is quite common to be passing various objects of a common base-class around between functions. When base-class functions are invoked, it almost always results in a miscompare (because the type-checker is looking for the base-type). In this case, we drop down to a small cache of recently used datatypes. If we've used a pointer of the same type recently, it will be in the cache and we can match against it. For tight loops, this results in about 10-15% overhead over finding a match on the first try. Finally, as a last resort, we need to search the internal pointer tables for a match. This involves a combination of hash table lookup and linear search. If a match is found, it is placed into the cache and the result returned. If not, we finally report a type-mismatch.

As a rule of thumb, C++ programs require somewhat more processing than C programs, but this seems to be avoidable. Also, keep in mind that performance penalties in the type-checker don't necessarily translate into big penalties in the overall application. Performance is most greatly affected by the efficiency of the target scripting language and the types of operations your C code is performing.


SWIG 1.1 - Last Modified : Mon Aug 4 10:47:13 1997
cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/Arguments.html0000644000175000000620000002711012561312226022353 0ustar stevestaff Argument Handling

7 Argument Handling

Disclaimer: This chapter is under construction.

In Chapter 3, SWIG's treatment of basic datatypes and pointers was described. In particular, primitive types such as int and double are mapped to corresponding types in the target language. For everything else, pointers are used to refer to structures, classes, arrays, and other user-defined datatypes. However, in certain applications it is desirable to change SWIG's handling of a specific datatype. For example, you might want to return multiple values through the arguments of a function. This chapter describes some of the techniques for doing this.

7.1 The typemaps.i library

This section describes the typemaps.i library file--commonly used to change certain properties of argument conversion.

7.1.1 Introduction

Suppose you had a C function like this:

void add(double a, double b, double *result) {
	*result = a + b;
}

From reading the source code, it is clear that the function is storing a value in the double *result parameter. However, since SWIG does not examine function bodies, it has no way to know that this is the underlying behavior.

One way to deal with this is to use the typemaps.i library file and write interface code like this:

// Simple example using typemaps
%module example
%include "typemaps.i"

%apply double *OUTPUT { double *result };
extern void add(double a, double b, double *result);
The %apply directive tells SWIG that you are going to apply a special type handling rule to a type. The "double *OUTPUT" specification is the name of a rule that defines how to return an output value from an argument of type double *. This rule gets applied to all of the datatypes listed in curly braces-- in this case "double *result".

When the resulting module is created, you can now use the function like this (shown for Python):

>>> a = add(3,4)
>>> print a
7
>>>
In this case, you can see how the output value normally returned in the third argument has magically been transformed into a function return value. Clearly this makes the function much easier to use since it is no longer necessary to manufacture a special double * object and pass it to the function somehow.

Once a typemap has been applied to a type, it stays in effect for all future occurrences of the type and name. For example, you could write the following:

%module example
%include "typemaps.i"

%apply double *OUTPUT { double *result };
extern void add(double a, double b, double *result);
extern void sub(double a, double b, double *result);
extern void mul(double a, double b, double *result);
extern void div(double a, double b, double *result);
...
In this case, the double *OUTPUT rule is applied to all of the functions that follow.

Typemap transformations can even be extended to multiple return values. For example, consider this code:

%include "typemaps.i"
%apply int *OUTPUT { int *width, int *height };

// Returns a pair (width,height)
void getwinsize(int winid, int *width, int *height);
In this case, the function returns multiple values, allowing it to be used like this:
>>> w,h = genwinsize(wid)
>>> print w
400
>>> print h
300
>>>

It should also be noted that although the %apply directive is used to associate typemap rules to datatypes, you can also use the rule names directly in arguments. For example, you could write this:

// Simple example using typemaps
%module example
%include "typemaps.i"

extern void add(double a, double b, double *OUTPUT);
Typemaps stay in effect until they are explicitly deleted or redefined to something else. To clear a typemap, the %clear directive should be used. For example:
%clear double *result;      // Remove all typemaps for double *result

7.1.2 Input parameters

The following typemaps instruct SWIG that a pointer really only holds a single input value:

int *INPUT		
short *INPUT
long *INPUT
unsigned int *INPUT
unsigned short *INPUT
unsigned long *INPUT
double *INPUT
float *INPUT
When used, it allows values to be passed instead of pointers. For example, consider this function:
double add(double *a, double *b) {
	return *a+*b;
}
Now, consider this SWIG interface:

%module example
%include "typemaps.i"
...
extern double add(double *INPUT, double *INPUT);

When the function is used in the scripting language interpreter, it will work like this:

result = add(3,4)

7.1.3 Output parameters

The following typemap rules tell SWIG that pointer is the output value of a function. When used, you do not need to supply the argument when calling the function. Instead, one or more output values are returned.

int *OUTPUT
short *OUTPUT
long *OUTPUT
unsigned int *OUTPUT
unsigned short *OUTPUT
unsigned long *OUTPUT
double *OUTPUT
float *OUTPUT

These methods can be used as shown in an earlier example. For example, if you have this C function :

void add(double a, double b, double *c) {
	*c = a+b;
}

A SWIG interface file might look like this :

%module example
%include "typemaps.i"
...
extern void add(double a, double b, double *OUTPUT);

In this case, only a single output value is returned, but this is not a restriction. An arbitrary number of output values can be returned by applying the output rules to more than one argument (as shown previously).

If the function also returns a value, it is returned along with the argument. For example, if you had this:

extern int foo(double a, double b, double *OUTPUT);
The function will return two values like this:
iresult, dresult = foo(3.5, 2)

7.1.4 Input/Output parameters

When a pointer serves as both an input and output value you can use the following typemaps :

int *INOUT
short *INOUT
long *INOUT
unsigned int *INOUT
unsigned short *INOUT
unsigned long *INOUT
double *INOUT
float *INOUT

A C function that uses this might be something like this:

void negate(double *x) {
	*x = -(*x);
}

To make x function as both and input and output value, declare the function like this in an interface file :

%module example
%include typemaps.i
...
extern void negate(double *INOUT);

Now within a script, you can simply call the function normally :

a = negate(3);         # a = -3 after calling this
One subtle point of the INOUT rule is that many scripting languages enforce mutability constraints on primitive objects (meaning that simple objects like integers and strings aren't supposed to change). Because of this, you can't just modify the object's value in place as the underlying C function does in this example. Therefore, the INOUT rule returns the modified value as a new object rather than directly overwriting the value of the original input object.

Compatibility note : The INOUT rule used to be known as BOTH in earlier versions of SWIG. Backwards compatibility is preserved, but deprecated.

7.1.5 Using different names

As previously shown, the %apply directive can be used to apply the INPUT, OUTPUT, and INOUT typemaps to different argument names. For example:

// Make double *result an output value
%apply double *OUTPUT { double *result };

// Make Int32 *in an input value
%apply int *INPUT { Int32 *in };

// Make long *x inout
%apply long *INOUT {long *x};

To clear a rule, the %clear directive is used:

%clear double *result;
%clear Int32 *in, long *x;
Typemap declarations are lexically scoped so a typemap takes effect from the point of definition to the end of the file or a matching %clear declaration.

7.2 Applying constraints to input values

In addition to changing the handling of various input values, it is also possible to use typemaps to apply constraints. For example, maybe you want to insure that a value is positive, or that a pointer is non-NULL. This can be accomplished including the constraints.i library file.

7.2.1 Simple constraint example

The constraints library is best illustrated by the following interface file :

// Interface file with constraints
%module example
%include "constraints.i"

double exp(double x);
double log(double POSITIVE);         // Allow only positive values
double sqrt(double NONNEGATIVE);     // Non-negative values only
double inv(double NONZERO);          // Non-zero values
void   free(void *NONNULL);          // Non-NULL pointers only

The behavior of this file is exactly as you would expect. If any of the arguments violate the constraint condition, a scripting language exception will be raised. As a result, it is possible to catch bad values, prevent mysterious program crashes and so on.

7.2.2 Constraint methods

The following constraints are currently available

POSITIVE                     Any number > 0 (not zero)
NEGATIVE                     Any number < 0 (not zero)
NONNEGATIVE                  Any number >= 0
NONPOSITIVE                  Any number <= 0
NONZERO                      Nonzero number
NONNULL                      Non-NULL pointer (pointers only).

7.2.3 Applying constraints to new datatypes

The constraints library only supports the primitive C datatypes, but it is easy to apply it to new datatypes using %apply. For example :

// Apply a constraint to a Real variable
%apply Number POSITIVE { Real in };

// Apply a constraint to a pointer type
%apply Pointer NONNULL { Vector * };

The special types of "Number" and "Pointer" can be applied to any numeric and pointer variable type respectively. To later remove a constraint, the %clear directive can be used :

%clear Real in;
%clear Vector *;


SWIG 1.3 - Last Modified : October 13, 2002
cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/Warnings.html0000644000175000000620000003440412561312226022202 0ustar stevestaff Warning Messages

12 Warning Messages

12.1 Introduction

During compilation, SWIG may generate a variety of warning messages. For example:
example.i:16: Warning(501): Overloaded declaration ignored.  bar(double)
example.i:15: Warning(501): Previous declaration is bar(int)
Typically, warning messages indicate non-fatal problems with the input where the generated wrapper code will probably compile, but it may not work like you expect.

12.2 Warning message suppression

All warning messages have a numeric code that is shown in the warning message itself. To suppress the printing of a warning message, a number of techniques can be used. First, you can run SWIG with the -w command line option. For example:
% swig -python -w501 example.i
% swig -python -w501,505,401 example.i
Alternatively, warnings can be suppressed by inserting a special preprocessor pragma into the input file:
%module example
#pragma SWIG nowarn=501
#pragma SWIG nowarn=501,505,401
Finally, code-generation warnings can be disabled on a declaration by declaration basis using the %warnfilter directive. For example:
%module example
%warnfilter(501) foo;
...
int foo(int);
int foo(double);              // Silently ignored.
The %warnfilter directive has the same semantics as other declaration modifiers like %rename, %ignore, and %feature. For example, if you wanted to suppress a warning for a method in a class hierarchy, you could do this:
%warnfilter(501) Object::foo;
class Object {
public:
   int foo(int);
   int foo(double);      // Silently ignored
   ...
};

class Derived : public Object {
public:
   int foo(int);
   int foo(double);      // Silently ignored
   ...
};
Warnings can be suppressed for an entire class by supplying a class name. For example:
%warnfilter(501) Object;

class Object {
public:
   ...                      // All 501 warnings ignored in class
};
There is no option to suppress all SWIG warning messages. The warning messages are there for a reason---to tell you that something may be broken in your interface. Ignore the warning messages at your own peril.

12.3 Enabling additional warnings

Some warning messages are disabled by default and are generated only to provide additional diagnostics. All warning messages can be enabled using the -Wall option. For example:
% swig -Wall -python example.i
When -Wall is used, all other warning filters are disabled.

To selectively turn on extra warning messages, you can use the directives and options in the previous section--simply add a "+" to all warning numbers. For example:

% swig -w+309,+452 example.i
or
#pragma SWIG nowarn=+309,+452
or
%warnfilter(+309,+452) foo;
Note: selective enabling of warnings with %warnfilter overrides any global settings you might have made using -w or #pragma.

12.4 Issuing a warning message

Warning messages can be issued from an interface file using a number of directives. The %warn directive is the most simple:
%warn "750:This is your last warning!"
All warning messages are optionally prefixed by the warning number to use. If you are generating your own warnings, make sure you don't use numbers defined in the table at the end of this section.

The %ignorewarn directive is the same as %ignore except that it issues a warning message whenever a matching declaration is found. For example:

%ignorewarn("362:operator= ignored") operator=;
Warning messages can be associated with typemaps using the warning attribute of a typemap declaration. For example:
%typemap(in, warning="751:You are really going to regret this") blah * {
   ...
}
In this case, the warning message will be printed whenever the typemap is actually used.

12.5 Commentary

The ability to suppress warning messages is really only provided for advanced users and is not recommended in normal use. There are no plans to provide symbolic names or options that identify specific types or groups of warning messages---the numbers must be used explicitly.

Certain types of SWIG problems are errors. These usually arise due to parsing errors (bad syntax) or semantic problems for which there is no obvious recovery. There is no mechanism for suppressing error messages or handling errors as warnings---you must make changes to the input file to fix the problem.

12.6 Message output format

The output format for both warnings and errors can be selected for integration with your favourite IDE/editor. Editors and IDEs can usually parse error messages and if in the appropriate format will easily take you directly to the source of the error. The standard format is used by default except on Windows where the Microsoft format is used by default. These can be overridden using command line options, for example:
$ swig -python -Fstandard example.i
example.i:4: Syntax error in input.
$ swig -python -Fmicrosoft example.i
example.i(4): Syntax error in input.

12.7 Warning number reference

12.7.1 Deprecated features (100-199)

  • 101. Deprecated %extern directive.
  • 102. Deprecated %val directive.
  • 103. Deprecated %out directive.
  • 104. Deprecated %disabledoc directive.
  • 105. Deprecated %enabledoc directive.
  • 106. Deprecated %doconly directive.
  • 107. Deprecated %style directive.
  • 108. Deprecated %localstyle directive.
  • 109. Deprecated %title directive.
  • 110. Deprecated %section directive.
  • 111. Deprecated %subsection directive.
  • 112. Deprecated %subsubsection directive.
  • 113. Deprecated %addmethods directive.
  • 114. Deprecated %readonly directive.
  • 115. Deprecated %readwrite directive.
  • 116. Deprecated %except directive.
  • 117. Deprecated %new directive.
  • 118. Deprecated %typemap(except).
  • 119. Deprecated %typemap(ignore).
  • 120. Deprecated command line option (-c).

12.7.2 Preprocessor (200-299)

  • 201. Unable to find 'filename'.
  • 202. Could not evaluate 'expr'.

12.7.3 C/C++ Parser (300-399)

  • 301. class keyword used, but not in C++ mode.
  • 302. Identifier 'name' redefined (ignored).
  • 303. %extend defined for an undeclared class 'name'.
  • 304. Unsupported constant value (ignored).
  • 305. Bad constant value (ignored).
  • 306. 'identifier' is private in this context.
  • 307. Can't set default argument value (ignored)
  • 308. Namespace alias 'name' not allowed here. Assuming 'name'
  • 309. [private | protected] inheritance ignored.
  • 310. Template 'name' was already wrapped as 'name' (ignored)
  • 311. Template partial specialization not supported.
  • 312. Nested classes not currently supported (ignored).
  • 313. Unrecognized extern type "name" (ignored).
  • 314. 'identifier' is a lang keyword.
  • 315. Nothing known about 'identifier'.
  • 316. Repeated %module directive.
  • 317. Specialization of non-template 'name'.
  • 318. Instantiation of template name is ambiguous. Using templ at file:line
  • 319. No access specifier given for base class name (ignored).
  • 320. Explicit template instantiation ignored.
  • 321. identifier conflicts with a built-in name.
  • 322. Redundant redeclaration of 'name'.
  • 350. operator new ignored.
  • 351. operator delete ignored.
  • 352. operator+ ignored.
  • 353. operator- ignored.
  • 354. operator* ignored.
  • 355. operator/ ignored.
  • 356. operator% ignored.
  • 357. operator^ ignored.
  • 358. operator& ignored.
  • 359. operator| ignored.
  • 360. operator~ ignored.
  • 361. operator! ignored.
  • 362. operator= ignored.
  • 363. operator< ignored.
  • 364. operator> ignored.
  • 365. operator+= ignored.
  • 366. operator-= ignored.
  • 367. operator*= ignored.
  • 368. operator/= ignored.
  • 369. operator%= ignored.
  • 370. operator^= ignored.
  • 371. operator&= ignored.
  • 372. operator|= ignored.
  • 373. operator<< ignored.
  • 374. operator>>ignored.
  • 375. operator<<= ignored.
  • 376. operator>>= ignored.
  • 377. operator== ignored.
  • 378. operator!= ignored.
  • 379. operator<= ignored.
  • 380. operator>= ignored.
  • 381. operator&& ignored.
  • 382. operator|| ignored.
  • 383. operator++ ignored.
  • 384. operator-- ignored.
  • 385. operator, ignored.
  • 386. operator-<* ignored.
  • 387. operator-< ignored.
  • 388. operator() ignored.
  • 389. operator[] ignored.
  • 390. operator+ ignored (unary).
  • 391. operator- ignored (unary).
  • 392. operator* ignored (unary).
  • 393. operator& ignored (unary).
  • 394. operator new[] ignored.
  • 395. operator delete[] ignored.

12.7.4 Types and typemaps (400-499)

  • 401. Nothing known about class 'name'. Ignored.
  • 402. Base class 'name' is incomplete.
  • 403. Class 'name' might be abstract.
  • 450. Deprecated typemap feature ($source/$target).
  • 451. Setting const char * variable may leak memory.
  • 452. Reserved
  • 453. Can't apply (pattern). No typemaps are defined.
  • 460. Unable to use type type as a function argument.
  • 461. Unable to use return type type in function name.
  • 462. Unable to set variable of type type.
  • 463. Unable to read variable of type type.
  • 464. Unsupported constant value.
  • 465. Unable to handle type type.
  • 466. Unsupported variable type type.
  • 467. Overloaded declaration not supported (no type checking rule for 'type')
  • 468. No 'throw' typemap defined for exception type 'type'.

12.7.5 Code generation (500-599)

  • 501. Overloaded declaration ignored. decl
  • 502. Overloaded constructor ignored. decl
  • 503. Can't wrap 'identifier' unless renamed to a valid identifier.
  • 504. Function name must have a return type.
  • 505. Variable length arguments discarded.
  • 506. Can't wrap varargs with keyword arguments enabled.
  • 507. Adding native function name not supported (ignored).
  • 508. Declaration of 'name' shadows declaration accessible via operator->() at file:line.
  • 509. Overloaded declaration is shadowed by declaration at file:line.
  • 510. Friend function 'name' ignored.
  • 511. Can't use keyword arguments with overloaded functions.
  • 512. Overloaded declaration const ignored. Non-const method at file:line used.
  • 513. Can't generate wrappers for unnamed struct/class.
  • 514.
  • 515.
  • 516. Overloaded method declaration ignored. Method declaration at file:line used.

12.7.6 Language module specific (800-899)

  • 801. Wrong name (corrected to 'name'). (Ruby).
  • 810. No jni typemap defined for type (Java).
  • 811. No jtype typemap defined for type (Java).
  • 812. No jstype typemap defined for type (Java).
  • 813. Warning for classname: Base baseclass ignored. Multiple inheritance is not supported in Java. (Java).
  • 814. No javagetcptr typemap defined for type (Java).
  • 815. No javafinalize typemap defined for type (Java).
  • 816. No javaptrconstructormodifier typemap defined for type (Java).
  • 817. No javaout typemap defined for type (Java).
  • 818. No javain typemap defined for type (Java).
  • 830. No ctype typemap defined for type (C#).
  • 831. No cstype typemap defined for type (C#).
  • 832. No cswtype typemap defined for type (C#).
  • 833. Warning for classname: Base baseclass ignored. Multiple inheritance is not supported in C#. (C#).
  • 834. No csgetcptr typemap defined for type (C#).
  • 835. No csfinalize typemap defined for type (C#).
  • 836. No csptrconstructormodifier typemap defined for type (C#).
  • 837. No csout typemap defined for type (C#).
  • 838. No csin typemap defined for type (C#).

12.7.7 User defined (900-999)

These numbers can be used by your own application.

12.8 History

The ability to control warning messages was first added to SWIG-1.3.12.


SWIG 1.3 - Last Modified : June 28, 2003
cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/Customization.html0000644000175000000620000004006712561312226023264 0ustar stevestaff Customization Features

9 Customization Features

In many cases, it is desirable to change the default wrapping of particular declarations in an interface. For example, you might want to provide hooks for catching C++ exceptions, add assertions, or provide hints to the underlying code generator. This chapter describes some of these customization techniques. First, a discussion of exception handling is presented. Then, a more general-purpose customization mechanism known as "features" is described.

9.1 Exception handling with %exception

The %exception directive allows you to define a general purpose exception handler. For example, you can specify the following:

%exception {
    try {
        $action
    }
    catch (RangeError) {
        PyErr_SetString(PyExc_IndexError,"index out-of-bounds");
        return NULL;
    }
}

When defined, the code enclosed in braces is inserted directly into the low-level wrapper functions. The special symbol $action gets replaced with the actual operation to be performed (a function call, method invocation, attribute access, etc.). An exception handler remains in effect until it is explicitly deleted. This is done by using %exception with no code. For example:

%exception;   // Deletes any previously defined handler

Compatibility note: Previous versions of SWIG used a special directive %except for exception handling. That directive is still supported but is deprecated--%exception provides the same functionality, but is substantially more flexible.

9.1.1 Handling exceptions in C code

C has no formal exception handling mechanism so there are several approaches that might be used. A somewhat common technique is to simply set a special error code. For example:


/* File : except.c */

static char error_message[256];
static int error_status = 0;

void throw_exception(char *msg) {
	strncpy(error_message,msg,256);
	error_status = 1;
}

void clear_exception() {
	error_status = 0;
}
char *check_exception() {
	if (error_status) return error_message;
	else return NULL;
}

To use these functions, functions simply call throw_exception() to indicate an error occurred. For example :

double inv(double x) {
	if (x != 0) return 1.0/x;
	else {
		throw_exception("Division by zero");
		return 0;
	}
}

To catch the exception, you can write a simple exception handler such as the following (shown for Perl5) :

%exception {
    char *err;
    clear_exception();
    $action
    if ((err = check_exception())) {
       croak(err);
    }
}

In this case, when an error occurs, it is translated into a Perl error.

9.1.2 Exception handling with longjmp()

Exception handling can also be added to C code using the <setjmp.h> library. Here is a minimalistic implementation that relies on the C preprocessor :
/* File : except.c
   Just the declaration of a few global variables we're going to use */

#include <setjmp.h>
jmp_buf exception_buffer;
int exception_status;

/* File : except.h */
#include <setjmp.h>
extern jmp_buf exception_buffer;
extern int exception_status;

#define try if ((exception_status = setjmp(exception_buffer)) == 0)
#define catch(val) else if (exception_status == val)
#define throw(val) longjmp(exception_buffer,val)
#define finally else

/* Exception codes */

#define RangeError     1
#define DivisionByZero 2
#define OutOfMemory    3

Now, within a C program, you can do the following :

double inv(double x) {
	if (x) return 1.0/x;
	else throw(DivisionByZero);
}

Finally, to create a SWIG exception handler, write the following :

%{
#include "except.h"
%}

%exception {
	try {
		$action
	} catch(RangeError) {
		croak("Range Error");
	} catch(DivisionByZero) {
		croak("Division by zero");
	} catch(OutOfMemory) {
		croak("Out of memory");
	} finally {
		croak("Unknown exception");
	}
}
Note: This implementation is only intended to illustrate the general idea. To make it work better, you'll need to modify it to handle nested try declarations.

9.1.3 Handling C++ exceptions

Handling C++ exceptions is also straightforward. For example:

%exception {
	try {
		$action
	} catch(RangeError) {
		croak("Range Error");
	} catch(DivisionByZero) {
		croak("Division by zero");
	} catch(OutOfMemory) {
		croak("Out of memory");
	} catch(...) {
		croak("Unknown exception");
	}
}

The exception types need to be declared as classes elsewhere, possibly in a header file :

class RangeError {};
class DivisionByZero {};
class OutOfMemory {};

9.1.4 Defining different exception handlers

By default, the %exception directive creates an exception handler that is used for all wrapper functions that follow it. Unless there is a well-defined (and simple) error handling mechanism in place, defining one universal exception handler may be unwieldy and result in excessive code bloat since the handler is inlined into each wrapper function.

To fix this, you can be more selective about how you use the %exception directive. One approach is to only place it around critical pieces of code. For example:

%exception {
	... your exception handler ...
}
/* Define critical operations that can throw exceptions here */

%exception;

/* Define non-critical operations that don't throw exceptions */
More precise control over exception handling can be obtained by attaching an exception handler to specific declaration name. For example:
%exception allocate {
    try {
        $action
    } 
    catch (MemoryError) {
        croak("Out of memory");
    }
}
In this case, the exception handler is only attached to declarations named "allocate". This would include both global and member functions. The names supplied to %exception follow the same rules as for %rename. For example, if you wanted to define an exception handler for a specific class, you might write this:
%exception Object::allocate {
    try {
        $action
    } 
    catch (MemoryError) {
        croak("Out of memory");
    }
}
When a class prefix is supplied, the exception handler is applied to the corresponding declaration in the specified class as well as for identically named functions appearing in derived classes.

%exception can even be used to pinpoint a precise declaration when overloading is used. For example:

%exception Object::allocate(int) {
    try {
        $action
    } 
    catch (MemoryError) {
        croak("Out of memory");
    }
}
Attaching exceptions to specific declarations is a good way to reduce code bloat. It can also be a useful way to attach exceptions to specific parts of a header file. For example:
%module example
%{
#include "someheader.h"
%}

// Define a few exception handlers for specific declarations
%exception Object::allocate(int) {
    try {
        $action
    } 
    catch (MemoryError) {
        croak("Out of memory");
    }
}

%exception Object::getitem {
    try {
       $action
    }
    catch (RangeError) {
       croak("Index out of range");
    }
}
...
// Read a raw header file
%include "someheader.h"
Compatibility note: The %exception directive replaces the functionality provided by the deprecated "except" typemap. The typemap would allow exceptions to be thrown in the target language based on the return type of a function and was intended to be a mechanism for pinpointing specific declarations. However, it never really worked that well and the new %exception directive is much better.

9.1.5 Using The SWIG exception library

The exception.i library file provides support for creating language independent exceptions in your interfaces. To use it, simply put an "%include exception.i" in your interface file. This creates a function SWIG_exception() that can be used to raise common scripting language exceptions in a portable manner. For example :

// Language independent exception handler
%include exception.i       

%exception {
    try {
        $action
    } catch(RangeError) {
        SWIG_exception(SWIG_ValueError, "Range Error");
    } catch(DivisionByZero) {
        SWIG_exception(SWIG_DivisionByZero, "Division by zero");
    } catch(OutOfMemory) {
        SWIG_exception(SWIG_MemoryError, "Out of memory");
    } catch(...) {
        SWIG_exception(SWIG_RuntimeError,"Unknown exception");
    }
}

As arguments, SWIG_exception() takes an error type code (an integer) and an error message string. The currently supported error types are :

SWIG_MemoryError
SWIG_IOError
SWIG_RuntimeError
SWIG_IndexError
SWIG_TypeError
SWIG_DivisionByZero
SWIG_OverflowError
SWIG_SyntaxError
SWIG_ValueError
SWIG_SystemError
SWIG_UnknownError

Since the SWIG_exception() function is defined at the C-level it can be used elsewhere in SWIG. This includes typemaps and helper functions.

9.2 Object ownership and %newobject

A common problem in some applications is managing proper ownership of objects. For example, consider a function like this:
Foo *blah() {
   Foo *f = new Foo();
   return f;
}
If you wrap the function blah(), SWIG has no idea that the return value is a newly allocated object. As a result, the resulting extension module may produce a memory leak (SWIG is conservative and will never delete objects unless it knows for certain that the returned object was newly created).

To fix this, you can provide an extra hint to the code generator using the %newobject directive. For example:

%newobject blah;
Foo *blah();
%newobject works exactly like %rename and %exception. In other words, you can attach it to class members and parameterized declarations as before. For example:
%newobject ::blah();                   // Only applies to global blah
%newobject Object::blah(int,double);   // Only blah(int,double) in Object
%newobject *::copy;                    // Copy method in all classes
...
When %newobject is supplied, many language modules will arrange to take ownership of the return value. This allows the value to be automatically garbage-collected when it is no longer in use. However, this depends entirely on the target language (a language module may choose to ignore the %newobject directive).

Closely related to %newobject is a special typemap. The "newfree" typemap can be used to deallocate a newly allocated return value. It is only available on methods for which %newobject has been applied and is commonly used to clean-up string results. For example:

%typemap(newfree) char * "free($1);";
...
%newobject strdup;
...
char *strdup(const char *s);
In this case, the result of the function is a string in the target language. Since this string is a copy of the original result, the data returned by strdup() is no longer needed. The "newfree" typemap in the example simply releases this memory.

Compatibility note: Previous versions of SWIG had a special %new directive. However, unlike %newobject, it only applied to the next declaration. For example:

%new char *strdup(const char *s);
For now this is still supported but is deprecated.

How to shoot yourself in the foot: The %newobject directive is not a declaration modifier like the old %new directive. Don't write code like this:

%newobject
char *strdup(const char *s);
The results might not be what you expect.

9.3 Features and the %feature directive

Both %exception and %newobject are examples of a more general purpose customization mechanism known as "features." A feature is simply a user-definable property that is attached to specific declarations in an interface file. Features are attached using the %feature directive. For example:
%feature("except") Object::allocate {
    try {
        $action
    } 
    catch (MemoryError) {
        croak("Out of memory");
    }
}

%feature("new","1") *::copy;
In fact, the %exception and %newobject directives are really nothing more than macros involving %feature:
#define %exception %feature("except")
#define %newobject %feature("new","1")
The %feature directive follows the same name matching rules as the %rename directive (which is in fact just a special form of %feature). This means that features can be applied with pinpoint accuracy to specific declarations if needed.

When a feature is defined, it is given a name and a value. Most commonly, the value is supplied after the declaration name as shown for the "except" example above. However, if the feature is simple, a value might be supplied as an extra argument as shown for the "new" feature.

A feature stays in effect until it is explicitly disabled. A feature is disabled by supplying a %feature directive with no value. For example:

%feature("except") Object::allocate;    // Removes any previously defined feature

If no declaration name is given, a global feature is defined. This feature is then attached to every declaration that follows. This is how global exception handlers are defined. For example:

/* Define a global exception handler */
%feature("except") {
   try {
     $action
   }
   ...
}

... bunch of declarations ...

/* Disable the exception handler */
%feature("except");
%feature is a relatively new addition to SWIG that was not added until version 1.3.10. Its intended use is as a highly flexible customization mechanism that can be used to annotate declarations with additional information for use by specific target language modules. For example, in the Python module, you might use %feature to rewrite shadow class code as follows:
%module example
%rename(bar_id) bar(int,double);

// Rewrite bar() to allow some nice overloading

%feature("shadow") Foo::bar(int) %{
def bar(*args):
    if len(args) == 3:
         return apply(examplec.Foo_bar_id,args)
    return apply(examplec.Foo_bar,args)
%}
    
class Foo {
public:
    int bar(int x);
    int bar(int x, double y);
}
As of this writing, %feature is still experimental. Further details of its use will be described in the documentation for specific language modules.


SWIG 1.3 - Last Modified : June 1, 2003
cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/ch11.1.png0000644000175000000620000000467412561312226021133 0ustar stevestaff‰PNG  IHDR»bþñPLTEÿÿÿÌffîîîff™ÿÿfÿ™™ÿ3™ÌÿfÌ™™Ì3ÌÌfÿÿf™ff™3™ÿ33fÌ33ÌÝÝÝ3ÿ333ÿ™fÿ3fÌÿ3Ì™fÌ3™™ÿÿfÿÌf™3ff3™Ì33Ì3™»»»f33f™ÿ™3ÿ33ÌÿÌ™3Ì3f™ÿÌfÿ™f™f33™™3ÿ™ÿ3fDDDUÿÿ3ÿ™ÿ3ÌÌÿÌ™Ì33™ÿ™fÿfffÿf3™f3Ì™Ì33"""Ì™ÌÿÌÿÿfÿÿÌÌÌ™ÌfÿÌ3™ÿffÿ3ffÌ3ÿÿ3™33™™™3fÌfÿfÿfÌ33™f3fÌfÌ™3f3ÿf™™™3Ì3™3fÿ3Ìf3ÿˆˆˆ33ÿÿÌÌÿf™ÿ™ÌÌf3Ìÿ™ÿ3™Ìf™fÿÿ™™ÿîf333f̪f3™f3ÿÿÌ™™ÌÌÌÌffU™f™"3Ìffff™Ì33Ì3fÿ™™3ÿÿ™ÿÿ33ÿ3™ÌÌ݈D™Ìff3ÌÌ»™ÿ™3ÿ3ÿ™™Ì™fÌÿÿÿ™f™™3̙̙»w"™Ìÿ3ÌÿÌf™ªfÿ33Ì3f3ÌfˆD™™™Ìf3ª3ÌÌfÌ™™fªªªˆf3Ìwwwf™ÌÌ3ÿw"ÌfÿÿÌÌ™fÌ™™™Ìff™ÿ3wÿÿÌ3Ý™3™3™fÌ™ÿîÌÿÌf™ÿÌÿÿffÌÌ33ÿffUÿf3ÿ»Ìÿ™™33f3™fÿfÌfÌ3ÿÌf™33™3fÌÿ™ÌÿÌfÌÌÿÿ3ÿ™ffÌ3ÿfUUU3Ì3™™ÿÿÌ3îÿf3fÌD™3™ÿÌ™ÿÿ™3ÿ™Ì™™fÌÌÿÌ™ffÿfÿÝÿÌf3ffÌ™fÌm|ÚwIDATxÚb`CÿÿECÿÿECÿÿECÿÿECÿÿECÿÿECÿÿ‚¢ÿÔt4œÆ¦æðÿÿ»¡wÿÿ‚›MU‡2ÐÏp›>Í…ÿÿ"Ùìÿ´Œ»ÿ4»ÿC!îHp$ÿÿ"Éìÿ4Ìwÿi›ïþ…|G¢#ÿÿ»¡wÿÿÂ" ƒþ3À0X\Iþ+þÿ¦KõN0î°1æ?A³‰ˆ;j:vµ4‘ŽÄÿÿÂÜHÀÌd@ÅëI‰;¬†£˜‹ÛlÂqGU§Ó®ùFœ#ñÿÿÂ.ÓNLNÜa5&FÀl¢òõœNÃ|G”#ñÿÿ¢8°ö¸¨wÿ‰)Õhêô;|Aÿÿ¢Fâe a¾c m¾cù§aÿÿ"döZÆÝšÆÝÿ¡wÿ)ˆ;ÿÿÂ]—B…Áцø„‘ˆ¤¶U0 ÿ+Åð›MT[…zN§a[…8Gâ ÿÿºcbÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿB£{bs¯ÿÿÍwC7ßÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿBçÂ6¡mBæa?³€ø¸#Ý ämK„âŽdÓQöDÑ!îÈp šr ÿÿÂàÂMÆ?Ø‹ø|Gªÿ‘Eˆµ$ÓÿÓ3ß‘¨b0ÿÿ¢<îÈ9Ol0ÅÃ;ÿÿÂŒ;䓬àÇ€`á‚\ w¤[AJÜQâºÄ©D?V &ÿÿÂwhG ýG:†µ !?‚¼¸#Òt|µ)mãŽ8þG;† fÿÿ""îpþEŸ#hÑm²LÇ2èwˆ+îÿÿÂwpcñ™ŒÒô#9î(°‚ˆ¸#ÙtzljD?Z &ÿÿ"7î(j«jþ ¥¦“w(GàÒ îÐ[˜qÿÿÂwhGëÁNRe@+)‰;’¬øORßœÓÉ©ï(‰;ÒBø?FBÿÿÂÚ7‡Ÿƒû~f1ì,\ÄsH: ˆÙ!$Å ”3Eˆê›“j:Ýûæ$:{Üÿÿºcbÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ»¡wÿÿ‚sGï.rwÿÿ»¡wÿÿECÿÿECÿÿECÿÿECÿÿECÿÿECÿÿ™<ŒGD7ÓªIEND®B`‚cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/maketoc.py0000755000175000000620000000075612561312226021527 0ustar stevestaff#!/usr/local/bin/python import sys import os chs = open("chapters").readlines() f = open("Contents.html","w") print >>f, """ SWIG Users Manual

SWIG Users Manual

""" f.close() num = 0 for c in chs: c = c.strip() print "Processing %s" % c if c: os.system("python makechap.py %s %d >> Contents.html" % (c,num)) num += 1 f = open("Contents.html","a") print >>f, """ """ cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/Windows.html0000644000175000000620000002421512561312226022043 0ustar stevestaff Getting started on Windows

2 Getting started on Windows

This chapter describes SWIG usage on Microsoft Windows. Installing SWIG and running the examples is covered as well as building the SWIG executable and runtime libraries. Usage within the Unix like environments MinGW and Cygwin is also detailed.

2.1 Installation on Windows

SWIG does not come with the usual Windows type installation program, however it is quite easy to get started. The main steps are:
  • Download the swigwin zip package from the SWIG website and unzip into a directory. This is all that needs downloading for the Windows platform.
  • Set environment variables as described in the SWIG Windows Examples section in order to run examples using Visual C++.

2.1.1 Windows Executable

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. If you want to build your own swig.exe have a look at Building swig.exe on Windows.

2.1.2 Runtime Libraries

The vast majority of users do not use the SWIG runtime libraries so feel free to ignore this section. The Advanced Topics chapter has further details on the runtime libraries.

The runtime libraries which can be built have a Visual C++ project file (.dsp) file in the top level Runtime directory. Before starting Visual C++, set the environment variables for your target language as described in the SWIG Windows Examples section. Next start Visual C++ and load the project file for your target language. Visual Studio will create a workspace file for you. Ensure the Release build is selected then do a Rebuild All from the Build menu; the required environment variables are displayed with their current values. If all goes well the runtime library dll will appear in the Runtime directory.

Whenever using the runtime library, link against the .lib file which also is generated into this directory. Ensure the dll is in the Windows path when executing your program requiring the dll.

Note that the runtime libraries can also be built on Cygwin and is automatically done as part of the general build process on Cygwin.

2.2 SWIG Windows Examples

Using Microsoft Visual C++ is the most common approach to compiling and linking SWIG's output. The Examples directory has a few Visual C++ project files (.dsp files). These were produced by Visual C++ 6, although they should also work in Visual C++ 5. Later versions of Visual Studio should also be able to open and convert these project files. The C# examples come with .NET 2003 solution (.sln) and project files instead of Visual C++ 6 project files. The project files have been set up to execute SWIG in a custom build rule for the SWIG interface (.i) file. Alternatively run the examples using Cygwin.

More information on each of the examples is available with the examples distributed with SWIG (Examples/index.html).

2.2.1 Instructions for using the Examples with Visual Studio

Ensure the SWIG executable is as supplied in the SWIG root directory in order for the examples to work. Most languages require some environment variables to be set before running Visual C++. Note that Visual C++ must be re-started to pick up any changes in environment variables. Open up an example .dsp file, Visual C++ will create a workspace for you (.dsw file). Ensure the Release build is selected then do a Rebuild All from the Build menu. The required environment variables are displayed with their current values.

The list of required environment variables for each module language is also listed below. They are usually set from the Control Panel and System properties, but this depends on which flavour of Windows you are running. If you don't want to use environment variables then change all occurences of the environment variables in the .dsp files with hard coded values. If you are interested in how the project files are set up there is explanatory information in some of the language module's documentation.

2.2.1.1 Python

PYTHON_INCLUDE : Set this to the directory that contains python.h
PYTHON_LIB : Set this to the python library including path for linking

Example using Python 2.1.1:
PYTHON_INCLUDE: d:\python21\include
PYTHON_LIB: d:\python21\libs\python21.lib

2.2.1.2 TCL

TCL_INCLUDE : Set this to the directory containing tcl.h
TCL_LIB : Set this to the TCL library including path for linking

Example using ActiveTcl 8.3.3.3
TCL_INCLUDE: d:\tcl\include
TCL_LIB: d:\tcl\lib\tcl83.lib

2.2.1.3 Perl

PERL5_INCLUDE : Set this to the directory containing perl.h
PERL5_LIB : Set this to the Perl library including path for linking

Example using nsPerl 5.004_04:

PERL5_INCLUDE: D:\nsPerl5.004_04\lib\CORE
PERL5_LIB: D:\nsPerl5.004_04\lib\CORE\perl.lib

2.2.1.4 Java

JAVA_INCLUDE : Set this to the directory containing jni.h
JAVA_BIN : Set this to the bin directory containing javac.exe

Example using JDK1.3:
JAVA_INCLUDE: d:\jdk1.3\include
JAVA_BIN: d:\jdk1.3\bin

2.2.1.5 Ruby

RUBY_INCLUDE : Set this to the directory containing ruby.h
RUBY_LIB : Set this to the ruby library including path for linking

Example using Ruby 1.6.4:
RUBY_INCLUDE: D:\ruby\lib\ruby\1.6\i586-mswin32
RUBY_LIB: D:\ruby\lib\mswin32-ruby16.lib

2.2.1.6 C#

The C# examples do not require any environment variables to be set as a C# project file is included. Just open up the .sln solution file in Visual Studio .NET 2003 and do a Rebuild All from the Build menu. The accompanying C# and C++ project file are automatically used by the solution file.

2.2.2 Instructions for using the Examples with other compilers

If you do not have access to Visual C++ you will have to set up project files / Makefiles for your chosen compiler. There is a section in each of the language modules detailing what needs setting up using Visual C++ which may be of some guidance. Alternatively you may want to use Cygwin as described in the following section.

2.3 SWIG on Cygwin and MinGW

SWIG can also be compiled and run using Cygwin or MinGW which provides a Unix like front end to Windows and comes free with gcc, an ANSI C/C++ compiler. However, this is not a recommended approach as the prebuilt executable is supplied.

2.3.1 Building swig.exe on Windows

If you want to replicate the build of swig.exe that comes with the download, follow the MinGW instructions below. This is not necessary to use the supplied swig.exe. This information is provided for those that want to modify the SWIG source code in a Windows environment. Normally this is not needed, so most people will want to ignore this section.

2.3.1.1 Building swig.exe using MinGW and MSYS

  • Install MinGW and MSYS from the MinGW site. This provides a Unix environment on Windows.
  • Follow the usual Unix instructions in the README file in the SWIG root directory to build swig.exe from the MinGW command prompt.

2.3.1.2 Building swig.exe using Cygwin

Note that SWIG can also be built using Cygwin. However, the SWIG will then require the Cygwin DLL when executing. Follow the Unix instructions in the README file in the SWIG root directory. The runtime libraries are also built as part of this build process. Note that the Cygwin environment will also allow one to regenerate the autotool generated files which are supplied with the release distribution. These files are generated using the autogen.sh script and will only need regenerating in circumstances such as changing the build system.

2.3.1.3 Building swig.exe alternatives

If you don't want to install Cygwin or MinGW, use a different compiler to build SWIG. For example, all the source code files can be added to a Visual C++ project file in order to build swig.exe from the Visual C++ IDE.

2.3.2 Running the examples on Windows using Cygwin

The examples and test-suite work as successfully on Cygwin as on any other Unix operating system. The modules which are known to work are Python, Tcl, Perl, Ruby, Java and C#. Follow the Unix instructions in the README file in the SWIG root directory to build the examples.

cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/ch2.1.png0000644000175000000620000000611212561312226021040 0ustar stevestaff‰PNG  IHDRy•Š,zBPLTEÿÿÿÿÿÌÿÿ™ÿÿfÿÿ3ÿÿÿÌÿÿÌÌÿÌ™ÿÌfÿÌ3ÿÌÿ™ÿÿ™Ìÿ™™ÿ™fÿ™3ÿ™ÿfÿÿfÌÿf™ÿffÿf3ÿfÿ3ÿÿ3Ìÿ3™ÿ3fÿ33ÿ3ÿÿÿÌÿ™ÿfÿ3ÿÌÿÿÌÿÌÌÿ™ÌÿfÌÿ3ÌÿÌÌÿÌÌÌÌÌ™ÌÌfÌÌ3ÌÌÌ™ÿÌ™ÌÌ™™Ì™fÌ™3Ì™ÌfÿÌfÌÌf™ÌffÌf3ÌfÌ3ÿÌ3ÌÌ3™Ì3fÌ33Ì3ÌÿÌÌÌ™ÌfÌ3Ì™ÿÿ™ÿÌ™ÿ™™ÿf™ÿ3™ÿ™Ìÿ™Ì̙̙™Ìf™Ì3™Ì™™ÿ™™Ì™™™™™f™™3™™™fÿ™fÌ™f™™ff™f3™f™3ÿ™3Ì™3™™3f™33™3™ÿ™Ì™™™f™3™fÿÿfÿÌfÿ™fÿffÿ3fÿfÌÿfÌÌfÌ™fÌffÌ3fÌf™ÿf™Ìf™™f™ff™3f™ffÿffÌff™fffff3fff3ÿf3Ìf3™f3ff33f3fÿfÌf™fff3f3ÿÿ3ÿÌ3ÿ™3ÿf3ÿ33ÿ3Ìÿ3ÌÌ3Ì™3Ìf3Ì33Ì3™ÿ3™Ì3™™3™f3™33™3fÿ3fÌ3f™3ff3f33f33ÿ33Ì33™33f333333ÿ3Ì3™3f333ÿÿÿÌÿ™ÿfÿ3ÿÌÿÌÌÌ™ÌfÌ3Ì™ÿ™Ì™™™f™3™fÿfÌf™fff3f3ÿ3Ì3™3f333ÿÌ™f3îÝ»ªˆwUD"îÝ»ªˆwUD"îÝ»ªˆwUD"îîîÝÝÝ»»»ªªªˆˆˆwwwUUUDDD"""û‚™ IDATxÚb`ÿÿEÿÿEÿÿEÿÿEÿÿEÿÿEÿÿEÿÿEÿÿEÿÿEÿÿ¢ú?l-C ÿÿ ù yÿÿ¢MÈ—¼KKÓÿÿuñ@ùÿÿuñ@ùÿÿuñ@ùÿÿœ.ÆbÂm­ÿÿhcoB  ý'd(š!´ yÿÿà+ýO±q´ #Ú†<ÿÿ ù yÿÿðÿZdüGŠŒÿ`iXyÂR¾ ˜Â€U!Ât œÎ¥mÈÿÿø‡…¢ó 8ëÿXøü‡q¡Lr¨ á¦"TÀÌÄí^Ú†<ÿÿð\ zh¨ÀÓ!ñÿ?Š2Æf#v…È:Ð%&äÿÿ å#’ï)yXÑ„;ä1 ËòÿÿèÒ†¼Ç^ÎÿÇÐð 3*– H9ÿÿm›ÿH¥6zÈ#'UÜåÎGTðÚ½äù?@!ÿÿ<5,ÒÈìx} oüG&ÐˈÿHU3.…(HVÚÿÿÄí`¼±ÖàTH„ ´ yÿÿš!ÿŸØÇ©ðÿ€‡<ÿÿÊ!OI™Jg ÿÿ¼!ÿåG¤%8amCÿÿï(ÿÿuñ@ùÿÿuñ@ùÿÿ¢‹GW}ÿÿ ù yÿÿEÿÿEÿÿEÿÿ5ÈÐô ÿÿb!χ †jÐÿÿ!?$ƒÿÿ!?ƒÿÿ ùÿÿ ùÿÿ¢U†TBÿÿ&É~†;ÿÿÉ~H&xÿÿEÎÐ wÿÿúÉ~¨†;ÿÿòÉ~È<ÿÿâé~‡;ÿÿÒÉ~H‡;ÿÿÊÉ~h<ÿÿºÉ~¨‡;ÿÿÊÉ~h‡;ÿÿúé~¨ºÿÿêÉ~è:ÿÿEÿÿEÿÿEÿÿ"²Ý6 ¨¾‰ÿÿ ù yÿÿÂò£ùžâb$ÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ!ÿ(†<ÿÿ¢cÈÿÇHÄÙ†]ÑWKÑÛËxÍÿÿ¢™3ÐWúüG¿Ç-Fˆ»ð?6 þc³¿f A­ ÿÿ¢UÈÿÇð ®›úˆ·Û•°°Kèþ :üÖ Àîÿÿ¢‘càׯÒ*ä‘-øfßlåÿ  yÿÿ¢cЊ™ÿh!tíüä«íÿ£ß\brq‚"îVl!b ŠAþƼúÿÿ¢yÈ£\SÌ€|ý<Ò¥ëws£\í™aHy„5ÿQ­ è0¦AÈÿÿ€G½Ž›óžn´ §I yxF[Í‹j Ž `K^ÿÿG\?$‡<þr×EáøCž&¥ ÿÿ¢q ‹+Í#©!+ä‘¥1›=T y R=^}ÿÿ¢m«ý:z”ì‹rÝ=©!d*—`ÈÿÇV–àKóä^}ÿÿ¢}O ™B½ÔQ #I )ÅÒ¶ÁbÁì=7,ÎA úÿ(u-^GP°ç¯Fÿÿòã6ƒÙ™xÝÿÿú!?TSÿÿc•C2äÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ ù yÿÿ§mÐòt\ÿÿ ù yÿÿEÿÿEÿÿEÿÿEÿÿEÿÿEÿÿEÿÿEÿÿEÿÿUŸ˜Å"AIEND®B`‚cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/Scripting.html0000644000175000000620000003354212561312226022356 0ustar stevestaff Scripting Languages

3 Scripting Languages

This chapter provides a brief overview of scripting language extension programming and the mechanisms by which scripting language interpreters access C and C++ code.

3.1 The two language view of the world

When a scripting language is used to control a C program, the resulting system tends to look as follows:

In this programming model, the scripting language interpreter is used for high level control whereas the underlying functionality of the C/C++ program is accessed through special scripting language "commands." If you have ever tried to write your own simple command interpreter, you might view the scripting language approach to be a highly advanced implementation of that. Likewise, If you have ever used a package such as MATLAB or IDL, it is a very similar model--the interpreter executes user commands and scripts. However, most of the underlying functionality is written in a low-level language like C or Fortran.

The two-language model of computing is extremely powerful because it exploits the strengths of each language. C/C++ can be used for maximal performance and complicated systems programming tasks. Scripting languages can be used for rapid prototyping, interactive debugging, scripting, and access to high-level data structures such associative arrays.

3.2 How does a scripting language talk to C?

Scripting languages are built around a parser that knows how to execute commands and scripts. Within this parser, there is a mechanism for executing commands and accessing variables. Normally, this is used to implement the builtin features of the language. However, by extending the interpreter, it is usually possible to add new commands and variables. To do this, most languages define a special API for adding new commands. Furthermore, a special foreign function interface defines how these new commands are supposed to hook into the interpreter.

Typically, when you add a new command to a scripting interpreter you need to do two things; first you need to write a special "wrapper" function that serves as the glue between the interpreter and the underlying C function. Then you need to give the interpreter information about the wrapper by providing details about the name of the function, arguments, and so forth. The next few sections illustrate the process.

3.2.1 Wrapper functions

Suppose you have an ordinary C function like this :

int fact(int n) {
	if (n <= 1) return 1;
	else return n*fact(n-1);
}

In order to access this function from a scripting language, it is necessary to write a special "wrapper" function that serves as the glue between the scripting language and the underlying C function. A wrapper function must do three things :

  • Gather function arguments and make sure they are valid.
  • Call the C function.
  • Convert the return value into a form recognized by the scripting language.

As an example, the Tcl wrapper function for the fact() function above example might look like the following :

int wrap_fact(ClientData clientData, Tcl_Interp *interp,
		int argc, char *argv[]) {
	int result;
	int arg0;
	if (argc != 2) {
		interp->result = "wrong # args";
		return TCL_ERROR;
	}
	arg0 = atoi(argv[1]);
	result = fact(arg0);
	sprintf(interp->result,"%d", result);
	return TCL_OK;
}

Once you have created a wrapper function, the final step is to tell the scripting language about the new function. This is usually done in an initialization function called by the language when the module is loaded. For example, adding the above function to the Tcl interpreter requires code like the following :

int Wrap_Init(Tcl_Interp *interp) {
	Tcl_CreateCommand(interp, "fact", wrap_fact, (ClientData) NULL,
				(Tcl_CmdDeleteProc *) NULL);
	return TCL_OK;
}

When executed, Tcl will now have a new command called "fact" that you can use like any other Tcl command.

Although the process of adding a new function to Tcl has been illustrated, the procedure is almost identical for Perl and Python. Both require special wrappers to be written and both need additional initialization code. Only the specific details are different.

3.2.2 Variable linking

Variable linking refers to the problem of mapping a C/C++ global variable to a variable in the scripting language interpeter. For example, suppose you had the following variable:

double Foo = 3.5;

It might be nice to access it from a script as follows (shown for Perl):

$a = $Foo * 2.3;   # Evaluation
$Foo = $a + 2.0;   # Assignment

To provide such access, variables are commonly manipulated using a pair of get/set functions. For example, whenever the value of a variable is read, a "get" function is invoked. Similarly, whenever the value of a variable is changed, a "set" function is called.

In many languages, calls to the get/set functions can be attached to evaluation and assignment operators. Therefore, evaluating a variable such as $Foo might implicitly call the get function. Similarly, typing $Foo = 4 would call the underlying set function to change the value.

3.2.3 Constants

In many cases, a C program or library may define a large collection of constants. For example:
#define RED   0xff0000
#define BLUE  0x0000ff
#define GREEN 0x00ff00
To make constants available, their values can be stored in scripting language variables such as $RED, $BLUE, and $GREEN. Virtually all scripting languages provide C functions for creating variables so installing constants is usually a trivial exercise.

3.2.4 Structures and classes

Although scripting languages have no trouble accessing simple functions and variables, accessing C/C++ structures and classes present a different problem. This is because the implementation of structures is largely related to the problem of data representation and layout. Furthermore, certain language features are difficult to map to an interpreter. For instance, what does C++ inheritance mean in a Perl interface?

The most straightforward technique for handling structures is to implement a collection of accessor functions that hide the underlying representation of a structure. For example,

struct Vector {
	Vector();
	~Vector();
	double x,y,z;
};

can be transformed into the following set of functions :

Vector *new_Vector();
void delete_Vector(Vector *v);
double Vector_x_get(Vector *v);
double Vector_y_get(Vector *v);
double Vector_y_get(Vector *v);
void Vector_x_set(Vector *v, double x);
void Vector_y_set(Vector *v, double y);
void Vector_z_set(Vector *v, double z);

Now, from an interpreter these function might be used as follows:

% set v [new_Vector]
% Vector_x_set $v 3.5
% Vector_y_get $v
% delete_Vector $v
% ...

Since accessor functions provide a mechanism for accessing the internals of an object, the interpreter does not need to know anything about the actual representation of a Vector.

3.2.5 Shadow classes

In certain cases, it is possible to use the low-level accessor functions to create something known as a "shadow" class. A "shadow class" is a special kind of object that gets created in a scripting language to access a C/C++ class (or struct) in a way that looks like the original structure (that is, it "shadows" the real C++ class). For example, if you have the following C definition :

class Vector {
public:
	Vector();
	~Vector();
	double x,y,z;
};

A shadow classing mechanism would allow you to access the structure in a more natural manner from the interpreter. For example, in Python, you might want to do this:

>>> v = Vector()
>>> v.x = 3
>>> v.y = 4
>>> v.z = -13
>>> ...
>>> del v

Similarly, in Perl5 you may want the interface to work like this:

$v = new Vector;
$v->{x} = 3;
$v->{y} = 4;
$v->{z} = -13;

Finally, in Tcl :

Vector v
v configure -x 3 -y 4 -z 13

When shadow classes are used, two objects are at really work--one in the scripting language, and an underlying C/C++ object. Operations affect both objects equally and for all practical purposes, it appears as if you are simply manipulating a C/C++ object.

3.3 Building scripting language extensions

The final step in using a scripting language with your C/C++ application is adding your extensions to the scripting language itself. There are two primary approaches for doing this. The preferred technique is to build a dynamically loadable extension in the form a shared library. Alternatively, you can recompile the scripting language interpreter with your extensions added to it.

3.3.1 Shared libraries and dynamic loading

To create a shared library or DLL, you often need to look at the manual pages for your compiler and linker. However, the procedure for a few common machines is shown below:

# Build a shared library for Solaris
gcc -c example.c example_wrap.c -I/usr/local/include
ld -G example.o example_wrap.o -o example.so

# Build a shared library for Linux
agcc -fpic -c example.c example_wrap.c -I/usr/local/include
gcc -shared example.o example_wrap.o -o example.so

# Build a shared library for Irix
gcc -c example.c example_wrap.c -I/usr/local/include
ld -shared example.o example_wrap.o -o example.so

To use your shared library, you simply use the corresponding command in the scripting language (load, import, use, etc...). This will import your module and allow you to start using it. For example:

% load ./example.so
% fact 4
24
%

When working with C++ codes, the process of building shared libraries may be more complicated--primarily due to the fact that C++ modules may need additional code in order to operate correctly. On many machines, you can build a shared C++ module by following the above procedures, but changing the link line to the following :

c++ -shared example.o example_wrap.o -o example.so

3.3.2 Linking with shared libraries

When building extensions as shared libraries, it is not uncommon for your extension to rely upon other shared libraries on your machine. In order for the extension to work, it needs to be able to find all of these libraries at run-time. Otherwise, you may get an error such as the following :

>>> import graph
Traceback (innermost last):
  File "<stdin>", line 1, in ?
  File "/home/sci/data1/beazley/graph/graph.py", line 2, in ?
    import graphc
ImportError:  1101:/home/sci/data1/beazley/bin/python: rld: Fatal Error: cannot 
successfully map soname 'libgraph.so' under any of the filenames /usr/lib/libgraph.so:/
lib/libgraph.so:/lib/cmplrs/cc/libgraph.so:/usr/lib/cmplrs/cc/libgraph.so:
>>>

What this error means is that the extension module created by SWIG depends upon a shared library called "libgraph.so" that the system was unable to locate. To fix this problem, there are a few approaches you can take.

  • Link your extension and explicitly tell the linker where the required libraries are located. Often times, this can be done with a special linker flag such as -R, -rpath, etc. This is not implemented in a standard manner so read the man pages for your linker to find out more about how to set the search path for shared libraries.
  • Put shared libraries in the same directory as the executable. This technique is sometimes required for correct operation on non-Unix platforms.
  • Set the UNIX environment variable LD_LIBRARY_PATH to the directory where shared libraries are located before running Python. Although this is an easy solution, it is not recommended. Consider setting the path using linker options instead.

3.3.3 Static linking

With static linking, you rebuild the scripting language interpreter with extensions. The process usually involves compiling a short main program that adds your customized commands to the language and starts the interpreter. You then link your program with a library to produce a new scripting language executable.

Although static linking is supported on all platforms, this is not the preferred technique for building scripting language extensions. In fact, there are very few practical reasons for doing this--consider using shared libraries instead.


SWIG 1.3 - Last Modified : July 16, 2001
cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/ch9.table.2.png0000644000175000000620000000735512561312226022150 0ustar stevestaff‰PNG  IHDR-jGõ‘½PLTEÿÿÿÌffîîîîÿÿfÿ™™ÿ3™ÌÿfÌ™™Ì3ÌÌfÿÿf™ff™3™ÿ33fÌ33ÌÝÝÝÝ333ÿ™fÿ3fÌÿ3Ì™fÌ3™™ÿÿfÿÌf™3ff3™Ì33Ì3™»»»»3f™ÿ™3ÿ33ÌÿÌ™3Ì3f™ÿÌfÿ™f™f33™™3ÿ™ÿ3fDDDªÿÿ3ÿ™ÿ3ÌÌÿÌ™Ì33™ÿ™fÿfffÿf3™f3Ì™Ì33"""ˆÿÌÿÿfÿÿÌÌÌ™ÌfÿÌ3™ÿffÿ3ffÌ3ÿÿ3™33™™™3wÿfÿfÌ33™f3fÌfÌ™3f3ÿf™™™3Ì3™3fwf3ÿw33ÿÿÌÌÿf™ÿ™ÌÌf3Ìÿ™ÿ3™Ìf™fÿÿ™™ÿîf33ÝUV,ÿÌ™ÿÌÿfÿÿf3Ìfÿ™ÿ™Ì3™fÌ™3™™ÌÝUfffÌDÌÿÿffÿ3ªªªÌf™ÌÌ3Ìf3fffÌ™3f3™f3Ìÿff3"ÿÌfÿf333ÌÌ3Ìff™™Ìÿ™Ì™f™ff™™fÌ™D»DfÿÿÌ3f™ÌÿÿÌ™3ÌÌffÿ™™ÿ3ÿÌf™ÿ™f»"ªÌÌÌ3Ì3fÌÌÿÌÌÌÌf3Ì™™ÌÌ™™Ì™ffUUUfÌÿÿ3Ì™3ÿ3ÿÿÌÿÌÿffÿÌ™ÿÌf™™™f™™ÿ3™f3ÌÌfÌ3f3™™fˆ"ÿÿ™ÿ™ÿf3fÌfÌ™Ìf33ÿff™™™f™f™33™3ªfÌÿÿˆˆˆÿ™Ìÿ3ÿÌÿ™™3Ì3ÿÌf™Ì™™™33fÌ™3ÿˆîf™Ì3f33ÿ™3fÿÿ3ÌÿÿfÌÌ3ÿÌ3www33Ì™3ÿ3Ì{)î ¨IDATxÚb`£€XÿÿE£€xÿÿE£€xÿÿE£€xÿÿE£€xÿÿE£€xÿÿüè? ‹Ð@®=Ôuôÿaÿÿb É3yàrb ¢‡T¸ÕC#象ÿÿ"©²ÿ ÇJ%PeôJ-Ä$¦AÿÿM-´ÉæÃ³Xÿÿ:5úoÀÈÈ©&‚D!µM0t¡¦/$»› Èšþ#µL°»Œa2H²ÿ‘ÂIh† Rÿÿ©œ °ð‡'X$2ÀUÀ˘º ¤ØC*„P“² 4]0(bXÝ—@r‚Bò R’‚[88ÿÿ*5RlÿGκ ŒŸäÔ‚¤ 3µ0 D$ª]H4²£°¹©yŽn ª‹°¸m°ÿÿ2©…¢Ôòÿ?jÙ‚T^L- (5"ñþ'”Z°¹…PjaÔÿÿJ©©“KFÙ‚ÇØëB©MJåCµÔ2¨›Àÿÿ:©…kjAk¡à,[Pãæ?zMÄ€ÒhFmŸ Ò jM„ÙnÁ‘ZÐ[:(©Ñnaüíÿÿ\ô2µ«Á€ÚfEé91 +C뀠úÿ±ô¢þ£ôב5!÷Ìp¹uT‹‹Ñûnƒÿÿ‚e µFnFÉÿÿq‰e4µPÿÿ-ZFñÿÿB­jó²ÿÿE£€xÿÿE£€xÿÿE£€xÿÿE£€xÿÿE£€xÿÿE£€xÿÿBí]Ž‚Q€€ ÿÿB¤–Ñ CŬ7L}ÿÿM-£©…xÿÿM-£©…xÿÿM-£©…xÿÿM-£©…xÿÿM-£©…xÿÿM-£©…xÿÿM-´ [I¯Ã`R.?Ø5CÐ~1mnÿ:Ê¥¢ÿÿÂÑ0#ZðÆÁ S¤¼©åÿ0L-¨nÄŸZPêl©å?©©¹r$2` ÿÿÂZ°f\5Ñü½ÌÔòd¤–ÿHu–Ôò= 0`¯²0äð¥–ÿU>6¨"S ÿÿ¼œ! Ãøÿ§‡½ÒÄèjƒ&=’M¹í×s>`Þ( €Ž'qæFÊA„ûûwÊåí VO…=«0ÔÞÐ _TªÛq»Øh'i³~·mÿÿÂݳúO•ØÆÆR-¦j¡’ax𤑹ØlÿÿÂi)ÖäFòæ­ÿøê#ÿ¨RB…ÝÜ£–Y4H-¤•¶…ÿÿùâ©å?S ÿÿM-ƒ¿&ÂWS°S—¤’¢ÿÿM-ƒ>µ "ÿÿM-£©…xÿÿM-£©…xÿÿB‚Q€{?ÿÿ-[FËâ}ÿÿM-£©…xÿÿM-£©…xÿÿM-£©…xÿÿM-£©…xÿÿM-£©…xÿÿM-£©…xÿÿM-´ [’÷Ñ|—y3KMÿÿÂä±2†èÍB—Šruv3 xÚ§l?Õw ý§<•A4ÿÿÂÆ%jÙq›…Höuv3 tr¡l?Õw Q-µÿÿÂZðlÐ!~³ŠaÄl¢În¦Á—ZHÙODí]BX6"áØ²DÈGÿÿ™ZðmÐ!~³ê"c"¶Qg7Ó@'JöÑ`—Æòoœ[–øÿÿ"˜Z°¥¢7 !v"b.AǺ„Ÿ:»™]ja` ~?B-µv al-Á¹e‰€ÿÿ"/µ &|›…þ£ï†!°áƒ:»™{jÁ»Ÿ£H¦x—¡ÔBtMÿÿ¢(µ·Yè?^ Gj¡l7Ó I-äì'žZ(Ù%„»&"º) QÿÿÂÚƒ&°A‡¤ÍB h×ËáßDÝLƒ¦•KÞ~"䡪ìÂ܈„kËÿÿ"­ÛL£(ùO°N²ƒ$µÐß²nñüOd+ÿÿ"¶ÇNâî"6 aÝDén¦Á2:GwÈl"BDÿÿ,á;¼Àÿ,Zh˜ZÿÿM-ƒ1µÐk—ñš ÒÿÿM-ƒ³&œ>ÿÿM-£©…xÿÿM-£©…xÿÿBïÅŒ‚Q€{?ÿÿ-[FËâ}ÿÿM-£©…xÿÿM-£©…xÿÿM-£©…xÿÿM-£©…xÿÿM-£©…xÿÿM-£©…xÿÿM-´ [ØâL%hÛ^°ÞfApÂÿ*äÿÔKÑÕÿÿÂÆÅ¹Ð„´D¸.¦@ §a²ƒ‡ ‘WâNQ äoù/2‰N-Ä®ÿÿ"¨ï]BoúOTXƒDØ]øŸè4Oaj¡°&$6µÿÿÂ…ÿñÝ%DäF"ôsàQ·¡,7;ˆ¦4 å¥ÿ(W®»n |íåÔ½J(¢ÈK7l%úÒ"ÿÿÂYa¿KˆÈDÿ±j@ºòµ ú;ˆ¥–ÿ¨žD ´šˆØíDHñ‰Íl¤‚%Lɽ´ÂÿÿÂZplø`` bkzjAÙß‚¾P{8ì "¢&BÙóÀ–oIÞN„ºÑÝl¤f!j•Á@æ¥E6ÿÿ"1µ EI©-,þcižíDD¦Ô\‚'µÜN„™Z0ÃQa)šI»´Âÿÿ"&µüÇÑ>¥`#ѰÛA„#µ o Dj‰üG)cIÞN«‰Êd³qÕD d^ZaÿÿÂÚÊ%t—áDh{†P/B¹Dqxì ˜ØvaÙDÒv"Ô&?ö=Kƒ¡)‹üK‹ Lÿÿ"/°ÿS9Pñ˜9T6…P×-ÿém!ÊN ÿÿ"Ë>ªÝ:4|v “Ô‚sä "ÿÿœ¡=ÔÁzë§SjÿÿM-ƒ0µü°ŠçÎ"ˆ ÿÿM-ƒ²&¤>ÿÿM-£©…xÿÿM-£©…xÿÿBïÌŒ‚Q€{?ÿÿE£€xÿÿE£€xÿÿE£€xÿÿE£€xÿÿE£€xÿÿE£€xÿÿ+T¼‡úÆÍIEND®B`‚cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/ch11.2.png0000644000175000000620000000510012561312226021115 0ustar stevestaff‰PNG  IHDRênßå rPLTEÿÿÿÌffîîîff™ÿÿfÿ™™ÿ3™ÌÿfÌ™™Ì3ÌÌfÿÿf™ff™3™ÿ33fÌ33ÌÝÝÝ3ÿ333ÿ™fÿ3fÌÿ3Ì™fÌ3™™ÿÿfÿÌf™3ff3™Ì33Ì3™»»»f33f™ÿ™3ÿ33ÌÿÌ™3Ì3f™ÿÌfÿ™f™f33™™3ÿ™ÿ3fDDDUÿÿ3ÿ™ÿ3ÌÌÿÌ™Ì33™ÿ™fÿfffÿf3™f3Ì™Ì33"""Ì™ÌÿÌÿÿfÿÿÌÌÌ™ÌfÿÌ3™ÿffÿ3ffÌ3ÿÿ3™33™™™3fÌfÿfÿfÌ33™f3fÌfÌ™3f3ÿf™™™3Ì3™3fÿ3Ìf3ÿˆˆˆ33ÿÿÌÌÿf™ÿ™ÌÌf3Ìÿ™ÿ3™Ìf™fÿÿ™™ÿîf333f̪f3™f3ÿÿÌ™™ÌÌÌÌffU™f™"3Ìffff™Ì33Ì3fÿ™™3ÿÿ™ÿÿ33ÿ3™ÌÌ݈D™Ìff3ÌÌ»™ÿ™3ÿ3ÿ™™Ì™fÌÿÿÿ™f™™3̙̙»w"™Ìÿ3ÌÿÌf™ªfÿ33Ì3f3ÌfˆD™™™Ìf3ª3ÌÌfÌ™™fªªªˆf3Ìwwwf™ÌÌ3ÿw"ÌfÿÿÌÌ™fÌ™™™Ìff™ÿ3wÿÿÌ3Ý™3™3™fÌ™ÿîÌÿÌf™ÿÌÿÿffÌÌ33ÿffUÿf3ÿ»Ìÿ™™33f3™fÿfÌfÌ3ÿÌf™33™3fÌÿ™ÌÿÌfÌÌÿÿ3ÿ™ffÌ3ÿfUUU3Ì3™™ÿÿÌ3îÿf3fÌD™3™ÿÌ™ÿÿ™3ÿ™Ì™™fÌÌÿÌ™ffÿfÿÝÿÌf3ffÌ™fÌm|ÚûIDATxÚb`#ÿÿE#ÿÿE#ÿÿE#ÿÿE#ÿÿE#ÿÿE#ÿÿE#ÿÿE#ÿÿE#ÿÿE ÿ‡7€yÿÿ‘¾™žÿÿjç‡u‘cÿÿ‘¾™žÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿjBò( x¬­ùÿƒ9ônÿÿ¢’o‡ETÿÇ``jÇjÖЈjÿÿ¢–o‡E®†z-1—¨ÿÿ¢–o‡]TÿGp <˜0j†€Qƒ6Pÿÿ¢Ø·HÞúQ fþ‡E„ó/Ãɼqpÿÿ¢Ø·Pz§kJ¢ú?Ï# üQ ÿÿ¢–o†GTƒ|Î@ÐóÿÿŨÿÿ¢žo‡ITÿ'ÂóØ üQ ÿÿ¢’oÿÿgöQúÏ€ÙNüÍ2ÿÿ¢Ø·Hrâ_ kŽB‹)xù/Ë 4Z³lxÿÿ¢Ø· ¨j†ßhÙÏÿÿ‘¾™žÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿjy~°„(Âÿÿj2=ÿŸ ÿG¤#lÿÿ¢™oQâ¡CTãU0H¢ÿÿ¢o‡bTÿG_cÇð±’ÊDâ &31ôÞ¨ÿÿ¢¶oÿ#Ï|µ¨þwöþXš>¸0ªç1Êíÿƒ(ªÿÿ¢²oÿ£ú{à(å.ÔÃH$<òþã(¢ÿ£0STÿÿ¢o‡pT#/¸@¬"B,5Aõã?z¦`Ïÿÿ¢¶oÿœü½Àb@õ<þ|°åjÿÿ¢²o‡vŽ´–ym ÖèÄQW#þ™Éóÿÿ¢²o‘· Á¨†¯†ü_?‰B2 oyA.Qô£¯-$Q ÿÿ¢²o‘¶´ Ó~õ‚ÿS·á9ÿÿ¢‘oGZTÿÇÓƒ$ªÿÿ¢o‡ñhÙÐ݆ ÿÿ‘¾Å!OL à[í>('Žÿÿ"ÕCîØ’:[ä¥÷ÿh½ªÿƒ°§ ÿÿÌ r(E5ºØ Œjÿÿj´ÇhcùÄMÀ£úÿ ëj"<ÿÿj”ž&Ò) ÿÑôƨÿÿjôyd“Ø äø´Q ÿÿjìQMÒúˆñ`Šk„çÿÿj¬QMâÀÈÕÿÿj\s=¤L âÉ„çÿÿjÔ Ô‰ b'0f8cTÿÿjª Þ„çÿÿjêDõ @¸ÿÿê3ÿÿê3ÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿêãyÿÿjèé¡ÃÀ¼ ÿÿ‘¾™žÿÿêÿÿE#ÿÿE#ÿÿE#ÿÿE#ÿÿE#ÿÿÒèÎè¤[IEND®B`‚cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/Preface.html0000644000175000000620000002034112561312226021752 0ustar stevestaff Preface

0 Preface

0.1 Introduction

SWIG is a software development tool for building scripting language interfaces to C and C++ programs. Originally developed in 1995, SWIG was first used by scientists in the Theoretical Physics Division at Los Alamos National Laboratory for building user interfaces to simulation codes running on the Connection Machine 5 supercomputer. In this environment, scientists needed to work with huge amounts of simulation data, complex hardware, and a constantly changing code base. The use of a scripting language interface provided a simple yet highly flexible foundation for solving these types of problems. SWIG simplifies development by largely automating the task of scripting language integration--allowing developers and users to focus on more important problems.

Although SWIG was originally developed for scientific applications, it 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.

0.2 Special Introduction for Version 1.3

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.

0.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 (Maybe in 2003). Don't let the development status of SWIG-1.3 scare you---it is much more stable (and capable) than SWIG-1.1p5.

0.4 SWIG resources

The official location of SWIG related material is

http://www.swig.org

This site contains the latest version of the software, users guide, and information regarding bugs, installation problems, and implementation tricks.

You can also subscribe to the SWIG mailing list by visiting the page

http://mailman.cs.uchicago.edu/listinfo/swig

The mailing list often discusses some of the more technical aspects of SWIG along with information about beta releases and future work.

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

http://www.swig.org/cvs.html

0.5 Prerequisites

This manual assumes that you know how to write C/C++ programs and that you have at least heard of scripting languages such as Tcl, Python, and Perl. A detailed knowledge of these scripting languages is not required although some familiarity won't hurt. No prior experience with building C extensions to these languages is required---after all, this is what SWIG does automatically. However, you should be reasonably familiar with the use of compilers, linkers, and makefiles since making scripting language extensions is somewhat more complicated than writing a normal C program.

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

0.6 Organization of this manual

The first few chapters of this manual describe SWIG in general and 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.

0.7 How to avoid reading the manual

If you hate reading manuals, glance at the "Introduction" which contains a few simple examples. These examples contain about 95% of everything you need to know to use SWIG. After that, simply use the language-specific chapters as a reference. The SWIG distribution also comes with a large directory of examples that illustrate different topics.

0.8 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 regretable, SWIG-1.3 is an active development project. The primary goal of this effort 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.

0.9 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, and Harco de Hilster.

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.

0.10 Bug reports

Although every attempt has been made to make SWIG bug-free, we are also trying to make feature improvements that may introduce bugs. To report a bug, either send mail to the SWIG developer list at swig-dev@cs.uchicago.edu or report a bug at http://www.swig.org. In your report, be as specific as possible, including (if applicable), error messages, tracebacks (if a core dump occurred), corresponding portions of the SWIG interface file used, and any important pieces of the SWIG generated wrapper code. We can only fix bugs if we know about them.


SWIG 1.3 - Last Modified : March 9, 2003
cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/Php.html0000644000175000000620000004410612561312226021141 0ustar stevestaff SWIG and PHP4

20 SWIG and PHP4

Caution: This chapter (and module!) is still under construction In this chapter, we discuss SWIG's support of PHP4. The PHP4 module is still under development so some of the features below may not work properly (or at all!.)

The PHP4 module has undergone a lot of changes recently affecting the way shadow classes are implemented so you should read this document even if you thought you were familiar with what it said. The major change is that shadow classes are implemented inside the php module in C++ instead of in the generated .php file in php.

20.1 Preliminaries

In order to use this module, you will need to have a copy of the PHP 4.0 (or above) include files to compile the SWIG generated files. You can find these files by running 'php-config --includes'. To test the modules you will need either the php binary or the Apache php module. If you want to build your extension into php directly (without having the overhead of loading it into each script), you will need the complete PHP source tree available.

20.2 Building PHP4 Extensions

To build a PHP4 extension, run swig using the -php4 option as follows :

swig -php4 example.i

This will produce 3 files by default. The first file, example_wrap.c contains all of the C code needed to build a PHP4 extension. The second file, php_example.h contains the header information needed to link the extension into PHP. The third file, example.php can be included by your php scripts. It will attempt to dynamically load your extension, and is a place-holder for extra code specified in the interface file. If you want to build your extension using the phpize utility, or if you want to build your module into PHP directly, you can specify the -phpfull command line argument to swig.

The -phpfull will generate three extra files. The first extra file, config.m4 contains the shell code needed to enable the extension as part of the PHP4 build process. The second extra file, Makefile.in contains the information needed to build the final Makefile after substitutions. The third and final extra file, CREDITS should contain the credits for the extension.

To finish building the extension, you have two choices. You can either build the extension as a seperate object file which will then have to be explicitly loaded by each script. Or you can rebuild the entire php source tree and build the extension into the php executable/library so it will be available in every script. The first choice is the default, however it can be changed by passing the '-phpfull' command line switch to select the second build method.

20.2.1 Building a loadable extension

To build a dynamic module for PHP, you have two options. You can use the phpize utility, or you can do it manually.

To build manually, use a compile string similar to this (different for each OS):

	cc -I.. $(PHPINC) -fpic -c example_wrap.c
	cc -shared example_wrap.o -o libexample.so

To build with phpize, after you have run swig you will need to run the 'phpize' command (installed as part of php) in the same directory. This re-creates the php build environment in that directory. It also creates a configure file which includes the shell code from the config.m4 that was generated by SWIG, this configure script will accept a command line argument to enable the extension to be run ( by default the command line argument is --enable-modulename, however you can edit the config.m4 file before running phpize to accept --with-modulename. You can also add extra tests in config.m4 to check that a correct library version is installed or correct header files are included, etc, but you must edit this file before running phpize. ) If you like SWIG can generate simple extra tests for libraries and header files for you.

	swig -php4 -phpfull -withlibs "xapian omquery" --withincs "om.h"

Will include in the config.m4 search for libxapian.a or libxapian.so and search for libomquery.a or libomquery.so as well as a search for om.h

If you depend on source files not generated by SWIG, before generated configure file, you may need to edit the Makefile.in file. This contains the names of the source files to compile (just the wrapper file by default) and any additional libraries needed to be linked in. If there are extra C files to compile, you will need to add them to the Makefile.in, or add the names of libraries if they are needed. In simple cases SWIG is pretty good at generating a complete Makefile.in and config.m4 which need no further editing.

You then run the configure script with the command line argument needed to enable the extension. Then run make, which builds the extension. The extension object file will be left in the modules sub directory, you can move it to wherever it is convenient to call from your php script.

To test the extension from a PHP script, you need to load it first. You do this by putting the line,

	dl("/path/to/modulename.so");	// Load the module
at the start of each PHP file. SWIG also generates a php module, which attempts to do the dl() call for you:
	include("example.php");
A more complicated method which builds the module directly into the php executable is described below.

20.2.2 Basic PHP4 interface

20.2.3 Functions

C functions are converted into PHP functions. Default/optional arguments are also allowed. An interface file like this :

%module default
int foo(int a);
double bar(double, double b = 3.0);
...

Will be accessed in PHP like this :

dl("default.so"); $a = foo(2);
$b = bar(3.5, -1.5);
$c = bar(3.5);		# Use default argument for 2nd parameter

20.2.4 Global Variables

Global variables are difficult for PHP to handle, unlike Perl, their is no 'magic' way to intercept modifications made to variables, so changes in a PHP variable will not be reflected in its C equivalent. To get around the problem, two extra function are generated, Swig_sync_c() and Swig_sync_php(). These functions are called at the start and end of every function call, ensuring changes made in PHP are updated in C ( and vice versa. ) Because this is handled for you, you can modify the variables in PHP as normal, e.g.

%module example;
...
double seki = 2;
...
int example_func(void);

is accessed as follow :

dl("example.so");
print $seki;
$seki = $seki * 2;	# Does not affect C variable, still equal to 2
example_func();		# Syncs C variable to PHP Variable, now both 4
SWIG supports global variables of all C datatypes including pointers and complex objects.

20.2.5 Pointers

Pointers to C/C++ objects no longer represented as character strings such as:_523d3f4_Circle_p, instead they are represented as PHP resources, rather like MySQL connection handles.

You can also explicitly create a NULL pointer as a string "NULL" or by passing a null or empty value.

20.2.6 Structures and C++ classes

For structures and classes, SWIG produces accessor fuction for each member function and data. For example :

%module vector

class Vector {
public:
	double x,y,z;
	Vector();
	~Vector();
	double magnitude();
};

This gets turned into the following collection of PHP functions :

Vector_x_set($obj);
Vector_x_get($obj);
Vector_y_set($obj);
Vector_y_get($obj);
Vector_z_set($obj);
Vector_z_get($obj);
new_Vector();
delete_Vector($obj);
Vector_magnitude($obj);

To use the class, simply use these functions. However, SWIG also has a mechanism for creating shadow classes that hides these functions and uses an object oriented interface instead - see below

20.2.7 Constants

These work in much the same way as in C/C++, constants can be defined by using either the normal C pre-processor declarations, or the %constant SWIG directive. These will then be available from your PHP script as a PHP constant, (e.g. no dollar sign is needed to access them. ) For example, with a swig file like this,

%module example

#define PI 3.14159

%constant int E  = 2.71828

you can access from in your php script like this,

dl("libexample.so");

echo "PI = " . PI . "\n";

echo "E = " . E . "\n";

There are two peculiarities with using constants in PHP4. The first is that if you try to use an undeclared constant, it will evaulate to a string set to the constants name. For example,

%module example

#define EASY_TO_MISPELL	0

accessed incorrectly in PHP,

dl("libexample.so");

if(EASY_TO_MISPEL) {
	....
} else {
	....
}

will issue a warning about the undeclared constant, but will then evalute it and turn it into a string ('EASY_TO_MISPEL'), which evaluates to true, rather than the value of the constant which would be false. This is a feature.

The second 'feature' is that although constants are case sensitive (by default), you cannot declare a constant twice with alternative cases. E.g.,

%module example

#define TEST	Hello
#define Test	World

accessed from PHP,

dl("libexample.so"); echo TEST, Test;

will output "Hello Test" rather than "Hello World". This is because internally, all constants are stored in a hash table by their lower case name, so 'TEST' and 'Test' will map to the same hash element ('Test'). But, because we declared them case sensitive, the Zend engine will test if the case matches with the case the constant was declared with first.

So, in the example above, the TEST constant was declared first, and will be stored under the hash element 'test'. The 'Test' constant will also map to the same hash element 'test', but will not overwrite it. When called from the script, the TEST constant will again be mapped to the hash element 'test' so the constant will be retrieved. The case will then be checked, and will match up, so the value ('Hello') will be returned. When 'Test' is evaulated, it will also map to the same hash element 'test'. The same constant will be retrieved, this time though the case check will fail as 'Test' != 'TEST'. So PHP will assume that Test is a undeclared constant, and as explained above, will return it as a string set to the constant name ('Test'). Hence the script above will print 'Hello Test'. If they were declared non-case sensitive, the output would be 'Hello Hello', as both point to the same value, without the case test taking place. ( Apologies, this paragraph needs rewritting to make some sense. )

20.2.8 Shadow classes

To avoid having to call the various accessor function to get at structures or class members, we can turn C structs and C++ classes into PHP classes that can be be used directly in PHP scripts as objects and object methods. This is done by writing additional PHP code that builds PHP classes on top of the low-level SWIG interface. These PHP classes "shadow" an underlying C/C++ class. To have SWIG create shadow classes, use the -shadow option :

% swig -php4 -shadow tbc.i

This will produce the same files as before except that the final module will declare internal PHP classes with the same names as the classes in your .i file. No longer are the shadow classes defined in the .php file, it will not contain significantly more support PHP code. For the most part, the code is the same except that we can now access members of complex data structures using -> instead of the low level access or functions like before. .... ( more examples on the way ) ....

20.2.9 Constructors and Destructers

Constructors are used in PHP as in C++, they are called when the object is created and any arguments are passed to them. However, function overloading is not allowed in PHP so only one constructor can be used. This creates a problem when copying objects, as we cannot avoid creating a whole new one when all we want is to make it point to the same value as the original. This is currently worked around by doing the following,
  • Create the new PHP object
  • Delete the PHP objects pointer to the C object
  • Set the PHP object's pointer to the same as the original PHP object's pointer.
This is rather convoluted and hopefully will be improved upon in a later release.

Because the internal wrapped objects are wrapped in PHP resources, PHP handles the cleaning up when there are no more references to the wrapped object. 'RegisterShutdownFunction' is no longer needed for this. I am not sure if PHP resources are all freed at the end of a script, or when they each go out of scope.

20.2.10 Static Member Variables

Class variables are not supported in PHP, however class functions are, using '::' syntax. Static member variables are therefore accessed using a class function with the same name, which returns the current value of the class variable. For example
%module example

class Ko {
	static int threats;
	...
};

would be accessed in PHP as,

dl("libexample.so");

echo "There has now been " . Ko::threats() . " threats\n";

To set the static member variable, pass the value as the argument to the class function, e.g.

Ko::threats(10);

echo "There has now been " . Ko::threats() . " threats\n";

20.2.11 PHP4 Pragmas

There are a few pragmas understood by the PHP4 module. The first, include adds a file to be included by the generated PHP module. The second, code adds literal code to the generated PHP module. The third, phpinfo inserts code to the function called when PHP's phpinfo() function is called.
	/* example.i */

	%pragma(php4) include="foo.php"
	%pragma(php4) code="
	  function foo($bar) {
		/* do something */
	  }
	"
	%pragma(php4) phpinfo="
	  zend_printf("An example of PHP support through SWIG\n");
	  php_info_print_table_start();
	  php_info_print_table_header(2, \"Directive\", \"Value\");
	  php_info_print_table_row(2, \"Example support\", \"enabled\");
	  php_info_print_table_end();
	"

	%include "example.h"

20.2.12 Building extensions into php

This method, selected with the -phpfull command line switch, involves rebuilding the entire php source tree. Whilst more complicated to build, it does mean that the extension is then available without having to load it in each script.

After running swig with the -phpfull switch, you will be left with a shockingly similiar set of files to the previous build process. However you will then need to move these files to a subdirectory within the php source tree, this subdirectory you will need to create under the ext directory, with the name of the extension ( e.g mkdir php-4.0.6/ext/modulename .)

After moving the files into this directory, you will need to run the 'buildall' script in the php source directory. This rebuilds the configure script and includes the extra command line arguments from the module you have added.

Before running the generated configure file, you may need to edit the Makefile.in. This contains the names of the source files to compile ( just the wrapper file by default) and any additional libraries needed to link in. If their are extra C files to compile you will need to add them to the Makefile, or add the names of libraries if they are needed. In most cases Makefile.in will be complete, especially if you make use of -withlibs and -withincs

	swig -php4 -phpfull -withlibs "xapian omquery" --withincs "om.h"

Will include in the config.m4 and Makefile.in search for libxapian.a or libxapian.so and search for libomquery.a or libomquery.so as well as a search for om.h

You then need to run the configure command and pass the necessary command line arguments to enable your module ( by default this is --enable-modulename, but this can be changed by editing the config.m4 file in the modules directory before running the buildall script. In addition, extra tests can be added to the config.m4 file to ensure the correct libraries and header files are installed.)

Once configure has completed, you can run make to build php. If this all compiles correctly, you should end up with a php executable/library which contains your new module. You can test it with a php script which does not have the 'dl' command as used above.

20.2.13 To be furthered...

cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/Python.html0000644000175000000620000032205612561312226021676 0ustar stevestaff SWIG and Python

21 SWIG and Python

Caution: This chapter is under repair!

This chapter describes SWIG's support of Python. SWIG is compatible with most recent Python versions including Python 2.2 as well as older versions dating back to Python 1.5.2. For the best results, consider using Python 2.0 or newer.

This chapter covers most SWIG features, but certain low-level details are covered in less depth than in earlier chapters. At the very least, make sure you read the "SWIG Basics" chapter.

21.1 Overview

To build Python extension modules, SWIG uses a layered approach in which parts of the extension module are defined in C and other parts are defined in Python. The C layer contains low-level wrappers whereas Python code is used to define high-level features.

This layered approach recognizes the fact that certain aspects of extension building are better accomplished in each language (instead of trying to do everything in C or C++). Furthermore, by generating code in both languages, you get a lot more flexibility since you can enhance the extension module with support code in either language.

In describing the Python interface, this chapter starts by covering the basics of configuration, compiling, and installing Python modules. Next, the Python interface to common C and C++ programming features is described. Advanced customization features such as typemaps are then described followed by a discussion of low-level implementation details.

21.2 Preliminaries

21.2.1 Running SWIG

Suppose that you defined a SWIG module such as the following:
%module example
%{
#include "header.h"
%}
int fact(int n);
To build a Python module, run SWIG using the -python option :

$ swig -python example.i
If building a C++ extension, add the -c++ option:

$ swig -c++ -python example.i

This creates two different files; a C/C++ source file example_wrap.c or example_wrap.cxx and a Python source file example.py. 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 to create an extension module. The Python source file contains high-level support code. This is the file that you will import to use the module.

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 name of the Python file is derived from the module name specified with %module. If the module name is example, then a file example.py is created.

21.2.2 Getting the right header files

In order to compile the C/C++ wrappers, the compiler needs the Python.h header file. This file is usually contained in a directory such as

/usr/local/include/python2.0
The exact location may vary on your machine, but the above location is typical. If you are not entirely sure where Python is installed, you can run Python to find out. For example:
$ python
Python 2.1.1 (#1, Jul 23 2001, 14:36:06)
[GCC egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)] on linux2
Type "copyright", "credits" or "license" for more information.
>>> import sys
>>> print sys.prefix
/usr/local
>>>           

21.2.3 Compiling a dynamic module

The preferred approach to building an extension module is to compile it into a shared object file or DLL. To do this, you need to compile your program using comands like this (shown for Linux):

$ swig -python example.i
$ gcc -c example.c
$ gcc -c example_wrap.c -I/usr/local/include/python2.0
$ gcc -shared example.o example_wrap.o -o _example.so
The exact commands for doing this vary from platform to platform. However, SWIG tries to guess the right options when it is installed. Therefore, you may want to start with one of the examples in the SWIG/Examples/python directory. If that doesn't work, you will need to read the man-pages for your compiler and linker to get the right set of options. You might also check the SWIG Wiki for additional information.

When linking the module, the name of the output file has to match the name of the module prefixed by an underscore. If the name of your module is "example", then the name of the corresponding object file should be "_example.so" or "_examplemodule.so". The name of the module is specified using the %module directive or the -module command line option.

Compatibility Note: In SWIG-1.3.13 and earlier releases, module names did not include the leading underscore. This is because modules were normally created as C-only extensions without the extra Python support file (instead, creating Python code was supported as an optional feature). This has been changed in SWIG-1.3.14 and is consistent with other Python extension modules. For example, the socket module actually consists of two files; socket.py and _socket.so. Many other built-in Python modules follow a similar convention.

21.2.4 Using distutils

21.2.5 Static linking

An alternative approach to dynamic linking is to rebuild the Python interpreter with your extension module added to it. In the past, this approach was sometimes necesssary due to limitations in dynamic loading support on certain machines. However, the situation has improved greatly over the last few years and you should not consider this approach unless there is really no other option.

The usual procedure for adding a new module to Python involves finding the Python source, adding an entry to the Modules/Setup file, and rebuilding the interpreter using the Python Makefile. However, newer Python versions have changed the build process. You may need to edit the 'setup.py' file in the Python distribution instead.

In earlier versions of SWIG, the embed.i library file could be used to rebuild the interpreter. For example:

%module example

extern int fact(int);
extern int mod(int, int);
extern double My_variable;

%include embed.i       // Include code for a static version of Python

The embed.i library file includes supporting code that contains everything needed to rebuild Python. To rebuild the interpreter, you simply do something like this:

$ swig -python example.i
$ gcc example.c example_wrap.c \
        -Xlinker -export-dynamic \
        -DHAVE_CONFIG_H -I/usr/local/include/python2.1 \
	-I/usr/local/lib/python2.1/config \
	-L/usr/local/lib/python2.1/config -lpython2.1 -lm -ldl \
	-o mypython

You will need to supply the same libraries that were used to build Python the first time. This may include system libraries such as -lsocket, -lnsl, and -lpthread. Assuming this actually works, the new version of Python should be identical to the default version except that your extension module will be a built-in part of the interpreter.

Comment: In practice, you should probably try to avoid static linking if possible. Some programmers may be inclined to use static linking in the interest of getting better performance. However, the performance gained by static linking tends to be rather minimal in most situations (and quite frankly not worth the extra hassle in the opinion of this author).

Compatibility note: The embed.i library file is deprecated and has not been maintained for several years. Even though it appears to "work" with Python 2.1, no future support is guaranteed. If using static linking, you might want to rely on a different approach (perhaps using distutils).

21.2.6 Using your module

To use your module, simply use the Python import statement. If all goes well, you will be able to this:

$ python
>>> import example
>>> example.fact(4)
24
>>>
A common error received by first-time users is the following:
>>> import example
Traceback (most recent call last):
  File "", line 1, in ?
  File "example.py", line 2, in ?
    import _example
ImportError: No module named _example
If you get this message, it means that you either forgot to compile the wrapper code into an extension module or you didn't give the extension module the right name. Make sure that you compiled the wrappers into a module called _example.so. And don't forget the leading underscore (_).

Another possible error is the following:

>>> import example
Traceback (most recent call last):
  File "", line 1, in ?
ImportError: dynamic module does not define init function (init_example)
>>>                                                               
This error is almost always caused when a bad name is given to the shared object file. For example, if you created a file example.so instead of _example.so you would get this error. Alternatively, this error could arise if the name of the module is inconsistent with the module name supplied with the %module directive. Double-check the interface to make sure the module name and the shared object filename match. Another possible cause of this error is forgetting to link the SWIG-generated wrapper code with the rest of your application when creating the extension module.

Another common error is something similar to the following:

Traceback (most recent call last):
  File "example.py", line 3, in ?
    import example
ImportError: ./_example.so: undefined symbol: fact
This error usually indicates that you forgot to include some object files or libraries in the linking of the shared library file. Make sure you compile both the SWIG wrapper file and your original program into a shared library file. Make sure you pass all of the required libraries to the linker.

Sometimes unresolved symbols occur because a wrapper has been created for a function that doesn't actually exist in a library. This usually occurs when a header file includes a declaration for a function that was never actually implemented or it was removed from a library without updating the header file. To fix this, you can either edit the SWIG input file to remove the offending declaration or you can use the %ignore directive to ignore the declaration.

Finally, suppose that your extension module is linked with another library like this:

$ gcc -shared example.o example_wrap.o -L/home/beazley/projects/lib -lfoo \
      -o _example.so
If the foo library is compiled as a shared library, you might encounter the following problem when you try to use your module:
>>> import example
Traceback (most recent call last):
  File "", line 1, in ?
ImportError: libfoo.so: cannot open shared object file: No such file or directory
>>>                 
This error is generated because the dynamic linker can't locate the libfoo.so library. When shared libraries are loaded, the system normally only checks a few standard locations such as /usr/lib and /usr/local/lib. To fix this problem, there are several things you can do. First, you can recompile your extension module with extra path information. For example, on Linux you can do this:
$ gcc -shared example.o example_wrap.o -L/home/beazley/projects/lib -lfoo \
      -Xlinker -rpath /home/beazley/projects/lib  \
      -o _example.so
Alternatively, you can set the LD_LIBRARY_PATH environment variable to include the directory with your shared libraries. If setting LD_LIBRARY_PATH, be aware that setting this variable can introduce a noticeable performance impact on all other applications that you run. To set it only for Python, you might want to do this instead:
$ env LD_LIBRARY_PATH=/home/beazley/projects/lib python
Finally, you can use a command such as ldconfig (Linux) or crle (Solaris) to add additional search paths to the default system configuration (this requires root access and you will need to read the man pages).

21.2.7 Compilation of C++ extensions

Compilation of C++ extensions has traditionally been a tricky problem. Since the Python interpreter is written in C, you need to take steps to make sure C++ is properly initialized and that modules are compiled correctly.

On most machines, C++ extension modules should be linked using the C++ compiler. For example:

% swig -c++ -python example.i
% g++ -c example.cxx
% g++ -c example_wrap.cxx -I/usr/local/include/python2.0
% g++ -shared example.o example_wrap.o -o _example.so
In addition to this, you may need to include additional library files to make it work. For example, if you are using the Sun C++ compiler on Solaris, you often need to add an extra library -lCrun like this:

% swig -c++ -python example.i
% CC -c example.cxx
% CC -c example_wrap.cxx -I/usr/local/include/python2.0
% CC -G example.o example_wrap.o -L/opt/SUNWspro/lib -o _example.so -lCrun
Of course, the extra libraries to use are completely non-portable---you will probably need to do some experimentation.

Sometimes people have suggested that it is necessary to relink the Python interpreter using the C++ compiler to make C++ extension modules work. In the experience of this author, this has never actually appeared to be necessary. Relinking the interpreter with C++ really only includes the special run-time libraries described above---as long as you link your extension modules with these libraries, it should not be necessary to rebuild Python.

If you aren't entirely sure about the linking of a C++ extension, you might look at an existing C++ program. On many Unix machines, the ldd command will list library dependencies. This should give you some clues about what you might have to include when you link your extension module. For example:

$ ldd swig
        libstdc++-libc6.1-1.so.2 => /usr/lib/libstdc++-libc6.1-1.so.2 (0x40019000)
        libm.so.6 => /lib/libm.so.6 (0x4005b000)
        libc.so.6 => /lib/libc.so.6 (0x40077000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
$

As a final complication, a major weakness of C++ is that it does not define any sort of standard for binary linking of libraries. This means that C++ code compiled by different compilers will not link together properly as libraries nor is the memory layout of classes and data structures implemented in any kind of portable manner. In a monolithic C++ program, this problem may be unnoticed. However, in Python, it is possible for different extension modules to be compiled with different C++ compilers. As long as these modules are self-contained, this probably won't matter. However, if these modules start sharing data, you will need to take steps to avoid segmentation faults and other erratic program behavior. If working with lots of software components, you might want to investigate using a more formal standard such as COM.

21.2.8 Compiling for 64-bit platforms

On platforms that support 64-bit applications (Solaris, Irix, etc.), special care is required when building extension modules. On these machines, 64-bit applications are compiled and linked using a different set of compiler/linker options. In addition, it is not generally possible to mix 32-bit and 64-bit code together in the same application.

To utilize 64-bits, the Python executable will need to be recompiled as a 64-bit application. In addition, all libraries, wrapper code, and every other part of your application will need to be compiled for 64-bits. If you plan to use other third-party extension modules, they will also have to be recompiled as 64-bit extensions.

If you are wrapping commercial software for which you have no source code, you will be forced to use the same linking standard as used by that software. This may prevent the use of 64-bit extensions. It may also introduce problems on platforms that support more than one linking standard (e.g., -o32 and -n32 on Irix).

21.2.9 Building Python Extensions under Windows

Building a SWIG extension to Python under Windows is roughly similar to the process used with Unix. You will need to create a DLL that can be loaded into the interpreter. This section briefly describes the use of SWIG with Microsoft Visual C++. As a starting point, many of SWIG's examples include project files. You might want to take a quick look at these in addition to reading this section.

In Developer Studio, SWIG should be invoked as a custom build option. This is usually done as follows:

  • Open up a new workspace and use the AppWizard to select a DLL project.
  • Add both the SWIG interface file (the .i file), any supporting C files, and the name of the wrapper file that will be created by SWIG (ie. example_wrap.c). Note : If using C++, choose a different suffix for the wrapper file such as example_wrap.cxx. Don't worry if the wrapper file doesn't exist yet--Developer Studio keeps a reference to it.
  • Select the SWIG interface file and go to the settings menu. Under settings, select the "Custom Build" option.
  • Enter "SWIG" in the description field.
  • Enter "swig -python -o $(ProjDir)\$(InputName)_wrap.c $(InputPath)" in the "Build command(s) field"
  • Enter "$(ProjDir)\$(InputName)_wrap.c" in the "Output files(s) field".
  • Next, select the settings for the entire project and go to "C++:Preprocessor". Add the include directories for your Python installation under "Additional include directories".
  • Define the symbol __WIN32__ under preprocessor options.
  • Finally, select the settings for the entire project and go to "Link Options". Add the Python library file to your link libraries. For example "python21.lib". Also, set the name of the output file to match the name of your Python module (ie. _example.dll).
  • Build your project.

If all went well, SWIG will be automatically invoked whenever you build your project. Any changes made to the interface file will result in SWIG being automatically executed to produce a new version of the wrapper file.

To run your new Python extension, simply run Python and use the import command as normal. For example :

MSDOS > python
>>> import example
>>> print example.fact(4)
24
>>>
If you get an ImportError exception when importing the module, you may have forgotten to include aditional library files when you built your module. If you get an access violation or some kind of general protection fault immediately upon import, you have a more serious problem. This is often caused by linking your extension module against the wrong set of Win32 debug or thread libraries. You will have to fiddle around with the build options of project to try and track this down.

Some users have reported success in building extension modules using Cygwin and other compilers. However, the problem of building usable DLLs with these compilers tends to be rather problematic. For the latest information, you may want to consult the SWIG Wiki.

21.3 A tour of basic C/C++ wrapping

By default, SWIG tries to build a very natural Python interface to your C/C++ code. Functions are wrapped as functions, classes are wrapped as classes, and so forth. This section briefly covers the essential aspects of this wrapping.

21.3.1 Modules

The SWIG %module directive specifies the name of the Python module. If you specify `%module example', then everything is wrapped into a Python 'example' module. Underneath the covers, this module consists of a Python source file example.py and a low-level extension module _example.so. When choosing a module name, make sure you don't use the same name as a built-in Python command or standard module name.

21.3.2 Functions

Global functions are wrapped as new Python built-in functions. For example,

%module example
int fact(int n);

creates a built-in function example.fact(n) that works exactly like you think it does:

>>> import example
>>> print example.fact(4)
24
>>>

21.3.3 Global variables

C/C++ global variables are fully supported by SWIG. However, the underlying mechanism is somewhat different than you might expect due to the way that Python assignment works. When you type the following in Python

a = 3.4

"a" becomes a name for an object containing the value 3.4. If you later type

b = a

then "a" and "b" are both names for the object containing the value 3.4. Thus, there is only one object containing 3.4 and "a" and "b" are both names that refer to it. This is quite different than C where a variable name refers to a memory location in which a value is stored (and assignment copies data into that location). Because of this, there is no direct way to map variable assignment in C to variable assignment in Python.

To provide access to C global variables, SWIG creates a special object called `cvar' that is added to each SWIG generated module. Global variables are then accessed as attributes of this object. For example, consider this interface

// SWIG interface file with global variables
%module example
...
extern int My_variable;
extern double density;
...

Now look at the Python interface:

>>> import example
>>> # Print out value of a C global variable
>>> print example.cvar.My_variable
4
>>> # Set the value of a C global variable
>>> example.cvar.density = 0.8442
>>> # Use in a math operation
>>> example.cvar.density = example.cvar.density*1.10

If you make an error in variable assignment, you will receive an error message. For example:

>>> example.cvar.density = "Hello"
Traceback (most recent call last):
  File "", line 1, in ?
TypeError: C variable 'density (double )'
>>> 

If a variable is declared as const, it is wrapped as a read-only variable. Attempts to modify its value will result in an error.

To make ordinary variables read-only, you can use the %immutable directive. For example:

%immutable;
extern char *path;
%mutable;
The %immutable directive stays in effect until it is explicitly disabled using %mutable.

If you just want to make a specific variable immutable, supply a declaration name. For example:

%immutable path;
...
extern char *path;      // Read-only (due to %immutable)

If you would like to access variables using a name other than "cvar", it can be changed using the -globals option :

% swig -python -globals myvar example.i

Some care is in order when importing multiple SWIG modules. If you use the "from <file> import *" style of importing, you will get a name clash on the variable `cvar' and you will only be able to access global variables from the last module loaded. To prevent this, you might consider renaming cvar or making it private to the module by giving it a name that starts with a leading underscore. SWIG does not create cvar if there are no global variables in a module.

21.3.4 Constants and enums

C/C++ constants are installed as Python objects containing the appropriate value. To create a constant, use #define, enum, or the %constant directive. For example:
#define PI 3.14159
#define VERSION "1.0"

enum Beverage { ALE, LAGER, STOUT, PILSNER };

%constant int FOO = 42;
%constant const char *path = "/usr/local";
For enums, make sure that the definition of the enumeration actually appears in a header file or in the wrapper file somehow---if you just stick an enum in a SWIG interface without also telling the C compiler about it, the wrapper code won't compile.

Note: declarations declared as const are wrapped as read-only variables and will be accessed using the cvar object described in the previous section. They are not wrapped as constants. For further discussion about this, see the SWIG Basics chapter.

Constants are not guaranteed to remain constant in Python---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.

21.3.5 Pointers

C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with incomplete type information. Here is a rather simple interface:
%module example

FILE *fopen(const char *filename, const char *mode);
int fputs(const char *, FILE *);
int fclose(FILE *);
When wrapped, you will be able to use the functions in a natural way from Python. For example:
>>> import example
>>> f = example.fopen("junk","w")
>>> example.fputs("Hello World\n", f)
>>> example.fclose(f)
If this makes you uneasy, rest assured that there is no deep magic involved. Underneath the covers, pointers to C/C++ objects are simply represented as opaque values--normally an encoded character string like this:

>>> print f
_c0671108_p_FILE
>>>
This pointer value can be freely passed around to different C functions that expect to receive an object of type FILE *. The only thing you can't do is dereference the pointer from Python. Of course, that isn't much of a concern in this example.

As an alternative to strings, SWIG can encode pointers as a Python CObject type. CObjects are rarely discussed in most Python books or documentation. However, this is a special built-in type that can be used to hold raw C pointer values. Internally, a CObject is just a container that holds a raw void * along with some additional information such as a type-string.

If you want to use CObjects instead of strings, compile the SWIG wrapper code with the -DSWIG_COBJECT_TYPES option. For example:

% swig -python example.i
% gcc -c example.c
% gcc -c -DSWIG_COBJECT_TYPES example_wrap.c -I/usr/local/include/python2.0
% gcc -shared example.o example_wrap.o -o _example.so

The choice of whether or not to use strings or CObjects is mostly a matter of personal preference. There is no significant performance difference between using one type or the other (strings actually appear to be ever-so-slightly faster on the author's machine). Although CObjects feel more natural to some programmers, a disadvantage of this approach is that it makes debugging more difficult. For example, if you are using CObjects, you will get code that works like this:

>>> import example
>>> f = example.fopen("junk","w")
>>> f
<PyCObject object at 0x80c5e60>
>>> 
Notice how no clues regarding the actual type of f is shown. On the other hand, the string representation produces the following:
>>> f
'_c0671108_p_FILE'
>>>
For either pointer representation, the NULL pointer is represented by None.

As much as you might be inclined to modify a pointer value directly from Python, don't. The hexadecimal encoding is not necessarily the same as the logical memory address of the underlying object. Instead it is the raw byte encoding of the pointer value. The encoding will vary depending on the native byte-ordering of the platform (i.e., big-endian vs. little-endian). Similarly, don't try to manually cast a pointer to a new type by simply replacing the type-string. This may not work like you expect, it is particularly dangerous when casting C++ objects, and it won't work if you switch to a new pointer representation such as CObjects. If you need to cast a pointer or change its value, consider writing some helper functions instead. For example:

%inline %{
/* C-style cast */
Bar *FooToBar(Foo *f) {
   return (Bar *) f;
}

/* C++-style cast */
Foo *BarToFoo(Bar *b) {
   return dynamic_cast<Foo*>(b);
}

Foo *IncrFoo(Foo *f, int i) {
    return f+i;
}
%}
Also, if working with C++, you should always try to use the new C++ style casts. For example, in the above code, the C-style cast may return a bogus result whereas as the C++-style cast will return None if the conversion can't be performed.

21.3.6 Structures

If you wrap a C structure, it is wrapped by a Python class. This provides a very natural interface. For example,

struct Vector {
	double x,y,z;
};

is used as follows:

>>> v = example.Vector()
>>> v.x = 3.5
>>> v.y = 7.2
>>> print v.x, v.y, v.z
7.8 -4.5 0.0
>>> 

Similar access is provided for unions and the data members of C++ classes.

If you print out the value of v in the above example, you will see something like this:

>>> print v
<C Vector instance at _18e31408_p_Vector>
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 attribute. For example:
>>> print v.this
_18e31408_p_Vector
>>>
Further details about the Python proxy class are covered a little later.

const members of a structure are read-only. Data members can also be forced to be read-only using the %immutable directive. For example:

struct Foo {
   ...
   %immutable;
   int x;        /* Read-only members */
   char *name;
   %mutable;
   ...
};

When char * members of a structure are wrapped, the contents are assumed to be dynamically allocated using malloc or new (depending on whether or not SWIG is run with the -c++ option). When the structure member is set, the old contents will be released and a new value created. If this is not the behavior you want, you will have to use a typemap (described later).

If a structure contains arrays, access to those arrays is managed through pointers. For example, consider this:

struct Bar {
    int  x[16];
};
If accessed in Python, you will see behavior like this:
>>> b = example.Bar()
>>> print b.x
_801861a4_p_int
>>> 
This pointer can be passed around to functions that expect to receive an int * (just like C). You can also set the value of an array member using another pointer. For example:
>>> c = example.Bar()
>>> c.x = b.x             # Copy contents of b.x to c.x
For array assignment, SWIG copies the entire contents of the array starting with the data pointed to by b.x. In this example, 16 integers would be copied. Like C, SWIG makes no assumptions about bounds checking---if you pass a bad pointer, you may get a segmentation fault or access violation.

When a member of a structure is itself a structure, it is handled as a pointer. For example, suppose you have two structures like this:

struct Foo {
   int a;
};

struct Bar {
   Foo f;
};
Now, suppose that you access the f attribute of Bar like this:
>>> b = Bar()
>>> x = b.f
In this case, x is a pointer that points to the Foo that is inside b. This is the same value as generated by this C code:
Bar b;
Foo *x = &b->f;       /* Points inside b */
Because the pointer points inside the structure, you can modify the contents and everything works just like you would expect. For example:
>>> b = Bar()
>>> b.f.a = 3               # Modify attribute of structure member
>>> x = b.f                   
>>> x.a = 3                 # Modifies the same structure

21.3.7 C++ classes

C++ classes are wrapped by Python classes as well. For example, if you have this class,

class List {
public:
  List();
  ~List();
  int  search(char *item);
  void insert(char *item);
  void remove(char *item);
  char *get(int n);
  int  length;
};
you can use it in Python like this:
>>> l = example.List()
>>> l.insert("Ale")
>>> l.insert("Stout")
>>> l.insert("Lager")
>>> l.get(1)
'Stout'
>>> print l.length
3
>>>
Class data members are accessed in the same manner as C structures.

Static class members present a special problem for Python. Prior to Python-2.2, Python classes had no support for static methods and no version of Python supports static member variables in a manner that SWIG can utilize. Therefore, SWIG generates wrappers that try to work around some of these issues. To illustrate, suppose you have a class like this:

class Spam {
public:
   static void foo();
   static int bar;

};
In Python, the static member can be access in three different ways:
>>> example.Spam_foo()    # Spam::foo()
>>> s = example.Spam()
>>> s.foo()               # Spam::foo() via an instance
>>> example.Spam.foo()    # Spam::foo(). Python-2.2 only
The first two methods of access are supported in all versions of Python. The last technique is only available in Python-2.2 and later versions.

Static member variables are currently accessed as global variables. This means, they are accessed through cvar like this:

>>> print example.cvar.Spam_bar
7

21.3.8 C++ inheritance

SWIG is fully aware of issues related to C++ inheritance. Therefore, if you have classes like this
class Foo {
...
};

class Bar : public Foo {
...
};
those classes are wrapped into a hierarchy of Python classes that reflect the same inheritance structure. All of the usual Python utility functions work normally:
>>> b = Bar()
>>> instance(b,Foo)
1
>>> issubclass(Bar,Foo)
1
>>> issubclass(Foo,Bar)
0
Furthermore, if you have functions like this
void spam(Foo *f);
then the function spam() accepts Foo * or a pointer to any class derived from Foo.

It is safe to use multiple inheritance with SWIG.

21.3.9 Pointers, references, values, and arrays

In C++, there are many different ways a function might receive and manipulate objects. For example:
void spam1(Foo *x);      // Pass by pointer
void spam2(Foo &x);      // Pass by reference
void spam3(Foo x);       // Pass by value
void spam4(Foo x[]);     // Array of objects
In Python, there is no detailed distinction like this--specifically, there are only "objects". There are no pointers, references, arrays, and so forth. Because of this, SWIG unifies all of these types together in the wrapper code. For instance, if you actually had the above functions, it is perfectly legal to do this:
>>> f = Foo()           # Create a Foo
>>> spam1(f)            # Ok. Pointer
>>> spam2(f)            # Ok. Reference
>>> spam3(f)            # Ok. Value.
>>> spam4(f)            # Ok. Array (1 element)
Similar behavior occurs for return values. For example, if you had functions like this,
Foo *spam5();
Foo &spam6();
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 (Python will release this memory when the return value is garbage collected).

21.3.10 C++ overloaded functions

C++ overloaded functions, methods, and constructors are mostly supported by SWIG. For example, if you have two functions like this:
void foo(int);
void foo(char *c);
You can use them in Python in a straightforward manner:
>>> foo(3)           # foo(int)
>>> foo("Hello")     # foo(char *c)
Similarly, if you have a class like this,
class Foo {
public:
    Foo();
    Foo(const Foo &);
    ...
};
you can write Python code like this:
>>> f = Foo()          # Create a Foo
>>> g = Foo(f)         # Copy f
Overloading support is not quite as flexible as in C++. Sometimes there are methods that SWIG can't disambiguate. For example:
void spam(int);
void spam(short);
or
void foo(Bar *b);
void foo(Bar &b);
If declarations such as these appear, you will get a warning message like this:
example.i:12: Warning(509): Overloaded spam(short) is shadowed by spam(int) at example.i:11.
To fix this, you either need to ignore or rename one of the methods. For example:
%rename(spam_short) spam(short);
...
void spam(int);    
void spam(short);   // Accessed as spam_short
or
%ignore spam(short);
...
void spam(int);    
void spam(short);   // Ignored
SWIG resolves overloaded functions and methods using a disambiguation scheme that ranks and sorts declarations according to a set of type-precedence rules. The order in which declarations appear in the input does not matter except in situations where ambiguity arises--in this case, the first declaration takes precedence.

Please refer to the "SWIG and C++" chapter for more information about overloading.

21.3.11 C++ operators

Certain C++ overloaded operators can be handled automatically by SWIG. For example, consider a class like this:
class Complex {
private:
  double rpart, ipart;
public:
  Complex(double r = 0, double i = 0) : rpart(r), ipart(i) { }
  Complex(const Complex &c) : rpart(c.rpart), ipart(c.ipart) { }
  Complex &operator=(const Complex &c);
  Complex operator+(const Complex &c) const;
  Complex operator-(const Complex &c) const;
  Complex operator*(const Complex &c) const;
  Complex operator-() const;
  
  double re() const { return rpart; }
  double im() const { return ipart; }
};
When wrapped, it works like you expect:
>>> c = Complex(3,4)
>>> d = Complex(7,8)
>>> e = c + d
>>> e.re()
10.0
>>> e.im()
12.0
One restriction with operator overloading support is that SWIG is not able to fully handle operators that aren't defined as part of the class. For example, if you had code like this
class Complex {
...
friend Complex operator+(double, const Complex &c);
...
};
then SWIG doesn't know what to do with the friend function--in fact, it simply ignores it and issues a warning. You can still wrap the operator, but you may have to encapsulate it in a special function. For example:
%rename(Complex_add_dc) operator+(double, const Complex &);
...
Complex operator+(double, const Complex &c);
There are ways to make this operator appear as part of the class using the %extend directive. Keep reading.

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.

21.3.12 C++ namespaces

SWIG is aware of C++ namespaces, but 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,
%module example

namespace foo {
   int fact(int n);
   struct Vector {
       double x,y,z;
   };
};
it works in Python as follows:
>>> import example
>>> example.fact(3)
6
>>> v = example.Vector()
>>> v.x = 3.4
>>> print v.y
0.0
>>>
If your program has more than one namespace, name conflicts (if any) can be resolved using %rename For example:
%rename(Bar_spam) Bar::spam;

namespace Foo {
    int spam();
}

namespace Bar {
    int spam();
}
If you have more than one namespace and your want to keep their symbols separate, consider wrapping them as separate SWIG modules. For example, make the module name the same as the namespace and create extension modules for each namespace separately. If your program utilizes thousands of small deeply nested namespaces each with identical symbol names, well, then you get what you deserve.

21.3.13 C++ templates

C++ templates don't present a huge problem for SWIG. However, in order to create wrappers, you have to tell SWIG to create wrappers for a particular template instantiation. To do this, you use the %template directive. For example:
%module example
%{
#include "pair.h"
%}

template<class T1, class T2>
struct pair {
   typedef T1 first_type;
   typedef T2 second_type;
   T1 first;
   T2 second;
   pair();
   pair(const T1&, const T2&);
  ~pair();
};

%template(pairii) pair<int,int>;
In Python:
>>> import example
>>> p = example.pairii(3,4)
>>> p.first
3
>>> p.second
4
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.

21.3.14 C++ Smart Pointers

In certain C++ programs, it is common to use classes that have been wrapped by so-called "smart pointers." Generally, this involves the use of a template class that implements operator->() like this:
template<class T> class SmartPtr {
   ...
   T *operator->();
   ...
}
Then, if you have a class like this,
class Foo {
public:
     int x;
     int bar();
};
A smart pointer would be used in C++ as follows:
SmartPtr<Foo> p = CreateFoo();   // Created somehow (not shown)
...
p->x = 3;                        // Foo::x
int y = p->bar();                // Foo::bar
To wrap this in Python, simply tell SWIG about the SmartPtr class and the low-level Foo object. Make sure you instantiate SmartPtr using %template if necessary. For example:
%module example
...
%template(SmartPtrFoo) SmartPtr<Foo>;
...
Now, in Python, everything should just "work":
>>> p = example.CreateFoo()          # Create a smart-pointer somehow
>>> p.x = 3                          # Foo::x
>>> p.bar()                          # Foo::bar
If you ever need to access the underlying pointer returned by operator->() itself, simply use the __deref__() method. For example:
>>> f = p.__deref__()     # Returns underlying Foo *

21.4 Further details on the Python class interface

In the previous section, a high-level view of Python wrapping was presented. A key component of this wrapping is that structures and classes are wrapped by Python proxy classes. This provides a very natural Python interface and allows SWIG to support a number of advanced features such as operator overloading. However, a number of low-level details were omitted. This section provides a brief overview of how the proxy classes work.

21.4.1 Proxy classes

In the "SWIG basics" and "SWIG and C++" chapters, details of low-level structure and class wrapping are described. To summarize those chapters, if you have a class like this
class Foo {
public:
     int x;
     int spam(int);
     ...
then SWIG transforms it into a set of low-level procedural wrappers. For example:
Foo *new_Foo() {
    return new Foo();
}
void delete_Foo(Foo *f) {
    delete f;
}
int Foo_x_get(Foo *f) {
    return f->x;
}
void Foo_x_set(Foo *f, int value) {
    f->x = value;
}
int Foo_spam(Foo *f, int arg1) {
    return f->spam(arg1);
}
These wrappers can be found in the low-level extension module (e.g., _example).

Using these wrappers, SWIG generates a high-level Python proxy class like this (shown for Python 2.2):

import _example

class Foo(object):
     def __init__(self):
         self.this = _example.new_Foo()
         self.thisown = 1
     def __del__(self):
         if self.thisown:
               _example.delete_Foo(self.this)
     def spam(self,arg1):
         return _example.Foo_spam(self.this,arg1)
     x = property(_example.Foo_x_get, _example.Foo_x_set)
This class merely holds a pointer to the underlying C++ object (.this) and dispatches methods and member variable access to that object using the low-level accessor functions. From a user's point of view, it makes the class work normally:
>>> f = example.Foo()
>>> f.x = 3
>>> y = f.spam(5)
The fact that the class has been wrapped by a real Python class offers certain advantages. For instance, you can attach new Python methods to the class and you can even inherit from it (something not supported by Python built-in types until Python 2.2).

21.4.2 Memory management

Associated with proxy object, is an ownership flag .thisown The value of this flag determines who is responsible for deleting the underlying C++ object. If set to 1, the Python interpreter will destroy the C++ object when the proxy class is garbage collected. If set to 0 (or if the attribute is missing), then the destruction of the proxy class has no effect on the C++ object.

When an object is created by a constructor or returned by value, Python automatically takes ownership of the result. For example:

class Foo {
public:
    Foo();
    Foo bar();
};
In Python:
>>> f = Foo()
>>> f.thisown
1
>>> g = f.bar()
>>> g.thisown
1
On the other hand, when pointers are returned to Python, there is often no way to know where they came from. Therefore, the ownership is set to zero. For example:
class Foo {
public:
    ...
    Foo *spam();
    ...
};
>>> f = Foo()
>>> s = f.spam()
>>> print s.thisown
0
>>>
This behavior is especially important for classes that act as containers. For example, if a method returns a pointer to an object that is contained inside another object, you definitely don't want Python to assume ownership and destroy it!

Related to containers, ownership issues can arise whenever an object is assigned to a member or global variable. For example, consider this interface:

%module example

struct Foo {
    int  value;
    Foo  *next;
};

Foo *head = 0;
When wrapped in Python, careful observation will reveal that ownership changes whenever an object is assigned to a global variable. For example:
>>> f = example.Foo()
>>> f.thisown
1
>>> example.cvar.head = f           
>>> f.thisown
0
>>>
In this case, C is now holding a reference to the object---you probably don't want Python to destroy it. Similarly, this occurs for members. For example:
>>> f = example.Foo()
>>> g = example.Foo()
>>> f.thisown
1
>>> g.thisown
1
>>> f.next = g
>>> g.thisown
0
>>>

For the most part, memory management issues remain hidden. However, there are occasionally situations where you might have to manually change the ownership of an object. For instance, consider code like this:

class Node {
   Object *value;
public:
   void set_value(Object *v) { value = v; }
   ...
};
Now, consider the following Python code:
>>> v = Object()           # Create an object
>>> n = Node()             # Create a node
>>> n.set_value(v)         # Set value
>>> v.thisown
1
>>> del v
In this case, the object n is holding a reference to v internally. However, SWIG has no way to know that this has occurred. Therefore, Python still thinks that it has ownership of the object. Should the proxy object be destroyed, then the C++ destructor will be invoked and n will be holding a stale-pointer. If you're lucky, you will only get a segmentation fault.

To work around this, it is always possible to flip the ownership flag. For example,

>>> v.thisown = 0
It is also possible to deal with situations like this using typemaps--an advanced topic discussed later.

21.4.3 Python 2.2 and classic classes

SWIG makes every attempt to preserve backwards compatibility with older versions of Python to the extent that it is possible. However, 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.

To address differences between Python versions, SWIG currently emits dual-mode proxy class wrappers. In Python-2.2 and newer releases, these wrappers encapsulate C++ objects in new-style classes that take advantage of new features (static methods and properties). However, if these very same wrappers are imported into an older version of Python, old-style classes are used instead.

This dual-nature of the wrapper code means that you can create extension modules with SWIG and those modules will work with all versions of Python ranging from Python-1.4 to the very latest release. Moreover, the wrappers take advantage of Python-2.2 features when available.

For the most part, the interface presented to users is the same regardless of what version of Python is used. The only incompatibility lies in the handling of static member functions. In Python-2.2, they can be accessed via the 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).

21.5 Cross language polymorphism (experimental)

Proxy classes provide a more natural, object-oriented way to access extension classes. As described above, each proxy instance has an associated C++ instance, and method calls to the proxy are passed to the C++ instance transparently via C wrapper functions.

This arrangement is asymmetric in the sense that no corresponding mechanism exists to pass method calls down the inheritance chain from C++ to Python. In particular, if a C++ class has been extended in Python (by extending the proxy class), these extensions will not be visible from C++ code. Virtual method calls from C++ are thus not able access the lowest implementation in the inheritance chain.

Changes have been made to SWIG 1.3.18 to address this problem and make the relationship between C++ classes and proxy classes more symmetric. To achieve this goal, new classes called directors are introduced at the bottom of the C++ inheritance chain. The job of the directors is to route method calls correctly, either to C++ implementations higher in the inheritance chain or to Python implementations lower in the inheritance chain. The upshot is that C++ classes can be extended in Python and from C++ these extensions look exactly like native C++ classes. Neither C++ code nor Python code needs to know where a particular method is implemented: the combination of proxy classes, director classes, and C wrapper functions takes care of all the cross-language method routing transparently.

21.5.1 Enabling directors

The director feature is disabled by default. To use directors you must make two changes to the interface file. First, add the "directors" option to the %module directive, like this:
%module(directors="1") modulename
Without this option no director code will be generated. Second, you must use the %feature("director") directive to tell SWIG which classes and methods should get directors. The %feature directive can be applied globally, to specific classes, and to specific methods, like this:
 
// generate directors for all classes that have virtual methods
%feature("director");         

// genarate directors for all virtual methods in class Foo
%feature("director") Foo;      

// generate a director for just Foo::bar()
%feature("director") Foo::bar; 
You can use the %feature("nodirector") directive to turn off directors for specific classes or methods. So for example,
%feature("director") Foo;
%feature("nodirector") Foo::bar;
will generate directors for all virtual methods of class Foo except bar().

Directors can also be generated implicitly through inheritance. In the following, class Bar will get a director class that handles the methods one() and two() (but not three()):

%feature("director") Foo;
class Foo {
public:
    virtual void one();
    virtual void two();
};

class Bar: public Foo {
public:
    virtual void three();
};

21.5.2 Director classes

For each class that has directors enabled, SWIG generates a new class that derives from both the class in question and a special Swig::Director class. These new classes, referred to as director classes, can be loosely thought of as the C++ equivalent of the Python proxy classes. The director classes store a pointer to their underlying Python object and handle various issues related to object ownership. Indeed, this is quite similar to the "this" and "thisown" members of the Python proxy classes.

For simplicity let's ignore the Swig::Director class and refer to the original C++ class as the director's base class. By default, a director class extends all virtual methods in the inheritance chain of its base class (see the preceding section for how to modify this behavior). Thus all virtual method calls, whether they originate in C++ or in Python via proxy classes, eventually end up in at the implementation in the director class. The job of the director methods is to route these method calls to the appropriate place in the inheritance chain. By "appropriate place" we mean the method that would have been called if the C++ base class and its extensions in Python were seamlessly integrated. That seamless integration is exactly what the director classes provide, transparently skipping over all the messy extension API glue that binds the two languages together.

In reality, the "appropriate place" is one of only two possibilities: C++ or Python. Once this decision is made, the rest is fairly easy. If the correct implementation is in C++, then the lowest implementation of the method in the C++ inheritance chain is called explicitly. If the correct implementation is in Python, the Python API is used to call the method of the underlying Python object (after which the usual virtual method resolution in Python automatically finds the right implementation).

Now how does the director decide which language should handle the method call? The basic rule is to handle the method in Python, unless there's a good reason not to. The reason for this is simple: Python has the most "extended" implementation of the method. This assertion is guaranteed, since at a minimum the Python proxy class implements the method. If the method in question has been extended by a class derived from the proxy class, that extended implementation will execute exactly as it should. If not, the proxy class will route the method call into a C wrapper function, expecting that the method will be resolved in C++. The wrapper will call the virtual method of the C++ instance, and since the director extends this the call will end up right back in the director method. Now comes the "good reason not to" part. If the director method were to blindly call the Python method again, it would get stuck in an infinite loop. We avoid this situation by adding special code to the C wrapper function that tells the director method to not do this. The C wrapper function compares the pointer to the Python object that called the wrapper function to the pointer stored by the director. If these are the same, then the C wrapper function tells the director to resolve the method by calling up the C++ inheritance chain, preventing an infinite loop.

One more point needs to be made about the relationship between director classes and proxy classes. When a proxy class instance is created in Python, SWIG creates an instance of the original C++ class and assigns it to .this. This is exactly what happens without directors and is true even if directors are enabled for the particular class in question. When a class derived from a proxy class is created, however, SWIG then creates an instance of the corresponding C++ director class. The reason for this difference is that user-defined subclasses may override or extend methods of the original class, so the director class is needed to route calls to these methods correctly. For unmodified proxy classes, all methods are ultimately implemented in C++ so there is no need for the extra overhead involved with routing the calls through Python.

21.5.3 Ownership and object destruction

Memory management issues are slightly more complicated with directors than for proxy classes alone. Python instances hold a pointer to the associated C++ director object, and the director in turn holds a pointer back to the Python object. By default, proxy classes own their C++ director object and take care of deleting it when they are garbage collected.

This relationship can be reversed by calling the special __disown__() method of the proxy class. After calling this method, the .thisown flag is set to zero, and the director class increments the reference count of the Python object. When the director class is deleted it decrements the reference count. Assuming no outstanding references to the Python object remain, the Python object will be destroyed at the same time. This is a good thing, since directors and proxies refer to each other and so must be created and destroyed together. Destroying one without destroying the other will likely cause your program to segfault.

To help ensure that no references to the Python object remain after calling __disown__(), this method returns a weak reference to the Python object. Weak references are only available in Python versions 2.1 and higher, so for older versions you must exclicitly delete all references. Here is an example:

class Foo {
public:
    ...
};
class FooContainer {
public:
    void addFoo(Foo *);
    ...
};
>>> c = FooContainer()
>>> a = Foo().__disown()__
>>> c.addFoo(a)
>>> b = Foo()
>>> b = b.__disown()__
>>> c.addFoo(b)
>>> c.addFoo(Foo().__disown()__)
In this example, we are assuming that FooContainer will take care of deleting all the Foo pointers it contains at some point. Note that no hard references to the Foo objects remain in Python.

21.5.4 Exception unrolling

With directors routing method calls to Python, and proxies routing them to C++, the handling of exceptions is an important concern. By default, the directors ignore exceptions that occur during method calls that are resolved in Python. To handle such exceptions correctly, it is necessary to temporarily translate them into C++ exceptions. This can be done with the %feature("director:except") directive. The following code should suffice in most cases:
%feature("director:except") {
    if ($error != NULL) {
        throw Swig::DirectorMethodException();
    }
}
This code will check the Python error state after each method call from a director into Python, and throw a C++ exception if an error occured. This exception can be caught in C++ to implement an error handler. Currently no information about the Python error is stored in the Swig::DirectorMethodException object, but this will likely change in the future.

It may be the case that a method call originates in Python, travels up to C++ through a proxy class, and then back into Python via a director method. If an exception occurs in Python at this point, it would be nice for that exception to find its way back to the original caller. This can be done by combining a normal %exception directive with the director:except handler shown above. Here is an example of a suitable exception handler:

%exception {
    try { $action }
    catch (Swig::DirectorException &e) { SWIG_fail; }
}
The class Swig::DirectorException used in this example is actually a base class of Swig::DirectorMethodException, so it will trap this exception. Because the Python error state is still set when Swig::DirectorMethodException is thrown, Python will register the exception as soon as the C wrapper function returns.

21.5.5 Overhead and code bloat

Enabling directors for a class will generate a new director method for every virtual method in the class' inheritance chain. This alone can generate a lot of code bloat for large hierarchies. Method arguments that require complex conversions to and from target language types can result in large director methods. For this reason it is recommended that you selectively enable directors only for specific classes that are likely to be extended in Python and used in C++.

Compared to classes that do not use directors, the call routing in the director methods does add some overhead. In particular, at least one dynamic cast and one extra function call occur per method call from Python. Relative to the speed of Python execution this is probably completely negligible. For worst case routing, a method call that ultimately resolves in C++ may take one extra detour through Python in order to ensure that the method does not have an extended Python implementation. This could result in a noticible overhead in some cases.

Although directors make it natural to mix native C++ objects with Python objects (as director objects) via a common base class pointer, one should be aware of the obvious fact that method calls to Python objects will be much slower than calls to C++ objects. This situation can be optimized by selectively enabling director methods (using the %feature directive) for only those methods that are likely to be extended in Python.

21.5.6 Typemaps

Typemaps for input and output of most of the basic types from director classes have been written. These are roughly the reverse of the usual input and output typemaps used by the wrapper code. The typemap operation names are 'directorin', 'directorout', and 'directorargout'. The director code does not use any of the other kinds of typemaps yet. It is not clear at this point which kinds are appropriate and need to be supported.

Typemaps for STL classes are under construction. So far there is support for std::string, std::vector, and std::complex, although there's no guarantee these are fully functional yet.

21.5.7 Miscellaneous

21.6 Common customization features

The last section presented the absolute basics of C/C++ wrapping. If you do nothing but feed SWIG a header file, you will get an interface that mimics the behavior described. However, sometimes this isn't enough to produce a nice module. Certain types of functionality might be missing or the interface to certain functions might be awkward. This section describes some common SWIG features that are used to improve your the interface to an extension module.

21.6.1 C/C++ helper functions

Sometimes when you create a module, it is missing certain bits of functionality. For example, if you had a function like this
void set_transform(Image *im, double m[4][4]);
it would be accessible from Python, but there may be no easy way to call it. For example, you might get errors like this:
>>> a = [
...   [1,0,0,0],
...   [0,1,0,0],
...   [0,0,1,0],
...   [0,0,0,1]]
>>> set_transform(im,a)
Traceback (most recent call last):
  File "", line 1, in ?
TypeError: Type error. Expected _p_a_4__double
The problem here is that there is no easy way to construct and manipulate a suitable double [4][4] value to use. To fix this, you can write some extra C helper functions. Just use the %inline directive. For example:
%inline %{
/* Note: double[4][4] is equivalent to a pointer to an array double (*)[4] */
double (*new_mat44())[4] {
   return (double (*)[4]) malloc(16*sizeof(double));
}
void free_mat44(double (*x)[4]) {
   free(x);
}
void mat44_set(double x[4][4], int i, int j, double v) {
   x[i][j] = v;
}
double mat44_get(double x[4][4], int i, int j) {
   return x[i][j];
}
%}
From Python, you could then write code like this:
>>> a = new_mat44()
>>> mat44_set(a,0,0,1.0)
>>> mat44_set(a,1,1,1.0)
>>> mat44_set(a,2,2,1.0)
...
>>> set_transform(im,a)
>>>
Admittedly, this is not the most elegant looking approach. However, it works and it wasn't too hard to implement. It is possible to clean this up using Python code, typemaps, and other customization features as covered in later sections.

21.6.2 Adding additional Python code

If writing support code in C isn't enough, it is also possible to write code in Python. This code gets inserted in to the .py file created by SWIG. One use of Python code might be to supply a high-level interface to certain functions. For example:
void set_transform(Image *im, double x[4][4]);

...
/* Rewrite the high level interface to set_transform */
%pythoncode %{
def set_transform(im,x):
   a = new_mat44()
   for i in range(4):
       for j in range(4):
           mat44_set(a,i,j,x[i][j])
   _example.set_transform(im,a)
   free_mat44(a)
%}
In this example, set_transform() provides a high-level Python interface built on top of low-level helper functions. For example, this code now seems to work:
>>> a = [
...   [1,0,0,0],
...   [0,1,0,0],
...   [0,0,1,0],
...   [0,0,0,1]]
>>> set_transform(im,a)
>>>
Admittedly, this whole scheme for wrapping the two-dimension array argument is rather ad-hoc. Besides, shouldn't a Python list or a Numeric Python array just work normally? We'll get to those examples soon enough. For now, think of this example as an illustration of what can be done without having to rely on any of the more advanced customization features.

21.6.3 Class extension with %extend

One of the more interesting features of SWIG is that it can extend structures and classes with new methods--at least in the Python interface. Here is a simple example:
%module example
%{
#include "someheader.h"
%}

struct Vector {
   double x,y,z;
};

%extend Vector {
   char *__str__() {
       static char tmp[1024];
       sprintf(tmp,"Vector(%g,%g,%g)", self->x,self->y,self->z);
       return tmp;
   }
   Vector(double x, double y, double z) {
       Vector *v = (Vector *) malloc(sizeof(Vector));
       v->x = x;
       v->y = y;
       v->z = z;
       return v;
   }
};
Now, in Python
>>> v = example.Vector(2,3,4)
>>> print v
Vector(2,3,4)
>>>
%extend can be used for many more tasks than this. For example, if you wanted to overload a Python operator, you might do this:
%extend Vector {
    Vector __add__(Vector *other) {
         Vector v;
         v.x = self->x + other->x;
         v.y = self->y + other->y;
         v.z = self->z + other->z;
         return v;
    }
};
Use it like this:
>>> import example
>>> v = example.Vector(2,3,4)
>>> w = example.Vector(10,11,12)
>>> print v+w
Vector(12,14,16)
>>> 
%extend works with both C and C++ code. It does not modify the underlying object in any way---the extensions only show up in the Python interface.

21.6.4 Exception handling with %exception

If a C or C++ function throws an error, you may want to convert that error into a Python exception. To do this, you can use the %exception directive. %exception simply lets you rewrite part of the generated wrapper code to include an error check.

In C, a function often indicates an error by returning a status code (a negative number or a NULL pointer perhaps). Here is a simple example of how you might handle that:

%exception malloc {
  $action
  if (!result) {
     PyErr_SetString(PyExc_MemoryError,"Not enough memory");
     return NULL;
  }
}
void *malloc(size_t nbytes);
In Python,
>>> a = example.malloc(2000000000)
Traceback (most recent call last):
  File "", line 1, in ?
MemoryError: Not enough memory
>>>
If a library provides some kind of general error handling framework, you can also use that. For example:
%exception {
   $action
   if (err_occurred()) {
      PyErr_SetString(PyExc_RuntimeError, err_message());
      return NULL;
   }
}
No declaration name is given to %exception, it is applied to all wrapper functions.

C++ exceptions are also easy to handle. For example, you can write code like this:

%exception getitem {
   try {
      $action
   } catch (std::out_of_range &e) {
      PyErr_SetString(PyExc_IndexError, const_cast(e.what()));
      return NULL;
   }
}

class Base {
public:
     Foo *getitem(int index);      // Exception handled added
     ...
};

When raising a Python exception from C, use the PyErr_SetString() function as shown above. The following exception types can be used as the first argument.

PyExc_ArithmeticError
PyExc_AssertionError
PyExc_AttributeError
PyExc_EnvironmentError
PyExc_EOFError
PyExc_Exception
PyExc_FloatingPointError
PyExc_ImportError
PyExc_IndexError
PyExc_IOError
PyExc_KeyError
PyExc_KeyboardInterrupt
PyExc_LookupError
PyExc_MemoryError
PyExc_NameError
PyExc_NotImplementedError
PyExc_OSError
PyExc_OverflowError
PyExc_RuntimeError
PyExc_StandardError
PyExc_SyntaxError
PyExc_SystemError
PyExc_TypeError
PyExc_UnicodeError
PyExc_ValueError
PyExc_ZeroDivisionError
The language-independent exception.i library file can also be used to raise exceptions. See the SWIG Library chapter.

21.7 Tips and techniques

Although SWIG is largely automatic, there are certain types of wrapping problems that require additional user input. Examples include dealing with output parameters, strings, binary data, and arrays. This chapter discusses the common techniques for solving these problems.

21.7.1 Input and output parameters

A common problem in some C programs is handling parameters passed as simple pointers. For example:
void add(int x, int y, int *result) {
   *result = x + y;
}
or perhaps
int sub(int *x, int *y) {
   return *x-*y;
}
The easiest way to handle these situations is to use the typemaps.i file. For example:
%module example
%include "typemaps.i"

void add(int, int, int *OUTPUT);
int  sub(int *INPUT, int *INPUT);
In Python, this allows you to pass simple values. For example:
>>> a = add(3,4)
>>> print a
7
>>> b = sub(7,4)
>>> print b
3
>>>
Notice how the INPUT parameters allow integer values to be passed instead of pointers and how the OUTPUT parameter creates a return result.

If you don't want to use the names INPUT or OUTPUT, use the %apply directive. For example:

%module example
%include "typemaps.i"

%apply int *OUTPUT { int *result };
%apply int *INPUT  { int *x, int *y};

void add(int x, int y, int *result);
int  sub(int *x, int *y);

If a function mutates one of its parameters like this,

void negate(int *x) {
   *x = -(*x);
}
you can use INOUT like this:
%include "typemaps.i"
...
void negate(int *INOUT);
In Python, a mutated parameter shows up as a return value. For example:
>>> a = negate(3)
>>> print a
-3
>>>
Note: Since most primitive Python objects are immutable, it is not possible to perform in-place modification of a Python object passed as a parameter.

The most common use of these special typemap rules is to handle functions that return more than one value. For example, sometimes a function returns a result as well as a special error code:

/* send message, return number of bytes sent, along with success code */
int send_message(char *text, int len, int *success);
To wrap such a function, simply use the OUTPUT rule above. For example:
%module example
%include "typemaps.i"
%apply int *OUTPUT { int *success };
...
int send_message(char *text, int *success);
When used in Python, the function will return multiple values.
bytes, success = send_message("Hello World")
if not success:
    print "Whoa!"
else:
    print "Sent", bytes
Another common use of multiple return values are in query functions. For example:
void get_dimensions(Matrix *m, int *rows, int *columns);
To wrap this, you might use the following:
%module example
%include "typemaps.i"
%apply int *OUTPUT { int *rows, int *columns };
...
void get_dimensions(Matrix *m, int *rows, *columns);
Now, in Python:
>>> r,c = get_dimensions(m)
Be aware that the primary purpose of the typemaps.i file is to support primitive datatypes. Writing a function like this
void foo(Bar *OUTPUT);
may not have the intended effect since typemaps.i does not define an OUTPUT rule for Bar.

21.7.2 Simple pointers

If you must work with simple pointers such as int * or double * and you don't want to use typemaps.i, consider using the cpointer.i library file. For example:
%module example
%include "cpointer.i"

extern void add(int x, int y, int *result);
%pointer_functions(int, intp);
The %pointer_functions(type,name) macro generates five helper functions that can be used to create, destroy, copy, assign, and dereference a pointer. In this case, the functions are as follows:
int  *new_intp();
int  *copy_intp(int *x);
void  delete_intp(int *x);
void  intp_assign(int *x, int value);
int   intp_value(int *x);
In Python, you would use the functions like this:
>>> result = new_intp()
>>> print result
_108fea8_p_int
>>> add(3,4,result)
>>> print intp_value(result)
7
>>>
If you replace %pointer_functions() by %pointer_class(type,name), the interface is more class-like.
>>> result = intp()
>>> add(3,4,result)
>>> print result.value()
7
See the SWIG Library chapter for further details.

21.7.3 Unbounded C Arrays

Sometimes a C function expects an array to be passed as a pointer. For example,
int sumitems(int *first, int nitems) {
    int i, sum = 0;
    for (i = 0; i < nitems; i++) {
        sum += first[i];
    }
    return sum;
}
To wrap this into Python, you need to pass an array pointer as the first argument. A simple way to do this is to use the carrays.i library file. For example:
%include "carrays.i"
%array_class(int, intArray);
The %array_class(type, name) macro creates wrappers for an unbounded array object that can be passed around as a simple pointer like int * or double *. For instance, you will be able to do this in Python:
>>> a = intArray(10000000)         # Array of 10-million integers
>>> for i in xrange(10000):        # Set some values
...     a[i] = i
>>> sumitems(a,10000)
49995000
>>>
The array "object" created by %array_class() does not encapsulate pointers inside a special array object. In fact, there is no bounds checking or safety of any kind (just like in C). Because of this, the arrays created by this library are extremely low-level indeed. You can't iterate over them nor can you even query their length. In fact, any valid memory address can be accessed if you want (negative indices, indices beyond the end of the array, etc.). Needless to say, this approach is not going to suit all applications. On the other hand, this low-level approach is extremely efficient and well suited for applications in which you need to create buffers, package binary data, etc.

21.7.4 String handling

If a C function has an argument of char *, then a Python string can be passed as input. For example:
// C
void foo(char *s);

# Python
>>> foo("Hello")
When a Python string is passed as a parameter, the C function receives a pointer to the raw data contained in the string. Since Python strings are immutable, it is illegal for your program to change the value. In fact, doing so will probably crash the Python interpreter.

If your program modifies the input parameter or uses it to return data, consider using the cstring.i library file described in the SWIG Library chapter.

When functions return a char *, it is assumed to be a NULL-terminated string. Data is copied into a new Python string and returned.

If your program needs to work with binary data, you can use a typemap to expand a Python string into a pointer/length argument pair. As luck would have it, just such a typemap is already defined. Just do this:

%apply (char *STRING, int LENGTH) { (char *data, int size) };
...
int parity(char *data, int size, int initial);
Now in Python:
>>> parity("e\x09ffss\x00\x00\x01\nx", 0)
If you need to return binary data, you might use the cstring.i library file. The cdata.i library can also be used to extra binary data from arbitrary pointers.

21.7.5 Arrays

21.7.6 String arrays

21.7.7 STL wrappers

21.8 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 Python C API as well as the material in the "Typemaps" chapter.

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 primitive C-Python interface or if you want to elevate your guru status.

21.8.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 Python to C, you might define a typemap like this:

%module example

%typemap(in) int {
	$1 = (int) PyLong_AsLong($input);
	printf("Received an integer : %d\n",$1);
}
extern int fact(int n);

Typemaps are always associated with some specific aspect of code generation. In this case, the "in" method refers to the conversion of input arguments to C/C++. The datatype int is the datatype to which the typemap will be applied. The supplied C code is used to convert values. In this code a number of special variable prefaced by a $ are used. The $1 variable is placeholder for a local variable of type int. The $input variable is the input object of type PyObject *.

When this example is compiled into a Python module, it operates as follows:

>>> from example import *
>>> fact(6)
Received an integer : 6
720

In this example, the typemap is applied to all occurrences of the int datatype. You can refine this by supplying an optional parameter name. For example:

%module example

%typemap(in) int nonnegative {
	$1 = (int) PyLong_AsLong($input);
        if ($1 < 0) {
           PyErr_SetString(PyExc_ValueError,"Expected a nonnegative value.");
           return NULL;
        }
}
extern int fact(int nonnegative);
In this case, the typemap code is only attached to arguments that exactly match int nonnegative.

The application of a typemap to specific datatypes and argument names involves more than simple text-matching--typemaps are fully integrated into the SWIG C++ type-system. When you define a typemap for int, that typemap applies to int and qualified variations such as const int. In addition, the typemap system follows typedef declarations. For example:

%typemap(in) int n {
	$1 = (int) PyLong_AsLong($input);
	printf("n = %d\n",$1);
}
typedef int Integer;
extern int fact(Integer n);    // Above typemap is applied

Typemaps can also be defined for groups of consecutive arguments. For example:

%typemap(in) (char *str, int len) {
    $1 = PyString_AsString($input);
    $2 = PyString_Size($input);
};

int count(char c, char *str, int len);
When a multi-argument typemap is defined, the arguments are always handled as a single Python object. This allows the function to be used like this (notice how the length parameter is omitted):
>>> example.count('e','Hello World')
1
>>>

21.8.2 Python typemaps

The previous section illustrated an "in" typemap for converting Python objects to C. A variety of different typemap methods are defined by the Python module. For example, to convert a C integer back into a Python object, you might define an "out" typemap like this:
%typemap(out) int {
    $result = PyInt_FromLong((long) $1);
}
A detailed list of available methods can be found in the "Typemaps" chapter. However, the best source of typemap information (and examples) is probably the Python module itself. In fact, all of SWIG's default type handling is defined by typemaps. You can view these typemaps by looking at the python.swg file in the SWIG library. Just issue these commands:
$ swig -python -co python.swg
'python.swg' checked out from the SWIG library.
$ cat python.swg
Additional typemap examples can also be found in the typemaps.i file.

21.8.3 Typemap variables

Within typemap code, a number of special variables prefaced with a $ may appear. A full list of variables can be found in the "Typemaps" chapter. This is a list of the most common variables:

$1

A C local variable corresponding to the actual type specified in the %typemap directive. For input values, this is a C local variable that's supposed to hold an argument value. For output values, this is the raw result that's supposed to be returned to Python.

$input

A PyObject * holding a raw Python object with an argument or variable value.

$result

A PyObject * that holds the result to be returned to Python.

$1_name

The parameter name that was matched.

$1_type

The actual C datatype matched by the typemap.

$1_ltype

An assignable version of the datatype matched by the typemap (a type that can appear on the left-hand-side of a C assignment operation). This type is stripped of qualifiers and may be an altered version of $1_type. All arguments and local variables in wrapper functions are declared using this type so that their values can be properly assigned.
$symname
The Python name of the wrapper function being created.

21.8.4 Useful Python Functions

When you write a typemap, you usually have to work directly with Python objects. The following functions may prove to be useful.

Python Integer Functions

PyObject *PyInt_FromLong(long l);
long      PyInt_AsLong(PyObject *);
int       PyInt_Check(PyObject *);
Python Floating Point Functions
PyObject *PyFloat_FromDouble(double);
double    PyFloat_AsDouble(PyObject *);
int       PyFloat_Check(PyObject *);
Python String Functions
PyObject *PyString_FromString(char *);
PyObject *PyString_FromStringAndSize(char *, lint len);
int       PyString_Size(PyObject *);
char     *PyString_AsString(PyObject *);
int       PyString_Check(PyObject *);
Python List Functions
PyObject *PyList_New(int size);
int       PyList_Size(PyObject *list);
PyObject *PyList_GetItem(PyObject *list, int i);
int       PyList_SetItem(PyObject *list, int i, PyObject *item);
int       PyList_Insert(PyObject *list, int i, PyObject *item);
int       PyList_Append(PyObject *list, PyObject *item);
PyObject *PyList_GetSlice(PyObject *list, int i, int j);
int       PyList_SetSlice(PyObject *list, int i, int , PyObject *list2);
int       PyList_Sort(PyObject *list);
int       PyList_Reverse(PyObject *list);
PyObject *PyList_AsTuple(PyObject *list);
int       PyList_Check(PyObject *);
Python Tuple Functions
PyObject *PyTuple_New(int size);
int       PyTuple_Size(PyObject *);
PyObject *PyTuple_GetItem(PyObject *, int i);
int       PyTuple_SetItem(PyObject *, int i, pyObject *item);
PyObject *PyTuple_GetSlice(PyObject *t, int i, int j);
int       PyTuple_Check(PyObject *);
Python Dictionary Functions
write me
Python File Conversion Functions
PyObject *PyFile_FromFile(FILE *f);
FILE     *PyFile_AsFile(PyObject *);
int       PyFile_Check(PyObject *);
Abstract Object Interface
write me

21.9 Typemap Examples

This section includes a few examples of typemaps. For more examples, you might look at the files "python.swg" and "typemaps.i" in the SWIG library.

21.9.1 Converting Python list to a char **

A common problem in many C programs is the processing of command line arguments, which are usually passed in an array of NULL terminated strings. The following SWIG interface file allows a Python list object to be used as a char ** object.

%module argv

// This tells SWIG to treat char ** as a special case
%typemap(in) char ** {
  /* Check if is a list */
  if (PyList_Check($input)) {
    int size = PyList_Size($input);
    int i = 0;
    $1 = (char **) malloc((size+1)*sizeof(char *));
    for (i = 0; i < size; i++) {
      PyObject *o = PyList_GetItem($input,i);
      if (PyString_Check(o))
	$1[i] = PyString_AsString(PyList_GetItem($input,i));
      else {
	PyErr_SetString(PyExc_TypeError,"list must contain strings");
	free($1);
	return NULL;
      }
    }
    $1[i] = 0;
  } else {
    PyErr_SetString(PyExc_TypeError,"not a list");
    return NULL;
  }
}

// This cleans up the char ** array we malloc'd before the function call
%typemap(freearg) char ** {
  free((char *) $1);
}

// Now a test function
%inline %{
int print_args(char **argv) {
    int i = 0;
    while (argv[i]) {
         printf("argv[%d] = %s\n", i,argv[i]);
         i++;
    }
    return i;
}
%}

When this module is compiled, the wrapped C function now operates as follows :

>>> from argv import *
>>> print_args(["Dave","Mike","Mary","Jane","John"])
argv[0] = Dave
argv[1] = Mike
argv[2] = Mary
argv[3] = Jane
argv[4] = John
5
In the example, two different typemaps are used. The "in" typemap is used to receive an input argument and convert it to a C array. Since dynamic memory allocation is used to allocate memory for the array, the "freearg" typemap is used to later release this memory after the execution of the C function.

21.9.2 Expanding a Python object into multiple arguments

Suppose that you had a collection of C functions with arguments such as the following:
int foo(int argc, char **argv);
In the previous example, a typemap was written to pass a Python list as the char **argv. This allows the function to be used from Python as follows:
>>> foo(4, ["foo","bar","spam","1"])
Although this works, it's a little awkward to specify the argument count. To fix this, a multi-argument typemap can be defined. This is not very difficult--you only have to make slight modifications to the previous example:
%typemap(in) (int argc, char **argv) {
  /* Check if is a list */
  if (PyList_Check($input)) {
    int i;
    $1 = PyList_Size($input);
    $2 = (char **) malloc(($1+1)*sizeof(char *));
    for (i = 0; i < $1; i++) {
      PyObject *o = PyList_GetItem($input,i);
      if (PyString_Check(o))
	$2[i] = PyString_AsString(PyList_GetItem($input,i));
      else {
	PyErr_SetString(PyExc_TypeError,"list must contain strings");
	free($2);
	return NULL;
      }
    }
    $2[i] = 0;
  } else {
    PyErr_SetString(PyExc_TypeError,"not a list");
    return NULL;
  }
}

%typemap(freearg) (int argc, char **argv) {
  free((char *) $2);
}
When writing a multiple-argument typemap, each of the types is referenced by a variable such as $1 or $2. The typemap code simply fills in the appropriate values from the supplied Python object.

With the above typemap in place, you will find it no longer necessary to supply the argument count. This is automatically set by the typemap code. For example:

>>> foo(["foo","bar","spam","1"])

21.9.3 Using typemaps to return arguments

A common problem in some C programs is that values may be returned in arguments rather than in the return value of a function. For example :

/* Returns a status value and two values in out1 and out2 */
int spam(double a, double b, double *out1, double *out2) {
	... Do a bunch of stuff ...
	*out1 = result1;
	*out2 = result2;
	return status;
};

A typemap can be used to handle this case as follows :

%module outarg

// This tells SWIG to treat an double * argument with name 'OutValue' as
// an output value.  We'll append the value to the current result which 
// is guaranteed to be a List object by SWIG.

%typemap(argout) double *OutValue {
    PyObject *o, *o2, *o3;
    o = PyFloat_FromDouble(*$1);
    if ((!$result) || ($result == Py_None)) {
        $result = o;
    } else {
        if (!PyTuple_Check($result)) {
            PyObject *o2 = $result;
            $result = PyTuple_New(1);
            PyTuple_SetItem(target,0,o2);
        }
        o3 = PyTuple_New(1);
        PyTuple_SetItem(o3,0,o);
        o2 = $result;
        $result = PySequence_Concat(o2,o3);
        Py_DECREF(o2);
        Py_DECREF(o3);
    }
}

int spam(double a, double b, double *OutValue, double *OutValue);

The typemap works as follows. First, a check is made to see if any previous result exists. If so, it is turned into a tuple and the new output value is concatenated to it. Otherwise, the result is returned normally. For the sample function spam(), there are three output values--meaning that the function will return a 3-tuple of the results.

As written, the function must accept 4 arguments as input values, last two being pointers to doubles. If these arguments are only used to hold output values (and have no meaningful input value), an additional typemap can be written. For example:

%typemap(in,numinputs=0) double *OutValue(double temp) {
    $1 = &temp;
}

By specifying numinputs=0, the input value is ignored. However, since the argument still has to be set to some meaningful value before calling C, it is set to point to a local variable temp. When the function stores its output value, it will simply be placed in this local variable. As a result, the function can now be used as follows:

>>> a = spam(4,5)
>>> print a
(0, 2.45, 5.0)
>>> x,y,z = spam(4,5)
>>>

21.9.4 Mapping Python tuples into small arrays

In some applications, it is sometimes desirable to pass small arrays of numbers as arguments. For example :

extern void set_direction(double a[4]);       // Set direction vector

This too, can be handled used typemaps as follows :

// Grab a 4 element array as a Python 4-tuple
%typemap(in) double[4](double temp[4]) {   // temp[4] becomes a local variable
  int i;
  if (PyTuple_Check($input)) {
    if (!PyArg_ParseTuple($input,"dddd",temp,temp+1,temp+2,temp+3)) {
      PyErr_SetString(PyExc_TypeError,"tuple must have 4 elements");
      return NULL;
    }
    $1 = &temp[0];
  } else {
    PyErr_SetString(PyExc_TypeError,"expected a tuple.");
    return NULL;
  }
}

This allows our set_direction function to be called from Python as follows :

>>> set_direction((0.5,0.0,1.0,-0.25))

Since our mapping copies the contents of a Python tuple into a C array, such an approach would not be recommended for huge arrays, but for small structures, this approach works fine.

21.9.5 Mapping sequences to C arrays

Suppose that you wanted to generalize the previous example to handle C arrays of different sizes. To do this, you might write a typemap as follows:
// Map a Python sequence into any sized C double array
%typemap(in) double[ANY](double temp[$1_dim0]) {
  int i;
  if (!PySequence_Check($input)) {
      PyErr_SetString(PyExc_TypeError,"Expecting a sequence");
      return NULL;
  }
  if (PyObject_Length($input) != $1_dim0) {
      PyErr_SetString(PyExc_ValueError,"Expecting a sequence with $1_dim0 elements");
      return NULL;
  }
  for (i =0; i < $1_dim0; i++) {
      PyObject *o = PySequence_GetItem($input,i);
      if (!PyFloat_Check(o)) {
         PyErr_SetString(PyExc_ValueError,"Expecting a sequence of floats");
         return NULL;
      }
      temp[i] = PyFloat_AsDouble(o);
  }
  $1 = &temp[0];
}
In this case, the variable $1_dim0 is expanded to match the array dimensions actually used in the C code. This allows the typemap to be applied to types such as:
void foo(double x[10]);
void bar(double a[4], double b[8]);
Since the above typemap code gets inserted into every wrapper function where used, it might make sense to use a helper function instead. This will greatly reduce the amount of wrapper code. For example:
%{
static int convert_darray(PyObject *input, double *ptr, int size) {
  int i;
  if (!PySequence_Check(input)) {
      PyErr_SetString(PyExc_TypeError,"Expecting a sequence");
      return 0;
  }
  if (PyObject_Length(input) != size) {
      PyErr_SetString(PyExc_ValueError,"Sequence size mismatch");
      return 0;
  }
  for (i =0; i < size; i++) {
      PyObject *o = PySequence_GetItem(input,i);
      if (!PyFloat_Check(o)) {
         PyErr_SetString(PyExc_ValueError,"Expecting a sequence of floats");
         return 0;
      }
      ptr[i] = PyFloat_AsDouble(o);
  }
  return 1;
}
%}

%typemap(in) double [ANY](double temp[$1_dim0]) {
   if (!convert_darray($input,temp,$1_dim0))) {
      return NULL;
   }
   $1 = &temp[0];
}

21.9.6 Pointer handling

Occasionally, it might be necessary to convert pointer values that have been stored using the SWIG typed-pointer representation. Since there are several ways in which pointers can be represented, the following two functions are used to safely perform this conversion:

int SWIG_ConvertPtr(PyObject *obj, void **ptr, swig_type_info *ty, int flags)

Converts a Python object obj to a C pointer. The result of the conversion is placed into the pointer located at ptr. ty is a SWIG type descriptor structure. flags is used to handle error checking and other aspects of conversion. It is the bitwise-or of several flag values including SWIG_POINTER_EXCEPTION and SWIG_POINTER_DISOWN. The first flag makes the function raise an exception on type error. The second flag additionally steals ownership of an object. Returns 0 on success and -1 on error.

PyObject *Swig_NewPointerObj(void *ptr, swig_type_info *ty, int own)

Creates a new Python pointer object. ptr is the pointer to convert, ty is the SWIG type descriptor structure that describes the type, and own is a flag that indicates whether or not Python should take ownership of the pointer.
Both of these functions require the use of a special SWIG type-descriptor structure. This structure contains information about the mangled name of the datatype, type-equivalence information, as well as information about converting pointer values under C++ inheritance. For a type of Foo *, the type descriptor structure is usually accessed as follows:
Foo *f;
if (SWIG_ConvertPtr($input, (void **) &f, SWIGTYPE_p_Foo, SWIG_POINTER_EXCEPTION) == -1) return NULL;

PyObject *obj;
obj = SWIG_NewPointerObj(f, SWIGTYPE_p_Foo, 0);
In a typemap, the type descriptor should always be accessed using the special typemap variable $1_descriptor. For example:
%typemap(in) Foo * {
   if ((SWIG_ConvertPtr($input,(void **) &$1, $1_descriptor,SWIG_POINTER_EXCEPTION)) == -1) return NULL;
}

If necessary, the descriptor for any type can be obtained using the $descriptor() macro in a typemap. For example:

%typemap(in) Foo * {
   if ((SWIG_ConvertPtr($input,(void **) &$1, $descriptor(Foo *), SWIG_POINTER_EXCEPTION)) == -1) return NULL;
}
Although the pointer handling functions are primarily intended for manipulating low-level pointers, both functions are fully aware of Python shadow classes (described shortly). Specifically, SWIG_ConvertPtr() will retrieve a pointer from any object that has a this attribute. In addition, SWIG_NewPointerObj() can automatically generate a shadow class object (if applicable).
SWIG 1.3 - Last Modified : August 7, 2002
cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/Typemaps.html0000644000175000000620000025136312561312226022221 0ustar stevestaff Typemaps

8 Typemaps

Disclaimer: This chapter is under construction!

8.1 Introduction

Chances are, you are reading this chapter for one of two reasons; you either want to customize SWIG's behavior or you overheard someone mumbling some incomprehensible drivel about "typemaps" and you asked yourself "typemaps, what are those?" That said, let's start with a short disclaimer that "typemaps" are an advanced customization feature that provide direct access to SWIG's low-level code generator. Not only that, they are an integral part of the SWIG C++ type system (a non-trivial topic of its own). Typemaps are generally not a required part of using SWIG. Therefore, you might want to re-read the earlier chapters if you have found your way to this chapter with only a vaque idea of what SWIG already does by default.

8.1.1 Type conversion

One of the most important problems in wrapper code generation is the conversion 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 not a simple of matter of simply linking code together with the C linker. Instead, SWIG has to know something about how data is represented in each language and how it can be manipulated.

To illustrate, suppose you had a simple C function like this:

int factorial(int n);
To access this function from Python, a pair of Python API functions are used to convert integer values. For example:
long PyInt_AsLong(PyObject *obj);      /* Python --> C */
PyObject *PyInt_FromLong(long x);      /* C --> Python */
The first function is used to convert the input argument from a Python integer object to C long. The second function is used to convert a value from C back into a Python integer object.

Inside the wrapper function, you might see these functions used like this:

PyObject *wrap_factorial(PyObject *self, PyObject *args) {
    int       arg1;
    int       result;
    PyObject *obj1;
    PyObject *resultobj;

    if (!PyArg_ParseTuple("O:factorial", &obj1)) return NULL;
    arg1 = PyInt_AsLong(obj1);
    result = factorial(arg1);
    resultobj = PyInt_FromLong(result);
    return resultobj;
}

Every target language supported by SWIG has functions that work in a similar manner. For example, in Perl, the following functions are used:

IV SvIV(SV *sv);                     /* Perl --> C */
void sv_setiv(SV *sv, IV val);       /* C --> Perl */
In Tcl:
int Tcl_GetLongFromObj(Tcl_Interp *interp, Tcl_Obj *obj, long *value);
Tcl_Obj *Tcl_NewIntObj(long value);
The precise details are not so important. What is important is that all of the underlying type conversion is handled by collections of utility functions and short bits of C code like this---you simply have to read the extension documentation for your favorite language to know how it works (an exercise left to the reader).

8.1.2 Typemaps

Since type handling is so central to wrapper code generation, SWIG allows it to be completely defined (or redefined) by the user. To do this, a special %typemap directive is used. For example:
/* Convert from Python --> C */
%typemap(in) int {
    $1 = PyInt_AsLong($input);
}

/* Convert from C --> Python */
%typemap(out) int {
    $result = PyInt_FromLong($1);
}
At first glance, this code will look a little confusing. However, there is really not much to it. The first typemap (the "in" typemap) is used to convert a value from the target language to C. The second typemap (the "out" typemap) is used to convert in the other direction. The content of each typemap is a small fragment of C code that is inserted directly into the SWIG generated wrapper functions. Within this code, a number of special variables prefixed with a $ are expanded. These are really just placeholders for C variables that are generated in the course of creating the wrapper function. In this case, $input refers to an input object that needs to be converted to C and $result refers to an object that is going to be returned by a wrapper function. $1 refers to a C variable that has the same type as specified in the typemap declaration (an int in this example).

A short example might make this a little more clear. If you were wrapping a function like this:

int gcd(int x, int y);
A wrapper function would look approximately like this:
PyObject *wrap_gcd(PyObject *self, PyObject *args) {
   int arg1;
   int arg2;
   int result;
   PyObject *obj1;
   PyObject *obj2;
   PyObject *resultobj;

   if (!PyArg_ParseTuple("OO:gcd", &obj1, &obj2)) return NULL;

   /* "in" typemap, argument 1 */   
   {
      arg1 = PyInt_AsLong(obj1);
   }

   /* "in" typemap, argument 2 */   
   {
      arg2 = PyInt_AsLong(obj2);
   }

   result = gcd(arg1,arg2);

   /* "out" typemap, return value */
   {
      resultobj = PyInt_FromLong(result);
   }

   return resultobj;
}
In this code, you can see how the typemap code has been inserted into the function. You can also see how the special $ variables have been expanded to match certain variable names inside the wrapper function. This is really the whole idea behind typemaps--they simply let you insert arbitrary code into different parts of the generated wrapper functions. Because arbitrary code can be inserted, it possible to completely change the way in which values are converted.

8.1.3 Pattern matching

As the name implies, the purpose of a typemap is to "map" C datatypes to types in the target language. Once a typemap is defined for a C datatype, it is applied to all future occurrences of that type in the input file. For example:
/* Convert from Perl --> C */
%typemap(in) int {
   $1 = SvIV($input);
}

...
int factorial(int n);
int gcd(int x, int y);
int count(char *s, char *t, int max);
The matching of typemaps to C datatypes is more than a simple textual match. In fact, typemaps are fully built into the underlying type system. Therefore, typemaps are unaffected by typedef, namespaces, and other declarations that might hide the underlying type. For example, you could have code like this:
/* Convert from Ruby--> C */
%typemap(in) int {
   $1 = NUM2INT($input);
}
...
typedef int Integer;
namespace foo {
    typedef Integer Number;
};

int foo(int x);
int bar(Integer y);
int spam(foo::Number a, foo::Number b);
In this case, the typemap is still applied to the proper arguments even though typenames don't always match the text "int". This ability to track types is a critical part of SWIG--in fact, all of the target language modules work merely define a set of typemaps for the basic types. Yet, it is never necessary to write new typemaps for typenames introduced by typedef.

In addition to tracking typenames, typemaps may also be specialized to match against a specific argument name. For example, you could write a typemap like this:

%typemap(in) double nonnegative {
   $1 = PyFloat_AsDouble($input);
   if ($1 < 0) {
        PyErr_SetString(PyExc_ValueError,"argument must be nonnegative.");
        return NULL;
   }
}

...
double sin(double x);
double cos(double x);
double sqrt(double nonnegative);

typedef double Real;
double log(Real nonnegative);
...
For certain tasks such as input argument conversion, typemaps can be defined for sequences of consecutive arguments. For example:
%typemap(in) (char *str, int len) {
    $1 = PyString_AsString($input);   /* char *str */
    $2 = PyString_Size($input);       /* int len   */
}
...
int count(char *str, int len, char c);
In this case, a single input object is expanded into a pair of C arguments. This example also provides a hint to the unusual variable naming scheme involving $1, $2, and so forth.

8.1.4 Reusing typemaps

Typemaps are normally defined for specific type and argument name patterns. However, typemaps can also be copied and reused. One way to do this is to use assignment like this:
%typemap(in) Integer = int;   
%typemap(in) (char *buffer, int size) = (char *str, int len);
A more general form of copying is found in the %apply directive like this:
%typemap(in) int {
   /* Convert an integer argument */
   ...
}
%typemap(out) int {
   /* Return an integer value */
   ...
}

/* Apply all of the integer typemaps to size_t */
%apply int { size_t };    
%apply merely takes all of the typemaps that are defined for one type and applies them to other types. Note: you can include a comma separated set of types in the { ... } part of %apply.

It should be noted that it is not necessary to copy typemaps for types that are related by typedef. For example, if you have this,

typedef int size_t;
then SWIG already knows that the int typemaps apply. You don't have to do anything.

8.1.5 What can be done with typemaps?

The primary use of typemaps is for defining wrapper generation behavior at the level of individual C/C++ datatypes. There are currently six general categories of problems that typemaps address:

Argument handling

int foo(int x, double y, char *s);

  • Input argument conversion ("in" typemap).
  • Input argument type checking ("typecheck" typemap).
  • Output argument handling ("argout" typemap).
  • Input argument value checking ("check" typemap).
  • Input argument initialization ("arginit" typemap).
  • Default arguments ("default" typemap).
  • Input argument resource management ("freearg" typemap).

Return value handling

int foo(int x, double y, char *s);

  • Function return value conversion ("out" typemap).
  • Return value resource management ("ret" typemap).
  • Resource management for newly allocated objects ("newfree" typemap).

Exception handling

int foo(int x, double y, char *s) throw(MemoryError, IndexError);

  • Handling of C++ exception specifiers. ("throw" typemap).

Global variables

int foo;

  • Assignment of a global variable. ("varin" typemap).
  • Reading a global variable. ("varout" typemap).

Member variables

struct Foo {
    int x[20];
};

  • Assignment of data to a class/structure member. ("memberin" typemap).

Constant creation

#define FOO 3
%constant int BAR = 42;
enum { ALE, LAGER, STOUT };

  • Creation of constant values. ("consttab" or "constcode" typemap).
Details of each of these typemaps will be covered shortly. Also, certain language modules may define additional typemaps that expand upon this list. For example, the Java module defines a variety of typemaps for controlling additional aspects of the Java bindings. Consult language specific documentation for further details.

8.1.6 What can't be done with typemaps?

Typemaps can't be used to define properties that apply to C/C++ declarations as a whole. For example, suppose you had a declaration like this,
Foo *make_Foo();
and you wanted to tell SWIG that make_Foo() returned a newly allocated object (for the purposes of providing better memory management). Clearly, this property of make_Foo() 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 Customization Features chapter for more information about that.

Typemaps also can't be used to rearrange or transform the order of arguments. For example, if you had a function like this:

void foo(int, char *);
you can't use typemaps to interchange the arguments, allowing you to call the function like this:
foo("hello",3)          # Reversed arguments
If you want to change the calling conventions of a function, write a helper function instead. For example:
%rename(foo) wrap_foo;
%inline %{
void wrap_foo(char *s, int x) {
   foo(x,s);
}
%}

8.1.7 The rest of this chapter

The rest of this chapter provides detailed information for people who want to write new typemaps. This information is of particular importance to anyone who intends to write a new SWIG target language module. Power users can also use this information to write application specific type conversion rules.

Since typemaps are strongly tied to the underlying C++ type system, subsequent sections assume that you are reasonably familiar with the basic details of values, pointers, references, arrays, type qualifiers (e.g., const), structures, namespaces, templates, and memory management in C/C++. If not, you would be well-advised to consult a copy of "The C Programming Language" by Kernighan and Ritchie or "The C++ Programming Language" by Stroustrup before going any further.

8.2 Typemap specifications

This section describes the behavior of the %typemap directive itself.

8.2.1 Defining a typemap

New typemaps are defined using the %typemap declaration. The general form of this declaration is as follows (parts enclosed in [ ... ] are optional):
%typemap(method [, modifiers]) typelist code ;
method is a simply a name that specifies what kind of typemap is being defined. It is usually a name like "in", "out", or "argout". The purpose of these methods is described later.

modifiers is an optional comma separated list of name="value" values. These are sometimes to attach extra information to a typemap and is often target-language dependent.

typelist is a list of the C++ type patterns that the typemap will match. The general form of this list is as follows:

typelist    :  typepattern [, typepattern, typepattern, ... ] ;

typepattern :  type [ (parms) ]
            |  type name [ (parms) ]
            |  ( typelist ) [ (parms) ]

Each type pattern is either a simple type, a simple type and argument name, or a list of types in the case of multi-argument typemaps. In addition, each type pattern can be parameterized with a list of temporary variables (parms). The purpose of these variables will be explained shortly.

code specifies the C code used in the typemap. It can take any one of the following forms:

code       : { ... }
           | " ... "
           | %{ ... %}
Here are some examples of valid typemap specifications:
/* Simple typemap declarations */
%typemap(in) int {
   $1 = PyInt_AsLong($input);
}
%typemap(in) int "$1 = PyInt_AsLong($input);";
%typemap(in) int %{ 
   $1 = PyInt_AsLong($input);
%}

/* Typemap with extra argument name */
%typemap(in) int nonnegative {
   ...
}

/* Multiple types in one typemap */
%typemap(in) int, short, long { 
   $1 = SvIV($input);
}

/* Typemap with modifiers */
%typemap(in,doc="integer") int "$1 = gh_scm2int($input);";

/* Typemap applied to patterns of multiple arguments */
%typemap(in) (char *str, int len),
             (char *buffer, int size)
{
   $1 = PyString_AsString($input);
   $2 = PyString_Size($input);
}

/* Typemap with extra pattern parameters */
%typemap(in, numinputs=0) int *output (int temp),
                          long *output (long temp)
{
   $1 = &temp;
}
Admittedly, it's not the most readable syntax at first glance. However, the purpose of the individual pieces will become clear.

8.2.2 Typemap scope

Once defined, a typemap remains in effect for all of the declarations that follow. A typemap may be redefined for different sections of an input file. For example:
// typemap1
%typemap(in) int {
...
}

int fact(int);                    // typemap1
int gcd(int x, int y);            // typemap1

// typemap2
%typemap(in) int {
...
}

int isprime(int);                 // typemap2
One exception to the typemap scoping rules pertains to the %extend declaration. %extend is used to attach new declarations to a class or structure definition. Because of this, all of the declarations in an %extend block are subject to the typemap rules that are in effect at the point where the class itself is defined. For example:
class Foo {
   ...
};

%typemap(in) int {
 ...
}

%extend Foo {
   int blah(int x);    // typemap has no effect.  Declaration is attached to Foo which 
                       // appears before the %typemap declaration.
};

8.2.3 Copying a typemap

A typemap is copied by using assignment. For example:
%typemap(in) Integer = int;
or this:
%typemap(in) Integer, Number, int32_t = int;
Types are often managed by a collection of different typemaps. For example:
%typemap(in)     int { ... }
%typemap(out)    int { ... }
%typemap(varin)  int { ... }
%typemap(varout) int { ... }
To copy all of these typemaps to a new type, use %apply. For example:
%apply int { Integer };            // Copy all int typemaps to Integer
%apply int { Integer, Number };    // Copy all int typemaps to both Integer and Number
The patterns for %apply follow the same rules as for %typemap. For example:
%apply int *output { Integer *output };                    // Typemap with name
%apply (char *buf, int len) { (char *buffer, int size) };  // Multiple arguments

8.2.4 Deleting a typemap

A typemap can be deleted by simply defining no code. For example:
%typemap(in) int;               // Clears typemap for int
%typemap(in) int, long, short;  // Clears typemap for int, long, short
%typemap(in) int *output;       
The %clear directive clears all typemaps for a given type. For example:
%clear int;                     // Removes all types for int
%clear int *output, long *output;
Note: Since SWIG's default behavior is defined by typemaps, clearing a fundamental type like int will make that type unusable unless you also define a new set of typemaps immediately after the clear operation.

8.2.5 Placement of typemaps

Typemap declarations can be declared in the global scope, within a C++ namespace, and within a C++ class. For example:
%typemap(in) int {
   ...
}

namespace std {
    class string;
    %typemap(in) string {
        ...
    }
}

class Bar {
public:
    typedef const int & const_reference;
    %typemap(out) const_reference {
         ...
    }
};
When a typemap appears inside a namespace or class, it stays in effect until the end of the SWIG input (just like before). However, the typemap takes the local scope into account. Therefore, this code
namespace std {
    class string;
    %typemap(in) string {
       ...
    }
}
is really defining a typemap for the type std::string. You could have code like this:
namespace std {
    class string;
    %typemap(in) string {          /* std::string */
       ...
    }
}

namespace Foo {
    class string;
    %typemap(in) string {          /* Foo::string */
       ...
    }
}
In this case, there are two completely distinct typemaps that apply to two completely different 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.

8.3 Pattern matching rules

The section describes the pattern matching rules by which C datatypes are associated with typemaps.

8.3.1 Basic matching rules

Typemaps are matched using both a type and a name (typically the name of a argument). For a given TYPE NAME pair, the following rules are applied, in order, to find a match. The first typemap found is used.
  • Typemaps that exactly match TYPE and NAME.
  • Typemaps that exactly match TYPE only.
If TYPE includes qualifiers (const, volatile, etc.), they are stripped and the following checks are made:
  • Typemaps that match the stripped TYPE and NAME.
  • Typemaps that match the stripped TYPE only.
If TYPE is an array. The following transformation is made:
  • Replace all dimensions to [ANY] and look for a generic array typemap.
To illustrate, suppose that you had a function like this:
int foo(const char *s);
To find a typemap for the argument const char *s, SWIG will search for the following typemaps:
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)
When more than one typemap rule might be defined, only the first match found is actually used. Here is an example that shows how some of the basic rules are applied:
%typemap(in) int *x {
   ... typemap 1
}

%typemap(in) int * {
   ... typemap 2
}

%typemap(in) const int *z {
   ... typemap 3
}

%typemap(in) int [4] {
   ... typemap 4
}

%typemap(in) int [ANY] {
   ... 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)

8.3.2 Typedef reductions

If no match is found using the rules in the previous section, SWIG applies a typedef reduction to the type and repeats the typemap search for the reduced type. To illustrate, suppose you had code like this:
%typemap(in) int {
   ... typemap 1
}

typedef int Integer;
void blah(Integer x);
To find the typemap for Integer x, SWIG will first search for the following typemaps:
Integer x
Integer
Finding no match, it then applies a reduction Integer -> int to the type and repeats the search.
int x
int      --> match: typemap 1
Even though two types might be the same via typedef, SWIG allows typemaps to be defined for each typename independently. This allows for interesting customization possibilities based solely on the typename itself. For example, you could write code like this:
typedef double  pdouble;     // Positive double

// typemap 1
%typemap(in) double {
   ... get a double ...
}
// typemap 2
%typemap(in) pdouble {
   ... get a positive double ...
}
double sin(double x);           // typemap 1
pdouble sqrt(pdouble x);        // typemap 2
When reducing the type, only one typedef reduction is applied at a time. The search process continues to apply reductions until a match is found or until no more reductions can be made.

For complicated types, the reduction process can generate a long list of patterns. Consider the following:

typedef int Integer;
typedef Integer Row4[4];
void foo(Row4 rows[10]);
To find a match for the Row4 rows[10] argument, SWIG would check the following patterns, stopping only when it found a match:
Row4 rows[10]
Row4 [10]
Row4 rows[ANY]
Row4 [ANY]

# Reduce Row4 --> Integer[4]
Integer rows[10][4]
Integer [10][4]
Integer rows[ANY][ANY]
Integer [ANY][ANY]

# Reduce Integer --> int
int rows[10][4]
int [10][4]
int rows[ANY][ANY]
int [ANY][ANY]
For parametized types like templates, the situation is even more complicated. Suppose you had some declarations like this:
typedef int Integer;
typedef foo<Integer,Integer> fooii;
void blah(fooii *x);
In this case, the following typemap patterns are searched for the argument fooii *x:
fooii *x
fooii *

# Reduce fooii --> foo<Integer,Integer>
foo<Integer,Integer> *x
foo<Integer,Integer> *

# Reduce Integer -> int
foo<int, Integer> *x
foo<int, Integer> *

# Reduce Integer -> int
foo<int, int> *x
foo<int, int> *
Typemap reductions are always applied to the left-most type that appears. Only when no reductions can be made to the left-most type are reductions made to other parts of the type. This behavior means that you could define a typemap for foo<int,Integer>, but a typemap for foo<Integer,int> would never be matched. Admittedly, this is rather esoteric--there's little practical reason to write a typemap quite like that. Of course, you could rely on this to confuse your coworkers even more.

8.3.3 Default typemaps

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:
%typemap(in) int   "convert an int";
%typemap(in) short "convert a short";
%typemap(in) float "convert a float";
...
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.

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:

%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 ...  } 
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:

%typemap(in) SWIGTYPE   { ... handle an unknown type ... }
This typemap is important because it is the rule that gets triggered when call or return by value is used. For instance, if you have a declaration like this:
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).

By redefining SWIGTYPE it may be possible to implement other behavior. For example, if you cleared all typemaps for SWIGTYPE, SWIG simply won't wrap any unknown datatype (which might be useful for debugging). Alternatively, you might modify SWIGTYPE to marshal 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.

8.3.4 Multi-arguments typemaps

When multi-argument typemaps are specified, they take precedence over any typemaps specified for a single type. For example:

%typemap(in) (char *buffer, int len) {
   // typemap 1
}

%typemap(in) char *buffer {
   // typemap 2
}

void foo(char *buffer, int len, int count); // (char *buffer, int len)
void bar(char *buffer, int blah);           // char *buffer
Multi-argument typemaps are also more restrictive in the way that they are matched. Currently, the first argument follows the matching rules described in the previous section, but all subsequent arguments must match exactly.

8.4 Code generation rules

This section describes rules by which typemap code is inserted into the generated wrapper code.

8.4.1 Scope

When a typemap is defined like this:
%typemap(in) int {
   $1 = PyInt_AsLong($input);
}
the typemap code is inserted into the wrapper function using a new block scope. In other words, the wrapper code will look like this:
wrap_whatever() {
    ...
    // Typemap code
    {                    
       arg1 = PyInt_AsLong(obj1);
    }
    ...
}
Because the typemap code is enclosed in its own block, it is legal to declare temporary variables for use during typemap execution. For example:
%typemap(in) short {
   long temp;          /* Temporary value */
   if (Tcl_GetLongFromObj(interp, $input, &temp) != TCL_OK) {
      return TCL_ERROR;
   }
   $1 = (short) temp;
}
Of course, any variables that you declare inside a typemap are destroyed as soon as the typemap code has executed (they are not visible to other parts of the wrapper function or other typemaps that might use the same variable names).

Occasionally, typemap code will be specified using a few alternative forms. For example:

%typemap(in) int "$1 = PyInt_AsLong($input);";
%typemap(in) int %{
$1 = PyInt_AsLong($input);
%}
These two 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.

8.4.2 Declaring new local variables

Sometimes it is useful to declare a new local variable that exists within the scope of the entire wrapper function. A good example of this might be an application in which you wanted to marshal strings. Suppose you had a C++ function like this
int foo(std::string *s);
and you wanted to pass a native string in the target language as an argument. For instance, in Perl, you wanted the function to work like this:
$x = foo("Hello World");
To do this, you can't just pass a raw Perl string as the std::string * argument. Instead, you have to create a temporary std::string object, copy the Perl string data into it, and then pass a pointer to the object. To do this, simply specify the typemap with an extra parameter like this:
%typemap(in) std::string * (std::string temp) {
    unsigned int len;
    char        *s;
    s = SvPV($input,len);         /* Extract string data */
    temp.assign(s,len);           /* Assign to temp */
    $1 = &temp;                   /* Set argument to point to temp */
}
In this case, temp becomes a local variable in the scope of the entire wrapper function. For example:
wrap_foo() {
   std::string temp;    <--- Declaration of temp goes here
   ...

   /* Typemap code */
   {
      ...
      temp.assign(s,len);
      ...
   } 
   ...
}
When you set temp to a value, it persists for the duration of the wrapper function and gets cleaned up automatically on exit.

It is perfectly safe to use more than one typemap involving local variables in the same declaration. For example, you could declare a function as :

void foo(std::string *x, std::string *y, std::string *z);

This is safely handled because SWIG actually renames all local variable references by appending an argument number suffix. Therefore, the generated code would actually look like this:
wrap_foo() {
   int *arg1;    /* Actual arguments */
   int *arg2;
   int *arg3;
   std::string temp1;    /* Locals declared in the typemap */
   std::string temp2;
   std::string temp3;
   ...
   {
       char *s;
       unsigned int len;
       ...
       temp1.assign(s,len);
       arg1 = *temp1;
   }
   {
       char *s;
       unsigned int len;
       ...
       temp2.assign(s,len);
       arg2 = &temp2;
   }
   {
       char *s;
       unsigned int len;
       ...
       temp3.assign(s,len);
       arg3 = &temp3;
   }
   ...
}

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.

8.4.3 Special variables

Within all typemaps, the following special variables are expanded.

VariableMeaning
$n A C local variable corresponding to type n in the typemap pattern.
$argnum Argument number. Only available in typemaps related to argument conversion
$n_name Argument name
$n_type Real C datatype of type n.
$n_ltype ltype of type n
$n_mangle Mangled form of type n. For example _p_Foo
$n_descriptor Type descriptor structure for type n. For example SWIGTYPE_p_Foo. This is primarily used when interacting with the run-time type checker (described later).
$*n_type Real C datatype of type n with one pointer removed.
$*n_ltype ltype of type n with one pointer removed.
$*n_mangle Mangled form of type n with one pointer removed.
$*n_descriptor Type descriptor structure for type n with one pointer removed.
$&n_type Real C datatype of type n with one pointer added.
$&n_ltype ltype of type n with one pointer added.
$&n_mangle Mangled form of type n with one pointer added.
$&n_descriptor Type descriptor structure for type n with one pointer added.
$n_basetype Base typename with all pointers and qualifiers stripped.

Within the table, $n refers to a specific type within the typemap specification. For example, if you write this

%typemap(in) int *INPUT {

}
then $1 refers to int *INPUT. If you have a typemap like this,
%typemap(in) (int argc, char *argv[]) {
  ...
}
then $1 refers to int argc and $2 refers to char *argv[].

Substitutions related to types and names always fill in values from the actual code that was matched. This is useful when a typemap might match multiple C datatype. For example:

%typemap(in)  int, short, long {
   $1 = ($1_ltype) PyInt_AsLong($input);
}
In this case, $1_ltype is replaced with the datatype that is actually matched.

When typemap code is emitted, the C/C++ datatype of the special variables $1 and $2 is always an "ltype." An "ltype" is simply a type that can legally appear on the left-hand side of a C assignment operation. Here are a few examples of types and ltypes:

type              ltype
------            ----------------
int               int
const int         int
conts int *       int *
int [4]           int *
int [4][5]        int (*)[5]
In most cases a ltype is simply the C datatype with qualifiers stripped off. In addition, arrays are converted into pointers.

Variables such as $&1_type and $*1_type are used to safely modify the type by removing or adding pointers. Although not needed in most typemaps, these substitutions are sometimes needed to properly work with typemaps that convert values between pointers and values.

If necessary, type related substitutions can also be used when declaring locals. For example:

%typemap(in) int * ($*1_type temp) {
    temp = PyInt_AsLong($input);
    $1 = &temp;
}

There is one word of caution about declaring local variables in this manner. If you declare a local variable using a type substitution such as $1_ltype temp, it won't work like you expect for arrays and certain kinds of pointers. For example, if you wrote this,

%typemap(in) int [10][20] {
   $1_ltype temp;
}
then the declaration of temp will be expanded as
int (*)[20] temp;
This is illegal C syntax and won't compile. There is currently no straightforward way to work around this problem in SWIG due to the way that typemap code is expanded and processed. However, one possible workaround is to simply pick an alternative type such as void * and use casts to get the correct type when needed. For example:
%typemap(in) int [10][20] {
   void *temp;
   ...
   (($1_ltype) temp)[i][j] = x;    /* set a value */
   ...
}
Another approach, which only works for arrays is to use the $1_basetype substitution. For example:
%typemap(in) int [10][20] {
   $1_basetype temp[10][20];
   ...
   temp[i][j] = x;    /* set a value */
   ...
}

8.5 Common typemap methods

The set of typemaps recognized by a language module may vary. However, the following typemap methods are nearly universal:

8.5.1 "in" typemap

The "in" typemap is used to convert function arguments from the target language to C. For example:
%typemap(in) int {
   $1 = PyInt_AsLong($input);
}
The following special variables are available:
$input            - Input object holding value to be converted.
$symname          - Name of function/method being wrapped
This is probably the most commonly redefined typemap because it can be used to implement customized conversions.

In addition, the "in" typemap allows the number of converted arguments to be specified. For example:

// Ignored argument.
%typemap(in, numinputs=0) int *out (int temp) {
    $1 = &temp;
}
At this time, only zero or one arguments may be converted.

Compatibility note: Specifying numinputs=0 is the same as the old "ignore" typemap.

8.5.2 "typecheck" typemap

The "typecheck" typemap is used to support overloaded functions and methods. It merely checks an argument to see whether or not it matches a specific type. For example:
%typemap(typecheck,precedence=SWIG_TYPECHECK_INTEGER) int {
   $1 = PyInt_Check($input) ? 1 : 0;
}
For typechecking, the $1 variable is always a simple integer that is set to 1 or 0 depending on whether or not 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."

8.5.3 "out" typemap

The "out" typemap is used to convert function/method return values from C into the target language. For example:
%typemap(out) int {
   $result = PyInt_FromLong($1);
}
The following special variables are available.
$result           - Result object returned to target language.
$symname          - Name of function/method being wrapped

8.5.4 "arginit" typemap

The "arginit" typemap is used to set the initial value of a function argument--before any conversion has occurred. This is not normally necessary, but might be useful in highly specialized applications. For example:
// Set argument to NULL before any conversion occurs
%typemap(arginit) int *data {
   $1 = NULL;
}

8.5.5 "default" typemap

The "default" typemap is used to turn an argument into a default argument. For example:
%typemap(default) int flags {
   $1 = DEFAULT_FLAGS;
}
...
int foo(int x, int y, int flags);
The primary use of this typemap is to either change the wrapping of default arguments or specify a default argument in a language where they aren't supported (like C).

Once a default typemap has been applied to an argument, all arguments that follow must have default values.

8.5.6 "check" typemap

The "check" typemap is used to supply value checking code during argument conversion. The typemap is applied after arguments have been converted. For example:
%typemap(check) int positive {
   if ($1 <= 0) {
       SWIG_exception(SWIG_ValueError,"Expected positive value.");
   }
}

8.5.7 "argout" typemap

The "argout" typemap is used to return values from arguments. This is most commonly used to write wrappers for C/C++ functions that need to return multiple values. The "argout" typemap is almost always combined with an "in" typemap---possibly to ignore the input value. For example:
/* Set the input argument to point to a temporary variable */
%typemap(in, numinputs=0) int *out (int temp) {
   $1 = &temp;
}

%typemap(argout) int *out {
   // Append output value $1 to $result
   ...
}
The following special variables are available.
$result           - Result object returned to target language.
$input            - The original input object passed.
$symname          - Name of function/method being wrapped
The code supplied to the "argout" typemap is always placed after the "out" typemap. If multiple return values are used, the extra return values are often appended to return value of the function.

See the typemaps.i library for examples.

8.5.8 "freearg" typemap

The "freearg" typemap is used to cleanup argument data. It is only used when an argument might have allocated resources that need to be cleaned up when the wrapper function exits. The "freearg" typemap usually cleans up argument resources allocated by the "in" typemap. For example:
// Get a list of integers
%typemap(in) int *items {
   int nitems = Length($input);    
   $1 = (int *) malloc(sizeof(int)*nitems);
}
// Free the list 
%typemap(freearg) int *items {
   free($1);
}
The "freearg" typemap inserted at the end of the wrapper function, just before control is returned back to the target language. This code is also placed into a special variable $cleanup that may be used in other typemaps whenever a wrapper function needs to abort prematurely.

8.5.9 "newfree" typemap

The "newfree" typemap is used in conjunction with the %newobject directive and is used to deallocate memory used by the return result of a function. For example:
%typemap(newfree) string * {
   delete $1;
}
%typemap(out) string * {
   $result = PyString_FromString($1->c_str());
}
...

%newobject foo;
...
string *foo();

8.5.10 "memberin" typemap

The "memberin" typemap is used to copy data from an already converted input value into a structure member. It is typically used to handle array members and other special cases. For example:
%typemap(memberin) int [4] {
   memmove($1, $input, 4*sizeof(int));
}
It is rarely necessary to write "memberin" typemaps---SWIG already provides a default implementation for arrays, strings, and other objects.

8.5.11 "varin" typemap

The "varin" typemap is used to convert objects in the target language to C for the purposes of assigning to a C/C++ global variable. This is implementation specific.

8.5.12 "varout" typemap

The "varout" typemap is used to convert a C/C++ object to an object in the target language when reading a C/C++ global variable. This is implementation specific.

8.6 Some typemap examples

This section contains a few examples. Consult language module documentation for more examples.

8.6.1 Typemaps for arrays

A common use of typemaps is to provide support for C arrays appearing both as arguments to functions and as structure members.

For example, suppose you had a function like this:

void set_vector(int type, float value[4]);
If you wanted to handle float value[4] as a list of floats, you might write a typemap similar to this:

%typemap(in) float value[4] (float temp[4]) {
  int i;
  if (!PySequence_Check($input)) {
    PyErr_SetString(PyExc_ValueError,"Expected a sequence");
    return NULL;
  }
  if (PySequence_Length($input) != 4) {
    PyErr_SetString(PyExc_ValueError,"Size mismatch. Expected 4 elements");
    return NULL;
  }
  for (i = 0; i < 4; i++) {
    PyObject *o = PySequence_GetItem($input,i);
    if (PyNumber_Check(o)) {
      temp[i] = (float) PyFloat_AsDouble(o);
    } else {
      PyErr_SetString(PyExc_ValueError,"Sequence elements must be numbers");      
      return NULL;
    }
  }
  $1 = temp;
}
In this example, the variable temp allocates a small array on the C stack. The typemap then populates this array and passes it to the underlying C function.

When used from Python, the typemap allows the following type of function call:

>>> set_vector(type, [ 1, 2.5, 5, 20 ])

If you wanted to generalize the typemap to apply to arrays of all dimensions you might write this:

%typemap(in) float value[ANY] (float temp[$1_dim0]) {
  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;
  }
  for (i = 0; i < $1_dim0; i++) {
    PyObject *o = PySequence_GetItem($input,i);
    if (PyNumber_Check(o)) {
      temp[i] = (float) PyFloat_AsDouble(o);
    } else {
      PyErr_SetString(PyExc_ValueError,"Sequence elements must be numbers");      
      return NULL;
    }
  }
  $1 = temp;
}
In this example, the special variable $1_dim0 is expanded with the actual array dimensions. Multidimensional arrays can be matched in a similar manner. For example:
%typemap(python,in) float matrix[ANY][ANY] (float temp[$1_dim0][$1_dim1]) {
   ... convert a 2d array ...
}
For large arrays, it may be impractical to allocate storage on the stack using a temporary variable as shown. To work with heap allocated data, the following technique can be used.
%typemap(in) float value[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");      
      return NULL;
    }
  }
}
%typemap(freearg) float value[ANY] {
   if ($1) free($1);
}
In this case, an array is allocated using malloc. The freearg typemap is then used to release the argument after the function has been called.

Another common use of array typemaps is to provide support for array structure members. Due to subtle differences between pointers and arrays in C, you can't just "assign" to a array structure member. Instead, you have to explicitly copy elements into the array. For example, suppose you had a structure like this:

struct SomeObject {
	float  value[4];
        ...
};
When SWIG runs, it won't produce any code to set the vec member. 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.

These warning messages indicate that SWIG does not know how you want to set the vec field.

To fix this, you can supply a special "memberin" typemap like this:

%typemap(memberin) float [ANY] {
  int i;
  for (i = 0; i < $1_dim0; i++) {
      $1[i] = $input[i];
  }
}

The memberin typemap is used to set a structure member from data that has already been converted from the target language to C. In this case, $input is the local variable in which converted input data is stored. This typemap then copies this data into the structure.

When combined with the earlier typemaps for arrays, the combination of the "in" and "memberin" typemap allows the following usage:

>>> s = SomeObject()
>>> s.x = [1, 2.5, 5, 10]

Related to structure member input, it may be desirable to return structure members as a new kind of object. For example, in this example, you will get very odd program behavior where the structure member can be set nicely, but reading the member simply returns a pointer:

>>> s = SomeObject()
>>> s.x = [1, 2.5, 5. 10]
>>> print s.x
_1008fea8_p_float
>>> 
To fix this, you can write an "out" typemap. For example:
%typemap(out) float [ANY] {
  int i;
  $result = PyList_New($1_dim0);
  for (i = 0; i < $1_dim0; i++) {
    PyObject *o = PyFloat_FromDouble((double) $1[i]);
    PyList_SetItem($result,i,o);
  }
}
Now, you will find that member access is quite nice:
>>> s = SomeObject()
>>> s.x = [1, 2.5, 5, 10]
>>> print s.x
[ 1, 2.5, 5, 10]
Compatibility Note: SWIG1.1 used to provide a special "memberout" typemap. However, it was mostly useless and has since been eliminated. To return structure members, simply use the "out" typemap.

8.6.2 Implementing constraints with typemaps

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 :

%module math

%typemap(check) double posdouble {
	if ($1 < 0) {
		croak("Expecting a positive number");
	}
}

...
double sqrt(double posdouble);

This provides a sanity check to your wrapper function. If a negative number is passed to this function, a Perl exception will be raised and your program terminated with an error message.

This kind of checking can be particularly useful when working with pointers. For example :

%typemap(check) Vector * {
    if ($1 == 0) {
        PyErr_SetString(PyExc_TypeError,"NULL Pointer not allowed");
        return NULL;
   }
}

will prevent any function involving a Vector * from accepting 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.

8.7 Multi-argument typemaps

So far, the typemaps presented have focused on the problem of dealing with single values. For example, converting a single input object to a single argument in a function call. However, certain conversion problems are difficult to handle in this manner. As an example, consider the example at the very beginning of this chapter:
int foo(int argc, char *argv[]);
Suppose that you wanted to wrap this function so that it accepted a single list of strings like this:
>>> foo(["ale","lager","stout"])
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.

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 maps perform the conversion described for the above example:

%typemap(in) (int argc, char *argv[]) {
  int i;
  if (!PyList_Check($input)) {
    PyErr_SetString(PyExc_ValueError, "Expecting a list");
    return NULL;
  }
  $1 = PyList_Size($input);
  $2 = (char **) malloc(($1+1)*sizeof(char *));
  for (i = 0; i < $1; i++) {
    PyObject *s = PyList_GetItem($input,i);
    if (!PyString_Check(s)) {
        free($2);
        PyErr_SetString(PyExc_ValueError, "List items must be strings");
        return NULL;
    }
    $2[i] = PyString_AsString(s);
  }
  $2[i] = 0;
}

%typemap(freearg) (int argc, char *argv[]) {
   if ($2) free($2);
}
A multi-argument map is always specified by surrounding the arguments with parentheses as shown. For example:
%typemap(in) (int argc, char *argv[]) { ... }
Within the typemap code, the variables $1, $2, and so forth refer to each type in the map. All of the usual substitutions apply--just use the appropriate $1 or $2 prefix on the variable name (e.g., $2_type, $1_ltype, etc.)

Multi-argument typemaps always have precedence over simple typemaps and SWIG always performs longest-match searching. Therefore, you will get the following behavior:

%typemap(in) int argc                              { ... typemap 1 ... }
%typemap(in) (int argc, char *argv[])              { ... typemap 2 ... }
%typemap(in) (int argc, char *argv[], char *env[]) { ... typemap 3 ... }

int foo(int argc, char *argv[]);                   // Uses typemap 2
int bar(int argc, int x);                          // Uses typemap 1
int spam(int argc, char *argv[], char *env[]);     // Uses typemap 3
It should be stressed that multi-argument typemaps can appear anywhere in a function declaration and can appear more than once. For example, you could write this:
%typemap(in) (int scount, char *swords[]) { ... }
%typemap(in) (int wcount, char *words[]) { ... }

void search_words(int scount, char *swords[], int wcount, char *words[], int maxcount);
Other directives such as %apply and %clear also work with multi-argument maps. For example:
%apply (int argc, char *argv[]) {
    (int scount, char *swords[]),
    (int wcount, char *words[])
};
...
%clear (int scount, char *swords[]), (int wcount, char *words[]);
...
Although multi-argument typemaps may seem like an exotic, little used feature, there are several situations where they make sense. First, suppose you wanted to wrap functions similar to the low-level read() and write() system calls. For example:
typedef unsigned int size_t;

int read(int fd, void *rbuffer, size_t len);
int write(int fd, void *wbuffer, size_t len);
As is, the only way to use the functions would be to allocate memory and pass some kind of pointer as the second argument---a process that might require the use of a helper function. However, using multi-argument maps, the functions can be transformed into something more natural. For example, you might write typemaps like this:
// typemap for an outgoing buffer
%typemap(in) (void *wbuffer, size_t len) {
   if (!PyString_Check($input)) {
       PyErr_SetString(PyExc_ValueError, "Expecting a string");
       return NULL;
   }
   $1 = (void *) PyString_AsString($input);
   $2 = PyString_Size($input);
}

// typemap for an incoming buffer
%typemap(in) (void *rbuffer, size_t len) {
   if (!PyInt_Check($input)) {
       PyErr_SetString(PyExc_ValueError, "Expecting an integer");
       return NULL;
   }
   $2 = PyInt_AsLong($input);
   if ($2 < 0) {
       PyErr_SetString(PyExc_ValueError, "Positive integer expected");
       return NULL;
   }
   $1 = (void *) malloc($2);
}

// Return the buffer.  Discarding any previous return result
%typemap(argout) (void *rbuffer, size_t len) {
   Py_XDECREF($result);   /* Blow away any previous result */
   if (result < 0) {      /* Check for I/O error */
       free($1);
       PyErr_SetFromErrno(PyExc_IOError);
       return NULL;
   }
   $result = PyString_FromStringAndSize($1,result);
   free($1);
}
(note: In the above example, $result and result are two different variables. result is the real C datatype that was returned by the function. $result is the scripting language object being returned to the interpreter.).

Now, in a script, you can write code that simply passes buffers as strings like this:

>>> f = example.open("Makefile")
>>> example.read(f,40)
'TOP        = ../..\nSWIG       = $(TOP)/.'
>>> example.read(f,40)
'./swig\nSRCS       = example.c\nTARGET    '
>>> example.close(f)
0
>>> g = example.open("foo", example.O_WRONLY | example.O_CREAT, 0644)
>>> example.write(g,"Hello world\n")
12
>>> example.write(g,"This is a test\n")
15
>>> example.close(g)
0
>>>
A number of multi-argument typemap problems also arise in libraries that perform matrix-calculations--especially if they are mapped onto low-level Fortran or C code. For example, you might have a function like this:
int is_symmetric(double *mat, int rows, int columns);
In this case, you might want to pass some kind of higher-level object as an matrix. To do this, you could write a multi-argument typemap like this:
%typemap(in) (double *mat, int rows, int columns) {
    MatrixObject *a;
    a = GetMatrixFromObject($input);     /* Get matrix somehow */

    /* Get matrix properties */
    $1 = GetPointer(a);
    $2 = GetRows(a);
    $3 = GetColumns(a);
}
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).

8.8 The run-time type checker

A critical part of SWIG's operation is that of its run-time type checker. When pointers, arrays, and objects are wrapped by SWIG, they are normally converted into typed pointer objects. For example, an instance of Foo * might be a string encoded like this:
_108e688_p_Foo
At a basic level, the type checker simply restores some type-safety to extension modules. However, the type checker is also responsible for making sure that wrapped C++ classes are handled correctly---especially when inheritance is used. This is especially important when an extension module makes use of multiple inheritance. For example:
class Foo {
   int x;
};

class Bar {
   int y;
};

class FooBar : public Foo, public Bar {
   int z;
};
When the class FooBar is organized in memory, it contains the contents of the classes Foo and Bar as well as its own data members. For example:
FooBar --> | -----------|  <-- Foo
           |   int x    |
           |------------|  <-- Bar
           |   int y    |
           |------------|
           |   int z    |
           |------------|
Because of the way that base class data is stacked together, the casting of a Foobar * to either of the base classes may change the actual value of the pointer. This means that it is generally not safe to represent pointers using a simple integer or a bare void *---type tags are needed to implement correct handling of pointer values (and to make adjustments when needed).

In the wrapper code generated for each language, pointers are handled through the use of special type descriptors and conversion functions. For example, if you look at the wrapper code for Python, you will see code like this:

if ((SWIG_ConvertPtr(obj0,(void **) &arg1, SWIGTYPE_p_Foo,1)) == -1) return NULL;                                 
In this code, SWIGTYPE_p_Foo is the type descriptor that describes Foo *. The type descriptor is actually a pointer to a structure that contains information about the type name to use in the target language, a list of equivalent typenames (via typedef or inheritance), and pointer value handling information (if applicable). The SWIG_ConvertPtr() function is simply a utility function that takes a pointer object in the target language and a type-descriptor objects and uses this information to generate a C++ pointer. However, the exact name and calling conventions of the conversion function depends on the target language (see language specific chapters for details).

When pointers are converted in a typemap, the typemap code often looks similar to this:

%typemap(in) Foo * {
  if ((SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor)) == -1) return NULL;
}
The most critical part is the typemap is the use of the $1_descriptor special variable. When placed in a typemap, this is expanded into the SWIGTYPE_* type descriptor object above. As a general rule, you should always use $1_descriptor instead of trying to hard-code the type descriptor name directly.

There is another reason why you should always use the $1_descriptor variable. When this special variable is expanded, SWIG marks the corresponding type as "in use." When type-tables and type information is emitted in the wrapper file, descriptor information is only generated for those datatypes that were actually used in the interface. This greatly reduces the size of the type tables and improves efficiency.

Occassionally, you might need to write a typemap that needs to convert pointers of other types. To handle this, a special macro substition $descriptor(type) can be used to generate the SWIG type descriptor name for any C datatype. For example:

%typemap(in) Foo * {
  if ((SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor)) == -1) {
     Bar *temp;
     if ((SWIG_ConvertPtr($input), (void **) &temp, $descriptor(Bar *)) == -1) {
         return NULL;
     }
     $1 = (Foo *) temp;
  }
}
The primary use of $descriptor(type) is when writing typemaps for container objects and other complex data structures. There are some restrictions on the argument---namely it must be a fully defined C datatype. It can not be any of the special typemap variables.

In certain cases, SWIG may not generate type-descriptors like you expect. For example, if you are converting pointers in some non-standard way or working with an unusual combination of interface files and modules, you may find that SWIG omits information for a specific type descriptor. To fix this, you may need to use the %types directive. For example:

%types(int *, short *, long *, float *, double *);
When %types is used, SWIG generates type-descriptor information even if those datatypes never appear elsewhere in the interface file.

A final problem related to the type-checker is the conversion of types in code that is external to the SWIG wrapper file. This situation is somewhat rare in practice, but occasionally a programmer may want to convert a typed pointer object into a C++ pointer somewhere else in their program. The only problem is that the SWIG type descriptor objects are only defined in the wrapper code and not normally accessible.

To correctly deal with this situation, the following technique can be used:


/* Some non-SWIG file */

/* External declarations */
extern void *SWIG_TypeQuery(const char *);
extern int   SWIG_ConvertPtr(PyObject *, void **ptr, void *descr);

void foo(PyObject *o) {
   Foo *f;
   static void *descr = 0;
   if (!descr) {
      descr = SWIG_TypeQuery("Foo *");    /* Get the type descriptor structure for Foo */
      assert(descr);
   }
   if ((SWIG_ConvertPtr(o,(void **) &f, descr) == -1)) {
       abort();
   }
   ...
}
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 common.swg in the SWIG library contains all of the source 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.

8.9 Typemaps and overloading

In many target languages, SWIG fully supports C++ overloaded methods and functions. For example, if you have a collection of functions like this:
int foo(int x);
int foo(double x);
int foo(char *s, int y);
You can access the functions in a normal way from the scripting interpreter:
# Python
foo(3)           # foo(int)
foo(3.5)         # foo(double)
foo("hello",5)   # foo(char *, int)

# Tcl
foo 3            # foo(int)
foo 3.5          # foo(double)
foo hello 5      # foo(char *, int)
To implement overloading, SWIG generates a separate wrapper function for each overloaded method. For example, the above functions would produce something roughly like this:
// wrapper pseudocode
_wrap_foo_0(argc, args[]) {       // foo(int)
   int arg1;
   int result;
   ...
   arg1 = FromInteger(args[0]);
   result = foo(arg1);
   return ToInteger(result);
}

_wrap_foo_1(argc, args[]) {       // foo(double)
   double arg1;
   int result;
   ...
   arg1 = FromDouble(args[0]);
   result = foo(arg1);
   return ToInteger(result);
}

_wrap_foo_2(argc, args[]) {       // foo(char *, int)
   char *arg1;
   int   arg2;
   int result;
   ...
   arg1 = FromString(args[0]);
   arg2 = FromInteger(args[1]);
   result = foo(arg1,arg2);
   return ToInteger(result);
}

Next, a dynamic dispatch function is generated:
_wrap_foo(argc, args[]) {
   if (argc == 1) {
       if (IsInteger(args[0])) {
           return _wrap_foo_0(argc,args);
       } 
       if (IsDouble(args[0])) {
           return _wrap_foo_1(argc,args);
       }
   }
   if (argc == 2) {
       if (IsString(args[0]) && IsInteger(args[1])) {
          return _wrap_foo_2(argc,args);
       }
   }
   error("No matching function!\n");
}
The purpose of the dynamic dispatch function is to select the appropriate C++ function based on argument types---a task that must be performed at runtime in most of SWIG's target languages.

The generation of the dynamic dispatch function is a relatively tricky affair. Not only must input typemaps be taken into account (these typemaps can radically change the types of arguments accepted), but overloaded methods must also be sorted and checked in a very specific order to resolve potential ambiguity. A high-level overview of this ranking process is found in the "SWIG and C++" chapter. What isn't mentioned in that chapter is the mechanism by which it is implemented---as a collection of typemaps.

To support dynamic dispatch, SWIG first defines a general purpose type hierarchy as follows:

Symbolic Name                   Precedence Value
------------------------------  ------------------
SWIG_TYPECHECK_POINTER           0  
SWIG_TYPECHECK_VOIDPTR           10 
SWIG_TYPECHECK_BOOL              15 
SWIG_TYPECHECK_UINT8             20 
SWIG_TYPECHECK_INT8              25 
SWIG_TYPECHECK_UINT16            30 
SWIG_TYPECHECK_INT16             35 
SWIG_TYPECHECK_UINT32            40 
SWIG_TYPECHECK_INT32             45 
SWIG_TYPECHECK_UINT64            50 
SWIG_TYPECHECK_INT64             55 
SWIG_TYPECHECK_UINT128           60 
SWIG_TYPECHECK_INT128            65 
SWIG_TYPECHECK_INTEGER           70 
SWIG_TYPECHECK_FLOAT             80 
SWIG_TYPECHECK_DOUBLE            90 
SWIG_TYPECHECK_COMPLEX           100 
SWIG_TYPECHECK_UNICHAR           110 
SWIG_TYPECHECK_UNISTRING         120 
SWIG_TYPECHECK_CHAR              130 
SWIG_TYPECHECK_STRING            140 
SWIG_TYPECHECK_BOOL_ARRAY        1015 
SWIG_TYPECHECK_INT8_ARRAY        1025 
SWIG_TYPECHECK_INT16_ARRAY       1035 
SWIG_TYPECHECK_INT32_ARRAY       1045 
SWIG_TYPECHECK_INT64_ARRAY       1055 
SWIG_TYPECHECK_INT128_ARRAY      1065 
SWIG_TYPECHECK_FLOAT_ARRAY       1080 
SWIG_TYPECHECK_DOUBLE_ARRAY      1090 
SWIG_TYPECHECK_CHAR_ARRAY        1130 
SWIG_TYPECHECK_STRING_ARRAY      1140 
(These precedence levels are defined in swig.swg, a library file that's included by all target language modules.)

In this table, the precedence-level determines the order in which types are going to be checked. Low values are always checked before higher values. For example, integers are checked before floats, single values are checked before arrays, and so forth.

Using the above table as a guide, each target language defines a collection of "typecheck" typemaps. The follow excerpt from the Python module illustrates this:

/* Python type checking rules */
/* Note:  %typecheck(X) is a macro for %typemap(typecheck,precedence=X) */

%typecheck(SWIG_TYPECHECK_INTEGER)
	 int, short, long,
 	 unsigned int, unsigned short, unsigned long,
	 signed char, unsigned char,
	 long long, unsigned long long,
	 const int &, const short &, const long &,
 	 const unsigned int &, const unsigned short &, const unsigned long &,
	 const long long &, const unsigned long long &,
	 enum SWIGTYPE,
         bool, const bool & 
{
  $1 = (PyInt_Check($input) || PyLong_Check($input)) ? 1 : 0;
}

%typecheck(SWIG_TYPECHECK_DOUBLE)
	float, double,
	const float &, const double &
{
  $1 = (PyFloat_Check($input) || PyInt_Check($input) || PyLong_Check($input)) ? 1 : 0;
}

%typecheck(SWIG_TYPECHECK_CHAR) char {
  $1 = (PyString_Check($input) && (PyString_Size($input) == 1)) ? 1 : 0;
}

%typecheck(SWIG_TYPECHECK_STRING) char * {
  $1 = PyString_Check($input) ? 1 : 0;
}

%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] {
  void *ptr;
  if (SWIG_ConvertPtr($input, (void **) &ptr, $1_descriptor, 0) == -1) {
    $1 = 0;
    PyErr_Clear();
  } else {
    $1 = 1;
  }
}

%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE {
  void *ptr;
  if (SWIG_ConvertPtr($input, (void **) &ptr, $&1_descriptor, 0) == -1) {
    $1 = 0;
    PyErr_Clear();
  } else {
    $1 = 1;
  }
}

%typecheck(SWIG_TYPECHECK_VOIDPTR) void * {
  void *ptr;
  if (SWIG_ConvertPtr($input, (void **) &ptr, 0, 0) == -1) {
    $1 = 0;
    PyErr_Clear();
  } else {
    $1 = 1;
  }
}

%typecheck(SWIG_TYPECHECK_POINTER) PyObject *
{
  $1 = ($input != 0);
}
It might take a bit of contemplation, but this code has merely organized all of the basic C++ types, provided some simple type-checking code, and assigned each type a precedence value.

Finally, to generate the dynamic dispatch function, SWIG uses the following algorithm:

  • Overloaded methods are first sorted by the number of required arguments.
  • Methods with the same number of arguments are then sorted by precedence values of argument types.
  • Typecheck typemaps are then emitted to produce a dispatch function that checks arguments in the correct order.
If you haven't written any typemaps of your own, it is unnecessary to worry about the typechecking rules. However, if you have written new input typemaps, you might have to supply a typechecking rule as well. An easy way to do this is to simply copy one of the existing typechecking rules. Here is an example,
// Typemap for a C++ string
%typemap(in) std::string {
    if (PyString_Check($input)) {
         $1 = std::string(PyString_AsString($input));
     } else {
         SWIG_exception(SWIG_TypeError, "string expected");
     }
}
// Copy the typecheck code for "char *".  
%typemap(typecheck) std::string = char *;
The bottom line: If you are writing new typemaps and you are using overloaded methods, you will probably have to write typecheck code or copy existing code. Since this is a relatively new SWIG feature, there are few examples to work with. However, you might look at some of the existing library files likes 'typemaps.i' for a guide.

Notes:

  • Typecheck typemaps are not used for non-overloaded methods. Because of this, it is still always necessary to check types in any "in" typemaps.

  • The dynamic dispatch process is only meant to be a heuristic. There are many corner cases where SWIG simply can't disambiguate types to the same degree as C++. The only way to resolve this ambiguity is to use the %rename directive to rename one of the overloaded methods (effectively eliminating overloading).

  • Typechecking may be partial. For example, if working with arrays, the typecheck code might simply check the type of the first array element and use that to dispatch to the correct function. Subsequent "in" typemaps would then perform more extensive type-checking.

  • Make sure you read the section on overloading in the "SWIG and C++" chapter.

8.10 More about %apply and %clear

In order to implement certain kinds of program behavior, it is sometimes necessary to write sets of typemaps. For example, to support output arguments, one often writes a set of typemaps like this:
%typemap(in,numinputs=0) int *OUTPUT (int temp) {
   $1 = &temp;
}
%typemap(argout) int *OUTPUT {
   // return value somehow
}
To make it easier to apply the typemap to different argument types and names, the %apply directive performs a copy of all typemaps from one type to another. For example, if you specify this,
%apply int *OUTPUT { int *retvalue, int32 *output };
then all of the int *OUTPUT typemaps are copied to int *retvalue and int32 *output.

However, there is a subtle aspect of %apply that needs more description. Namely, %apply does not overwrite a typemap rule if it is already defined for the target datatype. This behavior allows you to do two things:

  • You can specialize parts of a complex typemap rule by first defining a few typemaps and then using %apply to incorporate the remaining pieces.

  • Sets of different typemaps can be applied to the same datatype using repeated %apply directives.
For example:
%typemap(in) int *INPUT (int temp) {
   temp = ... get value from $input ...;
   $1 = &temp;
}

%typemap(check) int *POSITIVE {
   if (*$1 <= 0) {
      SWIG_exception(SWIG_ValueError,"Expected a positive number!\n");
      return NULL;
   }
}

...
%apply int *INPUT     { int *invalue };
%apply int *POSITIVE  { int *invalue };
Since %apply does not overwrite or replace any existing rules, the only way to reset behavior is to use the %clear directive. %clear removes all typemap rules defined for a specific datatype. For example:
%clear int *invalue;

8.11 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");      
      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 huge. 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;
}
%}

8.12 Passing data between typemaps

It is also important to note that the primary use of local variables is to create stack-allocated objects for temporary use inside a wrapper function (this is faster and less-prone to error than allocating data on the heap). In general, the variables are not intended to pass information between different types of typemaps. However, this can be done if you realize that local names have the argument number appended to them. For example, you could do this:

%typemap(in) int *(int temp) {
   temp = (int) PyInt_AsLong($input);
   $1 = &temp;
}

%typemap(argout) int * {
   PyObject *o = PyInt_FromLong(temp$argnum);
   ...
}
In this case, the $argnum variable is expanded into the argument number. Therefore, the code will reference the appropriate local such as temp1 and temp2. It should be noted that there are plenty of opportunities to break the universe here and that accessing locals in this manner should probably be avoided. At the very least, you should make sure that the typemaps sharing information have exactly the same types and names.

8.13 Where to go for more information?

The best place to find out more information about writing typemaps is to look in the SWIG library. Most language modules define all of their default behavior using typemaps. These are found in files such as python.swg, perl5.swg, tcl8.swg and so forth. The typemaps.i file in the library also contains numerous examples. You should look at these files to get a feel for how to define typemaps of your own.


SWIG 1.3 - Last Modified : June 1 , 2003
cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/Tcl.html0000644000175000000620000022576712561312226021152 0ustar stevestaff SWIG and Tcl

23 SWIG and Tcl

Caution: This chapter is under repair!

This chapter discusses SWIG's support of Tcl. SWIG currently requires Tcl 8.0 or a later release. Earlier releases of SWIG supported Tcl 7.x, but this is no longer supported.

23.1 Preliminaries

To build a Tcl module, run SWIG using the -tcl option :

$ swig -tcl example.i
If building a C++ extension, add the -c++ option:

$ swig -c++ -tcl example.i

This creates a file example_wrap.c or example_wrap.cxx that contains all of the code needed to 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.

23.1.1 Getting the right header files

In order to compile the wrapper code, the compiler needs the tcl.h header file. This file is usually contained in the directory

/usr/local/include
Be aware that some Tcl versions install this header file with a version number attached to it. If this is the case, you should probably make a symbolic link so that tcl.h points to the correct header file.

23.1.2 Compiling a dynamic module

The preferred approach to building an extension module is to compile it into a shared object file or DLL. To do this, you will need to compile your program using comands like this (shown for Linux):

$ swig -tcl example.i
$ gcc -c example.c
$ gcc -c example_wrap.c -I/usr/local/include
$ gcc -shared example.o example_wrap.o -o example.so
The exact commands for doing this vary from platform to platform. SWIG tries to guess the right options when it is installed. Therefore, you may want to start with one of the examples in the SWIG/Examples/tcl directory. If that doesn't work, you will need to read the man-pages for your compiler and linker to get the right set of options. You might also check the SWIG Wiki for additional information.

When linking the module, the name of the output file has to match the name of the module. If the name of your SWIG module is "example", the name of the corresponding object file should be "example.so". The name of the module is specified using the %module directive or the -module command line option.

23.1.3 Static linking

An alternative approach to dynamic linking is to rebuild the Tcl interpreter with your extension module added to it. In the past, this approach was sometimes necesssary due to limitations in dynamic loading support on certain machines. However, the situation has improved greatly over the last few years and you should not consider this approach unless there is really no other option.

The usual procedure for adding a new module to Tcl involves writing a special function Tcl_AppInit() and using it to initialize the interpreter and your module. With SWIG, the tclsh.i and wish.i library files can be used to rebuild the tclsh and wish interpreters respectively. For example:

%module example

extern int fact(int);
extern int mod(int, int);
extern double My_variable;

%include tclsh.i       // Include code for rebuilding tclsh

The tclsh.i library file includes supporting code that contains everything needed to rebuild tclsh. To rebuild the interpreter, you simply do something like this:

$ swig -tcl example.i
$ gcc example.c example_wrap.c \
        -Xlinker -export-dynamic \
        -DHAVE_CONFIG_H -I/usr/local/include/ \
	-L/usr/local/lib -ltcl -lm -ldl \
	-o mytclsh

You will need to supply the same libraries that were used to build Tcl the first time. This may include system libraries such as -lsocket, -lnsl, and -lpthread. If this actually works, the new version of Tcl should be identical to the default version except that your extension module will be a built-in part of the interpreter.

Comment: In practice, you should probably try to avoid static linking if possible. Some programmers may be inclined to use static linking in the interest of getting better performance. However, the performance gained by static linking tends to be rather minimal in most situations (and quite frankly not worth the extra hassle in the opinion of this author).

23.1.4 Using your module

To use your module, simply use the Tcl load command. If all goes well, you will be able to this:

$ tclsh
% load ./example.so
% fact 4
24
%
A common error received by first-time users is the following:
% load ./example.so
couldn't find procedure Example_Init
% 
This error is almost always caused when the name of the shared object file doesn't match the name of the module supplied using the SWIG %module directive. Double-check the interface to make sure the module name and the shared object file match. Another possible cause of this error is forgetting to link the SWIG-generated wrapper code with the rest of your application when creating the extension module.

Another common error is something similar to the following:

% load ./example.so
couldn't load file "./example.so": ./example.so: undefined symbol: fact
% 
This error usually indicates that you forgot to include some object files or libraries in the linking of the shared library file. Make sure you compile both the SWIG wrapper file and your original program into a shared library file. Make sure you pass all of the required libraries to the linker.

Sometimes unresolved symbols occur because a wrapper has been created for a function that doesn't actually exist in a library. This usually occurs when a header file includes a declaration for a function that was never actually implemented or it was removed from a library without updating the header file. To fix this, you can either edit the SWIG input file to remove the offending declaration or you can use the %ignore directive to ignore the declaration.

Finally, suppose that your extension module is linked with another library like this:

$ gcc -shared example.o example_wrap.o -L/home/beazley/projects/lib -lfoo \
      -o example.so
If the foo library is compiled as a shared library, you might get the following problem when you try to use your module:
% load ./example.so
couldn't load file "./example.so": libfoo.so: cannot open shared object file:
No such file or directory
%        
This error is generated because the dynamic linker can't locate the libfoo.so library. When shared libraries are loaded, the system normally only checks a few standard locations such as /usr/lib and /usr/local/lib. To fix this problem, there are several things you can do. First, you can recompile your extension module with extra path information. For example, on Linux you can do this:
$ gcc -shared example.o example_wrap.o -L/home/beazley/projects/lib -lfoo \
      -Xlinker -rpath /home/beazley/projects/lib \
      -o example.so
Alternatively, you can set the LD_LIBRARY_PATH environment variable to include the directory with your shared libraries. If setting LD_LIBRARY_PATH, be aware that setting this variable can introduce a noticeable performance impact on all other applications that you run. To set it only for Tcl, you might want to do this instead:
$ env LD_LIBRARY_PATH=/home/beazley/projects/lib tclsh
Finally, you can use a command such as ldconfig to add additional search paths to the default system configuration (this requires root access and you will need to read the man pages).

23.1.5 Compilation of C++ extensions

Compilation of C++ extensions has traditionally been a tricky problem. Since the Tcl interpreter is written in C, you need to take steps to make sure C++ is properly initialized and that modules are compiled correctly.

On most machines, C++ extension modules should be linked using the C++ compiler. For example:

% swig -c++ -tcl example.i
% g++ -c example.cxx
% g++ -c example_wrap.cxx -I/usr/local/include
% g++ -shared example.o example_wrap.o -o example.so
In addition to this, you may need to include additional library files to make it work. For example, if you are using the Sun C++ compiler on Solaris, you often need to add an extra library -lCrun like this:

% swig -c++ -tcl example.i
% CC -c example.cxx
% CC -c example_wrap.cxx -I/usr/local/include
% CC -G example.o example_wrap.o -L/opt/SUNWspro/lib -o example.so -lCrun
Of course, the extra libraries to use are completely non-portable---you will probably need to do some experimentation.

Sometimes people have suggested that it is necessary to relink the Tcl interpreter using the C++ compiler to make C++ extension modules work. In the experience of this author, this has never actually appeared to be necessary. Relinking the interpreter with C++ really only includes the special run-time libraries described above---as long as you link your extension modules with these libraries, it should not be necessary to rebuild Tcl.

If you aren't entirely sure about the linking of a C++ extension, you might look at an existing C++ program. On many Unix machines, the ldd command will list library dependencies. This should give you some clues about what you might have to include when you link your extension module. For example:

$ ldd swig
        libstdc++-libc6.1-1.so.2 => /usr/lib/libstdc++-libc6.1-1.so.2 (0x40019000)
        libm.so.6 => /lib/libm.so.6 (0x4005b000)
        libc.so.6 => /lib/libc.so.6 (0x40077000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
$

As a final complication, a major weakness of C++ is that it does not define any sort of standard for binary linking of libraries. This means that C++ code compiled by different compilers will not link together properly as libraries nor is the memory layout of classes and data structures implemented in any kind of portable manner. In a monolithic C++ program, this problem may be unnoticed. However, in Tcl, it is possible for different extension modules to be compiled with different C++ compilers. As long as these modules are self-contained, this probably won't matter. However, if these modules start sharing data, you will need to take steps to avoid segmentation faults and other erratic program behavior. If working with lots of software components, you might want to investigate using a more formal standard such as COM.

23.1.6 Compiling for 64-bit platforms

On platforms that support 64-bit applications (Solaris, Irix, etc.), special care is required when building extension modules. On these machines, 64-bit applications are compiled and linked using a different set of compiler/linker options. In addition, it is not generally possible to mix 32-bit and 64-bit code together in the same application.

To utilize 64-bits, the Tcl executable will need to be recompiled as a 64-bit application. In addition, all libraries, wrapper code, and every other part of your application will need to be compiled for 64-bits. If you plan to use other third-party extension modules, they will also have to be recompiled as 64-bit extensions.

If you are wrapping commercial software for which you have no source code, you will be forced to use the same linking standard as used by that software. This may prevent the use of 64-bit extensions. It may also introduce problems on platforms that support more than one linking standard (e.g., -o32 and -n32 on Irix).

23.1.7 Setting a package prefix

To avoid namespace problems, you can instruct SWIG to append a package prefix to all of your functions and variables. This is done using the -prefix option as follows :

swig -tcl -prefix Foo example.i

If you have a function "bar" in the SWIG file, the prefix option will append the prefix to the name when creating a command and call it "Foo_bar".

23.1.8 Using namespaces

Alternatively, you can have SWIG install your module into a Tcl namespace by specifying the -namespace option :

swig -tcl -namespace example.i

By default, the name of the namespace will be the same as the module name, but you can override it using the -prefix option.

When the -namespace option is used, objects in the module are always accessed with the namespace name such as Foo::bar.

23.2 Building Tcl/Tk Extensions under Windows 95/NT

Building a SWIG extension to Tcl/Tk under Windows 95/NT is roughly similar to the process used with Unix. Normally, you will want to produce a DLL that can be loaded into tclsh or wish. This section covers the process of using SWIG with Microsoft Visual C++. although the procedure may be similar with other compilers.

23.2.1 Running SWIG from Developer Studio

If you are developing your application within Microsoft developer studio, SWIG can be invoked as a custom build option. The process roughly follows these steps :

  • Open up a new workspace and use the AppWizard to select a DLL project.
  • Add both the SWIG interface file (the .i file), any supporting C files, and the name of the wrapper file that will be created by SWIG (ie. example_wrap.c). Note : If using C++, choose a different suffix for the wrapper file such as example_wrap.cxx. Don't worry if the wrapper file doesn't exist yet--Developer studio will keep a reference to it around.
  • Select the SWIG interface file and go to the settings menu. Under settings, select the "Custom Build" option.
  • Enter "SWIG" in the description field.
  • Enter "swig -tcl -o $(ProjDir)\$(InputName)_wrap.c $(InputPath)" in the "Build command(s) field"
  • Enter "$(ProjDir)\$(InputName)_wrap.c" in the "Output files(s) field".
  • Next, select the settings for the entire project and go to "C++:Preprocessor". Add the include directories for your Tcl installation under "Additional include directories".
  • Finally, select the settings for the entire project and go to "Link Options". Add the Tcl library file to your link libraries. For example "tcl80.lib". Also, set the name of the output file to match the name of your Tcl module (ie. example.dll).
  • Build your project.

Now, assuming all went well, SWIG will be automatically invoked when you build your project. Any changes made to the interface file will result in SWIG being automatically invoked to produce a new version of the wrapper file. To run your new Tcl extension, simply run tclsh or wish and use the load command. For example :


MSDOS > tclsh80
% load example.dll
% fact 4
24
%

23.2.2 Using NMAKE

Alternatively, SWIG extensions can be built by writing a Makefile for NMAKE. To do this, make sure the environment variables for MSVC++ are available and the MSVC++ tools are in your path. Now, just write a short Makefile like this :

# Makefile for building various SWIG generated extensions

SRCS          = example.c
IFILE         = example
INTERFACE     = $(IFILE).i
WRAPFILE      = $(IFILE)_wrap.c

# Location of the Visual C++ tools (32 bit assumed)

TOOLS         = c:\msdev
TARGET        = example.dll
CC            = $(TOOLS)\bin\cl.exe
LINK          = $(TOOLS)\bin\link.exe
INCLUDE32     = -I$(TOOLS)\include
MACHINE       = IX86

# C Library needed to build a DLL

DLLIBC        = msvcrt.lib oldnames.lib  

# Windows libraries that are apparently needed
WINLIB        = kernel32.lib advapi32.lib user32.lib gdi32.lib comdlg32.lib 
winspool.lib

# Libraries common to all DLLs
LIBS          = $(DLLIBC) $(WINLIB) 

# Linker options
LOPT      = -debug:full -debugtype:cv /NODEFAULTLIB /RELEASE /NOLOGO /
MACHINE:$(MACHINE) -entry:_DllMainCRTStartup@12 -dll

# C compiler flags

CFLAGS    = /Z7 /Od /c /nologo
TCL_INCLUDES  = -Id:\tcl8.0a2\generic -Id:\tcl8.0a2\win
TCLLIB        = d:\tcl8.0a2\win\tcl80.lib

tcl::
	..\..\swig -tcl -o $(WRAPFILE) $(INTERFACE)
	$(CC) $(CFLAGS) $(TCL_INCLUDES) $(SRCS) $(WRAPFILE)
	set LIB=$(TOOLS)\lib
	$(LINK) $(LOPT) -out:example.dll $(LIBS) $(TCLLIB) example.obj example_wrap.obj

To build the extension, run NMAKE (you may need to run vcvars32 first). This is a pretty minimal Makefile, but hopefully its enough to get you started. With a little practice, you'll be making lots of Tcl extensions.

23.3 A tour of basic C/C++ wrapping

By default, SWIG tries to build a very natural Tcl interface to your C/C++ code. Functions are wrapped as functions, classes are wrapped in an interface that mimics the style of Tk widgets and [incr Tcl] classes. This section briefly covers the essential aspects of this wrapping.

23.3.1 Modules

The SWIG %module directive specifies the name of the Tcl module. If you specify `%module example', then everything is compiled into an extension module example.so. When choosing a module name, make sure you don't use the same name as a built-in Tcl command.

One pitfall to watch out for is module names involving numbers. If you specify a module name like %module md5, you'll find that the load command no longer seems to work:

% load ./md5.so
couldn't find procedure Md_Init
To fix this, supply an extra argument to load like this:
% load ./md5.so md5

23.3.2 Functions

Global functions are wrapped as new Tcl built-in commands. For example,

%module example
int fact(int n);

creates a built-in function fact that works exactly like you think it does:

% load ./example.so
% fact 4
24
% set x [fact 6]
%

23.3.3 Global variables

C/C++ global variables are wrapped by Tcl global variables. For example:
// SWIG interface file with global variables
%module example
...
extern double density;
...

Now look at the Tcl interface:

% puts $density          # Output value of C global variable
1.0
% set density 0.95       # Change value

If you make an error in variable assignment, you will get an error message. For example:

% set density "hello"
can't set "density": Type error. expected a double.
%

If a variable is declared as const, it is wrapped as a read-only variable. Attempts to modify its value will result in an error.

To make ordinary variables read-only, you can use the %immutable directive. For example:

%immutable;
extern char *path;
%mutable;
The %immutable directive stays in effect until it is explicitly disabled using %mutable.

If you just want to make a specific variable immutable, supply a declaration name. For example:

%immutable path;
...
extern char *path;      // Read-only (due to %immutable)

23.3.4 Constants and enums

C/C++ constants are installed as global Tcl variables containing the appropriate value. To create a constant, use #define, enum, or the %constant directive. For example:
#define PI 3.14159
#define VERSION "1.0"

enum Beverage { ALE, LAGER, STOUT, PILSNER };

%constant int FOO = 42;
%constant const char *path = "/usr/local";
For enums, make sure that the definition of the enumeration actually appears in a header file or in the wrapper file somehow---if you just stick an enum in a SWIG interface without also telling the C compiler about it, the wrapper code won't compile.

Note: declarations declared as const are wrapped as read-only variables and will be accessed using the cvar object described in the previous section. They are not wrapped as constants. For further discussion about this, see the SWIG Basics chapter.

Constants are not guaranteed to remain constant in Tcl---the value of the constant could be accidentally reassigned.You will just have to be careful.

A peculiarity of installing constants as variables is that it is necessary to use the Tcl global statement to access constants in procedure bodies. For example:

proc blah {} {
   global FOO
   bar $FOO
}
If a program relies on a lot of constants, this can be extremely annoying. To fix the problem, consider using the following typemap rule:
%apply int CONSTANT { int x };
#define FOO 42
...
void bar(int x);
When applied to an input argument, the CONSTANT rule allows a constant to be passed to a function using its actual value or a symbolic identifier name. For example:
proc blah {} {
   bar FOO
}
When an identifier name is given, it is used to perform an implicit hash-table lookup of the value during argument conversion. This allows the global statement to be ommitted.

23.3.5 Pointers

C/C++ pointers are fully supported by SWIG. Furthermore, SWIG has no problem working with incomplete type information. Here is a rather simple interface:
%module example

FILE *fopen(const char *filename, const char *mode);
int fputs(const char *, FILE *);
int fclose(FILE *);
When wrapped, you will be able to use the functions in a natural way from Tcl. For example:
% load ./example.so
% set f [fopen junk w]
% fputs "Hello World\n" $f
% fclose $f
If this makes you uneasy, rest assured that there is no deep magic involved. Underneath the covers, pointers to C/C++ objects are simply represented as opaque values--normally an encoded character string like this:

% puts $f
_c0671108_p_FILE
% 
This pointer value can be freely passed around to different C functions that expect to receive an object of type FILE *. The only thing you can't do is dereference the pointer from Tcl.

The NULL pointer is represented by the string NULL.

As much as you might be inclined to modify a pointer value directly from Tcl, don't. The hexadecimal encoding is not necessarily the same as the logical memory address of the underlying object. Instead it is the raw byte encoding of the pointer value. The encoding will vary depending on the native byte-ordering of the platform (i.e., big-endian vs. little-endian). Similarly, don't try to manually cast a pointer to a new type by simply replacing the type-string. This may not work like you expect and it is particularly dangerous when casting C++ objects. If you need to cast a pointer or change its value, consider writing some helper functions instead. For example:

%inline %{
/* C-style cast */
Bar *FooToBar(Foo *f) {
   return (Bar *) f;
}

/* C++-style cast */
Foo *BarToFoo(Bar *b) {
   return dynamic_cast<Foo*>(b);
}

Foo *IncrFoo(Foo *f, int i) {
    return f+i;
}
%}
Also, if working with C++, you should always try to use the new C++ style casts. For example, in the above code, the C-style cast may return a bogus result whereas as the C++-style cast will return None if the conversion can't be performed.

23.3.6 Structures

If you wrap a C structure, it is wrapped by a Tcl interface that somewhat resembles a Tk widget. This provides a very natural interface. For example,

struct Vector {
	double x,y,z;
};

is used as follows:

% Vector v
% v configure -x 3.5 -y 7.2
% puts "[v cget -x] [v cget -y] [v cget -z]"
3.5 7.2 0.0
% 

Similar access is provided for unions and the data members of C++ classes.

In the above example, v is a name that's used for the object. However, underneath the covers, there's a pointer to a raw C structure. This can be obtained by looking at the -this attribute. For example:

% puts [v cget -this]
_88e31408_p_Vector
Further details about the relationship between the Tcl and the underlying C structure are covered a little later.

const members of a structure are read-only. Data members can also be forced to be read-only using the %immutable directive. For example:

struct Foo {
   ...
   %immutable;
   int x;        /* Read-only members */
   char *name;
   %mutable;
   ...
};

When char * members of a structure are wrapped, the contents are assumed to be dynamically allocated using malloc or new (depending on whether or not SWIG is run with the -c++ option). When the structure member is set, the old contents will be released and a new value created. If this is not the behavior you want, you will have to use a typemap (described later).

If a structure contains arrays, access to those arrays is managed through pointers. For example, consider this:

struct Bar {
    int  x[16];
};
If accessed in Tcl, you will see behavior like this:
% Bar b
% puts [b cget -x]
_801861a4_p_int
% 
This pointer can be passed around to functions that expect to receive an int * (just like C). You can also set the value of an array member using another pointer. For example:
% Bar c
% c configure -x [b cget -x]   # Copy contents of b.x to c.x
For array assignment, SWIG copies the entire contents of the array starting with the data pointed to by b.x. In this example, 16 integers would be copied. Like C, SWIG makes no assumptions about bounds checking---if you pass a bad pointer, you may get a segmentation fault or access violation.

When a member of a structure is itself a structure, it is handled as a pointer. For example, suppose you have two structures like this:

struct Foo {
   int a;
};

struct Bar {
   Foo f;
};
Now, suppose that you access the f attribute of Bar like this:
% Bar b
% set x [b cget -f]
In this case, x is a pointer that points to the Foo that is inside b. This is the same value as generated by this C code:
Bar b;
Foo *x = &b->f;       /* Points inside b */
However, one peculiarity of accessing a substructure like this is that the returned value does work quite like you might expect. For example:
% Bar b
% set x [b cget -f]
% x cget -a
invalid command name "x"
This is because the returned value was not created in a normal way from the interpreter (x is not a command object). To make it function normally, just evaluate the variable like this:
% Bar b
% set x [b cget -f]
% $x cget -a
0
%
In this example, x points inside the original structure. This means that modifications work just like you would expect. For example:

% Bar b
% set x [b cget -f]
% $x configure -a 3            # Modifies contents of f (inside b)
% [b cget -f] -configure -a 3  # Same thing
In many of these structure examples, a simple name like "v" or "b" has been given to wrapped structures. If necessary, this name can be passed to functions that expect to receive an object. For example, if you have a function like this,
void blah(Foo *f);
you can call the function in Tcl as follows:
% Foo x            # Create a Foo object 
% blah x           # Pass the object to a function
It is also possible to call the function using the raw pointer value. For instance:
% blah [x cget -this]   # Pass object to a function
It is also possible to create and use objects using variables. For example:
% set b [Bar]            # Create a Bar
% $b cget -f             # Member access
% puts $b
_108fea88_p_Bar
%
Finally, to destroy objects created from Tcl, you can either let the object name go out of scope or you can explicitly delete the object. For example:
% Foo f                 # Create object f
% rename f ""
or
% Foo f                 # Create object f
% f -delete
Note: Tcl only destroys the underlying object if it has ownership. See the memory management section that appears shortly.

23.3.7 C++ classes

C++ classes are wrapped as an extension of structure wrapping. For example, if you have this class,

class List {
public:
  List();
  ~List();
  int  search(char *item);
  void insert(char *item);
  void remove(char *item);
  char *get(int n);
  int  length;
};
you can use it in Tcl like this:
% List x
% x insert Ale
% x insert Stout
% x insert Lager
% x get 1
Stout
% puts [l cget -length]
3
%
Class data members are accessed in the same manner as C structures.

Static class members are accessed as global functions or variables. To illustrate, suppose you have a class like this:

class Spam {
public:
   static void foo();
   static int bar;

};
In Tcl, the static member is accessed as follows:
% Spam_foo        # Spam::foo()
% puts $Spam_bar  # Spam::bar

23.3.8 C++ inheritance

SWIG is fully aware of issues related to C++ inheritance. Therefore, if you have classes like this
class Foo {
...
};

class Bar : public Foo {
...
};
An object of type Bar can be used where a Foo is expected. For example, if you have this function:
void spam(Foo *f);
then the function spam() accepts a Foo * or a pointer to any class derived from Foo. For instance:
% Foo f      # Create a Foo
% Bar b      # Create a Bar
% spam f     # OK
% spam b     # OK

It is safe to use multiple inheritance with SWIG.

23.3.9 Pointers, references, values, and arrays

In C++, there are many different ways a function might receive and manipulate objects. For example:
void spam1(Foo *x);      // Pass by pointer
void spam2(Foo &x);      // Pass by reference
void spam3(Foo x);       // Pass by value
void spam4(Foo x[]);     // Array of objects
In Tcl, there is no detailed distinction like this. Because of this, SWIG unifies all of these types together in the wrapper code. For instance, if you actually had the above functions, it is perfectly legal to do this:
% Foo f             # Create a Foo
% spam1 f           # Ok. Pointer
% spam2 f           # Ok. Reference
% spam3 f           # Ok. Value.
% spam4 f           # Ok. Array (1 element)
Similar behavior occurs for return values. For example, if you had functions like this,
Foo *spam5();
Foo &spam6();
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 (Tcl will release this memory when the return value is garbage collected).

23.3.10 C++ overloaded functions

C++ overloaded functions, methods, and constructors are mostly supported by SWIG. For example, if you have two functions like this:
void foo(int);
void foo(char *c);
You can use them in Tcl in a straightforward manner:
% foo 3            # foo(int)
% foo Hello        # foo(char *c)
Similarly, if you have a class like this,
class Foo {
public:
    Foo();
    Foo(const Foo &);
    ...
};
you can write Tcl code like this:
% Foo f                # Create a Foo
% Foo g f              # Copy f
Overloading support is not quite as flexible as in C++. Sometimes there are methods that SWIG can't disambiguate. For example:
void spam(int);
void spam(short);
or
void foo(Bar *b);
void foo(Bar &b);
If declarations such as these appear, you will get a warning message like this:
example.i:12: Warning(509): Overloaded spam(short) is shadowed by spam(int) at example.i:11.
To fix this, you either need to ignore or rename one of the methods. For example:
%rename(spam_short) spam(short);
...
void spam(int);    
void spam(short);   // Accessed as spam_short
or
%ignore spam(short);
...
void spam(int);    
void spam(short);   // Ignored
SWIG resolves overloaded functions and methods using a disambiguation scheme that ranks and sorts declarations according to a set of type-precedence rules. The order in which declarations appear in the input does not matter except in situations where ambiguity arises--in this case, the first declaration takes precedence.

Please refer to the "SWIG and C++" chapter for more information about overloading.

23.3.11 C++ operators

Certain C++ overloaded operators can be handled automatically by SWIG. For example, consider a class like this:
class Complex {
private:
  double rpart, ipart;
public:
  Complex(double r = 0, double i = 0) : rpart(r), ipart(i) { }
  Complex(const Complex &c) : rpart(c.rpart), ipart(c.ipart) { }
  Complex &operator=(const Complex &c);
  Complex operator+(const Complex &c) const;
  Complex operator-(const Complex &c) const;
  Complex operator*(const Complex &c) const;
  Complex operator-() const;
  
  double re() const { return rpart; }
  double im() const { return ipart; }
};
When wrapped, it works like this:
% Complex c 3 4
% Complex d 7 8
% set e [c + d]
% $e re
10.0
% $e im
12.0
It should be stressed that operators in SWIG have no relationship to operators in Tcl. In fact, the only thing that's happening here is that an operator like operator + has been renamed to a method +. Therefore, the statement [c + d] is really just invoking the + method on c. When more than operator is defined (with different arguments), the standard method overloading facilities are used. Here is a rather odd looking example:
% Complex c 3 4
% Complex d 7 8
% set e [c - d]       # operator-(const Complex &)
% puts "[$e re] [$e im]"
10.0 12.0
% set f [c -]         # operator-()
% puts "[$f re] [$f im]"
-3.0 -4.0
%
One restriction with operator overloading support is that SWIG is not able to fully handle operators that aren't defined as part of the class. For example, if you had code like this
class Complex {
...
friend Complex operator+(double, const Complex &c);
...
};
then SWIG doesn't know what to do with the friend function--in fact, it simply ignores it and issues a warning. You can still wrap the operator, but you may have to encapsulate it in a special function. For example:
%rename(Complex_add_dc) operator+(double, const Complex &);
...
Complex operator+(double, const Complex &c);
There are ways to make this operator appear as part of the class using the %extend directive. Keep reading.

23.3.12 C++ namespaces

SWIG is aware of C++ namespaces, but 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,
%module example

namespace foo {
   int fact(int n);
   struct Vector {
       double x,y,z;
   };
};
it works in Tcl as follows:
% load ./example.so
% fact 3
6
% Vector v
% v configure -x 3.4
If your program has more than one namespace, name conflicts (if any) can be resolved using %rename For example:
%rename(Bar_spam) Bar::spam;

namespace Foo {
    int spam();
}

namespace Bar {
    int spam();
}
If you have more than one namespace and your want to keep their symbols separate, consider wrapping them as separate SWIG modules. For example, make the module name the same as the namespace and create extension modules for each namespace separately. If your program utilizes thousands of small deeply nested namespaces each with identical symbol names, well, then you get what you deserve.

23.3.13 C++ templates

C++ templates don't present a huge problem for SWIG. However, in order to create wrappers, you have to tell SWIG to create wrappers for a particular template instantiation. To do this, you use the %template directive. For example:
%module example
%{
#include "pair.h"
%}

template<class T1, class T2>
struct pair {
   typedef T1 first_type;
   typedef T2 second_type;
   T1 first;
   T2 second;
   pair();
   pair(const T1&, const T2&);
  ~pair();
};

%template(pairii) pair<int,int>;
In Tcl:
% pairii p 3 4
% p cget -first
3
% p cget -second
4
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

In certain C++ programs, it is common to use classes that have been wrapped by so-called "smart pointers." Generally, this involves the use of a template class that implements operator->() like this:
template<class T> class SmartPtr {
   ...
   T *operator->();
   ...
}
Then, if you have a class like this,
class Foo {
public:
     int x;
     int bar();
};
A smart pointer would be used in C++ as follows:
SmartPtr<Foo> p = CreateFoo();   // Created somehow (not shown)
...
p->x = 3;                        // Foo::x
int y = p->bar();                // Foo::bar
To wrap this in Tcl, simply tell SWIG about the SmartPtr class and the low-level Foo object. Make sure you instantiate SmartPtr using %template if necessary. For example:
%module example
...
%template(SmartPtrFoo) SmartPtr<Foo>;
...
Now, in Tcl, everything should just "work":
% set p [CreateFoo]                  # Create a smart-pointer somehow
% $p configure -x 3                  # Foo::x
% $p bar                             # Foo::bar
If you ever need to access the underlying pointer returned by operator->() itself, simply use the __deref__() method. For example:
% set f [$p __deref__]    # Returns underlying Foo *

23.4 Further details on the Tcl class interface

In the previous section, a high-level view of Tcl wrapping was presented. A key component of this wrapping is that structures and classes are wrapped by Tcl class-like objects. This provides a very natural Tcl interface and allows SWIG to support a number of advanced features such as operator overloading. However, a number of low-level details were omitted. This section provides a brief overview of how the proxy classes work.

23.4.1 Proxy classes

In the "SWIG basics" and "SWIG and C++" chapters, details of low-level structure and class wrapping are described. To summarize those chapters, if you have a class like this
class Foo {
public:
     int x;
     int spam(int);
     ...
then SWIG transforms it into a set of low-level procedural wrappers. For example:
Foo *new_Foo() {
    return new Foo();
}
void delete_Foo(Foo *f) {
    delete f;
}
int Foo_x_get(Foo *f) {
    return f->x;
}
void Foo_x_set(Foo *f, int value) {
    f->x = value;
}
int Foo_spam(Foo *f, int arg1) {
    return f->spam(arg1);
}
These wrappers are actually found in the Tcl extension module. For example, you can certainly do this:
% load ./example.so
% set f [new_Foo]
% Foo_x_get $f
0
% Foo_spam $f 3
1
%
However, in addition to this, the classname Foo is used as an object constructor function. This allows objects to be encapsulated objects that look a lot like Tk widgets as shown in the last section.

23.4.2 Memory management

Associated with each wrapped object, is an ownership flag thisown The value of this flag determines who is responsible for deleting the underlying C++ object. If set to 1, the Tcl interpreter destroys the C++ object when the proxy class is garbage collected. If set to 0 (or if the attribute is missing), then the destruction of the proxy class has no effect on the C++ object.

When an object is created by a constructor or returned by value, Tcl automatically takes ownership of the result. For example:

class Foo {
public:
    Foo();
    Foo bar();
};
In Tcl:
% Foo f
% f cget -thisown
1
% set g [f bar]
% $g cget -thisown
1
On the other hand, when pointers are returned to Tcl, there is often no way to know where they came from. Therefore, the ownership is set to zero. For example:
class Foo {
public:
    ...
    Foo *spam();
    ...
};
% Foo f
% set s [f spam]
% $s cget -thisown
0
% 
This behavior is especially important for classes that act as containers. For example, if a method returns a pointer to an object that is contained inside another object, you definitely don't want Tcl to assume ownership and destroy it!

Related to containers, ownership issues can arise whenever an object is assigned to a member or global variable. For example, consider this interface:

%module example

struct Foo {
    int  value;
    Foo  *next;
};

Foo *head = 0;
When wrapped in Tcl, careful observation will reveal that ownership changes whenever an object is assigned to a global variable. For example:
% Foo f
% f cget -thisown
1
% set head f
% f cget -thisown
0
In this case, C is now holding a reference to the object---you probably don't want Tcl to destroy it. Similarly, this occurs for members. For example:
% Foo f
% Foo g
% f cget -thisown
1
% g cget -thisown
1
% f configure -next g
% g cget -thisown 
0
%

For the most part, memory management issues remain hidden. However, there are occasionally situations where you might have to manually change the ownership of an object. For instance, consider code like this:

class Node {
   Object *value;
public:
   void set_value(Object *v) { value = v; }
   ...
};
Now, consider the following Tcl code:
% Object v                 # Create an object
% Node n                   # Create a node
% n setvalue v             # Set value
% v cget -thisown
1
% 
In this case, the object n is holding a reference to v internally. However, SWIG has no way to know that this has occurred. Therefore, Tcl still thinks that it has ownership of the object. Should the proxy object be destroyed, then the C++ destructor will be invoked and n will be holding a stale-pointer. If you're lucky, you will only get a segmentation fault.

To work around this, it is always possible to flip the ownership flag. For example,

% v -disown              # Give ownership to C/C++
% v -acquire             # Acquire ownership
It is also possible to deal with situations like this using typemaps--an advanced topic discussed later.

23.5 Input and output parameters

A common problem in some C programs is handling parameters passed as simple pointers. For example:
void add(int x, int y, int *result) {
   *result = x + y;
}
or perhaps
int sub(int *x, int *y) {
   return *x+*y;
}
The easiest way to handle these situations is to use the typemaps.i file. For example:
%module example
%include "typemaps.i"

void add(int, int, int *OUTPUT);
int  sub(int *INPUT, int *INPUT);
In Tcl, this allows you to pass simple values instead of pointer. For example:
set a [add 3 4]
puts $a
7
Notice how the INPUT parameters allow integer values to be passed instead of pointers and how the OUTPUT parameter creates a return result.

If you don't want to use the names INPUT or OUTPUT, use the %apply directive. For example:

%module example
%include "typemaps.i"

%apply int *OUTPUT { int *result };
%apply int *INPUT  { int *x, int *y};

void add(int x, int y, int *result);
int  sub(int *x, int *y);

If a function mutates one of its parameters like this,

void negate(int *x) {
   *x = -(*x);
}
you can use INOUT like this:
%include "typemaps.i"
...
void negate(int *INOUT);
In Tcl, a mutated parameter shows up as a return value. For example:
set a [negate 3]
puts $a
-3

The most common use of these special typemap rules is to handle functions that return more than one value. For example, sometimes a function returns a result as well as a special error code:

/* send message, return number of bytes sent, along with success code */
int send_message(char *text, int len, int *success);
To wrap such a function, simply use the OUTPUT rule above. For example:
%module example
%include "typemaps.i"
%apply int *OUTPUT { int *success };
...
int send_message(char *text, int *success);
When used in Tcl, the function will return multiple values as a list.
set r [send_message "Hello World"]
set bytes [lindex $r 0]
set success [lindex $r 1]
Another common use of multiple return values are in query functions. For example:
void get_dimensions(Matrix *m, int *rows, int *columns);
To wrap this, you might use the following:
%module example
%include "typemaps.i"
%apply int *OUTPUT { int *rows, int *columns };
...
void get_dimensions(Matrix *m, int *rows, *columns);
Now, in Perl:
set dim [get_dimensions $m]
set r  [lindex $dim 0]
set c  [lindex $dim 1]

23.6 Exception handling

The %exception directive can be used to create a user-definable exception handler in charge of converting exceptions in your C/C++ program into Tcl exceptions. The chapter on customization features contains more details, but suppose you extended the array example into a C++ class like the following :

class RangeError {};   // Used for an exception

class DoubleArray {
  private:
    int n;
    double *ptr;
  public:
    // Create a new array of fixed size
    DoubleArray(int size) {
      ptr = new double[size];
      n = size;
    }
    // Destroy an array
    ~DoubleArray() {
       delete ptr;
    }
    // Return the length of the array
    int   length() {
      return n;
    }

    // Get an item from the array and perform bounds checking.
    double getitem(int i) {
      if ((i >= 0) && (i < n))
        return ptr[i];
      else
        throw RangeError();
    }

    // Set an item in the array and perform bounds checking.
    void setitem(int i, double val) {
      if ((i >= 0) && (i < n))
        ptr[i] = val;
      else {
        throw RangeError();
      }
    }
  };

The functions associated with this class can throw a C++ range exception for an out-of-bounds array access. We can catch this in our Tcl extension by specifying the following in an interface file :

%exception {
  try {
    $action                // Gets substituted by actual function call
  }
  catch (RangeError) {
    Tcl_SetStringObj(tcl_result,"Array index out-of-bounds");
    return TCL_ERROR;
  }
}

As shown, the exception handling code will be added to every wrapper function. Since this is somewhat inefficient. You might consider refining the exception handler to only apply to specific methods like this:

%exception getitem {
  try {
    $action
  }
  catch (RangeError) {
    Tcl_SetStringObj(tcl_result,"Array index out-of-bounds");
    return TCL_ERROR;
  }
}

%exception setitem {
  try {
    $action
  }
  catch (RangeError) {
    Tcl_SetStringObj(tcl_result,"Array index out-of-bounds");
    return TCL_ERROR;
  }
}
In this case, the exception handler is only attached to methods and functions named getitem and setitem.

If you had a lot of different methods, you can avoid extra typing by using a macro. For example:

%define RANGE_ERROR
{
  try {
    $action
  }
  catch (RangeError) {
    Tcl_SetStringObj(tcl_result,"Array index out-of-bounds");
    return TCL_ERROR;
  }
}
%enddef

%exception getitem RANGE_ERROR;
%exception setitem RANGE_ERROR;
Since SWIG's exception handling is user-definable, you are not limited to C++ exception handling. See the chapter on "Customization Features" for more examples.

23.7 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 Tcl C API as well as the material in the "Typemaps" chapter.

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 primitive C-Tcl interface.

23.7.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 Tcl to C, you might define a typemap like this:

%module example

%typemap(in) int {
        if (Tcl_GetIntFromObj(interp,$input,&$1) == TCL_ERROR) return TCL_ERROR;
	printf("Received an integer : %d\n",$1);
}
extern int fact(int n);

Typemaps are always associated with some specific aspect of code generation. In this case, the "in" method refers to the conversion of input arguments to C/C++. The datatype int is the datatype to which the typemap will be applied. The supplied C code is used to convert values. In this code a number of special variable prefaced by a $ are used. The $1 variable is placeholder for a local variable of type int. The $input variable is the input object of type Tcl_Obj *.

When this example is compiled into a Tcl module, it operates as follows:

% load ./example.so
% fact 6
Received an integer : 6
720

In this example, the typemap is applied to all occurrences of the int datatype. You can refine this by supplying an optional parameter name. For example:

%module example

%typemap(in) int n {
        if (Tcl_GetIntFromObj(interp,$input,&$1) == TCL_ERROR) return TCL_ERROR;
	printf("n = %d\n",$1);
}
extern int fact(int n);
In this case, the typemap code is only attached to arguments that exactly match int n.

The application of a typemap to specific datatypes and argument names involves more than simple text-matching--typemaps are fully integrated into the SWIG type-system. When you define a typemap for int, that typemap applies to int and qualified variations such as const int. In addition, the typemap system follows typedef declarations. For example:

%typemap(in) int n {
        if (Tcl_GetIntFromObj(interp,$input,&$1) == TCL_ERROR) return TCL_ERROR;
	printf("n = %d\n",$1);
}
typedef int Integer;
extern int fact(Integer n);    // Above typemap is applied
However, the matching of typedef only occurs in one direction. If you defined a typemap for Integer, it is not applied to arguments of type int.

Typemaps can also be defined for groups of consecutive arguments. For example:

%typemap(in) (char *str, int len) {
    $1 = Tcl_GetStringFromObj($input,&$2);
};

int count(char c, char *str, int len);
When a multi-argument typemap is defined, the arguments are always handled as a single Tcl object. This allows the function to be used like this (notice how the length parameter is ommitted):
% count e "Hello World"
1

23.7.2 Tcl typemaps

The previous section illustrated an "in" typemap for converting Tcl objects to C. A variety of different typemap methods are defined by the Tcl module. For example, to convert a C integer back into a Tcl object, you might define an "out" typemap like this:
%typemap(out) int {
    Tcl_SetObjResult(interp,Tcl_NewIntObj($1));
}
The following list details all of the typemap methods that can be used by the Tcl module:

%typemap(in)

Converts Tcl objects to input function arguments

%typemap(out)
Converts return value of a C function to a Tcl object

%typemap(varin)
Assigns a C global variable from a Tcl object

%typemap(varout)
Returns a C global variable as a Tcl object

%typemap(freearg)
Cleans up a function argument (if necessary)

%typemap(argout)
Output argument processing

%typemap(ret)
Cleanup of function return values

%typemap(consttab)
Creation of Tcl constants (constant table)

%typemap(constcode)
Creation of Tcl constants (init function)
%typemap(memberin)
Setting of structure/class member data

%typemap(globalin)
Setting of C global variables

%typemap(check)
Checks function input values.

%typemap(default)
Set a default value for an argument (making it optional).
%typemap(arginit)
Initialize an argument to a value before any conversions occur.
Examples of these methods will appear shortly.

23.7.3 Typemap variables

Within typemap code, a number of special variables prefaced with a $ may appear. A full list of variables can be found in the "Typemaps" chapter. This is a list of the most common variables:

$1

A C local variable corresponding to the actual type specified in the %typemap directive. For input values, this is a C local variable that's supposed to hold an argument value. For output values, this is the raw result that's supposed to be returned to Tcl.

$input

A Tcl_Obj * holding a raw Tcl object with an argument or variable value.

$result

A Tcl_Obj * that holds the result to be returned to Tcl.

$1_name

The parameter name that was matched.

$1_type

The actual C datatype matched by the typemap.

$1_ltype

An assignable version of the datatype matched by the typemap (a type that can appear on the left-hand-side of a C assignment operation). This type is stripped of qualifiers and may be an altered version of $1_type. All arguments and local variables in wrapper functions are declared using this type so that their values can be properly assigned.
$symname
The Tcl name of the wrapper function being created.

23.7.4 Converting a Tcl list to a char **

A common problem in many C programs is the processing of command line arguments, which are usually passed in an array of NULL terminated strings. The following SWIG interface file allows a Tcl list to be used as a char ** object.

%module argv

// This tells SWIG to treat char ** as a special case
%typemap(in) char ** {
     Tcl_Obj **listobjv;
     int       nitems;
     int       i;
     if (Tcl_ListObjGetElements(interp, $input, &nitems, &listobjv) == TCL_ERROR) {
        return TCL_ERROR;
     }
     $1 = (char **) malloc((nitems+1)*sizeof(char *));
     for (i = 0; i < nitems; i++) {
        $1[i] = Tcl_GetStringFromObj(listobjv[i],0);
     }
     $1[i] = 0;
}

// This gives SWIG some cleanup code that will get called after the function call
%typemap(freearg) char ** {
     if ($1) {
        free($1);
     }
}

// Now a test functions
%inline %{
int print_args(char **argv) {
    int i = 0;
    while (argv[i]) {
         printf("argv[%d] = %s\n", i,argv[i]);
         i++;
    }
    return i;
}
%}
%include tclsh.i

In Tcl:

% print_args {John Guido Larry}
argv[0] = John
argv[1] = Guido
argv[2] = Larry
3

23.7.5 Returning values in arguments

The "argout" typemap can be used to return a value originating from a function argument. For example :

// A typemap defining how to return an argument by appending it to the result
%typemap(argout) double *outvalue {
     Tcl_Obj *o = Tcl_NewDoubleObj($1);
     Tcl_ListObjAppendElement(interp,$result,o);
}

// A typemap telling SWIG to ignore an argument for input
// However, we still need to pass a pointer to the C function
%typemap(in,numinputs=0) double *outvalue (double temp) {
     $1 = &temp;
}

// Now a function returning two values
int mypow(double a, double b, double *outvalue) {
        if ((a < 0) || (b < 0)) return -1;
        *outvalue = pow(a,b);
        return 0;
};

When wrapped, SWIG matches the argout typemap to the "double *outvalue" argument. The numinputs=0 specification tells SWIG to simply ignore this argument when generating wrapper code. As a result, a Tcl function using these typemaps will work like this :

% mypow 2 3     # Returns two values, a status value and the result
0 8
%

23.7.6 Useful functions

The following tables provide some functions that may be useful in writing Tcl typemaps.

Integers

Tcl_Obj   *Tcl_NewIntObj(int Value);
void       Tcl_SetIntObj(Tcl_Obj *obj, int Value);
int        Tcl_GetIntFromObj(Tcl_Interp *, Tcl_Obj *obj, int *ip);
Floating Point
Tcl_Obj  *Tcl_NewDoubleObj(double Value);
void      Tcl_SetDoubleObj(Tcl_Obj *obj, double value);
int       Tcl_GetDoubleFromObj(Tcl_Interp *, Tcl_Obj *o, double *dp);
Strings
Tcl_Obj  *Tcl_NewStringObj(char *str, int len);
void      Tcl_SetStringObj(Tcl_Obj *obj, char *str, int len);
char     *Tcl_GetStringFromObj(Tcl_Obj *obj, int *len);
void      Tcl_AppendToObj(Tcl_Obj *obj, char *str, int len);
Lists
Tcl_Obj  *Tcl_NewListObj(int objc, Tcl_Obj *objv);
int       Tcl_ListObjAppendList(Tcl_Interp *, Tcl_Obj *listPtr, Tcl_Obj *elemListPtr);
int       Tcl_ListObjAppendElement(Tcl_Interp *, Tcl_Obj *listPtr, Tcl_Obj *element);
int       Tcl_ListObjGetElements(Tcl_Interp *, Tcl_Obj *listPtr, int *objcPtr, Tcl_Obj ***objvPtr);
int       Tcl_ListObjLength(Tcl_Interp *, Tcl_Obj *listPtr, int *intPtr);
int       Tcl_ListObjIndex(Tcl_Interp *, Tcl_Obj *listPtr, int index, Tcl_Obj_Obj **objptr);
int       Tcl_ListObjReplace(Tcl_Interp *, Tcl_Obj *listPtr, int first, int count, int objc, Tcl_Obj *objv);
Objects
Tcl_Obj *Tcl_DuplicateObj(Tcl_Obj *obj);
void     Tcl_IncrRefCount(Tcl_Obj *obj);
void     Tcl_DecrRefCount(Tcl_Obj *obj);
int      Tcl_IsShared(Tcl_Obj *obj);

23.7.7 Standard typemaps

The following typemaps show how to convert a few common kinds of objects between Tcl and C (and to give a better idea of how typemaps work)

Integer conversion

%typemap(in) int, short, long {
   int temp;
   if (Tcl_GetIntFromObj(interp, $input, &temp) == TCL_ERROR)
      return TCL_ERROR;
   $1 = ($1_ltype) temp;
}

%typemap(out) int, short, long {
   Tcl_SetIntObj($result,(int) $1);
}
Floating point conversion
%typemap(in) float, double {
   double temp;
   if (Tcl_GetDoubleFromObj(interp, $input, &temp) == TCL_ERROR)
       return TCL_ERROR;
   $1 = ($1_ltype) temp;
}

%typemap(out) float, double {
   Tcl_SetDoubleObj($result, $1);
}
String Conversion
%typemap(in) char * {
   int len;
   $1 = Tcl_GetStringFromObj(interp, &len);
   }
}

%typemap(out) char * {
   Tcl_SetStringObj($result,$1);
}

23.7.8 Pointer handling

SWIG pointers are mapped into Tcl strings containing the hexadecimal value and type. The following functions can be used to create and read pointer values.

int SWIG_ConvertPtr(Tcl_Obj *obj, void **ptr, swig_type_info *ty, int flags)

Converts a Tcl object obj to a C pointer. The result of the conversion is placed into the pointer located at ptr. ty is a SWIG type descriptor structure. flags is used to handle error checking and other aspects of conversion. It is currently reserved for future expansion. Returns 0 on success and -1 on error.

Tcl_Obj *SWIG_NewPointerObj(void *ptr, swig_type_info *ty, int flags)

Creates a new Tcl pointer object. ptr is the pointer to convert, ty is the SWIG type descriptor structure that describes the type, and own is a flag reserved for future expansion.
Both of these functions require the use of a special SWIG type-descriptor structure. This structure contains information about the mangled name of the datatype, type-equivalence information, as well as information about converting pointer values under C++ inheritance. For a type of Foo *, the type descriptor structure is usually accessed as follows:
Foo *f;
if (SWIG_ConvertPtr($input, (void **) &f, SWIGTYPE_p_Foo, 0) == -1) return NULL;

Tcl_Obj *;
obj = SWIG_NewPointerObj(f, SWIGTYPE_p_Foo, 0);
In a typemap, the type descriptor should always be accessed using the special typemap variable $1_descriptor. For example:
%typemap(in) Foo * {
   if ((SWIG_ConvertPtr($input,(void **) &$1, $1_descriptor,0)) == -1) return NULL;
}

If necessary, the descriptor for any type can be obtained using the $descriptor() macro in a typemap. For example:

%typemap(in) Foo * {
   if ((SWIG_ConvertPtr($input,(void **) &$1, $descriptor(Foo *), 0)) == -1) return NULL;
}

23.8 Turning a SWIG module into a Tcl Package.

Tcl 7.4 introduced the idea of an extension package. By default, SWIG generates all of the code necessary to create a package. To set the package version, simply use the -pkgversion option. For example:
% swig -tcl -pkgversion 2.3 example.i
After building the SWIG generated module, you need to execute the "pkg_mkIndex" command inside tclsh. For example :

unix > tclsh
% pkg_mkIndex . example.so
% exit

This creates a file "pkgIndex.tcl" with information about the package. To use your

package, you now need to move it to its own subdirectory which has the same name as the package. For example :

./example/
	   pkgIndex.tcl           # The file created by pkg_mkIndex
	   example.so             # The SWIG generated module

Finally, assuming that you're not entirely confused at this point, make sure that the example subdirectory is visible from the directories contained in either the tcl_library or auto_path variables. At this point you're ready to use the package as follows :

unix > tclsh
% package require example
% fact 4
24
%

If you're working with an example in the current directory and this doesn't work, do this instead :

unix > tclsh
% lappend auto_path .
% package require example
% fact 4
24

As a final note, most SWIG examples do not yet use the package commands. For simple extensions it may be easier just to use the load command instead.

23.9 Building new kinds of Tcl interfaces (in Tcl)

One of the most interesting aspects of Tcl and SWIG is that you can create entirely new kinds of Tcl interfaces in Tcl using the low-level SWIG accessor functions. For example, suppose you had a library of helper functions to access arrays :

/* File : array.i */
%module array

%inline %{
double *new_double(int size) {
        return (double *) malloc(size*sizeof(double));
}
void delete_double(double *a) {
        free(a);
}
double get_double(double *a, int index) {
        return a[index];
}
void set_double(double *a, int index, double val) {
        a[index] = val;
}
int *new_int(int size) {
        return (int *) malloc(size*sizeof(int));
}
void delete_int(int *a) {
        free(a);
}
int get_int(int *a, int index) {
        return a[index];
}
int set_int(int *a, int index, int val) {
        a[index] = val;
}
%}

While these could be called directly, we could also write a Tcl script like this :

proc Array {type size} {
    set ptr [new_$type $size]
    set code {
        set method [lindex $args 0]
        set parms [concat $ptr [lrange $args 1 end]]
        switch $method {
            get {return [eval "get_$type $parms"]}
            set {return [eval "set_$type $parms"]}
            delete {eval "delete_$type $ptr; rename $ptr {}"}
        }
    }
    # Create a procedure
    uplevel "proc $ptr args {set ptr $ptr; set type $type;$code}"
    return $ptr
}

Our script allows easy array access as follows :

set a [Array double 100]                   ;# Create a double [100]
for {set i 0} {$i < 100} {incr i 1} {      ;# Clear the array
	$a set $i 0.0
}
$a set 3 3.1455                            ;# Set an individual element
set b [$a get 10]                          ;# Retrieve an element

set ia [Array int 50]                      ;# Create an int[50]
for {set i 0} {$i < 50} {incr i 1} {       ;# Clear it
	$ia set $i 0
}
$ia set 3 7                                ;# Set an individual element
set ib [$ia get 10]                        ;# Get an individual element

$a delete                                  ;# Destroy a
$ia delete                                 ;# Destroy ia

The cool thing about this approach is that it makes a common interface for two different types of arrays. In fact, if we were to add more C datatypes to our wrapper file, the Tcl code would work with those as well--without modification. If an unsupported datatype was requested, the Tcl code would simply return with an error so there is very little danger of blowing something up (although it is easily accomplished with an out of bounds array access).

23.9.1 Shadow classes

A similar approach can be applied to shadow classes. The following example is provided by Erik Bierwagen and Paul Saxe. To use it, run SWIG with the -noobject option (which disables the builtin object oriented interface). When running Tcl, simply source this file. Now, objects can be used in a more or less natural fashion.

# swig_c++.tcl
# Provides a simple object oriented interface using
# SWIG's low level interface.
#

proc new {objectType handle_r args} {
    # Creates a new SWIG object of the given type,
    # returning a handle in the variable "handle_r".
    #
    # Also creates a procedure for the object and a trace on
    # the handle variable that deletes the object when the
    # handle varibale is overwritten or unset
    upvar $handle_r handle
    #
    # Create the new object
    #
    eval set handle \[new_$objectType $args\]
    #
    # Set up the object procedure
    #
    proc $handle {cmd args} "eval ${objectType}_\$cmd $handle \$args"
    #
    # And the trace ...
    #
    uplevel trace variable $handle_r uw "{deleteObject $objectType $handle}"
    #
    # Return the handle so that 'new' can be used as an argument to a procedure
    #
    return $handle
}

proc deleteObject {objectType handle name element op} {
    #
    # Check that the object handle has a reasonable form
    #
    if {![regexp {_[0-9a-f]*_(.+)_p} $handle]} {
        error "deleteObject: not a valid object handle: $handle"
    }
    #
    # Remove the object procedure
    #
    catch {rename $handle {}}
    #
    # Delete the object
    #
    delete_$objectType $handle
}

proc delete {handle_r} {
    #
    # A synonym for unset that is more familiar to C++ programmers
    #
    uplevel unset $handle_r
}

To use this file, we simply source it and execute commands such as "new" and "delete" to manipulate objects. For example :

// list.i
%module List
%{
#include "list.h"
%}

// Very simple C++ example

class List {
public:
  List();  // Create a new list
  ~List(); // Destroy a list
  int  search(char *value);
  void insert(char *);  // Insert a new item into the list
  void remove(char *);  // Remove item from list
  char *get(int n);     // Get the nth item in the list
  int  length;          // The current length of the list
static void print(List *l);  // Print out the contents of the list
};

Now a Tcl script using the interface...

load ./list.so list       ; # Load the module
source swig_c++.tcl       ; # Source the object file

new List l
$l insert Dave
$l insert John
$l insert Guido
$l remove Dave
puts $l length_get

delete l

The cool thing about this example is that it works with any C++ object wrapped by SWIG and requires no special compilation. Proof that a short, but clever Tcl script can be combined with SWIG to do many interesting things.


SWIG 1.3 - Last Modified : May 28, 2002
cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/Pike.html0000644000175000000620000001330612561312226021300 0ustar stevestaff SWIG and Pike

5 SWIG and Pike

This chapter describes SWIG support for Pike. As of this writing, the SWIG Pike module is still under development and is not considered ready for prime time. The Pike module is being developed against the Pike 7.4.10 release and may not be compatible with previous versions of Pike.

This chapter covers most SWIG features, but certain low-level details are covered in less depth than in earlier chapters. At the very least, make sure you read the "SWIG Basics" chapter.

5.1 Preliminaries

5.1.1 Running SWIG

Suppose that you defined a SWIG module such as the following:
%module example

%{
#include "example.h"
%}

int fact(int n);
To build a C extension module for Pike, run SWIG using the -pike option :
$ swig -pike example.i
If you're building a C++ extension, be sure to add the -c++ option:
$ swig -c++ -pike example.i
This creates a single source file named example_wrap.c (or example_wrap.cxx, if you ran SWIG with the -c++ option). The SWIG-generated source file contains the low-level wrappers that need to be compiled and linked with the rest of your C/C++ application to create an extension module.

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:

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

5.1.2 Getting the right header files

In order to compile the C/C++ wrappers, the compiler needs to know the path to the Pike header files. These files are usually contained in a directory such as

/usr/local/pike/7.4.10/include/pike
There doesn't seem to be any way to get Pike itself to reveal the location of these files, so you may need to hunt around for them. You're looking for files with the names global.h, program.h and so on.

5.1.3 Using your module

To use your module, simply use Pike's import statement:
$ pike
Pike v7.4 release 10 running Hilfe v3.5 (Incremental Pike Frontend)
> import example;
> fact(4);
(1) Result: 24

5.2 Basic C/C++ Mapping

5.2.1 Modules

All of the code for a given SWIG module is wrapped into a single Pike module. Since the name of the shared library that implements your module ultimately determines the module's name (as far as Pike is concerned), SWIG's %module directive doesn't really have any significance.

5.2.2 Functions

Global functions are wrapped as new Pike built-in functions. For example,
%module example

int fact(int n);
creates a new built-in function example.fact(n) that works exactly as you'd expect it to:
> import example;
> fact(4);
(1) Result: 24

5.2.3 Global variables

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

double Foo;
will result in two functions, Foo_get() and Foo_set():
> import example;
> Foo_get();
(1) Result: 3.000000
> Foo_set(3.14159);
(2) Result: 0
> Foo_get();
(3) Result: 3.141590

5.2.4 Constants and enumerated types

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

5.2.5 Constructors and Destructors

Constructors are wrapped as create() methods, and destructors are wrapped as destroy() methods, for Pike classes.

5.2.6 Static Members

Since Pike doesn't support static methods or data for Pike classes, static member functions in your C++ classes are wrapped as regular functions and static member variables are wrapped as pairs of functions (one to get the value of the static member variable, and another to set it). The names of these functions are prepended with the name of the class. For example, given this C++ class declaration:
class Shape
{
public:
    static void print();
    static int nshapes;
};
SWIG will generate a Shape_print() method that invokes the static Shape::print() member function, as well as a pair of methods, Shape_nshapes_get() and Shape_nshapes_set(), to get and set the value of Shape::nshapes.cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/Chicken.html0000644000175000000620000004263112561312226021757 0ustar stevestaff SWIG and Chicken

24 SWIG and Chicken

This chapter describes SWIG's support of CHICKEN. CHICKEN is a Scheme-to-C compiler supporting most of the language features as defined in the Revised^5 Report on Scheme. Its main attributes are that it

  1. generates portable C code
  2. includes a customizable interpreter
  3. links to C libraries with a simple Foreign Function Interface
  4. supports full tail-recursion and first-class continuations
When confronted with a large C library, CHICKEN users can use SWIG to generate CHICKEN wrappers for the C library. However, the real advantages of using SWIG with CHICKEN are its support for C++ -- object-oriented code is difficult to wrap by hand in CHICKEN -- and its typed pointer representation, essential for C and C++ libraries involving structures or classes.

24.1 Preliminaries

CHICKEN support was introduced to SWIG in version 1.3.18. SWIG relies on some recent additions to CHICKEN, which are only present in releases of CHICKEN with version number greater than or equal to 1.0.

CHICKEN can be downloaded from http://www.call-with-current-continuation.org/chicken.html You may want to look at any of the examples in Examples/chicken/ or Examples/GIFPlot/Chicken for the basic steps to run SWIG CHICKEN. We will generically refer to the wrapper as the generated files.

24.1.1 Running SWIG in C mode

To run SWIG CHICKEN in C mode, use the -chicken option.

% swig -chicken example.i
To allow the wrapper to take advantage of future CHICKEN code generation improvements, part of the wrapper is direct CHICKEN function calls (example_wrap.c) and part is CHICKEN Scheme (example.scm). The basic Scheme code must be compiled to C using your system's CHICKEN compiler.
% chicken example.scm -output-file oexample.c
So for the C mode of SWIG CHICKEN, example_wrap.c and oexample.c are the files that must be compiled to object files and linked into your project.

24.1.2 Running SWIG in C++ mode

To run SWIG CHICKEN in C++ mode, use the -chicken -c++ option.

% swig -chicken -c++ example.i
This will generate example_wrap.cxx, example.scm, example-generic.scm and example-clos.scm. The basic Scheme code must be compiled to C using your system's CHICKEN compiler.
% chicken example.scm -output-file oexample.c
So for the C++ mode of SWIG CHICKEN, example_wrap.cxx and oexample.c are the files that must be compiled to object files and linked into your project.

24.2 Code Generation

24.2.1 Naming Conventions

Given a C variable, function or constant declaration named Foo_Bar_to_Foo_Baz, the declaration will be available in CHICKEN as an identifier ending with foo-bar->foo-baz. That is, an underscore is converted to a dash, '_to_' is converted to an arro, and all characters are sent to lowercase.

Additionally, there is a mixed mode that can be specified with the -mixed option on the SWIG command line. In this mode, the above rules apply with the addition that changes in case are indications to SWIG CHICKEN to place a dash in the CHICKEN identifier. For example, a C declartaion named someDeclaration_xyz will be available as the CHICKEN identifier ending with some-declaration-xyz.

You may control what the CHICKEN identifier will be by using the %rename SWIG directive in the SWIG interface file.

24.2.2 Modules and Prefixes

SWIG CHICKEN does not use the standard CHICKEN module system (which has been deprecated); instead, it uses a prefix system. Specifying the module name as 'example' in SWIG CHICKEN can be done using either of:

  • Placing %module example in the SWIG interface file.
  • Using -module example on the SWIG command line.
CHICKEN will be able to access the module using the (declare (uses modulename)) CHICKEN Scheme form.

Normally, for a C declaration Foo_Bar with a module name of 'example', the corresponding CHICKEN identifier will be example:foo-bar. The module name and a colon is prefixed to the CHICKEN identifier (following normal naming conventions).

You may explicitly override the prefix with the SWIG command line option -prefix whateverprefix, or you may remove the prefix with the option -noprefix.

24.2.3 Constants and Variables

Constants may be created using any of the four constructs in the interface file:

  1. #define MYCONSTANT1 ...
  2. %constant int MYCONSTANT2 = ...
  3. const int MYCONSTANT3 = ...
  4. enum { MYCONSTANT4 = ... };
In all cases, the constants may be accessed from with CHICKEN using the form (myconstant1); that is, the constants may be accessed using the read-only parameter form.

Variables are accessed using the full parameter form. For example, to set the C variable "int my_variable;", use the Scheme form (my-variable 2345). To get the C variable, use (my-variable).

24.2.4 Functions

C functions declared in the SWIG interface file will have corresponding CHICKEN Scheme procedures. For example, the C function "int sqrt(double x);" will be available using the Scheme form (sqrt 2345.0). A void return value will give C_SCHEME_UNDEFINED as a result.

A function may return more than one value by using the OUTPUT specifier (see Lib/chicken/typemaps.i). They will be returned as a Scheme list if there is more than one result (that is, a non-void return value and at least one argout parameter, or a void return value and at least two argout parameters).

24.3 TinyCLOS

The author of TinyCLOS, Gregor Kiczales, describes TinyCLOS as:

Tiny CLOS is a Scheme implementation of a `kernelized' CLOS, with a metaobject protocol. The implementation is even simpler than the simple CLOS found in `The Art of the Metaobject Protocol,' weighing in at around 850 lines of code, including (some) comments and documentation.
Almost all good Scheme books describe how to use metaobjects and generic procedures to implement an object-oriented Scheme system. Please consult a Scheme book if you are unfamiliar with the concept.

CHICKEN has a modified version of TinyCLOS, which SWIG CHICKEN uses in C++ mode. SWIG CHICKEN generates a xxx-generic.scm and a xxx-clos.scm file, which contain TinyCLOS macros. When using these macros, you will need to (include "xxx-generic") all the generic macros your program needs, and then (include "xxx-clos") all the metaobject (class) macros your program needs.

SWIG CHICKEN will call the destructor for all TinyCLOS objects that are garbage-collected by CHICKEN. It also allows access to the underlying low-level Scheme procedures with (de)-marshaling of any TinyCLOS parameters. It is best to learn the TinyCLOS system by running the Examples/chicken/class/ example.

24.4 Compilation

Please refer to CHICKEN - A practical and portable Scheme system - User's manual for detailed help on how to compile C code for use in a CHICKEN program. Briefly, to compile C code, be sure to add `chicken-config -cflags` or `chicken-config -shared -cflags` to your compiler options. Use the -shared option if you want to create a dynamically loadable module. You might also want to use the much simpler csc or csc.bat.

24.5 Linkage

Please refer to CHICKEN - A practical and portable Scheme system - User's manual for detailed help on how to link object files to create a CHICKEN Scheme program. Briefly, to link object files, be sure to add `chicken-config -extra-libs -libs` or `chicken-config -shared -extra-libs -libs`to your linker options. Use the -shared option if you want to create a dynamically loadable module.

All the following examples assume that the module is named 'example' and the following occurs when run:

% chicken-config -home
CHICKEN_HOME=/usr/local/share/chicken
Substitute /usr/local/share/chicken as appropriate for your platform.

24.5.1 Customized Interpreter

We will assume your files are in a directory /home/jonah/examples. Make a file as follows:

;; precsi.scm
(declare (unit precsi))
(declare (uses example))

;; any other code you want run before the main interpreter is executed
      
Run SWIG on your interface file as usual, create the 2 wrapper object files, and then either
% cd /usr/local/share/chicken
% chicken /usr/local/share/chicken/src/csi.scm -optimize-level 3 -quiet \
        -include-path /usr/local/share/chicken/src \
        -prologue /usr/local/share/chicken/src/build.scm \
        -prelude "(declare (uses posix precsi))" \
        -output-file /home/jonah/examples/csi-example.c
% cd /home/jonah/examples
% chicken precsi.scm -optimize-level 3 --explicit-use \
        -output-file precsi.c
% gcc precsi.c csi.c wrapper_object_files \
        `chicken-config -libs` `chicken-config -extra-libs` -o csi-example
	
      
or
% extend-csi precsi -output-file csi-example

24.6 Typemaps

The Chicken module handles all types via typemaps. This information is read from Lib/chicken/typemaps.i and Lib/chicken/chicken.swg.

Two Chicken-specific typemaps are supported: clos_in and clos_out. They are for converting TinyCLOS to and from low-level CHICKEN SWIG. Here is a quick example:

/* Let "Shape" objects be converted back and forth from TinyCLOS into
   low-level CHICKEN SWIG procedures */

%typemap(clos_in) Shape * = SIMPLE_CLOS_OBJECT *;
%typemap(clos_out) Shape * = SIMPLE_CLOS_OBJECT *;
	
The SIMPLE_CLOS_OBJECT will generally be all that is needed ... the definition of this is as follows:
/* TinyCLOS <--> Low-level CHICKEN */

%typemap("clos_in") SIMPLE_CLOS_OBJECT * "(slot-ref $input (quote this))"
%typemap("clos_out") SIMPLE_CLOS_OBJECT * "(make $class (quote this) $1)"
	
Now, in the example using "Shape" objects, all objects instantiated from Shape or any of its subclasses fully known to SWIG will have correct TinyCLOS representations based on SIMPLE_CLOS_OBJECT. SWIG "knows" the classes that are exposed in the SWIG interface file; it "fully knows" only those classes that are not forward declarations.

A real-world example of the "fully knows" problem is found in the VTK visualization library. All VTK classes are derived from vtkObject.
   /* FILE: vtkObject.h */
   class vtkObject {
      // ...
   };
	
   /* FILE: vtkWindow.h */
   #include "vtkObject.h"

   class vtkWindow : public vtkObject {
      // ...
   };
	
   /* FILE: vtkViewport.h */
   #include "vtkViewport.h"

   class vtkViewport : public vtkObject {
      // ...
   };
	
   /* FILE: vtkRenderWindow.h */
   #include "vtkWindow.h"

   class vtkRenderer;
   class vtkRenderWindow : public vtkWindow {
      // ...
      virtual void AddRenderer (vtkRenderer *rendererArg);
      // ...
   };
	
   /* FILE: vtkRenderer.h */
   #include "vtkViewport.h"

   class vtkRenderWindow;
   class vtkRenderer : public vtkViewport {
      // ...
      void SetRenderWindow(vtkRenderWindow *);
      // ...
   };
	
   /* FILE: vtk.i; SWIG interface file */
   %typemap(clos_in) vtkObject * = SIMPLE_CLOS_OBJECT *;
   %typemap(clos_out) vtkObject * = SIMPLE_CLOS_OBJECT *;
   %include "vtkObject.h"
   %include "vtkWindow.h"
   %include "vtkViewport.h"
   %include "vtkRenderWindow.h"
   %include "vtkRenderer.h"
	
After SWIG processes vtkObject.h (from the %include "vtkObject.h" line), SWIG will have the complete definition of the vtkObject class because vtkObject does not contain any references to any other classes. As it reads vtkWindow.h and vtkViewport.h, it will already have the definition of vtkObject, so it will not need a clos_in or clos_out typemap for the vtkWindow or vtkViewport subclasses of vtkObject. However, by the time SWIG gets to %include "vtkRenderWindow.h", it will not have the definition for the vtkRenderer class, even though it is used by vtkRenderWindow. We therefore must put in clos_in/clos_out typemaps for vtkRenderer.

24.7 Pointers

For pointer types, SWIG uses CHICKEN tagged pointers. A tagged pointer is an ordinary CHICKEN pointer with an extra slot for an arbitrary Scheme object. With SWIG CHICKEN, this Scheme object is a reference to a type-info structure. So each pointer used as input or output from the SWIG-generated CHICKEN wrappers will have type information attached to it. This will let the wrappers correctly determine which method should be called according to the object type hierarchy exposed in the SWIG interface files.

To construct a Scheme object from a C pointer, the wrapper code calls the function swig_new_pointer_obj(), passing stack allocation space of size SWIG_ALLOCSZ_POINTER (see definition in Lib/chicken/chickenrun.swg and also C_alloc() in the CHICKEN documentation) and a pointer to a struct representing the pointer type.

To get the pointer represented by a CHICKEN tagged pointer, the wrapper code calls the function swig_convert_ptr(), passing a pointer to a struct representing the expected pointer type. If the Scheme object passed was not a tagged pointer representing a compatible pointer, a non-zero value is returned.

Warning: The Chicken typechecking code seems to be broken (Bug #782468), so that type errors may not be reported.

24.8 Unsupported features

  • No exception handling.
cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/Library.html0000644000175000000620000010737112561312226022022 0ustar stevestaff SWIG Library

13 SWIG library

To help build extension modules, SWIG is packaged with a library of support files that you can include in your own interfaces. These files often define new SWIG directives or provide utility functions that can be used to access parts of the standard C and C++ libraries. This chapter provides a reference to the current set of supported library files.

Compatibility note: Older versions of SWIG included a number of library files for manipulating pointers, arrays, and other structures. Most these files are now deprecated and have been removed from the distribution. Alternative libraries provide similar functionality. Please read this chapter carefully if you used the old libraries.

13.1 The %include directive and library search path

Library files are included using the %include directive. When searching for files, directories are searched in the following order:

  • The current directory
  • Directories specified with the -I command line option
  • ./swig_lib
  • /usr/local/lib/swig_lib (or wherever you installed SWIG)
  • On Windows, SWIG also looks for the library relative to the location of swig.exe.

Within each directory, SWIG first looks for a subdirectory corresponding to a target language (e.g., python, tcl, etc.). If found, SWIG will search the language specific directory first. This allows for language-specific implementations of library files.

You can override the location of the SWIG library by setting the SWIG_LIB environment variable.

13.2 C Arrays and Pointers

This section describes library modules for manipulating low-level C arrays and pointers. The primary use of these modules is in supporting C declarations that manipulate bare pointers such as int *, double *, or void *. The modules can be used to allocate memory, manufacture pointers, dereference memory, and wrap pointers as class-like objects. Since these functions provide direct access to memory, their use is potentially unsafe and you should exercise caution.

13.2.1 cpointer.i

The cpointer.i module defines macros that can be used to used to generate wrappers around simple C pointers. The primary use of this module is in generating pointers to primitive datatypes such as int and double.

%pointer_functions(type,name)

Generates a collection of four functions for manipulating a pointer type *:

type *new_name()

Creates a new object of type type and returns a pointer to it. In C, the object is created using calloc(). In C++, new is used.

type *copy_name(type value)

Creates a new object of type type and returns a pointer to it. An initial value is set by copying it from value. In C, the object is created using calloc(). In C++, new is used.

type *delete_name(type *obj)

Deletes an object type type.

void name_assign(type *obj, type value)

Assigns *obj = value.

type name_value(type *obj)

Returns the value of *obj.
When using this macro, type may be any type and name must be a legal identifier in the target language. name should not correspond to any other name used in the interface file.
Here is a simple example of using %pointer_functions():
%module example
%include "cpointer.i"

/* Create some functions for working with "int *" */
%pointer_functions(int, intp);

/* A function that uses an "int *" */
void add(int x, int y, int *result);
Now, in Python:
>>> import example
>>> c = example.new_intp()     # Create an "int" for storing result
>>> example.add(3,4,c)         # Call function   
>>> example.intp_value(c)      # Dereference
7
>>> example.delete_intp(c)     # Delete

%pointer_class(type,name)

Wraps a pointer of type * inside a class-based interface. This interface is as follows:
struct name {
   name();                            // Create pointer object
  ~name();                            // Delete pointer object
   void assign(type value);           // Assign value
   type value();                      // Get value
   type *cast();                      // Cast the pointer to original type.
   static name *frompointer(type *);  // Create class wrapper from existing pointer
};
When using this macro, type is restricted to a simple type name like int, float, or Foo. Pointers and other complicated types are not allowed. name must be a valid identifier not already in use. When a pointer is wrapped as a class, the "class" may be transparently passed to any function that expects the pointer.

If the target language does not support proxy classes, the use of this macro will produce the example same functions as %pointer_functions() macro.

It should be noted that the class interface does introduce a new object or wrap a pointer inside a special structure. Instead, the raw pointer is used directly.

Here is the same example using a class instead:
%module example
%include "cpointer.i"

/* Wrap a class interface around an "int *" */
%pointer_class(int, intp);

/* A function that uses an "int *" */
void add(int x, int y, int *result);
Now, in Python (using proxy classes)
>>> import example
>>> c = example.intp()         # Create an "int" for storing result
>>> example.add(3,4,c)         # Call function   
>>> c.value()                  # Dereference
7
Of the two macros, %pointer_class is probably the most convenient when working with simple pointers. This is because the pointers are access like objects and they can be easily garbage collected (destruction of the pointer object destroys the underlying object).

%pointer_cast(type1, type2, name)

Creates a casting function that converts type1 to type2. The name of the function is name. For example:
%pointer_cast(int *, unsigned int *, int_to_uint);
In this example, the function int_to_uint() would be used to cast types in the target language.

Note: None of these macros can be used to safely work with strings (char * or char **).

Note: When working with simple pointers, typemaps can often be used to provide more seamless operation.

13.2.2 carrays.i

This module defines macros that assist in wrapping ordinary C pointers as arrays. The module does not provide any safety or an extra layer of wrapping--it merely provides functionality for creating, destroying, and modifying the contents of raw C array data.

%array_functions(type,name)

Creates four functions.

type *new_name(int nelements)

Creates a new array of objects of type type. In C, the array is allocated using calloc(). In C++, new [] is used.

type *delete_name(type *ary)

Deletes an array. In C, free() is used. In C++, delete [] is used.

type name_getitem(type *ary, int index)

Returns the value ary[index].

void name_setitem(type *ary, int index, type value)

Assigns ary[index] = value.
When using this macro, type may be any type and name must be a legal identifier in the target language. name should not correspond to any other name used in the interface file.

Here is an example of %array_functions(). Suppose you had a function like this:

void print_array(double x[10]) {
   int i;
   for (i = 0; i < 10; i++) {
      printf("[%d] = %g\n", i, x[i]);
   }
}
To wrap it, you might write this:
%module example

%include "carrays.i"
%array_functions(double, doubleArray);

void print_array(double x[10]);
Now, in a scripting language, you might write this:
a = new_doubleArray(10)           # Create an array
for i in range(0,10):
    doubleArray_setitem(a,i,2*i)  # Set a value
print_array(a)                    # Pass to C
delete_doubleArray(a)             # Destroy array

%array_class(type,name)

Wraps a pointer of type * inside a class-based interface. This interface is as follows:
struct name {
   name(int nelements);               // Create an array
  ~name();                            // Delete array
   type getitem(int index);           // Return item
   void setitem(index, type value);   // Set item
   type *cast();                      // Cast to original type
   static name *frompointer(type *);  // Create class wrapper from existing pointer
};
When using this macro, type is restricted to a simple type name like int or float. Pointers and other complicated types are not allowed. name must be a valid identifier not already in use. When a pointer is wrapped as a class, it can be transparently passed to any function that expects the pointer.

When combined with proxy classes, the %array_class() macro can be especially useful. For example:

%module example
%include "carrays.i"
%array_class(double, doubleArray);

void print_array(double x[10]);
Allows you to do this:
import example
c = example.doubleArray(10)  # Create double[10]
for i in range(0,10):
    c[i] = 2*i               # Assign values
example.print_array(c)       # Pass to C

Note: These macros do not encapsulate C arrays inside a special data structure or proxy. There is no bounds checking or safety of any kind. If you want this, you should consider using a special array object rather than a bare pointer.

Note: %array_functions() and %array_class() should not be used with types of char or char *.

13.2.3 cmalloc.i

This module defines macros for wrapping the low-level C memory allocation functions malloc(), calloc(), realloc(), and free().

%malloc(type [,name=type])

Creates a wrapper around malloc() with the following prototype:
type *malloc_name(int nbytes = sizeof(type));
If type is void, then the size parameter nbytes is required. The name parameter only needs to be specified when wrapping a type that is not a valid identifier (e.g., "int *", "double **", etc.).

%calloc(type [,name=type])

Creates a wrapper around calloc() with the following prototype:
type *calloc_name(int nobj =1, int sz = sizeof(type));
If type is void, then the size parameter sz is required.

%realloc(type [,name=type])

Creates a wrapper around realloc() with the following prototype:
type *realloc_name(type *ptr, int nitems);
Note: unlike the C realloc(), the wrapper generated by this macro implicitly includes the size of the corresponding type. For example, realloc_int(p, 100) reallocates p so that it holds 100 integers.

%free(type [,name=type])

Creates a wrapper around free() with the following prototype:
void free_name(type *ptr);

%sizeof(type [,name=type])

Creates the constant:
%constant int sizeof_name = sizeof(type);

%allocators(type [,name=type])

Generates wrappers for all five of the above operations.

Here is a simple example that illustrates the use of these macros:

// SWIG interface
%module example
%include "cmalloc.i"

%malloc(int);
%free(int);

%malloc(int *, intp);
%free(int *, intp);

%allocators(double);
Now, in a script:
>>> from example import *
>>> a = malloc_int()
>>> a
'_000efa70_p_int'
>>> free_int(a)    
>>> b = malloc_intp()
>>> b
'_000efb20_p_p_int'
>>> free_intp(b)
>>> c = calloc_double(50)
>>> c
'_000fab98_p_double'
>>> c = realloc_double(100000)
>>> free_double(c)
>>> print sizeof_double
8
>>>

13.2.4 cdata.i

The cdata.i module defines functions for converting raw C data to and from strings in the target language. The primary applications of this module would be packing/unpacking of binary data structures---for instance, if you needed to extract data from a buffer. The target language must support strings with embedded binary data in order for this to work.

char *cdata(void *ptr, int nbytes)

Converts nbytes of data at ptr into a string. ptr can be any pointer.

void memmove(void *ptr, char *s)

Copies all of the string data in s into the memory pointed to by ptr. The string may contain embedded NULL bytes. The length of the string is implicitly determined in the underlying wrapper code.
One use of these functions is packing and unpacking data from memory. Here is a short example:
// SWIG interface
%module example
%include "carrays.i"
%include "cdata.i"

%array_class(int, intArray);
Python example:
>>> a = intArray(10)
>>> for i in range(0,10):
...    a[i] = i
>>> b = cdata(a,40)
>>> b
'\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x00\x00\t'
>>> c = intArray(10)
>>> memmove(c,b)
>>> print c[4]
4
>>> 
Since the size of data is not always known, the following macro is also defined:

%cdata(type [,name=type])

Generates the following function for extracting C data for a given type.
char *cdata_name(int nitems)
nitems is the number of items of the given type to extract.
Note: These functions provide direct access to memory and can be used to overwrite data. Clearly they are unsafe.

13.3 C String Handling

A common problem when working with C programs is dealing with functions that manipulate raw character data using char *. In part, problems arise because there are different interpretations of char *---it could be a NULL-terminated string or it could point to binary data. Moreover, functions that manipulate raw strings may mutate data, perform implicit memory allocations, or utilize fixed-sized buffers.

The problems (and perils) of using char * are well-known. However, SWIG is not in the business of enforcing morality. The modules in this section provide basic functionality for manipulating raw C strings.

13.3.1 Default string handling

Suppose you have a C function with this prototype:
char *foo(char *s);
The default wrapping behavior for this function is to set s to a raw char * that refers to the internal string data in the target language. In other words, if you were using a language like Tcl, and you wrote this,
% foo Hello
then s would point to the representation of "Hello" inside the Tcl interpreter. When returning a char *, SWIG assumes that it is a NULL-terminated string and makes a copy of it. This gives the target language its own copy of the result.

There are obvious problems with the default behavior. First, since a char * argument points to data inside the target language, it is NOT safe for a function to modify this data (doing so may corrupt the interpreter and lead to a crash). Furthermore, the default behavior does not work well with binary data. Instead, strings are assumed to be NULL-terminated.

13.3.2 Passing binary data

If you have a function that expects binary data,
int parity(char *str, int len, int initial);
you can wrap the parameters (char *str, int len) as a single argument using a typemap. Just do this:
%apply (char *STRING, int LENGTH) { (char *str, int len) };
...
int parity(char *str, int len, int initial);
Now, in the target language, you can use binary string data like this:
>>> s = "H\x00\x15eg\x09\x20"
>>> parity(s,0)
In the wrapper function, the passed string will be expanded to a pointer and length parameter.

13.3.3 Using %newobject to release memory

If you have a function that allocates memory like this,
char *foo() {
   char *result = (char *) malloc(...);
   ...
   return result;
}
then the SWIG generated wrappers will have a memory leak--the returned data will be copied into a string object and the old contents ignored.

To fix the memory leak, use the %newobject directive.

%newobject foo;
...
char *foo();
This will release the result.

13.3.4 cstring.i

The cstring.i library file provides a collection of macros for dealing with functions that either mutate string arguments or which try to output string data through their arguments. An example of such a function might be this rather questionable implementation:
void get_path(char *s) {
    // Potential buffer overflow---uh, oh.
    sprintf(s,"%s/%s", base_directory, sub_directory);
}
...
// Somewhere else in the C program
{
    char path[1024];
    ...
    get_path(path);
    ...
}
(Off topic rant: If your program really has functions like this, you would be well-advised to replace them with safer alternatives involving bounds checking).

The macros defined in this module all expand to various combinations of typemaps. Therefore, the same pattern matching rules and ideas apply.

%cstring_bounded_output(parm, maxsize)

Turns parameter parm into an output value. The output string is assumed to be NULL-terminated and smaller than maxsize characters. Here is an example:
%cstring_bounded_output(char *path, 1024);
...
void get_path(char *path);
In the target language:
>>> get_path()
/home/beazley/packages/Foo/Bar
>>>
Internally, the wrapper function allocates a small buffer (on the stack) of the requested size and passes it as the pointer value. Data stored in the buffer is then returned as a function return value. If the function already returns a value, then the return value and the output string are returned together (multiple return values). If more than maxsize bytes are written, your program will crash with a buffer overflow!

%cstring_chunk_output(parm, chunksize)

Turns parameter parm into an output value. The output string is always chunksize and may contain binary data. Here is an example:
%cstring_chunk_output(char *packet, PACKETSIZE);
...
void get_packet(char *packet);
In the target language:
>>> get_packet()
'\xa9Y:\xf6\xd7\xe1\x87\xdbH;y\x97\x7f"\xd3\x99\x14V\xec\x06\xea\xa2\x88'
>>>
This macro is essentially identical to %cstring_bounded_output. The only difference is that the result is always chunksize characters. Furthermore, the result can contain binary data. If more than maxsize bytes are written, your program will crash with a buffer overflow!

%cstring_bounded_mutable(parm, maxsize)

Turns parameter parm into a mutable string argument. The input string is assumed to be NULL-terminated and smaller than maxsize characters. The output string is also assumed to be NULL-terminated and less than maxsize characters.
%cstring_bounded_mutable(char *ustr, 1024);
...
void make_upper(char *ustr);
In the target language:
>>> make_upper("hello world")
'HELLO WORLD'
>>>
Internally, this macro is almost exactly the same as %cstring_bounded_output. The only difference is that the parameter accepts an input value that is used to initialize the internal buffer. It is important to emphasize that this function does not mutate the string value passed---instead it makes a copy of the input value, mutates it, and returns it as a result. If more than maxsize bytes are written, your program will crash with a buffer overflow!

%cstring_mutable(parm [, expansion])

Turns parameter parm into a mutable string argument. The input string is assumed to be NULL-terminated. An optional parameter expansion specifies the number of extra characters by which the string might grow when it is modified. The output string is assumed to be NULL-terminated and less than the size of the input string plus any expansion characters.
%cstring_mutable(char *ustr);
...
void make_upper(char *ustr);

%cstring_mutable(char *hstr, HEADER_SIZE);
...
void attach_header(char *hstr);
In the target language:
>>> make_upper("hello world")
'HELLO WORLD'
>>> attach_header("Hello world")
'header: Hello world'
>>>
This macro differs from %cstring_bounded_mutable() in that a buffer is dynamically allocated (on the heap using malloc/new). This buffer is always large enough to store a copy of the input value plus any expansion bytes that might have been requested. It is important to emphasize that this function does not directly mutate the string value passed---instead it makes a copy of the input value, mutates it, and returns it as a result. If the function expands the result by more than expansion extra bytes, then the program will crash with a buffer overflow!

%cstring_output_maxsize(parm, maxparm)

This macro is used to handle bounded character output functions where both a char * and a maximum length parameter are provided. As input, a user simply supplies the maximum length. The return value is assumed to be a NULL-terminated string.
%cstring_output_maxsize(char *path, int maxpath);
...
void get_path(char *path, int maxpath);
In the target language:
>>> get_path(1024)
'/home/beazley/Packages/Foo/Bar'
>>>
This macro provides a safer alternative for functions that need to write string data into a buffer. User supplied buffer size is used to dynamically allocate memory on heap. Results are placed into that buffer and returned as a string object.

%cstring_output_withsize(parm, maxparm)

This macro is used to handle bounded character output functions where both a char * and a pointer int * are passed. Initially, the int * parameter points to a value containing the maximum size. On return, this value is assumed to contain the actual number of bytes. As input, a user simply supplies the maximum length. The output value is a string that may contain binary data.
%cstring_output_withsize(char *data, int *maxdata);
...
void get_data(char *data, int *maxdata);
In the target language:
>>> get_data(1024)
'x627388912'
>>> get_data(1024)
'xyzzy'
>>>
This macro is a somewhat more powerful version of %cstring_output_chunk(). Memory is dynamically allocated and can be arbitrary large. Furthermore, a function can control how much data is actually returned by changing the value of the maxparm argument.

%cstring_output_allocate(parm, release)

This macro is used to return strings that are allocated within the program and returned in a parameter of type char **. For example:
void foo(char **s) {
    *s = (char *) malloc(64);
    sprintf(*s, "Hello world\n");
}
The returned string is assumed to be NULL-terminated. release specifies how the allocated memory is to be released (if applicable). Here is an example:
%cstring_output_allocate(char **s, free(*$1));
...
void foo(char **s);
In the target language:
>>> foo()
'Hello world\n'
>>>

%cstring_output_allocate_size(parm, szparm, release)

This macro is used to return strings that are allocated within the program and returned in two parameters of type char ** and int *. For example:
void foo(char **s, int *sz) {
    *s = (char *) malloc(64);
    *sz = 64;
    // Write some binary data
    ...
}
The returned string may contain binary data. release specifies how the allocated memory is to be released (if applicable). Here is an example:
%cstring_output_allocate_size(char **s, int *slen, free(*$1));
...
void foo(char **s, int *slen);
In the target language:
>>> foo()
'\xa9Y:\xf6\xd7\xe1\x87\xdbH;y\x97\x7f"\xd3\x99\x14V\xec\x06\xea\xa2\x88'
>>>
This is the safest and most reliable way to return binary string data in SWIG. If you have functions that conform to another prototype, you might consider wrapping them with a helper function. For example, if you had this:
char  *get_data(int *len);
You could wrap it with a function like this:
void my_get_data(char **result, int *len) {
   *result = get_data(len);
}
Comments:
  • Support for the cstring.i module depends on the target language. Not all SWIG modules currently support this library.

  • Reliable handling of raw C strings is a delicate topic. There are many ways to accomplish this in SWIG. This library provides support for a few common techniques.

  • If used in C++, this library uses new and delete [] for memory allocation. If using ANSI C, the library uses malloc() and free().

  • Rather than manipulating char * directly, you might consider using a special string structure or class instead.

13.4 C++ Library

The library modules in this section provide access to parts of the standard C++ library. All of these modules are new in SWIG-1.3.12 and are only the beginning phase of more complete C++ library support including support for the STL.

13.4.1 std_string.i

The std_string.i library provides typemaps for converting C++ std::string objects to and from strings in the target scripting language. For example:
%module example
%include "std_string.i"

std::string foo();
void        bar(const std::string &x);
In the target language:
x = foo();                # Returns a string object
bar("Hello World");       # Pass string as std::string
This module only supports types std::string and const std::string &. Pointers and non-const references are left unmodified and returned as SWIG pointers.

This library file is fully aware of C++ namespaces. If you export std::string or rename it with a typedef, make sure you include those declarations in your interface. For example:

%module example
%include "std_string.i"

using namespace std;
typedef std::string String;
...
void foo(string s, const String &t);     // std_string typemaps still applied
Note: The std_string library is incompatible with Perl on some platforms. We're looking into it.

13.4.2 std_vector.i

The std_vector.i library provides support for the C++ 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:
%module example
%include "std_vector.i"

namespace std {
   %template(vectori) vector<int>;
   %template(vectord) vector<double>;
};
When a template vector<X> is instantiated a number of things happen:
  • A class that exposes the C++ API is created in the target language . This can be used to create objects, invoke methods, etc. This class is currently a subset of the real STL vector class.

  • Input typemaps are defined for vector<X>, const vector<X> &, and const vector<X> *. For each of these, a pointer vector<X> * may be passed or a native list object in the target language.

  • An output typemap is defined for vector<X>. In this case, the values in the vector are expanded into a list object in the target language.

  • For all other variations of the type, the wrappers expect to receive a vector<X> * object in the usual manner.

  • An exception handler for std::out_of_range is defined.

  • Optionally, special methods for indexing, item retrieval, slicing, and element assignment may be defined. This depends on the target language.

To illustrate the use of this library, consider the following functions:

/* File : example.h */

#include <vector>
#include <algorithm>
#include <functional>
#include <numeric>

double average(std::vector<int> v) {
    return std::accumulate(v.begin(),v.end(),0.0)/v.size();
}

std::vector<double> half(const std::vector<double>& v) {
    std::vector<double> w(v);
    for (unsigned int i=0; i<w.size(); i++)
        w[i] /= 2.0;
    return w;
}

void halve_in_place(std::vector<double>& v) {
    std::transform(v.begin(),v.end(),v.begin(),
                   std::bind2nd(std::divides<double>(),2.0));
}
To wrap with SWIG, you might write the following:
%module example
%{
#include "example.h"
%}

%include "std_vector.i"
// Instantiate templates used by example
namespace std {
   %template(IntVector) vector<int>;
   %template(DoubleVector) vector<double>;
}

// Include the header file with above prototypes
%include "example.h"
Now, to illustrate the behavior in the scripting interpreter, consider this Python example:
>>> from example import *
>>> iv = IntVector(4)         # Create an vector<int>
>>> for i in range(0,4):
...      iv[i] = i
>>> average(iv)               # Call method
1.5
>>> average([0,1,2,3])        # Call with list
1.5
>>> half([1,2,3])             # Half a list
(0.5,1.0,1.5)
>>> halve_in_place([1,2,3])   # Oops
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: Type error. Expected _p_std__vectorTdouble_t
>>> dv = DoubleVector(4)
>>> for i in range(0,4):
...       dv[i] = i
>>> halve_in_place(dv)       # Ok
>>> for i in dv:
...       print i
...
0.0
0.5
1.0
1.5
>>> dv[20] = 4.5
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "example.py", line 81, in __setitem__
    def __setitem__(*args): return apply(examplec.DoubleVector___setitem__,args)
IndexError: vector index out of range
>>>
This library module is fully aware of C++ namespaces. If you use vectors with other names, make sure you include the appropriate using or typedef directives. For example:
%include "std_vector.i"

namespace std {
    %template(IntVector) vector<int>;
}

using namespace std;
typedef std::vector Vector;

void foo(vector<int> *x, const Vector &x);

Note: This module makes use of several advanced SWIG features including templatized typemaps and template partial specialization. If you are tring to wrap other C++ code with templates, you might look at the code contained in std_vector.i. Alternatively, you can show them the code if you want to make their head explode.

Note: This module is defined for all SWIG target languages. However argument conversion details and the public API exposed to the interpreter vary.

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

13.5 Utility Libraries

13.5.1 exception.i

The exception.i library provides a language-independent function for raising a run-time exception in the target language.

SWIG_exception(int code, const char *message)

Raises an exception in the target language. code is one of the following symbolic constants:
SWIG_MemoryError
SWIG_IOError
SWIG_RuntimeError
SWIG_IndexError
SWIG_TypeError
SWIG_DivisionByZero
SWIG_OverflowError
SWIG_SyntaxError
SWIG_ValueError
SWIG_SystemError
message is a string indicating more information about the problem.
The primary use of this module is in writing language-independent exception handlers. For example:
%include "exception.i"
%exception std::vector::getitem {
    try {
        $action
    } catch (std::out_of_range& e) {
        SWIG_exception(SWIG_IndexError,const_cast(e.what()));
    }
}


SWIG 1.3 - Last Modified : May 29, 2002
cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/Ocaml.html0000644000175000000620000010056712561312226021451 0ustar stevestaff SWIG and Ocaml

18 SWIG and Ocaml

This chapter describes SWIG's support of Ocaml. Ocaml is a relatively recent addition to the ML family, and is a recent addition to SWIG. It's the second compiled, typed language to be added. Ocaml has widely acknowledged benefits for engineers, mostly derived from a sophistocated type system, compile-time checking which eliminates several classes of common programming errors, and good native performance. While all of this is wonderful, there are well-written C and C++ libraries that Ocaml users will want to take advantage of as part of their arsenal (such as SSL and gdbm), as well as their own mature C and C++ code. SWIG allows this code to be used in a natural, type-safe way with Ocaml, by providing the necessary, but repetetive glue code which creates and uses Ocaml values to communicate with C and C++ code. In addition, SWIG also produces the needed Ocaml source that binds variants, functions, classes, etc.

If you're not familiar with the Objective Caml language, you can visit The Ocaml Website.

18.1 Preliminaries

SWIG 1.3 works with Ocaml 3.04 and above. Given the choice, you should use the latest stable release. The SWIG Ocaml module has been tested on Linux (x86,PPC,Sparc) and Cygwin on Windows. The best way to determine whether your system will work is to compile the examples and test-suite which come with SWIG. You can do this by running make check from the SWIG root directory after installing SWIG. The Ocaml module has been tested using the system's dynamic linking (the usual -lxxx against libxxx.so, as well as with Gerd Stolpmann's Dl package . The ocaml_dynamic and ocaml_dynamic_cpp targets in the 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.

18.1.1 Running SWIG

The basics of getting a SWIG Ocaml module up and running can be seen from one of SWIG's example Makefiles, but is also described here. To build an Ocaml module, run SWIG using the -ocaml option.
%swig -ocaml example.i

This will produce 3 files. The file example_wrap.c contains all of the C code needed to build an Ocaml module. To build the module, you will compile the file example_wrap.c with ocamlc or ocamlopt to create the needed .o file. You will need to compile the resulting .ml and .mli files as well, and do the final link with -custom (not needed for native link).

18.1.2 Compiling the code

The O'Caml SWIG module now requires you to compile a module (Swig) separately. In addition to aggregating common SWIG functionality, the Swig module contains the data structure that represents C/C++ values. This allows easier data sharing between modules if two or more are combined, because the type of each SWIG'ed module's c_obj is derived from Swig.c_obj_t. This also allows SWIG to acquire new conversions painlessly, as well as giving the user more freedom with respect to custom typing. Use ocamlc or ocamlopt to compile your SWIG interface like:

% swig -ocaml -co swig.mli ; swig -ocaml co swig.ml
% ocamlc -c swig.mli ; ocamlc -c swig.ml
% ocamlc -c -ccopt "-I/usr/include/foo" example_wrap.c
% ocamlc -c example.mli
% ocamlc -c example.ml
            

ocamlc is aware of .c files and knows how to handle them. Unfortunately, it does not know about .cxx, .cc, or .cpp files, so when SWIG is invoked in C++ mode, you must:

% cp example_wrap.cxx example_wrap.cxx.c
% ocamlc -c ... -ccopt -xc++ example_wrap.cxx.c
% ...

18.1.3 The camlp4 module

The camlp4 module (swigp4.ml -> swigp4.cmo) contains a simple rewriter which makes C++ code blend more seamlessly with objective caml code. It's use is optional, but encouraged. The source file is included in the Lib/ocaml directory of the SWIG source distribution. You can checkout this file with "swig -ocaml -co swigp4.ml". You should compile the file with "ocamlc -I `camlp4 -where` -pp 'camlp4o pa_extend.cmo q_MLast.cmo' -c swigp4.ml"

The basic principle of the module is to recognize certain non-caml expressions and convert them for use with C++ code as interfaced by SWIG. The camlp4 module is written to work with generated SWIG interfaces, and probably isn't great to use with anything else.

Here are the main rewriting rules:

InputRewritten to
f'( ... ) as in
atoi'("0") or
_exit'(0)
f(C_list [ ... ]) as in
atoi (C_list [ C_string "0" ]) or
_exit (C_list [ C_int 0 ])
object -> method ( ... )(invoke object) "method" (C_list [ ... ])
object 'binop argument as in
a '+= b
(invoke object) "+=" argument as in
(invoke a) "+=" b
Note that because camlp4 always recognizes << and >>, they are replaced by lsl and lsr in operator names.
'unop object as in
'! a
(invoke a) "!" C_void
Smart pointer access like this
object '-> method ( args )
(invoke (invoke object "->" C_void))
Invoke syntax
object . '( ... )
(invoke object) "()" (C_list [ ... ])
Array syntax
object '[ 10 ]
(invoke object) "[]" (C_int 10)
Assignment syntax
let a = '10 and b = '"foo" and c = '1.0 and d = 'true
let a = C_int 10 and b = C_string "foo" and c = C_double 1.0 and d = C_bool true
Cast syntax
let a = _atoi '("2") as int
let b = (getenv "PATH") to string
This works for int, string, float, bool
let a = get_int (_atoi (C_string "2"))
let b = C_string (getenv "PATH")

18.1.4 Using your module

You can test-drive your module by building a toplevel ocaml interpreter. Consult the ocaml manual for details.

When linking any ocaml bytecode with your module, use the -custom option to build your functions into the primitive list. This option is not needed when you build native code.

18.1.5 Compilation problems and compiling with C++

As mentioned above, .cxx files need special handling to be compiled with ocamlc. Other than that, C code that uses class as a non-keyword, and C code that is too liberal with pointer types may not compile under the C++ compiler. Most code meant to be compiled as C++ will not have problems.

18.2 The low-level Ocaml/C interface

In order to provide access to overloaded functions, and provide sensible outputs from them, all C entites are represented as members of the c_obj type:

In the code as seen by the typemap writer, there is a value, swig_result, that always contains the current return data. It is a list, and must be appended with the caml_list_append function, or with functions and macros provided by objective caml.

type c_obj =
    C_void
  | C_bool of bool
  | C_char of char
  | C_uchar of char
  | C_short of int
  | C_ushort of int
  | C_int of int
  | C_uint of int32
  | C_int32 of int32
  | C_int64 of int64
  | C_float of float
  | C_double of float
  | C_ptr of int64 * int64
  | C_array of c_obj array
  | C_list of c_obj list
  | C_obj of (string -> c_obj -> c_obj)
  | C_string of string
  | C_enum of c_enum_t
A few functions exist which generate and return these:
  • caml_ptr_val receives a c_obj and returns a void *.  This should be used for all pointer purposes.
  • caml_long_val receives a c_obj and returns a long.  This should be used for most integral purposes.
  • caml_val_ptr receives a void * and returns a c_obj.
  • caml_val_bool receives a C int and returns a c_obj representing it's bool value.
  • caml_val_(u)?(char|short|int|long|float|double) receives an appropriate C value and returns a c_obj representing it.
  • caml_val_string receives a char * and returns a string value.
  • caml_val_string_len receives a char * and a length and returns a string value.
  • caml_val_obj receives a void * and an object type and returns a C_obj, which contains a closure giving method access.
Because of this style, a typemap can return any kind of value it wants from a function.  This enables out typemaps and inout typemaps to work well.  The one thing to remember about outputting values is that you must append them to the return list with swig_result = caml_list_append(swig_result,v).

 This function will return a new list that has your element appended. Upon return to caml space, the fnhelper function beautifies the result. A list containing a single item degrades to only that item (i.e. [ C_int 3 ] -> C_int 3), and a list containing more than one item is wrapped in C_list (i.e. [ C_char 'a' ; C_char 'b' -> C_list [ C_char 'a' ; C_char b ]).  This is in order to make return values easier to handle when functions have only one return value, such as constructors, and operators.  In addition, string, pointer, and object values are interchangable with respect to caml_ptr_val, so you can allocate memory as caml strings and still use the resulting pointers for C purposes, even using them to construct simple objects on. Note, though, that foreign C++ code does not respect the garbage collector, although the SWIG interface does.

The wild card type that you can use in lots of different ways is C_obj. It allows you to wrap any type of thing you like as an object using the same mechanism that the ocaml module does.  When evaluated in caml_ptr_val, the returned value is the result of a call to the object's "&" operator, taken as a pointer.

You should only construct values using objective caml, or using the functions caml_val_* functions provided as static functions to a SWIG ocaml module, as well as the caml_list_* functions. These functions provide everything a typemap needs to produce values. In addition, value items pass through directly, but you must make your own type signature for a function that uses value in this way.

18.2.1 The generated module

The SWIG %module directive specifies the name of the Ocaml module to be generated. If you specified `%module example', then your Ocaml code will be accessible in the module Example. The module name is always capitalized as is the ocaml convention. Note that you must not use any Ocaml keyword to name your module. Remember that the keywords are not the same as the C++ ones.

You can introduce extra code into the output wherever you like with SWIG. These are the places you can introduce code:
"header"This code is inserted near the beginning of the C wrapper file, before any function definitions.
"wrapper"This code is inserted in the function definition section.
"runtime"This code is inserted near the end of the C wrapper file.
"mli"This code is inserted into the caml interface file. Special signatures should be inserted here.
"ml"This code is inserted in the caml code defining the interface to your C code. Special caml code, as well as any initialization which should run when the module is loaded may be inserted here.
"classtemplate"The "classtemplate" place is special because it describes the output SWIG will generate for class definitions.

18.2.2 Enums

SWIG will wrap enumerations as polymorphic variants in the output Ocaml code, as above in C_enum.  In order to support all C++-style uses of enums, the function int_to_enum and enum_to_int are provided for ocaml code to produce and consume these values as integers.  Other than that, correct uses of enums will not have a problem.  Since enum labels may overlap between enums, the enum_to_int and int_to_enum functions take an enum type label as an argument. Example:

%module enum_test
%{
enum c_enum_type { a = 1, b, c = 4, d = 8 };
%}
enum c_enum_type { a = 1, b, c = 4, d = 8 };

The output mli contains:

type c_enum_type = [
  `unknown
| `c_enum_type
]
type c_enum_tag = [
  `int of int
| `a
| `b
| `c
| `d
]
val int_to_enum c_enum_type -> int -> c_obj
val enum_to_int c_enum_type -> c_obj -> c_obj
So it's possible to do this:
bash-2.05a$ ocamlmktop -custom enum_test_wrap.o enum_test.cmo -o enum_test_top
bash-2.05a$ ./enum_test_top 
        Objective Caml version 3.04

# open Enum_test ;;
# let x = C_enum `a ;;
val x : Enum_test.c_obj = C_enum `a
# enum_to_int `c_enum_type x ;;
- : Enum_test.c_obj = C_int 1
# int_to_enum `c_enum_type 4 ;;
- : Enum_test.c_obj = C_enum `c

18.2.3 Arrays

18.2.3.1 Simple types of bounded arrays

SWIG has support for array types, but you generally will need to provide a typemap to handle them. You can currently roll your own, or expand some of the macros provided (but not included by default) with the SWIG distribution.

By including "carray.i", you will get access to some macros that help you create typemaps for array types fairly easily.

%make_simple_array_typemap is the easiest way to get access to arrays of simple types with known bounds in your code, but this only works for arrays whose bounds are completely specified.

18.2.3.2 Complex and unbounded arrays

Unfortunately, unbounded arrays and pointers can't be handled in a completely general way by SWIG, because the end-condition of such an array can't be predicted. In some cases, it will be by consent (e.g. an array of four or more chars), sometimes by explicit length (char *buffer, int len), and sometimes by sentinel value (0,-1,etc.). 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.

18.2.3.3 Using an object

It's possible to use C++ to your advantage by creating a simple object that provides access to your array. This may be more desirable in some cases, since the object can provide bounds checking, etc., that prevents crashes.

Consider writing an object when the ending condition of your array is complex, such as using a required centinel, etc.

18.2.3.4 Example typemap for a function taking float * and int

This is a simple example in typemap for an array of float, where the length of the array is specified as an extra parameter. Other such typemaps will work similarly. In the example, the function printfloats is called with a float array, and specified length. The actual length reported in the len argument is the length of the array passed from ocaml, making passing an array into this type of function convenient.

tarray.i
%module tarray
%{
#include 

void printfloats( float *tab, int len ) {
	int i;

	for( i = 0; i < len; i++ ) {
		printf( "%f ", tab[i] );
	}

	printf( "\n" );  
}
%}

%typemap(in) (float *tab, int len) {
    int i;
    /* $*1_type */
    $2 = caml_array_len($input);
    $1 = ($*1_type *)malloc( $2 * sizeof( float ) );
    for( i = 0; i < $2; i++ ) {
        $1[i] = caml_double_val(caml_array_nth($input,i));
    }
}

void printfloats( float *tab, int len );
Sample Run
# open Tarray ;;
# _printfloats (C_array [| C_double 1.0 ; C_double 3.0 ; C_double 5.6666 |]) ;;
1.000000 3.000000 5.666600
- : Tarray.c_obj = C_void

18.2.4 C++ Classes

C++ classes, along with structs and unions are represented by C_obj (string -> c_obj -> c_obj) wrapped closures.  These objects contain a method list, and a type, which allow them to be used like C++ objects. When passed into typemaps that use pointers, they degrade to pointers through their "&" method.  Every method an object has is represented as a string in the object's method table, and each method table exists in memory only once.  In addition to any other operators an object might have, certain builtin ones are provided by SWIG: (all of these take no arguments (C_void))
"~"Delete this object
"&"Return an ordinary C_ptr value representing this object's address
"sizeof"If enabled with ("sizeof"="1") on the module node, return the object's size in char.
":methods"Returns a list of strings containing the names of the methods this object contains
":classof"Returns the name of the class this object belongs to.
":parents"Returns a list of all direct parent classes which have been wrapped by SWIG.
"::[parent-class]"Returns a view of the object as the indicated parent class. This is mainly used internally by the SWIG module, but may be useful to client programs.
"[member-variable]"Each member variable is wrapped as a method with an optional parameter. Called with one argument, the member variable is set to the value of the argument. With zero arguments, the value is returned.
Note that this string belongs to the wrapper object, and not the underlying pointer, so using create_[x]_from_ptr alters the returned value for the same object.

18.2.4.1 STL vector and string Example

Standard typemaps are now provided for STL vector and string. More are in the works. STL strings are passed just like normal strings, and returned as strings. STL string references don't mutate the original string, (which might be surprising), because Ocaml strings are mutable but have fixed length. Instead, use multiple returns, as in the argout_ref example.
example.i
%module example
%{
#include "example.h"
%}

%include stl.i

namespace std {
        %template(StringVector) std::vector < string >;
};

%include example.h
This example is in Examples/ocaml/stl

Since there's a makefile in that directory, the example is easy to build.

Here's a sample transcript of an interactive session using a string vector after making a toplevel (make toplevel). This example uses the camlp4 module.

bash-2.05a$ ./example_top 
        Objective Caml version 3.06

        Camlp4 Parsing version 3.06

# open Swig ;;
# open Example ;;
# let x = new_StringVector '() ;;
val x : Example.c_obj = C_obj 
# x -> ":methods" () ;;
- : Example.c_obj =
C_list
 [C_string "nop"; C_string "size"; C_string "empty"; C_string "clear";
  C_string "push_back"; C_string "[]"; C_string "="; C_string "set";
  C_string "~"; C_string "&"; C_string ":parents"; C_string ":classof";
  C_string ":methods"]
# x -> push_back ("foo") ;;
- : Example.c_obj = C_void
# x -> push_back ("bar") ;;
- : Example.c_obj = C_void
# x -> push_back ("baz") ;;
- : Example.c_obj = C_void
# x '[1] ;;
- : Example.c_obj = C_string "bar"
# x -> set (1,"spam") ;;
- : Example.c_obj = C_void
# x '[1] ;;
- : Example.c_obj = C_string "spam"
# for i = 0 to (x -> size() as int) - 1 do 
    print_endline ((x '[i to int]) as string) 
  done ;;
foo
bar
baz
- : unit = ()
# 

18.2.4.2 C++ Class Example

Here's a simple example using Trolltech's Qt Library:
qt.i
%module qt
%{
#include <qapplication.h>
#include <qpushbutton.h>
%}
class QApplication {
public:
        QApplication( int argc, char **argv );
        void setMainWidget( QWidget *widget );
        void exec();
};

class QPushButton {
public:
        QPushButton( char *str, QWidget *w );
        void resize( int x, int y );
        void show();
};

18.2.4.3 Compiling the example

bash-2.05a$ QTPATH=/your/qt/path
bash-2.05a$ for file in swig.mli swig.ml swigp4.ml ; do swig -ocaml -co $file ; done
bash-2.05a$ ocamlc -c swig.mli ; ocamlc -c swig.ml
bash-2.05a$ ocamlc -I `camlp4 -where` -pp "camlp4o pa_extend.cmo q_MLast.cmo" -c swigp4.ml
bash-2.05a$ swig -ocaml -c++ -I$QTPATH/include  qt.i
bash-2.05a$ mv qt_wrap.cxx qt_wrap.c
bash-2.05a$ ocamlc -c -ccopt -xc++ -ccopt -g -g -ccopt -I$QTPATH/include qt_wrap.c 
bash-2.05a$ ocamlc -c qt.mli
bash-2.05a$ ocamlc -c qt.ml
bash-2.05a$ ocamlmktop -custom swig.cmo -I `camlp4 -where` \
  camlp4o.cma swigp4.cmo qt_wrap.o qt.cmo -o qt_top -cclib \
  -L$QTPATH/lib -cclib -lqt

18.2.4.4 Sample Session

bash-2.05a$ ./qt_top 
        Objective Caml version 3.06

        Camlp4 Parsing version 3.06

# open Swig ;;
# open Qt ;;
# let a = new_QApplication '(0,0) ;;
val a : Qt.c_obj = C_obj 
# let hello = new_QPushButton '("hi",0) ;;
val hello : Qt.c_obj = C_obj 
# hello -> resize (100,30) ;;
- : Qt.c_obj = C_void
# hello -> show () ;;
- : Qt.c_obj = C_void
# a -> exec () ;;

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

18.2.5 Director Classes

18.2.5.1 Director Introduction

Director classes are classes which allow Ocaml code to override the public methods of a C++ object. This facility allows the user to use C++ libraries that require a derived class to provide application specific functionality in the context of an application or utility framework.

You can turn on director classes by using an optional module argument like this:

%module(directors="1") ... // Turn on the director class for a specific class like this: %feature("director") class foo { ... };

18.2.5.2 Overriding Methods in Ocaml

Because the Ocaml language module treats C++ method calls as calls to a certain function, all you need to do is to define the function that will handle the method calls in terms of the public methods of the object, and any other relevant information. The function new_derived_object uses a stub class to call your methods in place of the ones provided by the underlying implemenation. The object you receive is the underlying object, so you are free to call any methods you want from within your derived method. Note that calls to the underlying object do not invoke Ocaml code. You need to handle that yourself.

new_derived_object receives your function, the function that creates the underlying object, and any constructor arguments, and provides an object that you can use in any usual way. When C++ code calls one of the object's methods, the object invokes the Ocaml function as if it had been invoked from Ocaml, allowing any method definitions to override the C++ ones.

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

18.2.5.3 Director Usage Example

example_prog.ml
open Swig
open Example

...

let triangle_class pts ob meth args =
  match meth with
      "cover" ->
        (match args with
             C_list [ x_arg ; y_arg ] ->
	     let xa = x_arg as float
	     and ya = y_arg as float in
	       (point_in_triangle pts xa ya) to bool
           | _ -> raise (Failure "cover needs two double arguments."))
    | _ -> (invoke ob) meth args ;;

let triangle =
  new_derived_object 
    new_shape
    (triangle_class ((0.0,0.0),(0.5,1.0),(1.0,0.0)))
    '() ;;

let _ = _draw_shape_coverage '(triangle, C_int 60, C_int 20) ;;

This is the meat of what you need to do. The actual "class" definition containing the overloaded method is defined in the function triangle_class. This is a lot like the class definitions emitted by SWIG, if you look at example.ml, which is generated when SWIG consumes example.i. Basically, you are given the arguments as a c_obj and the method name as a string, and you must intercept the method you are interested in and provide whatever return value you need. Bear in mind that the underlying C++ code needs the right return type, or an exception will be thrown. This exception will generally be Failure, or NotObject. You must call other ocaml methods that you rely on yourself. Due to the way directors are implemented, method calls on your object from with ocaml code will always invoke C++ methods even if they are overridden in ocaml.

In the example, the draw_shape_coverage function plots the indicated number of points as either covered (x) or uncovered ( ) between 0 and 1 on the X and Y axes. Your shape implementation can provide any coverage map it likes, as long as it responds to the "cover" method call with a boolean return (the underlying method returns bool). This might allow a tricky shape implementation, such as a boolean combination, to be expressed in a more effortless style in ocaml, while leaving the "engine" part of the program in C++.

18.2.5.4 Creating director objects

The definition of the actual object triangle can be described this way:

let triangle = new_derived_object new_shape (triangle_class ((0.0,0.0),(0.5,1.0),(1.0,0.0))) '()

The first argument to new_derived_object, new_shape is the method which returns a shape instance. This function will be invoked with the third argument will be appended to the argument list [ C_void ]. In the example, the actual argument list is sent as (C_list [ C_void ; C_void ]). The augmented constructor for a director class needs the first argument to determine whether it is being constructed as a derived object, or as an object of the indicated type only (in this case shape). The Second argument is a closure that will be added to the final C_obj.

The actual object passed to the self parameter of the director object will be a C_director_core, containing a c_obj option ref and a c_obj. The c_obj provided is the same object that will be returned from new_derived object, that is, the object exposing the overridden methods. The other part is an option ref that will have its value extracted before becoming the ob parameter of your class closure. This ref will contain None if the C++ object underlying is ever destroyed, and will consequently trigger an exception when any method is called on the object after that point (the actual raise is from an inner function used by new_derived_object, and throws NotObject). This prevents a deleted C++ object from causing a core dump, as long as the object is destroyed properly.

18.2.5.5 Typemaps for directors, directorin, directorout, directorargout

Special typemaps exist for use with directors, the directorin, directorout, directorargout are used in place of in, out, argout typemaps, except that their direction is reversed. They provide for you to provide argout values, as 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.

18.2.5.6 directorin typemap

The directorin typemap is used when you will receive arguments from a call made by C++ code to you, therefore, values will be translated from C++ to ocaml. You must provide some valid C_obj value. This is the value your ocaml code receives when you are called. In general, a simple directorin typemap can use the same body as a simple out typemap.

18.2.5.7 directorout typemap

The directorout typemap is used when you will send an argument from your code back to the C++ caller. That is; directorout specifies a function return conversion. You can usually use the same body as an in typemap for the same type, except when there are special requirements for object ownership, etc.

18.2.5.8 directorargout typemap

C++ allows function arguments which are by pointer (*) and by reference (&) to receive a value from the called function, as well as sending one there. Sometimes, this is the main purpose of the argument given. directorargout typemaps allow your caml code to emulate this by specifying additional return values to be put into the output parameters. The SWIG ocaml module is a bit loose in order to make code eaiser to write. In this case, your return to the caller must be a list containing the normal function return first, followed by any argout values in order. These argout values will be taken from the list and assigned to the values to be returned to C++ through directorargout typemaps. 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.

18.2.6 Exceptions

Catching exceptions is now supported using SWIG's %exception feature. A simple but not too useful example is provided by the throw_exception testcase in Examples/test-suite. You can provide your own exceptions, too. cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/ch11.3.png0000644000175000000620000000557612561312226021137 0ustar stevestaff‰PNG  IHDRÞvwSPLTEÿÿÿÌffîîîff™ÿÿfÿ™™ÿ3™ÌÿfÌ™™Ì3ÌÌfÿÿf™ff™3™ÿ33fÌ33ÌÝÝÝ3ÿ333ÿ™fÿ3fÌÿ3Ì™fÌ3™™ÿÿfÿÌf™3ff3™Ì33Ì3™»»»f33f™ÿ™3ÿ33ÌÿÌ™3Ì3f™ÿÌfÿ™f™f33™™3ÿ™ÿ3fDDDUÿÿ3ÿ™ÿ3ÌÌÿÌ™Ì33™ÿ™fÿfffÿf3™f3Ì™Ì33"""Ì™ÌÿÌÿÿfÿÿÌÌÌ™ÌfÿÌ3™ÿffÿ3ffÌ3ÿÿ3™33™™™3fÌfÿfÿfÌ33™f3fÌfÌ™3f3ÿf™™™3Ì3™3fÿ3Ìf3ÿˆˆˆ33ÿÿÌÌÿf™ÿ™ÌÌf3Ìÿ™ÿ3™Ìf™fÿÿ™™ÿîf333f̪f3™f3ÿÿÌ™™ÌÌÌÌffU™f™"3Ìffff™Ì33Ì3fÿ™™3ÿÿ™ÿÿ33ÿ3™ÌÌ݈D™Ìff3ÌÌ»™ÿ™3ÿ3ÿ™™Ì™fÌÿÿÿ™f™™3̙̙»w"™Ìÿ3ÌÿÌf™ªfÿ33Ì3f3ÌfˆD™™™Ìf3ª3ÌÌfÌ™™fªªªˆf3Ìwwwf™ÌÌ3ÿw"ÌfÿÿÌÌ™fÌ™™™Ìff™ÿ3wÿÿÌ3Ý™3™3™fÌ™ÿîÌÿÌf™ÿÌÿÿffÌÌ33ÿffUÿf3ÿ»Ìÿ™™33f3™fÿfÌfÌ3ÿÌf™33™3fÌÿ™ÌÿÌfÌÌÿÿ3ÿ™ffÌ3ÿfUUU3Ì3™™ÿÿÌ3îÿf3fÌD™3™ÿÌ™ÿÿ™3ÿ™Ì™™fÌÌÿÌ™ffÿfÿÝÿÌf3ffÌ™fÌm|Ú9IDATxÚb`ÃÿÿEÃÿÿEÃÿÿEÃÿÿEÃÿÿEÃÿÿšè?ÍÀ0 (ÿÿÞa½ÿÿªÑ;´Ì0ÿÿÞa½ÿÿNÑ‹¿xý?£ÿÿV¹÷?Žhü?bs/ÿÿÞa½ÿÿžÑ‹À •Ì€ò`‚Ã=zÿÿfÑ Éÿ ˆxýi x hîÐŽqÿÿn¹÷?fÆš«‰ŠÞ!ßÿÿšqI…èÅq(BÃa¤ÿÿÑû3Wá¬{ÿŸ{ñ¥¤a2Žÿÿ*Ñû-clZý§,z†GôÿÿbBñ‹œ·p¨CjCý‡6´þ#šÏÿQÄ´œ‡EüÿÿRÑKóæ,¶ºwH·¯ÿÿ’±K§1gd[‡hÿÿ­*bë^j7ÒÑ£tèÅ1ÿÿÜQ‹+Xé5ß‹½ó4„âÿÿôQ‹-Ño:WD•8ÿÿ ½ÜÁ:28âÿÿÌ™­C;„’ã ÿÿüQ;uÐÆ1ÿÿrC¥ÑBÄÆ`ŒcÿÿZ™G7˜üÎôpcÿÿZQKŘ¡å˜ãà‰cÿÿŠ•U£wx×Çÿÿ:™–6Ñ;ÌÛ\ÿÿjQKµ0£ãlÐÆ1ÿÿ‚‡ÿ8ÖÁ ÚèÀ8ÿÿB™¹GóŸJnú?D“8±ÿÿRQ‹ˆWêD/ÀŒ‡Ñ3ŽÿÿZ¡jBùO­„2ˆãÿÿ"™–vQñ% ÿÿ2QK»ˆø?ðE3'ÿÿ:Ž¥]ü¾Áÿÿ™–öqðØf ÿÿQKóùüa;·ÿÿ¢¹ÿ¾ÌB'ÿÿ¢Nï‘ÖvÐÁóÿÿ ­µad ½ãÿÿMña•Šè\DÿÿEÃÿÿÂZÐá0zž66˜O6£±ÛÿÿÞa½ÿÿ¢iU‡7zéW?ÓÓ®5Ó0ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿ©¶£ã’ <¦ý'+zI¶ ËÕ Dúšr«h½d¸U9¦ÛÿÿÂXµüÇÄ_4ÝÍÄÚ„y,ñ¹—TOýÇâKÚå^2‚E Ómÿÿ¢bô’›{sô2 ñèÿÿ½È7Ýþ‡—h—k¢äYr£—t›ÈŽ^Š=EÓè%Õuh÷cº ÿÿ"*zaiérÍÿÿQ„¨½ÄÚD…è%Ò*ëyjE/q®ûtg1V·ÿÿ"%zq]Kýè%Ñ&J¢— U¤%%*G/׌^ÿÿ½p‹ðÙ…rï*¹ÑKªM¤˜¨%-©ž¢kô’è:´»ˆ1Ýÿÿ¢8z©Ñ´"Ñ&RZèäE/ž¶qÑ ¿4˜ыްǽÿÿ½h·W#.?F­¨½¤ØôŸ‚a R=EnLjìè%-Èÿcíì ÿÿÂ?¬;×Ö|ƒºõrkœ÷t’2¬A‚Mÿ±\Jʰ)ž¢ÿ°‰®#½ÿÿ”Öƒ’ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÞa½ÿÿÂTAŸ»Üéyg<ï§'1Fhê6ÿÿÞa½ÿÿEÃÿÿEÃÿÿEÃÿÿEÃÿÿEÃÿÿEÃÿÿEÃÿÿEÃÿÿt³ ölTIEND®B`‚cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/Modules.html0000644000175000000620000001376212561312226022026 0ustar stevestaff Working with Modules

14 Working with Modules

When first working with SWIG, users commonly start by creating a single module. That is, you might define a single SWIG interface that wraps some set of C code. You then compile all of the generated wrapper code into a module and use it. For large applications, however, this approach is problematic---the size of the generated wrapper code can be rather large. Moreover, it is probably easier to manage the scripting interface when it is broken up into smaller pieces.

This chapter describes the problem of using SWIG in programs where you want to create a collection of modules.

14.1 The SWIG runtime code

All SWIG-generated wrapper modules include a set of functions commonly known as the "SWIG runtime." These functions are primarily related to the runtime type system which checks pointer types and performs other tasks such as proper casting of pointer values in C++.

By default, the runtime functions are private to each SWIG-generated module. That is, the runtime functions are declared with "static" linkage and are visible only to the wrapper functions defined in that module. If two completely different SWIG modules are loaded, this presents no problem---each module uses its own private runtime code. The only problem with this approach is that when more than one SWIG module is used in the same application, those modules often need to share type information. This is especially true for C++ programs where SWIG must collect and share information about inheritance relationships that cross module boundaries.

To solve the problem of sharing information across modules, the SWIG runtime functions need to be exposed in a way that allows data to be shared between modules. The next section describes how to do that.

14.2 Compiling Multiple SWIG modules

Suppose that you have three SWIG interface files A.i, B.i, and C.i and suppose that these modules interact with each other. To make this work, there are two approaches you can take:

Option 1: Designate one module to provide the runtime code

With this option, one of the modules is designated as providing the runtime environment. This is done with the -runtime option like this:

% swig -runtime -c++ -python A.i
The other modules are then compiled without runtime support. This is done by supplying the -noruntime option like this:
% swig -noruntime -c++ -python B.i
% swig -noruntime -c++ -python C.i
To use the modules, you compile and link everything as before, but you need to make sure that module A is loaded before all of the other modules are used---otherwise you will unresolved symbols.

Now, the bad news: This approach may or may not work depending on the platform you are using, what target language you are using, and the way that shared libraries work on the system. On many systems, the symbols contained in dynamically loaded modules are private. Therefore, even though module A provides the runtime code, the other modules won't be able to find it. You'll know if this is the case if you try to load the other modules and you get errors about unresolved SWIG_* functions.

Option 2: Build a runtime library

The second way to work with multiple modules is to create a special runtime library module. To do this, you first build a runtime library like this:

% swig -runtime -python swigrun.i
% # Build a shared library --- this is different on every machine! (shown for Linux)
% gcc -fpic swigrun_wrap.c -o swigrun_wrap.o
% gcc -shared swigrun_wrap.o -o libswigrunpy.so
Now, you compile all of the normal SWIG modules using the -noruntime option:
% swig -noruntime -c++ -python A.i
% swig -noruntime -c++ -python B.i
% swig -noruntime -c++ -python C.i
Finally, when linking the dynamically loadable modules, you need to link again the special runtime library above. For example (Linux) :
% g++ -shared A_wrap.o -L. -lswigrunpy -o _A.so
% g++ -shared B_wrap.o -L. -lswigrunpy -o _B.so
% g++ -shared C_wrap.o -L. -lswigrunpy -o _C.so
Again, all of the details will vary depending on what compiler you use, the platform, target language, and so forth. The key point is that the runtime needs to be contained in a shared/dynamic library and you need to link all of the modules against that library.

When you use the modules created using this technique, the runtime code will be automatically loaded when the modules are imported. Moreover, since all of the modules are linked against the same runtime library, they will share that code.

14.3 A word of caution about static libraries

When working with multiple SWIG modules, you should take care not to use static libraries. For example, if you have a static library libfoo.a and you link a collection of SWIG modules with that library, each module will get its own private copy of the library code inserted into it. This is very often NOT what you want and it can lead to unexpected or bizarre program behavior. When working with dynamically loadable modules, you should try to work exclusively with shared libaries.

14.4 References

Due to the complexity of working with shared libraries and multiple modules, it might be a good idea to consult an outside reference. John Levine's "Linkers and Loaders" is highly recommended.


SWIG 1.3 - Last Modified : November 22, 2003
cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/Ruby.html0000644000175000000620000024664012561312226021342 0ustar stevestaff SWIG and Ruby

22 SWIG and Ruby

This chapter describes SWIG's support of Ruby.


22.1 Preliminaries

SWIG 1.3 is known to work with Ruby versions 1.6 and later. Given the choice, you should use the latest stable version of Ruby. You should also determine if your system supports shared libraries and dynamic loading. SWIG will work with or without dynamic loading, but the compilation process will vary.

This chapter covers most SWIG features, but in less depth than is found in earlier chapters. At the very least, make sure you also read the "SWIG Basics" chapter. It is also assumed that the reader has a basic understanding of Ruby.

22.1.1 Running SWIG

To build a Ruby module, run SWIG using the -ruby option:

$ swig -ruby example.i
If building a C++ extension, add the -c++ option:

$ swig -c++ -ruby example.i

This creates a file example_wrap.c (example_wrap.cxx if compiling a C++ extension) that contains all of the code needed to build a Ruby extension module. To finish building the module, you need to compile this file and link it with the rest of your program.

22.1.2 Getting the right header files

In order to compile the wrapper code, the compiler needs the ruby.h header file. This file is usually contained in a directory such as

/usr/local/lib/ruby/1.6/i686-linux/ruby.h
The exact location may vary on your machine, but the above location is typical. If you are not entirely sure where Ruby is installed, you can run Ruby to find out. For example:
$ ruby -e 'puts $:.join("\n")'
/usr/local/lib/ruby/site_ruby/1.6 
/usr/local/lib/ruby/site_ruby/1.6/i686-linux 
/usr/local/lib/ruby/site_ruby 
/usr/local/lib/ruby/1.6 
/usr/local/lib/ruby/1.6/i686-linux 
. 

22.1.3 Compiling a dynamic module

Ruby extension modules are typically compiled into shared libraries that the interpreter loads dynamically at runtime. Since the exact commands for doing this vary from platform to platform, your best bet is to follow the steps described in the README.EXT file from the Ruby distribution:

  1. Create a file called extconf.rb that looks like the following:
    require 'mkmf'
    create_makefile('example')
    
  2. Type the following to build the extension:

    $ ruby extconf.rb
    $ make
    $ make install
    
Of course, there is the problem that mkmf does not work correctly on all platforms, e.g, HPUX. If you need to add your own make rules to the file that extconf.rb produces, you can add this:
open("Makefile", "a") { |mf|
   puts <<EOM
   # Your make rules go here
   EOM
}
to the end of the extconf.rb file. If for some reason you don't want to use the standard approach, you'll need to determine the correct compiler and linker flags for your build platform. For example, a typical sequence of commands for the Linux operating system would look something like this:

$ swig -ruby example.i
$ gcc -c example.c
$ gcc -c example_wrap.c -I/usr/local/lib/ruby/1.6/i686-linux 
$ gcc -shared example.o example_wrap.o -o example.so
For other platforms it may be necessary to compile with the -fPIC option to generate position-independent code. If in doubt, consult the manual pages for your compiler and linker to determine the correct set of options. You might also check the SWIG Wiki for additional information.

22.1.4 Using your module

Ruby module names must be capitalized, but the convention for Ruby feature names is to use lowercase names. So, for example, the Etc extension module is imported by requiring the etc feature:
# The feature name begins with a lowercase letter... require 'etc' # ... but the module name begins with an uppercase letter puts "Your login name: #{Etc.getlogin}"
To stay consistent with this practice, you should always specify a lowercase module name with SWIG's %module directive. SWIG will automatically correct the resulting Ruby module name for your extension. So for example, a SWIG interface file that begins with:
%module example
will result in an extension module using the feature name "example" and Ruby module name "Example".

22.1.5 Static linking

An alternative approach to dynamic linking is to rebuild the Ruby interpreter with your extension module added to it. In the past, this approach was sometimes necessary due to limitations in dynamic loading support on certain machines. However, the situation has improved greatly over the last few years and you should not consider this approach unless there is really no other option.

The usual procedure for adding a new module to Ruby involves finding the Ruby source, adding an entry to the ext/Setup file, adding your directory to the list of extensions in the file, and finally rebuilding Ruby.

22.1.6 Compilation of C++ extensions

On most machines, C++ extension modules should be linked using the C++ compiler. For example:

$ swig -c++ -ruby example.i
$ g++ -c example.cxx
$ g++ -c example_wrap.cxx -I/usr/local/lib/ruby/1.6/i686-linux
$ g++ -shared example.o example_wrap.o -o example.so
If you've written an extconf.rb script to automatically generate a Makefile for your C++ extension module, keep in mind that (as of this writing) Ruby still uses gcc and not g++ as its linker. As a result, the required C++ runtime library support will not be automatically linked into your extension module and it may fail to load on some platforms. A workaround for this problem is use the mkmf module's append_library() method to add one of the C++ runtime libraries to the list of libraries linked into your extension, e.g.
require 'mkmf'
$libs = append_library($libs, "supc++")
create_makefile('example')

22.2 Building Ruby Extensions under Windows 95/NT

Building a SWIG extension to Ruby under Windows 95/NT is roughly similar to the process used with Unix. Normally, you will want to produce a DLL that can be loaded into the Ruby interpreter. For all recent versions of Ruby, the procedure described above (i.e. using an extconf.rb script) will work with Windows as well; you should be able to build your code into a DLL by typing:
C:\swigtest> ruby extconf.rb
C:\swigtest> nmake
C:\swigtest> nmake install
The remainder of this section covers the process of compiling SWIG-generated Ruby extensions with Microsoft Visual C++ 6 (i.e. within the Developer Studio IDE, instead of using the command line tools). In order to build extensions, you may need to download the source distribution to the Ruby package, as you will need the Ruby header files.

22.2.1 Running SWIG from Developer Studio

If you are developing your application within Microsoft developer studio, SWIG can be invoked as a custom build option. The process roughly follows these steps :

  • Open up a new workspace and use the AppWizard to select a DLL project.
  • Add both the SWIG interface file (the .i file), any supporting C files, and the name of the wrapper file that will be created by SWIG (i.e.. example_wrap.c). Note : If using C++, choose a different suffix for the wrapper file such as example_wrap.cxx. Don't worry if the wrapper file doesn't exist yet--Developer Studio will keep a reference to it around.
  • Select the SWIG interface file and go to the settings menu. Under settings, select the "Custom Build" option.
  • Enter "SWIG" in the description field.
  • Enter "swig -ruby -o $(ProjDir)\$(InputName)_wrap.c $(InputPath)" in the "Build command(s) field". You may have to include the path to swig.exe.
  • Enter "$(ProjDir)\$(InputName)_wrap.c" in the "Output files(s) field".
  • Next, select the settings for the entire project and go to the C/C++ tab and select the Preprocessor category. Add NT=1 to the Preprocessor definitions. This must be set else you will get compilation errors. Also add IMPORT to the preprocessor definitions, else you may get runtime errors. Also add the include directories for your Ruby installation under "Additional include directories".
  • Next, select the settings for the entire project and go to the Link tab and select the General category. Set the name of the output file to match the name of your Ruby module (i.e.. example.dll). Next add the Ruby library file to your link libraries under Object/Library modules. For example "mswin32-ruby16.lib. You also need to add the path to the library under the Input tab - Additional library path.
  • Build your project.

Now, assuming all went well, SWIG will be automatically invoked when you build your project. Any changes made to the interface file will result in SWIG being automatically invoked to produce a new version of the wrapper file. To run your new Ruby extension, simply run Ruby and use the require command as normal. For example if you have this ruby file run.rb:

# file: run.rb
require 'Example'

# Call a c function
print "Foo = ", Example.Foo, "\n"
Ensure the dll just built is in your path or current directory, then run the Ruby script from the DOS/Command prompt:
C:\swigtest> ruby run.rb
Foo = 3.0


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

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

22.3.1 Modules

The SWIG %module directive specifies the name of the Ruby module. If you specify:
%module example
then everything is wrapped into a Ruby module named Example that is nested directly under the global module. You can specify a more deeply nested module by specifying the fully-qualified module name in quotes, e.g.
%module "Foo::Bar::Spam"
Starting with SWIG 1.3.20, you can also choose to wrap everything into the global module by specifying the -globalmodule option on the SWIG command line, i.e.
$ swig -ruby -globalmodule example.i
Note that this does not relieve you of the requirement of specifying the SWIG module name with the %module directive (or the -module command-line option) as described earlier.

When choosing a module name, do not use the same name as a built-in Ruby command or standard module name, as the results may be unpredictable. Similarly, if you're using the -globalmodule option to wrap everything into the global module, take care that the names of your constants, classes and methods don't conflict with any of Ruby's built-in names.

22.3.2 Functions

Global functions are wrapped as Ruby module methods. For example, given the SWIG interface file example.i:

%module example

int fact(int n);
and C source file example.c:
int fact(int n) {
  if (n == 0)
    return 1;
  return (n * fact(n-1));
}
SWIG will generate a method fact in the Example module that can be used like so:

$ irb
irb(main):001:0> require 'example'
true
irb(main):002:0> Example.fact(4)
24

22.3.3 Variable Linking

C/C++ global variables are wrapped as a pair of singleton methods for the module: one to get the value of the global variable and one to set it. For example, the following SWIG interface file declares two global variables:
// SWIG interface file with global variables
%module example
...
extern int    variable1;
extern double Variable2;
...

Now look at the Ruby interface:

$ irb
irb(main):001:0> require 'Example'
true
irb(main):002:0> Example.variable1 = 2
2
irb(main):003:0> Example.Variable2 = 4 * 10.3
41.2
irb(main):004:0> Example.Variable2
41.2

If you make an error in variable assignment, you will receive an error message. For example:

irb(main):005:0> Example.Variable2 = "hello"
TypeError: no implicit conversion to float from string
  from (irb):5:in `Variable2='
  from (irb):5

If a variable is declared as const, it is wrapped as a read-only variable. Attempts to modify its value will result in an error.

To make ordinary variables read-only, you can also use the %immutable directive. For example:

%immutable;
extern char *path;
%mutable;
The %immutable directive stays in effect until it is explicitly disabled using %mutable.

22.3.4 Constants

C/C++ constants are wrapped as module constants initialized to the appropriate value. To create a constant, use #define or the %constant directive. For example:
#define PI 3.14159
#define VERSION "1.0"

%constant int FOO = 42;
%constant const char *path = "/usr/local";

const int BAR = 32;
Remember to use the :: operator in Ruby to get at these constant values, e.g.

$ irb
irb(main):001:0> require 'Example'
true
irb(main):002:0> Example::PI
3.14159

22.3.5 Pointers

"Opaque" pointers to arbitrary C/C++ types (i.e. types that aren't explicitly declared in your SWIG interface file) are wrapped as data objects. So, for example, consider a SWIG interface file containing only the declarations:

Foo *get_foo();
void set_foo(Foo *foo);
For this case, the get_foo() method returns an instance of an internally generated Ruby class:
irb(main):001:0> foo = Example::get_foo()
#<SWIG::TYPE_p_Foo:0x402b1654>
A NULL pointer is always represented by the Ruby nil object.

22.3.6 Structures

C/C++ structs are wrapped as Ruby classes, with accessor methods (i.e. "getters" and "setters") for all of the struct members. For example, this struct declaration:

struct Vector {
    double x, y;
};
gets wrapped as a Vector class, with Ruby instance methods x, x=, y and y=. These methods can be used to access structure data from Ruby as follows:

$ irb
irb(main):001:0> require 'Example'
true
irb(main):002:0> f = Example::Vector.new
#<Example::Vector:0x4020b268>
irb(main):003:0> f.x = 10
nil
irb(main):004:0> f.x
10.0

Similar access is provided for unions and the public data members of C++ classes.

const members of a structure are read-only. Data members can also be forced to be read-only using the %immutable directive (in C++, private may also be used). For example:

struct Foo {
   ...
   %immutable;
   int x;        /* Read-only members */
   char *name;
   %mutable;
   ...
};

When char * members of a structure are wrapped, the contents are assumed to be dynamically allocated using malloc or new (depending on whether or not SWIG is run with the -c++ option). When the structure member is set, the old contents will be released and a new value created. If this is not the behavior you want, you will have to use a typemap (described shortly).

Array members are normally wrapped as read-only. For example, this code:

struct Foo {
   int x[50];
};
produces a single accessor function like this:
int *Foo_x_get(Foo *self) {
    return self->x;
};
If you want to set an array member, you will need to supply a "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).

When structure members are wrapped, they are handled as pointers. For example,

struct Foo {
   ...
};

struct Bar {
   Foo f;
};
generates accessor functions such as this:
Foo *Bar_f_get(Bar *b) {
    return &b->f;
}

void Bar_f_set(Bar *b, Foo *val) {
    b->f = *val;
}

22.3.7 C++ classes

Like structs, C++ classes are wrapped by creating a new Ruby class of the same name with accessor methods for the public class member data. Additionally, public member functions for the class are wrapped as Ruby instance methods, and public static member functions are wrapped as Ruby singleton methods. So, given the C++ class declaration:

class List {
public:
  List();
  ~List();
  int  search(char *item);
  void insert(char *item);
  void remove(char *item);
  char *get(int n);
  int  length;
  static void print(List *l);
};

SWIG would create a List class with:

  • instance methods search, insert, remove, and get;
  • instance methods length and length= (to get and set the value of the length data member); and,
  • a print singleton method for the class.

In Ruby, these functions are used as follows:

require 'Example'

l = Example::List.new

l.insert("Ale")
l.insert("Stout")
l.insert("Lager")
Example.print(l)
l.length()
----- produces the following output 
Lager
Stout
Ale
3

22.3.8 C++ Inheritance

The SWIG type-checker is fully aware of C++ inheritance. Therefore, if you have classes like this:
class Parent {
    ...
};

class Child : public Parent {
    ...
};
those classes are wrapped into a hierarchy of Ruby classes that reflect the same inheritance structure. All of the usual Ruby utility methods work normally:
irb(main):001:0> c = Child.new
#<Bar:0x4016efd4>
irb(main):002:0> c.instance_of? Child
true
irb(main):003:0> b.instance_of? Parent
false
irb(main):004:0> b.is_a? Child
true
irb(main):005:0> b.is_a? Parent
true
irb(main):006:0> Child < Parent
true
irb(main):007:0> Child > Parent
false
Furthermore, if you have a function like this:
void spam(Parent *f);
then the function spam() accepts Parent* or a pointer to any class derived from Parent.

Until recently, the Ruby module for SWIG didn't support multiple inheritance, and this is still the default behavior. This doesn't mean that you can't wrap C++ classes which inherit from multiple base classes; it simply means that only the first base class listed in the class declaration is considered, and any additional base classes are ignored. As an example, consider a SWIG interface file with a declaration like this:

class Derived : public Base1, public Base2
{
    ...
};
For this case, the resulting Ruby class (Derived) will only consider Base1 as its superclass. It won't inherit any of Base2's member functions or data and it won't recognize Base2 as an "ancestor" of Derived (i.e. the is_a? relationship would fail). When SWIG processes this interface file, you'll see a warning message like:
example.i:5: Warning(802): Warning for Derived: Base Base2 ignored. Multiple inheritance is not supported in Ruby.
Starting with SWIG 1.3.20, the Ruby module for SWIG provides limited support for multiple inheritance. Because the approach for dealing with multiple inheritance introduces some limitations, this is an optional feature that you can activate with the -minherit command-line option:
$ swig -c++ -ruby -minherit example.i
Using our previous example, if your SWIG interface file contains a declaration like this:
class Derived : public Base1, public Base2
{
    ...
};
and you run SWIG with the -minherit command-line option, then you will end up with a Ruby class Derived that appears to "inherit" the member data and functions from both Base1 and Base2. What actually happens is that three different top-level classes are created, with Ruby's Object class as their superclass. Each of these classes defines a nested module named Impl, and it's in these nested Impl modules that the actual instance methods for the classes are defined, i.e.
class Base1
  module Impl
    # Define Base1 methods here
  end
  include Impl
end

class Base2
  module Impl
    # Define Base2 methods here
  end
  include Impl
end

class Derived
  module Impl
    include Base1::Impl
    include Base2::Impl
    # Define Derived methods here
  end
  include Impl
end
Observe that after the nested Impl module for a class is defined, it is mixed-in to the class itself. Also observe that the Derived::Impl module first mixes-in its base classes' Impl modules, thus "inheriting" all of their behavior.

The primary drawback is that, unlike the default mode of operation, neither Base1 nor Base2 is a true superclass of Derived anymore:

obj = Derived.new
obj.is_a? Base1    # this will return false...
obj.is_a? Base2    # ... and so will this
In most cases, this is not a serious problem since objects of type Derived will otherwise behave as though they inherit from both Base1 and Base2 (i.e. they exhibit "Duck Typing").

22.3.9 C++ Overloaded Functions

C++ overloaded functions, methods, and constructors are mostly supported by SWIG. For example, if you have two functions like this:
void foo(int);
void foo(char *c);
You can use them in Ruby in a straightforward manner:
irb(main):001:0> foo(3)           # foo(int)
irb(main):002:0> foo("Hello")     # foo(char *c)
Similarly, if you have a class like this,
class Foo {
public:
    Foo();
    Foo(const Foo &);
    ...
};
you can write Ruby code like this:
irb(main):001:0> f = Foo.new          # Create a Foo
irb(main):002:0> g = Foo.new(f)       # Copy f
Overloading support is not quite as flexible as in C++. Sometimes there are methods that SWIG can't disambiguate. For example:
void spam(int);
void spam(short);
or
void foo(Bar *b);
void foo(Bar &b);
If declarations such as these appear, you will get a warning message like this:
example.i:12: Warning(509): Overloaded spam(short) is shadowed by spam(int) at example.i:11.
To fix this, you either need to ignore or rename one of the methods. For example:
%rename(spam_short) spam(short);
...
void spam(int);    
void spam(short);   // Accessed as spam_short
or
%ignore spam(short);
...
void spam(int);    
void spam(short);   // Ignored
SWIG resolves overloaded functions and methods using a disambiguation scheme that ranks and sorts declarations according to a set of type-precedence rules. The order in which declarations appear in the input does not matter except in situations where ambiguity arises--in this case, the first declaration takes precedence.

Please refer to the "SWIG and C++" chapter for more information about overloading.

22.3.10 C++ Operators

For the most part, overloaded operators are handled automatically by SWIG and do not require any special treatment on your part. So if your class declares an overloaded addition operator, e.g.
class Complex {
    ...
    Complex operator+(Complex &);
    ...
};
the resulting Ruby class will also support the addition (+) method correctly.

For cases where SWIG's built-in support is not sufficient, C++ operators can be wrapped using the %rename directive (available on SWIG 1.3.10 and later releases). All you need to do is give the operator the name of a valid Ruby identifier. For example:

%rename(add_complex) operator+(Complex &, Complex &);
...
Complex operator+(Complex &, Complex &);
Now, in Ruby, you can do this:
a = Example::Complex.new(2, 3)
b = Example::Complex.new(4, -1)
c = Example.add_complex(a, b)
More details about wrapping C++ operators into Ruby operators is discussed in the section on operator overloading.

22.3.11 C++ namespaces

SWIG is aware of C++ namespaces, but 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,
%module example

namespace foo {
   int fact(int n);
   struct Vector {
       double x,y,z;
   };
};
it works in Ruby as follows:
irb(main):001:0> require 'example'
true
irb(main):002:0> Example.fact(3)
6
irb(main):003:0> v = Example::Vector.new
#<Example::Vector:0x4016f4d4>
irb(main):004:0> v.x = 3.4
3.4
irb(main):004:0> v.y
0.0
If your program has more than one namespace, name conflicts (if any) can be resolved using %rename For example:
%rename(Bar_spam) Bar::spam;

namespace Foo {
    int spam();
}

namespace Bar {
    int spam();
}
If you have more than one namespace and your want to keep their symbols separate, consider wrapping them as separate SWIG modules. For example, make the module name the same as the namespace and create extension modules for each namespace separately. If your program utilizes thousands of small deeply nested namespaces each with identical symbol names, well, then you get what you deserve.

22.3.12 C++ templates

C++ templates don't present a huge problem for SWIG. However, in order to create wrappers, you have to tell SWIG to create wrappers for a particular template instantiation. To do this, you use the %template directive. For example:
%module example

%{
#include "pair.h"
%}

template<class T1, class T2>
struct pair {
   typedef T1 first_type;
   typedef T2 second_type;
   T1 first;
   T2 second;
   pair();
   pair(const T1&, const T2&);
  ~pair();
};

%template(Pairii) pair<int,int>;
In Ruby:
irb(main):001:0> require 'example'
true
irb(main):002:0> p = Example::Pairii.new(3, 4)
#<Example:Pairii:0x4016f4df>
irb(main):003:0> p.first
3
irb(main):004:0> p.second
4
On a related note, the standard SWIG library contains a number of modules that provide typemaps for standard C++ library classes (such as std::pair, std::string and std::vector). These library modules don't provide wrappers around the templates themselves, but they do make it convenient for users of your extension module to pass Ruby objects (such as arrays and strings) to wrapped C++ code that expects instances of standard C++ templates. For example, suppose the C++ library you're wrapping has a function that expects a vector of floats:
%module example

float sum(const std::vector<float>& values);
Rather than go through the hassle of writing an "in" typemap to convert an array of Ruby numbers into a std::vector<float>, you can just use the std_vector.i module from the standard SWIG library:
%module example

%include std_vector.i

float sum(const std::vector<float>& values);
Obviously, there is a lot more to template wrapping than shown in these examples. More details can be found in the SWIG and C++ chapter.

22.3.13 C++ Smart Pointers

In certain C++ programs, it is common to use classes that have been wrapped by so-called "smart pointers." Generally, this involves the use of a template class that implements operator->() like this:
template<class T> class SmartPtr {
   ...
   T *operator->();
   ...
}
Then, if you have a class like this,
class Foo {
public:
     int x;
     int bar();
};
A smart pointer would be used in C++ as follows:
SmartPtr<Foo> p = CreateFoo();   // Created somehow (not shown)
...
p->x = 3;                        // Foo::x
int y = p->bar();                // Foo::bar
To wrap this in Ruby, simply tell SWIG about the SmartPtr class and the low-level Foo object. Make sure you instantiate SmartPtr using %template if necessary. For example:
%module example
...
%template(SmartPtrFoo) SmartPtr<Foo>;
...
Now, in Ruby, everything should just "work":
irb(main):001:0> p = Example::CreateFoo()          # Create a smart-pointer somehow
#<Example::SmartPtrFoo:0x4016f4df>
irb(main):002:0> p.x = 3                          # Foo::x
3
irb(main):003:0> p.bar()                          # Foo::bar
If you ever need to access the underlying pointer returned by operator->() itself, simply use the __deref__() method. For example:
irb(main):004:0> f = p.__deref__()     # Returns underlying Foo *

22.3.14 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 secton just notes the differences that you need to be aware of when using this feature with Ruby.

22.3.14.1 Exception Unrolling

Whenever a C++ director class routes one of its virtual member function calls to a Ruby instance method, there's always the possibility that an exception will be raised in the Ruby code. By default, those exceptions are ignored, which simply means that the exception will be exposed to the Ruby interpreter. If you would like to change this behavior, you can use the %feature("director:except") directive to indicate what action should be taken when a Ruby exception is raised. The following code should suffice in most cases:
%feature("director:except") {
    throw Swig::DirectorMethodException($error);
}
When this feature is activated, the call to the Ruby instance method is "wrapped" using the rb_rescue2() function from Ruby's C API. If any Ruby exception is raised, it will be caught here and a C++ exception is raised in its place.

22.4 Input and output parameters

A common problem in some C programs is handling parameters passed as simple pointers. For example:
void add(int x, int y, int *result) {
   *result = x + y;
}
or
int sub(int *x, int *y) {
   return *x-*y;
}
The easiest way to handle these situations is to use the typemaps.i file. For example:
%module Example
%include "typemaps.i"

void add(int, int, int *OUTPUT);
int  sub(int *INPUT, int *INPUT);
In Ruby, this allows you to pass simple values. For example:
a = Example.add(3,4)
puts a
7
b = Example.sub(7,4)
puts b
3
Notice how the INPUT parameters allow integer values to be passed instead of pointers and how the OUTPUT parameter creates a return result.

If you don't want to use the names INPUT or OUTPUT, use the %apply directive. For example:

%module Example
%include "typemaps.i"

%apply int *OUTPUT { int *result };
%apply int *INPUT  { int *x, int *y};

void add(int x, int y, int *result);
int  sub(int *x, int *y);

If a function mutates one of its parameters like this,

void negate(int *x) {
   *x = -(*x);
}
you can use INOUT like this:
%include "typemaps.i"
...
void negate(int *INOUT);
In Ruby, a mutated parameter shows up as a return value. For example:
a = Example.negate(3)
print a
-3

The most common use of these special typemap rules is to handle functions that return more than one value. For example, sometimes a function returns a result as well as a special error code:

/* send message, return number of bytes sent, success code, and error_code */
int send_message(char *text, int *success, int *error_code);
To wrap such a function, simply use the OUTPUT rule above. For example:
%module example
%include "typemaps.i"
...
int send_message(char *, int *OUTPUT, int *OUTPUT);
When used in Ruby, the function will return an array of multiple values.
bytes, success, error_code = send_message("Hello World")
if not success
  print "error #{error_code} : in send_message"
else
  print "Sent", bytes
end
Another way to access multiple return values is to use the %apply rule. In the following example, the parameters rows and columns are related to SWIG as OUTPUT values through the use of %apply
%module Example
%include "typemaps.i"
%apply int *OUTPUT { int *rows, int *columns };
...
void get_dimensions(Matrix *m, int *rows, int*columns);
In Ruby:
r, c = Example.get_dimensions(m)

22.5 Simple exception handling

The SWIG %exception directive can be used to define a user-definable exception handler that can convert C/C++ errors into Ruby exceptions. The chapter on Customization Features contains more details, but suppose you have a C++ class like the following :

class DoubleArray {
  private:
    int n;
    double *ptr;
  public:
    // Create a new array of fixed size
    DoubleArray(int size) {
      ptr = new double[size];
      n = size;
    }
    // Destroy an array
    ~DoubleArray() {
       delete ptr;
    }
    // Return the length of the array
    int   length() {
      return n;
    }

    // Get an array item and perform bounds checking.
    double getitem(int i) {
      if ((i >= 0) && (i < n))
        return ptr[i];
      else
        throw RangeError();
    }
    // Set an array item and perform bounds checking.
    void setitem(int i, double val) {
      if ((i >= 0) && (i < n))
        ptr[i] = val;
      else {
        throw RangeError();
      }
    }
  };
Since several methods in this class can throw an exception for an out-of-bounds access, you might want to catch this in the Ruby extension by writing the following in an interface file:

%exception {
  try {
    $action
  }
  catch (const RangeError&) {
    static VALUE cpperror = rb_define_class("CPPError", rb_eStandardError);
    rb_raise(cpperror, "Range error.");
  }
}

class DoubleArray {
   ...
};
The exception handling code is inserted directly into generated wrapper functions. When an exception handler is defined, errors can be caught and used to gracefully raise a Ruby exception instead of forcing the entire program to terminate with an uncaught error.

As shown, the exception handling code will be added to every wrapper function. Because this is somewhat inefficient, you might consider refining the exception handler to only apply to specific methods like this:

%exception getitem {
  try {
    $action
  }
  catch (const RangeError&) {
    static VALUE cpperror = rb_define_class("CPPError", rb_eStandardError);
    rb_raise(cpperror, "Range error in getitem.");
  }
}

%exception setitem {
  try {
    $action
  }
  catch (const RangeError&) {
    static VALUE cpperror = rb_define_class("CPPError", rb_eStandardError);
    rb_raise(cpperror, "Range error in setitem.");
  }
}
In this case, the exception handler is only attached to methods and functions named getitem and setitem.

Since SWIG's exception handling is user-definable, you are not limited to C++ exception handling. See the chapter on Customization Features for more examples.

When raising a Ruby exception from C/C++, use the rb_raise() function as shown above. The first argument passed to rb_raise() is the exception type. You can raise a custom exception type (like the cpperror example shown above) or one of the built-in Ruby exception types. For a list of the standard Ruby exception classes, consult a Ruby reference such as Programming Ruby.


22.6 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 Ruby C API as well as the material in the "Typemaps" chapter.

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 primitive C-Ruby interface.

22.6.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 Ruby to C, you might define a typemap like this:

%module example

%typemap(in) int {
  $1 = (int) NUM2INT($input);
  printf("Received an integer : %d\n",$1);
}

extern int fact(int n);

Typemaps are always associated with some specific aspect of code generation. In this case, the "in" method refers to the conversion of input arguments to C/C++. The datatype int is the datatype to which the typemap will be applied. The supplied C code is used to convert values. In this code a number of special variables prefaced by a $ are used. The $1 variable is placeholder for a local variable of type int. The $input variable is the input Ruby object.

When this example is compiled into a Ruby module, the following sample code:

require 'example'

puts Example.fact(6)
prints the result:
Received an integer : 6
720

In this example, the typemap is applied to all occurrences of the int datatype. You can refine this by supplying an optional parameter name. For example:

%module example

%typemap(in) int n {
  $1 = (int) NUM2INT($input);
  printf("n = %d\n",$1);
}

extern int fact(int n);
In this case, the typemap code is only attached to arguments that exactly match "int n".

The application of a typemap to specific datatypes and argument names involves more than simple text-matching--typemaps are fully integrated into the SWIG type-system. When you define a typemap for int, that typemap applies to int and qualified variations such as const int. In addition, the typemap system follows typedef declarations. For example:

%typemap(in) int n {
    $1 = (int) NUM2INT($input);
    printf("n = %d\n",$1);
}

typedef int Integer;
extern int fact(Integer n);    // Above typemap is applied
However, the matching of typedef only occurs in one direction. If you defined a typemap for Integer, it is not applied to arguments of type int.

Typemaps can also be defined for groups of consecutive arguments. For example:

%typemap(in) (char *str, int len) {
    $1 = STR2CSTR($input);
    $2 = (int) RSTRING($input)->len;
};

int count(char c, char *str, int len);
When a multi-argument typemap is defined, the arguments are always handled as a single Ruby object. This allows the function count to be used as follows (notice how the length parameter is omitted):
puts Example.count('o','Hello World')
2

22.6.2 Ruby typemaps

The previous section illustrated an "in" typemap for converting Ruby objects to C. A variety of different typemap methods are defined by the Ruby module. For example, to convert a C integer back into a Ruby object, you might define an "out" typemap like this:
%typemap(out) int {
    $result = INT2NUM($1);
}
The following list details all of the typemap methods that can be used by the Ruby module:

%typemap(in)

Converts Ruby objects to input function arguments
%typemap(out)
Converts return value of a C function to a Ruby object
%typemap(varin)
Assigns a C global variable from a Ruby object
%typemap(varout)
Returns a C global variable as a Ruby object
%typemap(freearg)
Cleans up a function argument (if necessary)
%typemap(argout)
Output argument processing
%typemap(ret)
Cleanup of function return values
%typemap(memberin)
Setting of structure/class member data
%typemap(globalin)
Setting of C global variables
%typemap(check)
Checks function input values.
%typemap(default)
Set a default value for an argument (making it optional).
%typemap(arginit)
Initialize an argument to a value before any conversions occur.
Examples of these typemaps appears in the section on typemap examples

22.6.3 Typemap variables

Within a typemap, a number of special variables prefaced with a $ may appear. A full list of variables can be found in the "Typemaps" chapter. This is a list of the most common variables:

$1

A C local variable corresponding to the actual type specified in the %typemap directive. For input values, this is a C local variable that is supposed to hold an argument value. For output values, this is the raw result that is supposed to be returned to Ruby.
$input
A VALUE holding a raw Ruby object with an argument or variable value.
$result
A VALUE that holds the result to be returned to Ruby.
$1_name
The parameter name that was matched.
$1_type
The actual C datatype matched by the typemap.
$1_ltype
An assignable version of the datatype matched by the typemap (a type that can appear on the left-hand-side of a C assignment operation). This type is stripped of qualifiers and may be an altered version of $1_type. All arguments and local variables in wrapper functions are declared using this type so that their values can be properly assigned.
$symname
The Ruby name of the wrapper function being created.

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

22.6.4.1 C Datatypes to Ruby Objects

INT2NUM(long or int)  - int to Fixnum or Bignum
INT2FIX(long or int)  - int to Fixnum (faster than INT2NUM)
CHR2FIX(char)         - char to Fixnum
rb_str_new2(char*)    - char* to String
rb_float_new(double)  - double to Float

22.6.4.2 Ruby Objects to C Datatypes

          int NUM2INT(Numeric)
          int FIX2INT(Numeric)
 unsigned int NUM2UINT(Numeric)
 unsigned int FIX2UINT(Numeric)
         long NUM2LONG(Numeric)
         long FIX2LONG(Numeric)
unsigned long FIX2ULONG(Numeric)
         char NUM2CHR(Numeric or String)
       char * STR2CSTR(String)
       char * rb_str2cstr(String, int*length)
       double NUM2DBL(Numeric)

22.6.4.3 Macros for VALUE

RSTRING(str)->len

length of the Ruby string
RSTRING(str)->ptr
pointer to string storage
RARRAY(arr)->len
length of the Ruby array
RARRAY(arr)->capa
capacity of the Ruby array
RARRAY(arr)->ptr
pointer to array storage

22.6.4.4 Exceptions

void rb_raise(VALUE exception, const char *fmt, ...)

Raises an exception. The given format string fmt and remaining arguments are interpreted as with printf().
void rb_fatal(const char *fmt, ...)
Raises a fatal exception, terminating the process. No rescue blocks are called, but ensure blocks will be called. The given format string fmt and remaining arguments are interpreted as with printf().
void rb_bug(const char *fmt, ...)
Terminates the process immediately -- no handlers of any sort will be called. The given format string fmt and remaining arguments are interpreted as with printf(). You should call this function only if a fatal bug has been exposed.
void rb_sys_fail(const char *msg)
Raises a platform-specific exception corresponding to the last known system error, with the given string msg.
VALUE rb_rescue(VALUE (*body)(VALUE), VALUE args, VALUE(*rescue)(VALUE, VALUE), VALUE rargs)
Executes body with the given args. If a StandardError exception is raised, then execute rescue with the given rargs.
VALUE rb_ensure(VALUE(*body)(VALUE), VALUE args, VALUE(*ensure)(VALUE), VALUE eargs)
Executes body with the given args. Whether or not an exception is raised, execute ensure with the given rargs after body has completed.
VALUE rb_protect(VALUE (*body)(VALUE), VALUE args, int *result)
Executes body with the given args and returns nonzero in result if any exception was raised.
void rb_notimplement()
Raises a NotImpError exception to indicate that the enclosed function is not implemented yet, or not available on this platform.
void rb_exit(int status)
Exits Ruby with the given status. Raises a SystemExit exception and calls registered exit functions and finalizers.
void rb_warn(const char *fmt, ...)
Unconditionally issues a warning message to standard error. The given format string fmt and remaining arguments are interpreted as with printf().
void rb_warning(const char *fmt, ...)
Conditionally issues a warning message to standard error if Ruby was invoked with the -w flag. The given format string fmt and remaining arguments are interpreted as with printf().

22.6.4.5 Iterators

void rb_iter_break()

Breaks out of the enclosing iterator block.
VALUE rb_each(VALUE obj)
Invokes the each method of the given obj.
VALUE rb_yield(VALUE arg)
Transfers execution to the iterator block in the current context, passing arg as an argument. Multiple values may be passed in an array.
int rb_block_given_p()
Returns true if yield would execute a block in the current context; that is, if a code block was passed to the current method and is available to be called.
VALUE rb_iterate(VALUE (*method)(VALUE), VALUE args, VALUE (*block)(VALUE, VALUE), VALUE arg2)
Invokes method with argument args and block block. A yield from that method will invoke block with the argument given to yield, and a second argument arg2.
VALUE rb_catch(const char *tag, VALUE (*proc)(VALUE, VALUE), VALUE value)
Equivalent to Ruby's catch.
void rb_throw(const char *tag, VALUE value)
Equivalent to Ruby's throw.

22.6.5 Typemap Examples

This section includes a few examples of typemaps. For more examples, you might look at the examples in the Example/ruby directory.

22.6.6 Converting a Ruby array to a char **

A common problem in many C programs is the processing of command line arguments, which are usually passed in an array of NULL terminated strings. The following SWIG interface file allows a Ruby Array instance to be used as a char ** object.

%module argv

// This tells SWIG to treat char ** as a special case
%typemap(in) char ** {
  /* Get the length of the array */
  int size = RARRAY($input)->len;     
  int i;
  $1 = (char **) malloc((size+1)*sizeof(char *));
  /* Get the first element in memory */
  VALUE *ptr = RARRAY($input)->ptr;   
  for (i=0; i < size; i++, ptr++)
    /* Convert Ruby Object String to char* */
    $1[i]= STR2CSTR(*ptr); 
  $1[i]=NULL;  /* End of list */
}

// This cleans up the char ** array created before 
// the function call

%typemap(freearg) char ** {
  free((char *) $1);
}

// Now a test function
%inline %{
int print_args(char **argv) {
    int i = 0;
    while (argv[i]) {
         printf("argv[%d] = %s\n", i,argv[i]);
         i++;
    }
    return i;
}
%}

When this module is compiled, the wrapped C function now operates as follows :

require 'Argv'
Argv.print_args(["Dave","Mike","Mary","Jane","John"])
argv[0] = Dave
argv[1] = Mike
argv[2] = Mary
argv[3] = Jane
argv[4] = John
In the example, two different typemaps are used. The "in" typemap is used to receive an input argument and convert it to a C array. Since dynamic memory allocation is used to allocate memory for the array, the "freearg" typemap is used to later release this memory after the execution of the C function.

22.6.7 Collecting arguments in a hash

Ruby's solution to the "keyword arguments" capability of some other languages is to allow the programmer to pass in one or more key-value pairs as arguments to a function. All of those key-value pairs are collected in a single Hash argument that's presented to the function. If it makes sense, you might want to provide similar functionality for your Ruby interface. For example, suppose you'd like to wrap this C function that collects information about people's vital statistics:
void setVitalStats(const char *person, int nattributes, const char **names, int *values);
and you'd like to be able to call it from Ruby by passing in an arbitrary number of key-value pairs as inputs, e.g.
setVitalStats("Fred",
              'weight' => 270,
	      'age' => 42
	     )
To make this work, you need to write a typemap that expects a Ruby Hash as its input and somehow extracts the last three arguments (nattributes, names and values) needed by your C function. Let's start with the basics:
%typemap(in) (int nattributes, const char **names, const int *values) (VALUE keys_arr, int i, VALUE key, VALUE val) {
}
This %typemap directive tells SWIG that we want to match any function declaration that has the specified types and names of arguments somewhere in the argument list. The fact that we specified the argument names (nattributes, names and values) in our typemap is significant; this ensures that SWIG won't try to apply this typemap to other functions it sees that happen to have a similar declaration with different argument names. The arguments that appear in the second set of parentheses (keys_arr, i, key and val) define local variables that our typemap will need.

Since we expect the input argument to be a Hash, let's next add a check for that:

%typemap(in) (int nattributes, const char **names, const int *values) (VALUE keys_arr, int i, VALUE key, VALUE val) {
  Check_Type($input, T_HASH);
}
Check_Type() is just a macro (defined in the Ruby header files) that confirms that the input argument is of the correct type; if it isn't, an exception will be raised.

The next task is to determine how many key-value pairs are present in the hash; we'll assign this number to the first typemap argument ($1). This is a little tricky since the Ruby/C API doesn't provide a public function for querying the size of a hash, but we can get around that by calling the hash's size method directly and converting its result to a C int value:

%typemap(in) (int nattributes, const char **names, const int *values) (VALUE keys_arr, int i, VALUE key, VALUE val) {
  Check_Type($input, T_HASH);
  $1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, NULL));
}
So now we know the number of attributes. Next we need to initialize the second and third typemap arguments (i.e. the two C arrays) to NULL and set the stage for extracting the keys and values from the hash:
%typemap(in) (int nattributes, const char **names, const int *values) (VALUE keys_arr, int i, VALUE key, VALUE val) {
  Check_Type($input, T_HASH);
  $1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, NULL));
  $2 = NULL;
  $3 = NULL;
  if ($1 > 0) {
    $2 = (char **) malloc($1*sizeof(char *));
    $3 = (int *) malloc($1*sizeof(int));
  }
}
There are a number of ways we could extract the keys and values from the input hash, but the simplest approach is to first call the hash's keys method (which returns a Ruby array of the keys) and then start looping over the elements in that array:
%typemap(in) (int nattributes, const char **names, const int *values) (VALUE keys_arr, int i, VALUE key, VALUE val) {
  Check_Type($input, T_HASH);
  $1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, NULL));
  $2 = NULL;
  $3 = NULL;
  if ($1 > 0) {
    $2 = (char **) malloc($1*sizeof(char *));
    $3 = (int *) malloc($1*sizeof(int));
    keys_arr = rb_funcall($input, rb_intern("keys"), 0, NULL);
    for (i = 0; i < $1; i++) {
    }
  }
}
Recall that keys_arr and i are local variables for this typemap. For each element in the keys_arr array, we want to get the key itself, as well as the value corresponding to that key in the hash:
%typemap(in) (int nattributes, const char **names, const int *values) (VALUE keys_arr, int i, VALUE key, VALUE val) {
  Check_Type($input, T_HASH);
  $1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, NULL));
  $2 = NULL;
  $3 = NULL;
  if ($1 > 0) {
    $2 = (char **) malloc($1*sizeof(char *));
    $3 = (int *) malloc($1*sizeof(int));
    keys_arr = rb_funcall($input, rb_intern("keys"), 0, NULL);
    for (i = 0; i < $1; i++) {
      key = rb_ary_entry(keys_arr, i);
      val = rb_hash_aref($input, key);
    }
  }
}
To be safe, we should again use the Check_Type() macro to confirm that the key is a String and the value is a Fixnum:
%typemap(in) (int nattributes, const char **names, const int *values) (VALUE keys_arr, int i, VALUE key, VALUE val) {
  Check_Type($input, T_HASH);
  $1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, NULL));
  $2 = NULL;
  $3 = NULL;
  if ($1 > 0) {
    $2 = (char **) malloc($1*sizeof(char *));
    $3 = (int *) malloc($1*sizeof(int));
    keys_arr = rb_funcall($input, rb_intern("keys"), 0, NULL);
    for (i = 0; i < $1; i++) {
      key = rb_ary_entry(keys_arr, i);
      val = rb_hash_aref($input, key);
      Check_Type(key, T_STRING);
      Check_Type(val, T_FIXNUM);
    }
  }
}
Finally, we can convert these Ruby objects into their C equivalents and store them in our local C arrays:
%typemap(in) (int nattributes, const char **names, const int *values) (VALUE keys_arr, int i, VALUE key, VALUE val) {
  Check_Type($input, T_HASH);
  $1 = NUM2INT(rb_funcall($input, rb_intern("size"), 0, NULL));
  $2 = NULL;
  $3 = NULL;
  if ($1 > 0) {
    $2 = (char **) malloc($1*sizeof(char *));
    $3 = (int *) malloc($1*sizeof(int));
    keys_arr = rb_funcall($input, rb_intern("keys"), 0, NULL);
    for (i = 0; i < $1; i++) {
      key = rb_ary_entry(keys_arr, i);
      val = rb_hash_aref($input, key);
      Check_Type(key, T_STRING);
      Check_Type(val, T_FIXNUM);
      $2[i] = STR2CSTR(key);
      $3[i] = NUM2INT(val);
    }
  }
}
We're not done yet. Since we used malloc() to dynamically allocate the memory used for the names and values arguments, we need to provide a corresponding "freearg" typemap to free that memory so that there is no memory leak. Fortunately, this typemap is a lot easier to write:
%typemap(freearg) (int nattributes, const char **names, const int *values) {
  free((void *) $2);
  free((void *) $3);
}
All of the code for this example, as well as a sample Ruby program that uses the extension, can be found in the Examples/ruby/hashargs directory of the SWIG distribution.

22.6.8 Pointer handling

Occasionally, it might be necessary to convert pointer values that have been stored using the SWIG typed-pointer representation. Since there are several ways in which pointers can be represented, the following two functions are used to safely perform this conversion:

int SWIG_ConvertPtr(VALUE obj, void **ptr, swig_type_info *ty, int flags)

Converts a Ruby object obj to a C pointer whose address is ptr (i.e. ptr is a pointer to a pointer). The third argument, ty, is a pointer to a SWIG type descriptor structure. If ty is not NULL, that type information is used to validate type compatibility and other aspects of the type conversion. If flags is non-zero, any type errors encountered during this validation result in a Ruby TypeError exception being raised; if flags is zero, such type errors will cause SWIG_ConvertPtr() to return -1 but not raise an exception. If ty is NULL, no type-checking is performed.

VALUE SWIG_NewPointerObj(void *ptr, swig_type_info *ty, int own)

Creates a new Ruby pointer object. Here, ptr is the pointer to convert, ty is the SWIG type descriptor structure that describes the type, and own is a flag that indicates whether or not Ruby should take ownership of the pointer (i.e. whether Ruby should free this data when the corresponding Ruby instance is garbage-collected).
Both of these functions require the use of a special SWIG type-descriptor structure. This structure contains information about the mangled name of the datatype, type-equivalence information, as well as information about converting pointer values under C++ inheritance. For a type of Foo *, the type descriptor structure is usually accessed as follows:
Foo *foo;
SWIG_ConvertPtr($input, (void **) &foo, SWIGTYPE_p_Foo, 1);

VALUE obj;
obj = SWIG_NewPointerObj(f, SWIGTYPE_p_Foo, 0);
In a typemap, the type descriptor should always be accessed using the special typemap variable $1_descriptor. For example:
%typemap(in) Foo * {
   SWIG_ConvertPtr($input, (void **) &$1, $1_descriptor, 1);
}

22.6.8.1 Ruby Datatype Wrapping

VALUE Data_Wrap_Struct(VALUE class, void (*mark)(void *), void (*free)(void *), void *ptr)

Given a pointer ptr to some C data, and the two garbage collection routines for this data (mark and free), return a VALUE for the Ruby object.
VALUE Data_Make_Struct(VALUE class, c-type, void (*mark)(void *), void (*free)(void *), c-type *ptr)
Allocates a new instance of a C data type c-type, assigns it to the pointer ptr, then wraps that pointer with Data_Wrap_Struct() as above.
Data_Get_Struct(VALUE obj, c-type, c-type *ptr)
Retrieves the original C pointer of type c-type from the data object obj and assigns that pointer to ptr.

22.7 Operator overloading

SWIG allows operator overloading with, by using the %extend or %rename commands in SWIG and the following operator names (derived from Python):
 General 
__repr__      - inspect
__str__       - to_s
__cmp__       - <=>
__hash__      - hash
__nonzero__   - nonzero?

 Callable 
__call__      - call

 Collection 
__len__       - length
__getitem__   - []
__setitem__   - []=

 Numeric 
__add__       - +
__sub__       - -
__mul__       - *
__div__       - /
__mod__       - %
__divmod__    - divmod
__pow__       - **
__lshift__    - <<
__rshift__    - >>
__and__       - &
__xor__       - ^
__or__        - |
__neg__       - -@
__pos__       - +@
__abs__       - abs
__invert__    - ~
__int__       - to_i
__float__     - to_f
__coerce__    - coerce

Additions in 1.3.13  
__lt__        - < 
__le__        - <=
__eq__        - ==
__gt__        - >
__ge__        - >=

Note that although SWIG supports the __eq__ magic method name for defining an equivalence operator, there is no separate method for handling inequality since Ruby parses the expression a != b as !(a == b).

22.7.1 Example: STL Vector to Ruby Array

FIXME: This example is out of place here!

Another use for macros and type maps is to create a Ruby array from a STL vector of pointers. In essence, copy of all the pointers in the vector into a Ruby array. The use of the macro is to make the typemap so generic that any vector with pointers can use the type map. The following is an example of how to construct this type of macro/typemap and should give insight into constructing similar typemaps for other STL structures:

%define PTR_VECTOR_TO_RUBY_ARRAY(vectorclassname, classname)
%typemap(ruby, out) vectorclassname &, const vectorclassname & {
  VALUE arr = rb_ary_new2($1->size());
  vectorclassname::iterator i = $1->begin(), iend = $1->end();
  for ( ; i!=iend; i++ )
    rb_ary_push(arr, Data_Wrap_Struct(c ## classname.klass, 0, 0, *i));
  $result = arr;
}
%typemap(ruby, out) vectorclassname, const vectorclassname {
  VALUE arr = rb_ary_new2($1.size());
  vectorclassname::iterator i = $1.begin(), iend = $1.end();
  for ( ; i!=iend; i++ )
    rb_ary_push(arr, Data_Wrap_Struct(c ## classname.klass, 0, 0, *i));
  $result = arr;
}
%enddef
Note, that the "c ## classname.klass" is used in the preprocessor step to determine the actual object from the class name.

To use the macro with a class Foo, the following is used:

PTR_VECTOR_TO_RUBY_ARRAY(vector, Foo)
It is also possible to create a STL vector of Ruby objects:

%define RUBY_ARRAY_TO_PTR_VECTOR(vectorclassname, classname)
%typemap(ruby, in) vectorclassname &, const vectorclassname & {
  Check_Type($input, T_ARRAY);
  vectorclassname *vec = new vectorclassname;
  int len = RARRAY($input)->len;
  for (int i=0; i!=len; i++) {
    VALUE inst = rb_ary_entry($input, i);
    //The following _should_ work but doesn't on HPUX
    //    Check_Type(inst, T_DATA);
    classname *element = NULL;
    Data_Get_Struct(inst, classname, element);
    vec->push_back(element);
  }
  $1 = vec;
}

%typemap(ruby, freearg) vectorclassname &, const vectorclassname & {
  delete $1;
}
%enddef
It is also possible to create a Ruby array from a vector of static data types:

%define VECTOR_TO_RUBY_ARRAY(vectorclassname, classname) %typemap(ruby, out) vectorclassname &, const vectorclassname & { VALUE arr = rb_ary_new2($1->size()); vectorclassname::iterator i = $1->begin(), iend = $1->end(); for ( ; i!=iend; i++ ) rb_ary_push(arr, Data_Wrap_Struct(c ## classname.klass, 0, 0, &(*i))); $result = arr; } %typemap(ruby, out) vectorclassname, const vectorclassname { VALUE arr = rb_ary_new2($1.size()); vectorclassname::iterator i = $1.begin(), iend = $1.end(); for ( ; i!=iend; i++ ) rb_ary_push(arr, Data_Wrap_Struct(c ## classname.klass, 0, 0, &(*i))); $result = arr; } %enddef

22.8 Advanced Topics

22.8.1 Creating Multi-Module Packages

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

As an example, consider one module's interface file (shape.i) that defines our base class:

%module shape

%{
#include "Shape.h"
%}

class Shape {
protected:
    double xpos;
    double ypos;
protected:
    Shape(double x, double y);
public:
    double getX() const;
    double getY() const;
};
We also have a separate interface file (circle.i) that defines a derived class:
%module circle

%{
#include "Shape.h"
#include "Circle.h"
%}

// Import the base class definition from Shape module
%import shape.i

class Circle : public Shape {
protected:
    double radius;
public:
    Circle(double x, double y, double r);
    double getRadius() const;
};
Both of these modules should be compiled with SWIG's -c option so that the runtime library code is omitted from the wrapper files. We'll start by building the Shape extension module:

$ swig -c++ -ruby -c shape.i
SWIG generates a wrapper file named shape_wrap.cxx. To compile this into a dynamically loadable extension for Ruby, prepare an extconf.rb script using this template:

require 'mkmf'

# Since the SWIG runtime support library for Ruby (libswigrb.so)
# depends on the Ruby library, make sure it's in the list
# of libraries.
$libs = append_library($libs, Config::CONFIG['RUBY_INSTALL_NAME'])

# Now add the SWIG runtime support library
have_library('swigrb', 'SWIG_InitRuntime')

# Create the makefile
create_makefile('shape')
Run this script to create a Makefile and then type make to build the shared library:

$ ruby extconf.rb
checking for SWIG_InitRuntime() in -lswigrb... yes
creating Makefile

$ make
g++ -fPIC -g -O2  -I. -I/usr/local/lib/ruby/1.7/i686-linux \
        -I. -c shape_wrap.cxx
gcc -shared -L/usr/local/lib -o shape.so shape_wrap.o -L. \
	-lruby -lswigrb -lruby -lc
Note that depending on your installation, the outputs may be slightly different; these outputs are those for a Linux-based development environment. The end result should be a shared library (here, shape.so) containing the extension module code. Now repeat this process in a separate directory for the Circle module:
  1. Run SWIG to generate the wrapper code (circle_wrap.cxx);
  2. Write an extconf.rb script that your end-users can use to create a platform-specific Makefile for the extension;
  3. Build the shared library for this extension by typing make.
Once you've built both of these extension modules, you can test them interactively in IRB to confirm that the Shape and Circle modules are properly loaded and initialized:

$ irb
irb(main):001:0> require 'shape'
true
irb(main):002:0> require 'circle'
true
irb(main):003:0> c = Circle::Circle.new(5, 5, 20)
#<Circle::Circle:0xa097208>
irb(main):004:0> c.kind_of? Shape::Shape
true
irb(main):005:0> c.getX()
5.0

22.8.2 Defining Aliases

It's a fairly common practice in the Ruby built-ins and standard library to provide aliases for method names. For example, Array#size is an alias for Array#length. If you'd like to provide an alias for one of your class' instance methods, one approach is to use SWIG's %extend directive to add a new method of the aliased name that calls the original function. For example:

class MyArray {
public:
  // Construct an empty array
  MyArray();
  
  // Return the size of this array
  size_t length() const;
};

%extend MyArray {
  // MyArray#size is an alias for MyArray#length
  size_t size() const {
    return self->length();
  }
}
A better solution is to instead use the %alias directive (unique to SWIG's Ruby module). The previous example could then be rewritten as:

// MyArray#size is an alias for MyArray#length
%alias MyArray::length "size";

class MyArray {
public:
  // Construct an empty array
  MyArray();
  
  // Return the size of this array
  size_t length() const;
};
Multiple aliases can be associated with a method by providing a comma-separated list of aliases to the %alias directive, e.g.
%alias MyArray::length "amount,quantity,size";
From an end-user's standpoint, there's no functional difference between these two approaches; i.e. they should get the same result from calling either MyArray#size or MyArray#length. However, when the %alias directive is used, SWIG doesn't need to generate all of the wrapper code that's usually associated with added methods like our MyArray::size() example.

Note that the %alias directive is implemented using SWIG's "features" mechanism and so the same name matching rules used for other kinds of features apply (see the chapter on "Customization Features") for more details).

22.8.3 Predicate Methods

Predicate methods in Ruby are those which return either true or false. By convention, these methods' names end in a question mark; some examples from built-in Ruby classes include Array#empty? (which returns true for an array containing no elements) and Object#instance_of? (which returns true if the object is an instance of the specified class). For consistency with Ruby conventions you would also want your interface's predicate methods' names to end in a question mark and return true or false.

One cumbersome solution to this problem is to rename the method (using SWIG's %rename directive) and provide a custom typemap that converts the function's actual return type to Ruby's true or false. For example:

%rename("is_it_safe?") is_it_safe();

%typemap(out) int is_it_safe 
   "$result = ($1 != 0) ? Qtrue : Qfalse;";

int is_it_safe();
A better solution is to instead use the %predicate directive (unique to SWIG's Ruby module) to designate certain methods as predicate methods. For the previous example, this would look like:

%predicate is_it_safe();

int is_it_safe();
and to use this method from your Ruby code:
irb(main):001:0> Example::is_it_safe?
true
Note that the %predicate directive is implemented using SWIG's "features" mechanism and so the same name matching rules used for other kinds of features apply (see the chapter on "Customization Features") for more details).

22.8.4 Specifying Mixin Modules

The Ruby language doesn't support multiple inheritance, but it does allow you to mix one or more modules into a class using Ruby's include method. For example, if you have a Ruby class that defines an each instance method, e.g.

class Set
  def initialize
    @members = []
  end
  
  def each
    @members.each { |m| yield m }
  end
end
then you can mix-in Ruby's Enumerable module to easily add a lot of functionality to your class:

class Set
  include Enumerable
  
  def initialize
    @members = []
  end
  
  def each
    @members.each { |m| yield m }
  end
end
To get the same benefit for your SWIG-wrapped classes, you can use the %mixin directive to specify the names of one or more modules that should be mixed-in to a class. For the above example, the SWIG interface specification might look like this:
%mixin Set "Enumerable";

class Set {
public:
  // Constructor
  Set();
  
  // Iterates through set members
  void each();
};
Multiple modules can be mixed into a class by providing a comma-separated list of module names to the %mixin directive, e.g.
%mixin Set "Fee,Fi,Fo,Fum";
Note that the %mixin directive is implemented using SWIG's "features" mechanism and so the same name matching rules used for other kinds of features apply (see the chapter on "Customization Features") for more details).

22.8.5 Interacting with Ruby's Garbage Collector

This section is still unfinished!

By default, SWIG ensures that any C++ objects it creates are destroyed when the corresponding Ruby instance is garbage-collected. For example, if you have an interface like this:

class Foo
{
public:
    // Construct a new Foo object
    Foo();
};
When a user of this extension creates a new Foo instance from Ruby, it will construct a new C++ Foo object behind the scenes, and when that Ruby instance is garbage-collected, the same C++ object will be destroyed.

But in the real world, things aren't always that simple.

It is often the case, especially for C++ libraries, that objects contain references to other objects. For example, consider a class library that models a zoo and the animals in the zoo:

%module zoo

%{
#include 
#include 

#include "zoo.h"
%}

class Animal
{
protected:
    std::string name;
    
public:
    // Construct an animal with this name
    Animal(const char* nm) : name(nm) {}
    
    // Return the animal's name
    const char* getName() const { return name.c_str(); }
};

class Zoo
{
protected:
    std::vector animals;
    
public:
    // Construct an empty zoo
    Zoo() {}
    
    // Add a new animal to the zoo
    void addAnimal(Animal* animal) {
      animals.push_back(animal); 
    }
    
    // Return the number of animals in the zoo
    size_t getNumAnimals() const {
      return animals.size(); 
    }
    
    // Return a pointer to the ith animal
    Animal* getAnimal(size_t i) const {
      return animals[i]; 
    }
};

Basically, a Zoo is modeled as a "container" for animals. And we can SWIG this set of classes, and running irb gives the following:
$ irb
irb(main):001:0> require 'zoo'
true
irb(main):002:0> zoo = Zoo::Zoo.new
#<Zoo::Zoo:0xa090458>
irb(main):003:0> zoo.addAnimal(Zoo::Animal.new("Lassie"))
nil
irb(main):004:0> zoo.addAnimal(Zoo::Animal.new("Felix"))
nil
irb(main):005:0> zoo.getNumAnimals()
2
irb(main):006:0> zoo.getAnimal(0).getName()
"Lassie"
irb(main):007:0> GC.start
nil
irb(main):008:0> zoo.getAnimal(0).getName()
(irb):8: [BUG] Segmentation fault
ruby 1.7.2 (2002-03-25) [i386-cygwin]
Aborted (core dumped)
Observe that after the garbage collector runs (as a result of our call to GC.start) the call to Animal#getName causes a segmentation fault. To understand what went wrong requires a basic understanding of Ruby's "mark and sweep" garbage collection scheme.

Add brief discussion of mark and sweep here?

So the problem with our previous example is that during the GC "mark" phase, Ruby has no way of knowing that our two Animal instances ("Lassie" and "Felix") are still in use. As far as Ruby can tell, both of these objects are unreachable and should be garbage-collected. We'd like to fix things so that when the Zoo instance is visited during the "mark" phase, that it in turn marks the two animals as in use.

The Ruby/C API provides for this need by allowing extension developers to specify customized "mark" functions for data objects like our Zoo and Animal classes. This mark function takes a single argument, which is a pointer to the C++ object being marked; it should, in turn, call rb_gc_mark() for any instances that are reachable from the current object. The mark function for our Zoo class should therefore loop over all of the animals in the zoo and call rb_gc_mark() for each of the Ruby instances associated with those C++ Animal objects:

void Zoo_markfunc(void *ptr)
{
    Animal *cppAnimal;
    VALUE   rubyAnimal;
    Zoo *zoo;
    
    zoo = static_cast(ptr);
    for (size_t i = 0; i < zoo->getNumAnimals(); i++) {
        cppAnimal = zoo->getAnimal(i);
        rubyAnimal = SWIG_RubyInstanceFor(cppAnimal);
        rb_gc_mark(rubyAnimal);
    }
}
SWIG_RubyInstanceFor() is an imaginary function that takes a pointer to a C/C++ object as its input and returns a VALUE corresponding to the Ruby instance that wraps this object. Currently, SWIG doesn't keep track of this kind of mapping at all.

You can use the %markfunc directive to associate the name of this function with a SWIGed class:

%markfunc Zoo "Zoo_markfunc";
Note that the %markfunc and %freefunc directives are implemented using SWIG's' "features" mechanism and so the same name matching rules used for other kinds of features apply (see the chapter on "Customization Features") for more details).
SWIG 1.3 - Last Modified : 2003/11/25 21:18:28
cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/Introduction.html0000644000175000000620000003303112561312226023066 0ustar stevestaff Introduction

1 Introduction

1.1 What is SWIG?

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 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 build a usable interface in only a few minutes. Possible applications of SWIG include:

  • Building interpreted interfaces to existing C programs.
  • Rapid prototyping and application development.
  • Interactive debugging.
  • Reengineering or refactoring of legacy software into a scripting language components.
  • Making a graphical user interface (using Tk for example).
  • Testing of C libraries and programs (using scripts).
  • Building high performance C modules for scripting languages.
  • Making C programming more enjoyable (or tolerable depending on your point of view).
  • Impressing your friends.
  • Obtaining vast sums of research funding (although obviously not applicable to the author).

SWIG was originally designed to make it extremely easy for scientists and engineers to build extensible scientific software without having to get a degree in software engineering. Because of this, the use of SWIG tends to be somewhat informal and ad-hoc (e.g., SWIG does not require users to provide formal interface specifications as you would find in 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.

1.2 Why use SWIG?

As stated in the previous section, the primary purpose of SWIG is to simplify the task of integrating C/C++ with other programming languages. However, why would anyone want to do that? To answer that question, it is useful to list a few strengths of C/C++ programming:
  • Excellent support for writing programming libraries.
  • High performance (number crunching, data processing, graphics, etc.).
  • Systems programming and systems integration.
  • Large user community and software base.
Next, let's list a few problems with C/C++ programming
  • Writing a user interface is rather painful (i.e., consider programming with MFC, X11, GTK, or any number of other libraries).
  • Testing is time consuming (the compile/debug cycle).
  • Not easy to reconfigure or customize without recompilation.
  • Modularization can be tricky.
  • Security concerns (buffer overflow for instance).
To address these limitations, many programmers have arrived at the conclusion that it is much easier to use different programming languages for different tasks. For instance, writing a graphical user interface may be significantly easier in a scripting language like Python or Tcl (consider the reasons why millions of programmers have used languages like Visual Basic if you need more proof). An interactive interpreter might also serve as a useful debugging and testing tool. Other languages like Java might greatly simplify the task of writing distributed computing software. The key point is that different programming languages offer different strengths and weaknesses. Moreover, it is extremely unlikely that any programming is ever going to be perfect. Therefore, by combining languages together, you can utilize the best features of each language and greatly simplify certain aspects of software development.

From the standpoint of C/C++, a lot of people use SWIG because they want to break out of the traditional monolithic C programming model which usually results in programs that resemble this:

  • A collection of functions and variables that do something useful.
  • A main() program that starts everything.
  • A horrible collection of hacks that form some kind of user interface (but which no-one really wants to touch).
Instead of going down that route, incorporating C/C++ into a higher level language often results in a more modular design, less code, better flexibility, and increased programmer productivity.

SWIG tries to make the problem of C/C++ integration as painless as possible. This allows you to focus on the underlying C program and using the high-level language interface, but not the tedious and complex chore of making the two languages talk to each other. At the same time, SWIG recognizes that all applications are different. Therefore, it provides a wide variety of customization features that let you change almost every aspect of the language bindings. This is the main reason why SWIG has such a large user manual ;-).

1.3 A SWIG example

The best way to illustrate SWIG is with a simple example. Consider the following C code:

/* File : example.c */

double  My_variable  = 3.0;

/* Compute factorial of n */
int  fact(int n) {
	if (n <= 1) return 1;
	else return n*fact(n-1);
}

/* Compute n mod m */
int my_mod(int n, int m) {
	return(n % m);
}

Suppose that you wanted to access these functions and the global variable My_variable from Tcl. You start by making a SWIG interface file as shown below (by convention, these files carry a .i suffix) :

1.3.1 SWIG interface file

/* File : example.i */
%module example
%{
/* Put headers and other declarations here */
%}

extern double My_variable;
extern int    fact(int);
extern int    my_mod(int n, int m);

The interface file contains ANSI C function prototypes and variable declarations. The %module directive defines the name of the module that will be created by SWIG. The %{,%} block provides a location for inserting additional code such as C header files or additional C declarations.

1.3.2 The swig command

SWIG is invoked using the swig command. We can use this to build a Tcl module (under Linux) as follows :

unix > swig -tcl example.i
unix > gcc -c -fpic example.c example_wrap.c -I/usr/local/include
unix > gcc -shared example.o example_wrap.o -o example.so
unix > tclsh
% load ./example.so
% fact 4
24
% my_mod 23 7
2
% expr $My_variable + 4.5
7.5
%

The swig command produced a new file called example_wrap.c that should be compiled along with the example.c file. Most operating systems and scripting languages now support dynamic loading of modules. In our example, our Tcl module has been compiled into a shared library that can be loaded into Tcl. When loaded, Tcl can now access the functions and variables declared in the SWIG interface. A look at the file example_wrap.c reveals a hideous mess. However, you almost never need to worry about it.

1.3.3 Building a Perl5 module

Now, let's turn these functions into a Perl5 module. Without making any changes type the following (shown for Solaris):

unix > swig -perl5 example.i
unix > gcc -c example.c example_wrap.c \
	-I/usr/local/lib/perl5/sun4-solaris/5.003/CORE
unix > ld -G example.o example_wrap.o -o example.so		# This is for Solaris
unix > perl5.003
use example;
print example::fact(4), "\n";
print example::my_mod(23,7), "\n";
print $example::My_variable + 4.5, "\n";
<ctrl-d>
24
2
7.5
unix >

1.3.4 Building a Python module

Finally, let's build a module for Python (shown for Irix).

unix > swig -python example.i
unix > gcc -c -fpic example.c example_wrap.c -I/usr/local/include/python2.0
unix > gcc -shared example.o example_wrap.o -o _example.so
unix > python
Python 2.0 (#6, Feb 21 2001, 13:29:45)
[GCC egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)] on linux2
Type "copyright", "credits" or "license" for more information.     
>>> import example
>>> example.fact(4)
24
>>> example.my_mod(23,7)
2
>>> example.cvar.My_variable + 4.5
7.5

1.3.5 Shortcuts

To the truly lazy programmer, one may wonder why we needed the extra interface file at all. As it turns out, you can often do without it. For example, you could also build a Perl5 module by just running SWIG on the C header file and specifying a module name as follows

unix > swig -perl5 -module example example.h
unix > gcc -c example.c example_wrap.c \
	-I/usr/local/lib/perl5/sun4-solaris/5.003/CORE
unix > ld -G example.o example_wrap.o -o example.so
unix > perl5.003
use example;
print example::fact(4), "\n";
print example::my_mod(23,7), "\n";
print $example::My_variable + 4.5, "\n";
<ctrl-d>
24
2
7.5

1.4 Supported C/C++ language features

A primary goal of the SWIG project is to make the language binding process extremely easy. Although a few simple examples have been shown, SWIG is quite capable in supporting most of C++. Some of the major features include:
  • Full C99 preprocessing.
  • All ANSI C and C++ datatypes.
  • Functions, variables, and constants.
  • Classes.
  • Single and multiple inheritance.
  • Overloaded functions and methods.
  • Overloaded operators.
  • C++ templates (including member templates, specialization, and partial specialization).
  • Namespaces.
  • Variable length arguments.
  • C++ smart pointers.
Currently, the only major C++ feature not supported is nested classes--a limitation that will be removed in a future release.

It is important to stress that SWIG is not a simplistic C++ lexing tool like several apparently similar wrapper generation tools. SWIG not only parses C++, it implements the full C++ type system and it is able to understand C++ semantics. SWIG generates its wrappers with full knowledge of this information. As a result, you will find SWIG to be just as capable of dealing with nasty corner cases as it is in wrapping simple C++ code. In fact, SWIG is able handle C++ code that stresses the very limits of many C++ compilers.

1.5 Non-intrusive interface building

When used as intended, SWIG requires minimal (if any) modification to existing C code. This makes SWIG extremely easy to use with existing packages and promotes software reuse and modularity. By making the C code independent of the high level interface, you can change the interface and reuse the code in other applications. It is also possible to support different types of interfaces depending on the application.

1.6 Hands off code generation

SWIG is designed to produce working code that needs no hand-modification (in fact, if you look at the output, you probably won't want to modify it). Ideally, SWIG should be invoked automatically inside a Makefile just as one would call the C compiler. You should think of your scripting language interface being defined entirely by the input to SWIG, not the resulting output file. While this approach may limit flexibility for hard-core hackers, it allows others to forget about the low-level implementation details.

SWIG and freedom

No, this isn't a special section on the sorry state of world politics. However, it may be useful to know that SWIG was written with a certain "philosophy" about programming---namely that programmers are smart and that tools should just stay out of their way. Because of that, you will find that SWIG is extremely permissive in what it lets you get away with. In fact, you can use SWIG to go well beyond "shooting yourself in the foot" if dangerous programming is your goal. On the other hand, this kind of freedoom may be exactly what is needed to work with complicated and unusual C/C++ applications.

Ironically, the freedom that SWIG provides is countered by an extremely conservative approach to code generation. At it's core, SWIG tries to distill even the most advanced C++ code down to a small well-defined set of interface building techniques based on ANSI C programming. Because of this, you will find that SWIG interfaces can be easily compiled by virtually every C/C++ compiler and that they can be used on any platform. Again, this is an important part of staying out of the programmer's way----the last thing any developer wants to do is to spend their time debugging the output of a tool that relies on non-portable or unreliable programming features.


SWIG 1.3 - Last Modified : August 10, 2002
cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/SWIG.html0000644000175000000620000024452212561312226021167 0ustar stevestaff SWIG Basics

4 SWIG Basics

This chapter describes the basic operation of SWIG, the structure of its input files, and how it handles standard ANSI C declarations. C++ support is described in the next chapter. However, C++ programmers should still read this chapter to understand the basics. Specific details about each target language are described in later chapters.

4.1 Running SWIG

To run SWIG, use the swig command with one or more of the following options and a filename like this:

swig [ options ] filename

-chicken              Generate CHICKEN wrappers
-csharp               Generate C# wrappers
-guile                Generate Guile wrappers
-java                 Generate Java wrappers
-mzscheme             Generate Mzscheme wrappers
-ocaml                Generate Ocaml wrappers
-perl                 Generate Perl wrappers
-php                  Generate PHP wrappers
-pike                 Generate Pike wrappers
-python               Generate Python wrappers
-ruby                 Generate Ruby wrappers
-sexp                 Generate Lisp S-Expressions wrappers
-tcl                  Generate Tcl wrappers
-xml                  Generate XML wrappers
-c++                  Enable C++ parsing
-Dsymbol              Define a preprocessor symbol
-Fstandard            Display error/warning messages in commonly used format
-Fmicrosoft           Display error/warning messages in Microsoft format
-help                 Display all options
-Idir                 Add a directory to the file include path
-lfile                Include a SWIG library file.
-module name          Set the name of the SWIG module
-noruntime            Generate raw wrapper code (omit supporting code)
-o outfile            Name of output file
-outdir dir           Set language specific files output directory
-swiglib              Show location of SWIG library
-version              Show SWIG version number

This is a subset of commandline options. Additional options are also defined for each target language. A full list can be obtained by typing swig -help or swig -lang -help.

4.1.1 Input format

As input, SWIG expects a file containing ANSI C/C++ declarations and special SWIG directives. More often than not, this is a special SWIG interface file which is usually denoted with a special .i or .swg suffix. In certain cases, SWIG can be used directly on raw header files or source files. However, this is not the most typical case and there are several reasons why you might not want to do this (described later).

The most common format of a SWIG interface is as follows:

%module mymodule 
%{
#include "myheader.h"
%}
// Now list ANSI C/C++ declarations
int foo;
int bar(int x);
...
The name of the module is supplied using the special %module directive (or the -module command line option). This directive must appear at the beginning of the file and is used to name the resulting extension module (in addition, this name often defines a namespace in the target language). If the module name is supplied on the command line, it overrides the name specified with the %module directive.

Everything in the %{ ... %} block is simply copied verbatim to the resulting wrapper file created by SWIG. This section is almost always used to include header files and other declarations that are required to make the generated wrapper code compile. It is important to emphasize that just because you include a declaration in a SWIG input file, that declaration does not automatically appear in the generated wrapper code---therefore you need to make sure you include the proper header files in the %{ ... %} section. It should be noted that the text enclosed in %{ ... %} is not parsed or interpreted by SWIG. The %{...%} syntax and semantics in SWIG is analogous to that of the declarations section used in input files to parser generation tools such as yacc or bison.

4.1.2 SWIG Output

The output of SWIG is a C/C++ file that contains all of the wrapper code needed to build an extension module. SWIG may generate some additional files depending on the target language. By default, an input file with the name file.i is transformed into a file file_wrap.c or file_wrap.cxx (depending on whether or not the -c++ option has been used). The name of the output file can be changed using the -o option. In certain cases, file suffixes are used by the compiler to determine the source language (C, C++, etc.). Therefore, you have to use the -o option to change the suffix of the SWIG-generated wrapper file if you want something different than the default. For example:
$ swig -c++ -python -o example_wrap.cpp example.i

The C/C++ output file created by SWIG often contains everything that is needed to construct a extension module for the target scripting language. SWIG is not a stub compiler nor is it usually necessary to edit the output file (and if you look at the output, you probably won't want to). To build the final extension module, the SWIG output file is compiled and linked with the rest of your C/C++ program to create a shared library.

Many target languages will also generate proxy class files in the target language. The default output directory for these language specific files is the same directory as the generated C/C++ file. This can can be modified using the -outdir option. For example:

$ swig -c++ -python -outdir pyfiles -o cppfiles/example_wrap.cpp example.i
If the directories cppfiles and pyfiles exist, the following will be generated:
cppfiles/example_wrap.cpp
pyfiles/example.py

4.1.3 Comments

C and C++ style comments may appear anywhere in interface files. In previous versions of SWIG, comments were used to generate documentation files. However, this feature is currently under repair and will reappear in a later SWIG release.

4.1.4 C Preprocessor

Like C, SWIG preprocesses all input files through an enhanced version of the C preprocessor. All standard preprocessor features are supported including file inclusion, conditional compilation and macros. However, #include statements are ignored unless the -includeall command line option has been supplied. The reason for disabling includes is that SWIG is sometimes used to process raw C header files. In this case, you usually only want the extension module to include functions in the supplied header file rather than everything that might be included by that header file (i.e., system headers, C library functions, etc.).

It should also be noted that the SWIG preprocessor skips all text enclosed inside a %{...%} block. In addition, the preprocessor includes a number of macro handling enhancements that make it more powerful than the normal C preprocessor. These extensions are described in the "Preprocessor" chapter.

4.1.5 SWIG Directives

Most of SWIG's operation is controlled by special directives that are always preceded by a "%" to distinguish them from normal C declarations. These directives are used to give SWIG hints or to alter SWIG's parsing behavior in some manner.

Since SWIG directives are not legal C syntax, it is generally not possible to include them in header files. However, SWIG directives can be included in C header files using conditional compilation like this:

/* header.h  --- Some header file */

/* SWIG directives -- only seen if SWIG is running */ 
#ifdef SWIG
%module foo
#endif
SWIG is a special preprocessing symbol defined by SWIG when it is parsing an input file.

4.1.6 Parser Limitations

Although SWIG can parse most C/C++ declarations, it does not provide a complete C/C++ parser implementation. Most of these limitations pertain to very complicated type declarations and certain advanced C++ features. Specifically, the following features are not currently supported:

  • Non-conventional type declarations. For example, SWIG does not support declarations such as the following (even though this is legal C):
    /* Non-conventional placement of storage specifier (extern) */
    const int extern Number;
    
    /* Extra declarator grouping */
    Matrix (foo);    // A global variable
    
    /* Extra declarator grouping in parameters */
    void bar(Spam (Grok)(Doh));
    
    
    In practice, few (if any) C programmers actually write code like this since this style is never featured in programming books. However, if you're feeling particularly obfuscated, you can certainly break SWIG (although why would you want to?).

  • Running SWIG on C++ source files (what would appear in a .C or .cxx file) is not recommended. Even though SWIG can parse C++ class declarations, it ignores declarations that are decoupled from their original class definition (the declarations are parsed, but a lot of warning messages may be generated). For example:
    /* Not supported by SWIG */
    int foo::bar(int) {
        ... whatever ...
    }
    
  • Certain advanced features of C++ such as nested classes are not yet supported. Please see the section on using SWIG with C++ for more information.

In the event of a parsing error, conditional compilation can be used to skip offending code. For example:

#ifndef SWIG
... some bad declarations ...
#endif
Alternatively, you can just delete the offending code from the interface file.

One of the reasons why SWIG does not provide a full C++ parser implementation is that it has been designed to work with incomplete specifications and to be very permissive in its handling of C/C++ datatypes (e.g., SWIG can generate interfaces even when there are missing class declarations or opaque datatypes). Unfortunately, this approach makes it extremely difficult to implement certain parts of a C/C++ parser as most compilers use type information to assist in the parsing of more complex declarations (for the truly curious, the primary complication in the implementation is that the SWIG parser does not utilize a separate typedef-name terminal symbol as described on p. 234 of K&R).

4.2 Wrapping Simple C Declarations

SWIG wraps simple C declarations by creating an interface that closely matches the way in which the declarations would be used in a C program. For example, consider the following interface file:

%module example

extern double sin(double x);
extern int strcmp(const char *, const char *);
extern int Foo;
#define STATUS 50
#define VERSION "1.1"
In this file, there are two functions sin() and strcmp(), a global variable Foo, and two constants STATUS and VERSION. When SWIG creates an extension module, these declarations are accessible as scripting language functions, variables, and constants respectively. For example, in Tcl:

% sin 3
5.2335956
% strcmp Dave Mike
-1
% puts $Foo
42
% puts $STATUS
50
% puts $VERSION
1.1
Or in Python:

>>> example.sin(3)
5.2335956
>>> example.strcmp('Dave','Mike')
-1
>>> print example.cvar.Foo
42
>>> print example.STATUS
50
>>> print example.VERSION
1.1
Whenever possible, SWIG creates an interface that closely matches the underlying C/C++ code. However, due to subtle differences between languages, run-time environments, and semantics, it is not always possible to do so. The next few sections describes various aspects of this mapping.

4.2.1 Basic Type Handling

In order to build an interface, SWIG has to convert C/C++ datatypes to equivalent types in the target language. Generally, scripting languages provide a more limited set of primitive types than C. Therefore, this conversion process involves a certain amount of type coercion.

Most scripting languages provide a single integer type that is implemented using the int or long datatype in C. The following list shows all of the C datatypes that SWIG will convert to and from integers in the target language:

int
short
long
unsigned
signed
unsigned short
unsigned long
unsigned char
signed char
bool

When an integral value is converted from C, a cast is used to convert it to the representation in the target language. Thus, a 16 bit short in C may be promoted to a 32 bit integer. When integers are converted in the other direction, the value is cast back into the original C type. If the value is too large to fit, it is silently truncated.

unsigned char and signed char are special cases that are handled as small 8-bit integers. Normally, the char datatype is mapped as a one-character ASCII string.

The bool datatype is cast to and from an integer value of 0 and 1 unless the target language provides a special boolean type.

Some care is required when working with large integer values. Most scripting languages use 32-bit integers so mapping a 64-bit long integer may lead to truncation errors. Similar problems may arise with 32 bit unsigned integers (which may appear as large negative numbers). As a rule of thumb, the int datatype and all variations of char and short datatypes are safe to use. For unsigned int and long datatypes, you will need to carefully check the correct operation of your program after it has been wrapped with SWIG.

Although the SWIG parser supports the long long datatype, not all language modules support it. This is because long long usually exceeds the integer precision available in the target language. In certain modules such as Tcl and Perl5, long long integers are encoded as strings. This allows the full range of these numbers to be represented. However, it does not allow long long values to be used in arithmetic expressions. It should also be noted that although long long is part of the ISO C99 standard, it is not universally supported by all C compilers. Make sure you are using a compiler that supports long long before trying to use this type with SWIG.

SWIG recognizes the following floating point types :

float
double

Floating point numbers are mapped to and from the natural representation of floats in the target language. This is almost always a C double. The rarely used datatype of long double is not supported by SWIG.

The char datatype is mapped into a NULL terminated ASCII string with a single character. When used in a scripting language it shows up as a tiny string containing the character value. When converting the value back into C, SWIG takes a character string from the scripting language and strips off the first character as the char value. Thus if the value "foo" is assigned to a char datatype, it gets the value `f'.

The char * datatype is handled as a NULL-terminated ASCII string. SWIG maps this into a 8-bit character string in the target scripting language. SWIG converts character strings in the target language to NULL terminated strings before passing them into C/C++. The default handling of these strings does not allow them to have embedded NULL bytes. Therefore, the char * datatype is not generally suitable for passing binary data. However, it is possible to change this behavior by defining a SWIG typemap. See the chapter on Typemaps for details about this.

At this time, SWIG does not provide any special support for Unicode or wide-character strings (the C wchar_t type). This is a delicate topic that is poorly understood by many programmers and not implemented in a consistent manner across languages. For those scripting languages that provide Unicode support, Unicode strings are often available in an 8-bit representation such as UTF-8 that can be mapped to the char * type (in which case the SWIG interface will probably work). If the program you are wrapping uses Unicode, there is no guarantee that Unicode characters in the target language will use the same internal representation (e.g., UCS-2 vs. UCS-4). You may need to write some special conversion functions.

4.2.2 Global Variables

Whenever possible, SWIG maps C/C++ global variables into scripting language variables. For example,

%module example
double foo;

results in a scripting language variable like this:

# Tcl
set foo [3.5]                   ;# Set foo to 3.5
puts $foo                       ;# Print the value of foo

# Python
cvar.foo = 3.5                  # Set foo to 3.5
print cvar.foo                  # Print value of foo

# Perl
$foo = 3.5;                     # Set foo to 3.5
print $foo,"\n";                # Print value of foo

# Ruby
Module.foo = 3.5               # Set foo to 3.5
print Module.foo, "\n"         # Print value of foo
Whenever the scripting language variable is used, the underlying C global variable is accessed. Although SWIG makes every attempt to make global variables work like scripting language variables, it is not always possible to do so. For instance, in Python, all global variables must be accessed through a special variable object known as cvar (shown above). In Ruby, variables are accessed as attributes of the module. Other languages may convert variables to a pair of accessor functions. For example, the Java module generates a pair of functions double get_foo() and set_foo(double val) that are used to manipulate the value.

Finally, if a global variable has been declared as const, it only supports read-only access. Note: this behavior is new to SWIG-1.3. Earlier versions of SWIG incorrectly handled const and created constants instead.

4.2.3 Constants

Constants can be created using #define, enumerations, or a special %constant directive. The following interface file shows a few valid constant declarations :

#define I_CONST       5               // An integer constant
#define PI            3.14159         // A Floating point constant
#define S_CONST       "hello world"   // A string constant
#define NEWLINE       '\n'            // Character constant

enum boolean {NO=0, YES=1};
enum months {JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG,
             SEP, OCT, NOV, DEC};
%constant double BLAH = 42.37;
#define F_CONST (double) 5            // A floating pointer constant with cast
#define PI_4 PI/4
#define FLAGS 0x04 | 0x08 | 0x40

In #define declarations, the type of a constant is inferred by syntax. For example, a number with a decimal point is assumed to be floating point. In addition, SWIG must be able to fully resolve all of the symbols used in a #define in order for a constant to actually be created. This restriction is necessary because #define is also used to define preprocessor macros that are definitely not meant to be part of the scripting language interface. For example:
#define EXTERN extern

EXTERN void foo();
In this case, you probably don't want to create a constant called EXTERN (what would the value be?). In general, SWIG will not create constants for macros unless the value can be completely determined by the preprocessor. For instance, in the above example, the declaration
#define PI_4  PI/4
defines a constant because PI was already defined as a constant and the value is known.

The use of constant expressions is allowed, but SWIG does not evaluate them. Rather, it passes them through to the output file and lets the C compiler perform the final evaluation (SWIG does perform a limited form of type-checking however).

For enumerations, it is critical that the original enum definition be included somewhere in the interface file (either in a header file or in the %{,%} block). SWIG only translates the enumeration into code needed to add the constants to a scripting language. It needs the original enumeration declaration in order to get the correct enum values as assigned by the C compiler.

The %constant directive is used to more precisely create constants corresponding to different C datatypes. Although it is not usually not needed for simple values, it is more useful when working with pointers and other more complex datatypes. Typically, %constant is only used when you want to add constants to the scripting language interface that are not defined in the original header file.

4.2.4 A brief word about const

A common confusion with C programming is the semantic meaning of the const qualifier in declarations--especially when it is mixed with pointers and other type modifiers. In fact, previous versions of SWIG handled const incorrectly--a situation that SWIG-1.3.7 and newer releases have fixed.

Starting with SWIG-1.3, all variable declarations, regardless of any use of const, are wrapped as global variables. If a declaration happens to be declared as const, it is wrapped as a read-only variable. To tell if a variable is const or not, you need to look at the right-most occurrence of the const qualifier (that appears before the variable name). If the right-most const occurs after all other type modifiers (such as pointers), then the variable is const. Otherwise, it is not.

Here are some examples of const declarations.

const char a;           // A constant character
char const b;           // A constant character (the same)
char *const c;          // A constant pointer to a character
const char *const d;    // A constant pointer to a constant character
Here is an example of a declaration that is not const:
const char *e;          // A pointer to a constant character.  The pointer
                        // may be modified.
In this case, the pointer e can change---it's only the value being pointed to that is read-only.

Compatibility Note: One reason for changing SWIG to handle const declarations as read-only variables is that there are many situations where the value of a const variable might change. For example, a library might export a symbol as const in its public API to discourage modification, but still allow the value to change through some other kind of internal mechanism. Furthermore, programmers often overlook the fact that with a constant declaration like char *const, the underlying data being pointed to can be modified--it's only the pointer itself that is constant. In an embedded system, a const declaration might refer to a read-only memory address such as the location of a memory-mapped I/O device port (where the value changes, but writing to the port is not supported by the hardware). Rather than trying to build a bunch of special cases into the const qualifier, the new interpretation of const as "read-only" is simple and exactly matches the actual semantics of const in C/C++. If you really want to create a constant as in older versions of SWIG, use the %constant directive instead. For example:

%constant double PI = 3.14159;
or
#ifdef SWIG
#define const %constant
#endif
const double foo = 3.4;
const double bar = 23.4;
const int    spam = 42;
#ifdef SWIG
#undef const
#endif
...

4.2.5 A cautionary tale of char *

Before going any further, there is one bit of caution involving char * that must now be mentioned. When strings are passed from a scripting language to a C char *, the pointer usually points to string data stored inside the interpreter. It is almost always a really bad idea to modify this data. Furthermore, some languages may explicitly disallow it. For instance, in Python, strings are supposed be immutable. If you violate this, you will probably receive a vast amount of wrath when you unleash your module on the world.

The primary source of problems are functions that might modify string data in place. A classic example would be a function like this:

char *strcat(char *s, const char *t)
Although SWIG will certainly generate a wrapper for this, its behavior will be undefined. In fact, it will probably cause your application to crash with a segmentation fault or other memory related problem. This is because s refers to some internal data in the target language---data that you shouldn't be touching.

The bottom line: don't rely on char * for anything other than read-only input values. However, it must be noted that you could change the behavior of SWIG using typemaps.

4.3 Pointers and complex objects

Most C programs manipulate arrays, structures, and other types of objects. This section discusses the handling of these datatypes.

4.3.1 Simple pointers

Pointers to primitive C datatypes such as

int *
double ***
char **

are fully supported by SWIG. Rather than trying to convert the data being pointed to into a scripting representation, SWIG simply encodes the pointer itself into a representation that contains the actual value of the pointer and a type-tag. Thus, the SWIG representation of the above pointers (in Tcl), might look like this:

_10081012_p_int
_1008e124_ppp_double
_f8ac_pp_char

A NULL pointer is represented by the string "NULL" or the value 0 encoded with type information.

All pointers are treated as opaque objects by SWIG. Thus, a pointer may be returned by a function and passed around to other C functions as needed. For all practical purposes, the scripting language interface works in exactly the same way as you would use the pointer in a C program. The only difference is that there is no mechanism for dereferencing the pointer since this would require the target language to understand the memory layout of the underlying object.

The scripting language representation of a pointer value should never be manipulated directly. Even though the values shown look like hexadecimal addresses, the numbers used may differ from the actual machine address (e.g., on little-endian machines, the digits may appear in reverse order). Furthermore, SWIG does not normally map pointers into high-level objects such as associative arrays or lists (for example, converting an int * into an list of integers). There are several reasons why SWIG does not do this:

  • There is not enough information in a C declaration to properly map pointers into higher level constructs. For example, an int * may indeed be an array of integers, but if it contains ten million elements, converting it into a list object is probably a bad idea.

  • The underlying semantics associated with a pointer is not known by SWIG. For instance, an int * might not be an array at all--perhaps it is an output value!

  • By handling all pointers in a consistent manner, the implementation of SWIG is greatly simplified and less prone to error.

4.3.2 Run time pointer type checking

By allowing pointers to be manipulated from a scripting language, extension modules effectively bypass compile-time type checking in the C/C++ compiler. To prevent errors, a type signature is encoded into all pointer values and is used to perform run-time type checking. This type-checking process is an integral part of SWIG and can not be disabled or modified without using typemaps (described in later chapters).

Like C, void * matches any kind of pointer. Furthermore, NULL pointers can be passed to any function that expects to receive a pointer. Although this has the potential to cause a crash, NULL pointers are also sometimes used as sentinel values or to denote a missing/empty value. Therefore, SWIG leaves NULL pointer checking up to the application.

4.3.3 Derived types, structs, and classes

For everything else (structs, classes, arrays, etc...) SWIG applies a very simple rule :

Everything else is a pointer

In other words, SWIG manipulates everything else by reference. This model makes sense because most C/C++ programs make heavy use of pointers and SWIG can use the type-checked pointer mechanism already present for handling pointers to basic datatypes.

Although this probably sounds complicated, it's really quite simple. Suppose you have an interface file like this :

%module fileio
FILE *fopen(char *, char *);
int fclose(FILE *);
unsigned fread(void *ptr, unsigned size, unsigned nobj, FILE *);
unsigned fwrite(void *ptr, unsigned size, unsigned nobj, FILE *);
void *malloc(int nbytes);
void free(void *);

In this file, SWIG doesn't know what a FILE is, but since it's used as a pointer, so it doesn't really matter what it is. If you wrapped this module into Python, you can use the functions just like you expect :

# Copy a file 
def filecopy(source,target):
	f1 = fopen(source,"r")
	f2 = fopen(target,"w")
	buffer = malloc(8192)
	nbytes = fread(buffer,8192,1,f1)
	while (nbytes > 0):
		fwrite(buffer,8192,1,f2)
		nbytes = fread(buffer,8192,1,f1)
	free(buffer)

In this case f1, f2, and buffer are all opaque objects containing C pointers. It doesn't matter what value they contain--our program works just fine without this knowledge.

4.3.4 Undefined datatypes

When SWIG encounters an undeclared datatype, it automatically assumes that it is a structure or class. For example, suppose the following function appeared in a SWIG input file:

void matrix_multiply(Matrix *a, Matrix *b, Matrix *c);

SWIG has no idea what a "Matrix" is. However, it is obviously a pointer to something so SWIG generates a wrapper using its generic pointer handling code.

Unlike C or C++, SWIG does not actually care whether Matrix has been previously defined in the interface file or not. This allows SWIG to generate interfaces from only partial or limited information. In some cases, you may not care what a Matrix really is as long as you can pass an opaque reference to one around in the scripting language interface.

An important detail to mention is that SWIG will gladly generate wrappers for an interface when there are unspecified type names. However, all unspecified types are internally handled as pointers to structures or classes! For example, consider the following declaration:

void foo(size_t num);
If size_t is undeclared, SWIG generates wrappers that expect to receive a type of size_t * (this mapping is described shortly). As a result, the scripting interface might behave strangely. For example:
foo(40);
TypeError: expected a _p_size_t.
The only way to fix this problem is to make sure you properly declare type names using typedef.

4.3.5 Typedef

Like C, typedef can be used to define new type names in SWIG. For example:

typedef unsigned int size_t;

typedef definitions appearing in a SWIG interface are not propagated to the generated wrapper code. Therefore, they either need to be defined in an included header file or placed in the declarations section like this:
%{
/* Include in the generated wrapper file */
typedef unsigned int size_t;
%}
/* Tell SWIG about it */
typedef unsigned int size_t;
or
%inline %{
typedef unsigned int size_t;
%}
In certain cases, you might be able to include other header files to collect type information. For example:
%module example
%import "sys/types.h"
In this case, you might run SWIG as follows:
$ swig -I/usr/include -includeall example.i
It should be noted that your mileage will vary greatly here. System headers are notoriously complicated and may rely upon a variety of non-standard C coding extensions (e.g., such as special directives to GCC). Unless you exactly specify the right include directories and preprocessor symbols, this may not work correctly (you will have to experiment).

SWIG tracks typedef declarations and uses this information for run-time type checking. For instance, if you use the above typedef and had the following function declaration:

void foo(unsigned int *ptr);
The corresponding wrapper function will accept arguments of type unsigned int * or size_t *.

4.4 Other Practicalities

So far, this chapter has presented almost everything you need to know to use SWIG for simple interfaces. However, some C programs use idioms that are somewhat more difficult to map to a scripting language interface. This section describes some of these issues.

4.4.1 Passing structures by value

Sometimes a C function takes structure parameters that are passed by value. For example, consider the following function:

double dot_product(Vector a, Vector b);

To deal with this, SWIG transforms the function to use pointers by creating a wrapper equivalent to the following:

double wrap_dot_product(Vector *a, Vector *b) {
    Vector x = *a;
    Vector y = *b;
    return dot_product(x,y);
}

In the target language, the dot_product() function now accepts pointers to Vectors instead of Vectors. For the most part, this transformation is transparent so you might not notice.

4.4.2 Return by value

C functions that return structures or classes datatypes by value are more difficult to handle. Consider the following function:

Vector cross_product(Vector v1, Vector v2);

This function wants to return Vector, but SWIG only really supports pointers. As a result, SWIG creates a wrapper like this:

Vector *wrap_cross_product(Vector *v1, Vector *v2) {
        Vector x = *v1;
        Vector y = *v2;
        Vector *result;
        result = (Vector *) malloc(sizeof(Vector));
        *(result) = cross(x,y);
        return result;
}

or if SWIG was run with the -c++ option:

Vector *wrap_cross(Vector *v1, Vector *v2) {
        Vector x = *v1;
        Vector y = *v2;
        Vector *result = new Vector(cross(x,y)); // Uses default copy constructor
        return result;
}

In both cases, SWIG allocates a new object and returns a reference to it. It is up to the user to delete the returned object when it is no longer in use. Clearly, this will leak memory if you are unaware of the implicit memory allocation and don't take steps to free the result. That said, it should be noted that some language modules can now automatically track newly created objects and reclaim memory for you. Consult the documentation for each language module for more details.

It should also be noted that the handling of pass/return by value in C++ has some special cases. For example, the above code fragments don't work correctly if Vector doesn't define a default constructor. The section on SWIG and C++ has more information about this case.

4.4.3 Linking to structure variables

When global variables or class members involving structures are encountered, SWIG handles them as pointers. For example, a global variable like this

Vector unit_i;

gets mapped to an underlying pair of set/get functions like this :

Vector *unit_i_get() {
	return &unit_i;
}
void unit_i_set(Vector *value) {
	unit_i = *value;
}

Again some caution is in order. A global variable created in this manner will show up as a pointer in the target scripting language. It would be an extremely bad idea to free or destroy such a pointer. Also, C++ classes must supply a properly defined copy constructor in order for assignment to work correctly.

4.4.4 Linking to char *

When a global variable of type char * appears, SWIG uses malloc() or new to allocate memory for the new value. Specifically, if you have a variable like this
char *foo;
SWIG generates the following code:
/* C mode */
void foo_set(char *value) {
   if (foo) free(foo);
   foo = (char *) malloc(strlen(value)+1);
   strcpy(foo,value);
}

/* C++ mode.  When -c++ option is used */
void foo_set(char *value) {
   if (foo) delete [] foo;
   foo = new char[strlen(value)+1];
   strcpy(foo,value);
}
If this is not the behavior that you want, consider making the variable read-only using the %immutable directive. Alternatively, you might write a short assist-function to set the value exactly like you want. For example:
%inline %{
  void set_foo(char *value) {
       strncpy(foo,value, 50);
   }
%}
Note: If you write an assist function like this, you will have to call it as a function from the target scripting language (it does not work like a variable). For example, in Python you will have to write:
>>> set_foo("Hello World")
A common mistake with char * variables is to link to a variable declared like this:
char *VERSION = "1.0";
In this case, the variable will be readable, but any attempt to change the value results in a segmentation or general protection fault. This is due to the fact that SWIG is trying to release the old value using free or delete when the string literal value currently assigned to the variable wasn't allocated using malloc() or new. To fix this behavior, you can either mark the variable as read-only, write a typemap (as described in Chapter 6), or write a special set function as shown. Another alternative is to declare the variable as an array:
char VERSION[64] = "1.0";
When variables of type const char * are declared, SWIG still generates functions for setting and getting the value. However, the default behavior does not release the previous contents (resulting in a possible memory leak). In fact, you may get a warning message such as this when wrapping such a variable:
example.i:20. Typemap warning. Setting const char * variable may leak memory
The reason for this behavior is that const char * variables are often used to point to string literals. For example:
const char *foo = "Hello World\n";
Therefore, it's a really bad idea to call free() on such a pointer. On the other hand, it is legal to change the pointer to point to some other value. When setting a variable of this type, SWIG allocates a new string (using malloc or new) and changes the pointer to point to the new value. However, repeated modifications of the value will result in a memory leak since the old value is not released.

4.4.5 Arrays

Arrays are fully supported by SWIG, but they are always handled as pointers instead of mapping them to a special array object or list in the target language. Thus, the following declarations :

int foobar(int a[40]);
void grok(char *argv[]);
void transpose(double a[20][20]);

are processed as if they were really declared like this:

int foobar(int *a);
void grok(char **argv);
void transpose(double (*a)[20]);
Like C, SWIG does not perform array bounds checking. It is up to the user to make sure the pointer points a suitably allocated region of memory.

Multi-dimensional arrays are transformed into a pointer to an array of one less dimension. For example:

int [10];         // Maps to int *
int [10][20];     // Maps to int (*)[20]
int [10][20][30]; // Maps to int (*)[20][30]
It is important to note that in the C type system, a multidimensional array a[][] is NOT equivalent to a single pointer *a or a double pointer such as **a. Instead, a pointer to an array is used (as shown above) where the actual value of the pointer is the starting memory location of the array. The reader is strongly advised to dust off their C book and re-read the section on arrays before using them with SWIG.

Array variables are supported, but are read-only by default. For example:

int   a[100][200];
In this case, reading the variable 'a' returns a pointer of type int (*)[200] that points to the first element of the array &a[0][0]. Trying to modify 'a' results in an error. This is because SWIG does not know how to copy data from the target language into the array. To work around this limitation, you may want to write a few simple assist functions like this:
%inline %{
void a_set(int i, int j, int val) {
   a[i][j] = val;
}
int a_get(int i, int j) {
   return a[i][j];
}
%}
To dynamically create arrays of various sizes and shapes, it may be useful to write some helper functions in your interface. For example:
// Some array helpers
%inline %{
  /* Create any sort of [size] array */
  int *int_array(int size) {
     return (int *) malloc(size*sizeof(int));
  }
  /* Create a two-dimension array [size][10] */
  int (*int_array_10(int size))[10] {
     return (int (*)[10]) malloc(size*10*sizeof(int));
  }
%}
Arrays of char are handled as a special case by SWIG. In this case, strings in the target language can be stored in the array. For example, if you have a declaration like this,
char pathname[256];
SWIG generates functions for both getting and setting the value that are equivalent to the following code:
char *pathname_get() {
   return pathname;
}
void pathname_set(char *value) {
   strncpy(pathname,value,256);
}
In the target language, the value can be set like a normal variable.

4.4.6 Creating read-only variables

A read-only variable can be created by using the %immutable directive as shown :

// File : interface.i

int 	a; 			// Can read/write
%immutable;
int	b,c,d			// Read only variables
%mutable;
double	x,y			// read/write

The %immutable directive enables read-only mode until it is explicitly disabled using the %mutable directive. As an alternative to turning read-only mode off and on like this, individual declarations can also be tagged as immutable. For example:

%immutable x;               // Make x read-only
...
double x;                   // Read-only (from earlier %immutable directive)
double y;                   // Read-write
...
Read-only variables are also created when declarations are declared as const. For example:
const int foo;               /* Read only variable */
char * const version="1.0";  /* Read only variable */

Compatibility note: Read-only access used to be controlled by a pair of directives %readonly and %readwrite. Although these directives still work, they generate a warning message. Simply change the directives to %immutable; and %mutable; to silence the warning. Don't forget the extra semicolon!

4.4.7 Renaming and ignoring declarations

Normally, the name of a C declaration is used when that declaration is wrapped into the target language. However, this may generate a conflict with a keyword or already existing function in the scripting language. To resolve a name conflict, you can use the %rename directive as shown :

// interface.i

%rename(my_print) print;
extern void print(char *);

%rename(foo) a_really_long_and_annoying_name;
extern int a_really_long_and_annoying_name;

SWIG still calls the correct C function, but in this case the function print() will really be called "my_print()" in the target language.

The placement of the %rename directive is arbitrary as long as it appears before the declarations to be renamed. A common technique is to write code for wrapping a header file like this:

// interface.i

%rename(my_print) print;
%rename(foo) a_really_long_and_annoying_name;

%include "header.h"

%rename applies a renaming operation to all future occurrences of a name. The renaming applies to functions, variables, class and structure names, member functions, and member data. For example, if you had two-dozen C++ classes, all with a member function named `print' (which is a keyword in Python), you could rename them all to `output' by specifying :

%rename(output) print; // Rename all `print' functions to `output'

SWIG does not normally perform any checks to see if the functions it wraps are already defined in the target scripting language. However, if you are careful about namespaces and your use of modules, you can usually avoid these problems.

Closely related to %rename is the %ignore directive. %ignore instructs SWIG 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
...
%include "foo.h"       // Grab a header file
...
One use of %ignore is to selectively remove certain declarations from a header file without having to add conditional compilation to the header. However, it should be stressed that this only works for simple declarations. If you need to remove a whole section of problematic code, the SWIG preprocessor should be used instead.

More powerful variants of %rename and %ignore directives can be used to help wrap C++ overloaded functions and methods. This is described in the C++ chapter.

Compatibility note: Older versions of SWIG provided a special %name directive for renaming declarations. For example:

%name(output) extern void print(char *);
This directive is still supported, but it is deprecated and should probably be avoided. The %rename directive is more powerful and better supports wrapping of raw header file information.

4.4.8 Default/optional arguments

SWIG supports default arguments in both C and C++ code. For example:

int plot(double x, double y, int color=WHITE);

In this case, SWIG generates wrapper code where the default arguments are optional in the target language. For example, this function could be used in Tcl as follows :

% plot -3.4 7.5 				# Use default value
% plot -3.4 7.5 10				# set color to 10 instead

Although the ANSI C standard does not allow default arguments, default arguments specified in a SWIG interface work with both C and C++.

Note: There is a subtle semantic issue concerning the use of default arguments and the SWIG generated wrapper code. When default arguments are used, the default values are emitted into the wrappers and the function is invoked with a full set of arguments. This behavior is not 100% compatible with all uses of default arguments in C++. Please refer to the C++ chapter for further details.

4.4.9 Pointers to functions and callbacks

Occasionally, a C library may include functions that expect to receive pointers to functions--possibly to serve as callbacks. SWIG provides full support for function pointers provided that the callback functions are defined in C and not in the target language. For example, consider a function like this:
int binary_op(int a, int b, int (*op)(int,int));

When you first wrap something like this into an extension module, you may find the function to be impossible to use. For instance, in Python:

>>> def add(x,y):
...     return x+y
...
>>> binary_op(3,4,add)
Traceback (most recent call last):
  File "", line 1, in ?
TypeError: Type error. Expected _p_f_int_int__int
>>>
The reason for this error is that SWIG doesn't know how to map a scripting language function into a C callback. However, existing C functions can be used as arguments provided you install them as constants. One way to do this is to use the %constant directive like this:
/* Function with a callback */
int binary_op(int a, int b, int (*op)(int,int));

/* Some callback functions */
%constant int add(int,int);
%constant int sub(int,int);
%constant int mul(int,int);
In this case, add, sub, and mul become function pointer constants in the target scripting language. This allows you to use them as follows:
>>> binary_op(3,4,add)
7
>>> binary_op(3,4,mul)
12
>>>
Unfortunately, by declaring the callback functions as constants, they are no longer accesible as functions. For example:
>>> add(3,4)
Traceback (most recent call last):
  File "", line 1, in ?
TypeError: object is not callable: '_ff020efc_p_f_int_int__int'
>>>
If you want to make a function available as both a callback function and a function, you can use the %callback and %nocallback directives like this:
/* Function with a callback */
int binary_op(int a, int b, int (*op)(int,int));

/* Some callback functions */
%callback("%s_cb")
int add(int,int);
int sub(int,int);
int mul(int,int);
%nocallback
The argument to %callback is a printf-style format string that specifies the naming convention for the callback constants (%s gets replaced by the function name). The callback mode remains in effect until it is explicitly disabled using %nocallback. When you do this, the interface now works as follows:
>>> binary_op(3,4,add_cb)
7
>>> binary_op(3,4,mul_cb)
12
>>> add(3,4)
7
>>> mul(3,4)
12
Notice that when the function is used as a callback, special names such as add_cb is used instead. To call the function normally, just use the original function name such as add().

SWIG provides a number of extensions to standard C printf formatting that may be useful in this context. For instance, the following variation installs the callbacks as all upper-case constants such as ADD, SUB, and MUL:

/* Some callback functions */
%callback("%(upper)s")
int add(int,int);
int sub(int,int);
int mul(int,int);
%nocallback
A format string of "%(lower)s" converts all characters to lower-case. A string of "%(title)s" capitalizes the first character and converts the rest to lower case.

And now, a final note about function pointer support. Although SWIG does not normally allow callback functions to be written in the target language, this can be accomplished with the use of typemaps and other advanced SWIG features. This is described in a later chapter.

4.5 Structures and unions

This section describes the behavior of SWIG when processing ANSI C structures and union declarations. Extensions to handle C++ are described in the next section.

If SWIG encounters the definition of a structure or union, it creates a set of accessor functions. Although SWIG does not need structure definitions to build an interface, providing definitions make it possible to access structure members. The accessor functions generated by SWIG simply take a pointer to an object and allow access to an individual member. For example, the declaration :

struct Vector {
	double x,y,z;
}

gets transformed into the following set of accessor functions :

double Vector_x_get(struct Vector *obj) {
	return obj->x;
}
double Vector_y_get(struct Vector *obj) { 
	return obj->y;
}
double Vector_z_get(struct Vector *obj) { 
	return obj->z;
}
void Vector_x_set(struct Vector *obj, double value) {
	obj->x = value;
}
void Vector_y_set(struct Vector *obj, double value) {
	obj->y = value;
}
void Vector_z_set(struct Vector *obj, double value) {
	obj->z = value;
}
In addition, SWIG creates default constructor and destructor functions if none are defined in the interface. For example:
struct Vector *new_Vector() {
    return (Vector *) calloc(1,sizeof(struct Vector));
}
void delete_Vector(struct Vector *obj) {
    free(obj);
}
Using these low-level accessor functions, an object can be minimally manipulated from the target language using code like this:
v = new_Vector()
Vector_x_set(v,2)
Vector_y_set(v,10)
Vector_z_set(v,-5)
...
delete_Vector(v)
However, most of SWIG's language modules also provide a high-level interface that is more convenient. Keep reading.

4.5.1 Typedef and structures

SWIG supports the following construct which is quite common in C programs :

typedef struct {
	double x,y,z;
} Vector;

When encountered, SWIG assumes that the name of the object is `Vector' and creates accessor functions like before. The only difference is that the use of typedef allows SWIG to drop the struct keyword on its generated code. For example:
double Vector_x_get(Vector *obj) {
	return obj->x;
}
If two different names are used like this :

typedef struct vector_struct {
	double x,y,z;
} Vector;

the name Vector is used instead of vector_struct since this is more typical C programming style. If declarations defined later in the interface use the type struct vector_struct, SWIG knows that this is the same as Vector and it generates the appropriate type-checking code.

4.5.2 Character strings and structures

Structures involving character strings require some care. SWIG assumes that all members of type char * have been dynamically allocated using malloc() and that they are NULL-terminated ASCII strings. When such a member is modified, the previously contents will be released, and the new contents allocated. For example :

%module mymodule
...
struct Foo {
	char *name;
	...
}

This results in the following accessor functions :

char *Foo_name_get(Foo *obj) {
	return Foo->name;
}

char *Foo_name_set(Foo *obj, char *c) {
	if (obj->name) free(obj->name);
	obj->name = (char *) malloc(strlen(c)+1);
	strcpy(obj->name,c);
	return obj->name;
}

If this behavior differs from what you need in your applications, the SWIG "memberin" typemap can be used to change it. See the typemaps chapter for further details.

Note: If the -c++ option is used, new and delete are used to perform memory allocation.

4.5.3 Array members

Arrays may appear as the members of structures, but they will be read-only. SWIG will write an accessor function that returns the pointer to the first element of the array, but will not write a function to change the contents of the array itself. When this situation is detected, SWIG may generate a warning message such as the following :

interface.i:116. Warning. Array member will be read-only

To eliminate the warning message, typemaps can be used, but this is discussed in a later chapter. In many cases, the warning message is harmless.

4.5.4 Structure data members

Occasionally, a structure will contain data members that are themselves structures. For example:
typedef struct Foo {
   int x;
} Foo;

typedef struct Bar {
   int y;
   Foo f;           /* struct member */
} Bar;
When a structure member is wrapped, it is always handled as a pointer. For example:
Foo *Bar_f_get(Bar *b) {
   return &b->f;
}
void Bar_f_set(Bar *b, Foo *value) {
   b->f = *value;
}
The reasons for this are somewhat subtle but have to do with the problem of modifying and accessing data inside the data member. For example, suppose you wanted to modify the value of f.x of a Bar object like this:
Bar *b;
b->f.x = 37;
Translating this assignment to function calls (as would be used inside the scripting language interface) results in the following code:
Bar *b;
Foo_x_set(Bar_f_get(b),37);
In this code, if the Bar_f_get() function were to return a Foo instead of a Foo *, then the resulting modification would be applied to a copy of f and not the data member f itself. Clearly that's not what you want!

It should be noted that this transformation to pointers only occurs if SWIG knows that a data member is a structure or class. For instance, if you had a structure like this,

struct Foo {
   WORD   w;
};
and nothing was known about WORD, then SWIG will generate more normal accessor functions like this:
WORD Foo_w_get(Foo *f) {
    return f->w;
}
void Foo_w_set(FOO *f, WORD value) {
    f->w = value;
}
Compatibility Note: SWIG-1.3.11 and earlier releases transformed all non-primitive member datatypes to pointers. Starting in SWIG-1.3.12, this transformation only occurs if a datatype is known to be a structure, class, or union. This is unlikely to break existing code. However, if you need to tell SWIG that an undeclared datatype is really a struct, simply use a forward struct declaration such as "struct Foo;".

4.5.5 C constructors and destructors

When wrapping structures, it is generally useful to have a mechanism for creating and destroying objects. If you don't do anything, SWIG will automatically generate functions for creating and destroying objects using malloc() and free(). Note: the use of malloc() only applies when SWIG is used on C code (i.e., when the -c++ option is not supplied on the command line). C++ is handled differently.

If you don't want SWIG to generate constructors and destructors, you can use the %nodefault directive or the -no_default command line option. For example:

swig -no_default example.i 

or

%module foo
...
%nodefault;        // Don't create default constructors/destructors
... declarations ...
%makedefault;      // Reenable default constructors/destructors
If you need more precise control, %nodefault can selectively target individual structure definitions. For example:
%nodefault Foo;          // No default constructor/destructors for Foo
...
struct Foo {             // No default generated.
};

struct Bar {             // Default constructor/destructor generated.
};
Compatibility note: Prior to SWIG-1.3.7, SWIG did not generate default constructors or destructors unless you explicitly turned them on using -make_default. However, it appears that most users want to have constructor and destructor functions so it has now been enabled as the default behavior.

4.5.6 Adding member functions to C structures

Most languages provide a mechanism for creating classes and supporting object oriented programming. From a C standpoint, object oriented programming really just boils down to the process of attaching functions to structures. These functions normally operate on an instance of the structure (or object). Although there is a natural mapping of C++ to such a scheme, there is no direct mechanism for utilizing it with C code. However, SWIG provides a special %extend directive that makes it possible to attach methods to C structures for purposes of building an object oriented interface. Suppose you have a C header file with the following declaration :

/* file : vector.h */
...
typedef struct {
	double x,y,z;
} Vector;

You can make a Vector look alot like a class by writing a SWIG interface like this:

// file : vector.i
%module mymodule
%{
#include "vector.h"
%}

%include vector.h            // Just grab original C header file
%extend Vector {             // Attach these functions to struct Vector
	Vector(double x, double y, double z) {
		Vector *v;
		v = (Vector *v) malloc(sizeof(Vector));
		v->x = x;
		v->y = y;
		v->z = z;
		return v;
	}
	~Vector() {
		free(self);
	}
	double magnitude() {
		return sqrt(self->x*self->x+self->y*self->y+self->z*self->z);
	}
	void print() {
		printf("Vector [%g, %g, %g]\n", self->x,self->y,self->z);
	}
};

Now, when used with shadow classes in Python, you can do things like this :

>>> v = Vector(3,4,0)                 # Create a new vector
>>> print v.magnitude()                # Print magnitude
5.0
>>> v.print()                  # Print it out
[ 3, 4, 0 ]
>>> del v                      # Destroy it

The %extend directive can also be used inside the definition of the Vector structure. For example:

// file : vector.i
%module mymodule
%{
#include "vector.h"
%}

typedef struct {
	double x,y,z;
	%extend {
		Vector(double x, double y, double z) { ... }
		~Vector() { ... }
		...
	}
} Vector;

Finally, %extend can be used to access externally written functions provided they follow the naming convention used in this example :

/* File : vector.c */
/* Vector methods */
#include "vector.h"
Vector *new_Vector(double x, double y, double z) {
	Vector *v;
	v = (Vector *) malloc(sizeof(Vector));
	v->x = x;
	v->y = y;
	v->z = z;
	return v;
}
void delete_Vector(Vector *v) {
	free(v);
}

double Vector_magnitude(Vector *v) {
	return sqrt(v->x*v->x+v->y*v->y+v->z*v->z);
}

// File : vector.i
// Interface file
%module mymodule
%{
#include "vector.h"
%}

typedef struct {
	double x,y,z;
	%extend {
                Vector(int,int,int); // This calls new_Vector()
               ~Vector();            // This calls delete_Vector()
		double magnitude();  // This will call Vector_magnitude()
		...
	}
} Vector;
A little known feature of the %extend directive is that it can also be used to add synthesized attributes or to modify the behavior of existing data attributes. For example, suppose you wanted to make magnitude a read-only attribute of Vector instead of a method. To do this, you might write some code like this:
// Add a new attribute to Vector
%extend Vector {
    const double magnitude;
}
// Now supply the implementation of the Vector_magnitude_get function
%{
const double Vector_magnitude_get(Vector *v) {
  return (const double) return sqrt(v->x*v->x+v->y*v->y+v->z*v->z);
}
%}

Now, for all practial purposes, magnitude will appear like an attribute of the object.

A similar technique can also be used to work with problematic data members. For example, consider this interface:

struct Person {
   char name[50];
   ...
}
By default, the name attribute is read-only because SWIG does not normally know how to modify arrays. However, you can rewrite the interface as follows to change this:
struct Person {
    %extend {
       char *name;
    }
...
}

// Specific implementation of set/get functions
%{
char *Person_name_get(Person *p) {
   return p->name;
}
void Person_name_set(Person *p, char *val) {
   strncpy(p->name,val,50);
}
%}
Finally, it should be stressed that even though %extend can be used to add new data members, these new members can not require the allocation of additional storage in the object (e.g., their values must be entirely synthesized from existing attributes of the structure).

Compatibility note: The %extend directive is a new name for the %addmethods directive. Since %addmethods could be used to extend a structure with more than just methods, a more suitable directive name has been chosen.

4.5.7 Nested structures

Occasionally, a C program will involve structures like this :

typedef struct Object {
	int objtype;
	union {
		int 	ivalue;
		double	dvalue;
		char	*strvalue;
		void	*ptrvalue;
	} intRep;
} Object;

When SWIG encounters this, it performs a structure splitting operation that transforms the declaration into the equivalent of the following:

typedef union {
	int 		ivalue;
	double		dvalue;
	char		*strvalue;
	void		*ptrvalue;
} Object_intRep;

typedef struct Object {
	int objType;
	Object_intRep intRep;
} Object;

SWIG will then create an Object_intRep structure for use inside the interface file. Accessor functions will be created for both structures. In this case, functions like this would be created :

Object_intRep *Object_intRep_get(Object *o) {
	return (Object_intRep *) &o->intRep;
}
int Object_intRep_ivalue_get(Object_intRep *o) {
	return o->ivalue;
}
int Object_intRep_ivalue_set(Object_intRep *o, int value) {
	return (o->ivalue = value);
}
double Object_intRep_dvalue_get(Object_intRep *o) {
	return o->dvalue;
}
... etc ...

Although this process is a little hairy, it works like you would expect in the target scripting language--especially when shadow classes are used. For instance, in Perl:

# Perl5 script for accessing nested member
$o = CreateObject();                    # Create an object somehow
$o->{intRep}->{ivalue} = 7              # Change value of o.intRep.ivalue

If you have a lot nested structure declarations, it is advisable to double-check them after running SWIG. Although, there is a good chance that they will work, you may have to modify the interface file in certain cases.

4.5.8 Other things to note about structure wrapping

SWIG doesn't care if the declaration of a structure in a .i file exactly matches that used in the underlying C code (except in the case of nested structures). For this reason, there are no problems omitting problematic members or simply omitting the structure definition altogether. If you are happy passing pointers around, this can be done without ever giving SWIG a structure definition.

Starting with SWIG1.3, a number of improvements have been made to SWIG's code generator. Specifically, even though structure access has been described in terms of high-level accessor functions such as this,

double Vector_x_get(Vector *v) {
   return v->x;
}
most of the generated code is actually inlined directly into wrapper functions. Therefore, no function Vector_x_get() actually exists in the generated wrapper file. For example, when creating a Tcl module, the following function is generated instead:
static int
_wrap_Vector_x_get(ClientData clientData, Tcl_Interp *interp, 
                   int objc, Tcl_Obj *CONST objv[]) {
    struct Vector *arg1 ;
    double result ;
    
    if (SWIG_GetArgs(interp, objc, objv,"p:Vector_x_get self ",&arg0,
                     SWIGTYPE_p_Vector) == TCL_ERROR)
         return TCL_ERROR;
    result = (double ) (arg1->x);
    Tcl_SetObjResult(interp,Tcl_NewDoubleObj((double) result));
    return TCL_OK;
}
The only exception to this rule are methods defined with %extend. In this case, the added code is contained in a separate function.

Finally, it is important to note that most language modules may choose to build a more advanced interface. Although you may never use the low-level interface described here, most of SWIG's language modules use it in some way or another.

4.6 Code Insertion

Sometimes it is necessary to insert special code into the resulting wrapper file generated by SWIG. For example, you may want to include additional C code to perform initialization or other operations. There are four common ways to insert code, but it's useful to know how the output of SWIG is structured first.

4.6.1 The output of SWIG

When SWIG creates its output file, it is broken up into four sections corresponding to runtime libraries, headers, wrapper functions, and module initialization code (in that order).
  • Runtime libraries.
    This code is internal to SWIG and is used to include type-checking and other support functions that are used by the rest of the module.

  • Header section.
    This is user-defined support code that has been included by the %{ ... %} directive. Usually this consists of header files and other helper functions.

  • Wrapper code.
    These are the wrappers generated automatically by SWIG.

  • Module initialization.
    The function generated by SWIG to initialize the module upon loading.

4.6.2 Code insertion blocks

Code is inserted into the appropriate code section by using one of the following code insertion directives:
%runtime %{
   ... code in runtime section ...
%}

%header %{
   ... code in header section ...
%}

%wrapper %{
   ... code in wrapper section ...
%}

%init %{
   ... code in init section ...
%}
The bare %{ ... %} directive is a shortcut that is the same as %header %{ ... %}.

Everything in a code insertion block is copied verbatim into the output file and is not parsed by SWIG. Most SWIG input files have at least one such block to include header files and support C code. Additional code blocks may be placed anywhere in a SWIG file as needed.

%module mymodule
%{
#include "my_header.h"
%}
... Declare functions here
%{

void some_extra_function() {
  ...
}
%}

A common use for code blocks is to write "helper" functions. These are functions that are used specifically for the purpose of building an interface, but which are generally not visible to the normal C program. For example :

%{
/* Create a new vector */
static Vector *new_Vector() {
	return (Vector *) malloc(sizeof(Vector));
}

%}
// Now wrap it 
Vector *new_Vector();

4.6.3 Inlined code blocks

Since the process of writing helper functions is fairly common, there is a special inlined form of code block that is used as follows :

%inline %{
/* Create a new vector */
Vector *new_Vector() {
	return (Vector *) malloc(sizeof(Vector));
}
%}

The %inline directive inserts all of the code that follows verbatim into the header portion of an interface file. The code is then parsed by both the SWIG preprocessor and parser. Thus, the above example creates a new command new_Vector using only one declaration. Since the code inside an %inline %{ ... %} block is given to both the C compiler and SWIG, it is illegal to include any SWIG directives inside a %{ ... %} block.

4.6.4 Initialization blocks

When code is included in the %init section, it is copied directly into the module initialization function. For example, if you needed to perform some extra initialization on module loading, you could write this:

%init %{
	init_variables();
%}

4.7 An Interface Building Strategy

This section describes the general approach for building interface with SWIG. The specifics related to a particular scripting language are found in later chapters.

4.7.1 Preparing a C program for SWIG

SWIG doesn't require modifications to your C code, but if you feed it a collection of raw C header files or source code, the results might not be what you expect---in fact, they might be awful. Here's a series of steps you can follow to make an interface for a C program :

  • Identify the functions that you want to wrap. It's probably not necessary to access every single function in a C program--thus, a little forethought can dramatically simplify the resulting scripting language interface. C header files are particularly good source for finding things to wrap.
  • Create a new interface file to describe the scripting language interface to your program.
  • Copy the appropriate declarations into the interface file or use SWIG's %include directive to process an entire C source/header file.
  • Make sure everything in the interface file uses ANSI C/C++syntax.
  • Make sure all necessary `typedef' declarations and type-information is available in the interface file.
  • If your program has a main() function, you may need to rename it (read on).
  • Run SWIG and compile.

Although this may sound complicated, the process turns out to be fairly easy once you get the hang of it.

In the process of building an interface, SWIG may encounter syntax errors or other problems. The best way to deal with this is to simply copy the offending code into a separate interface file and edit it. However, the SWIG developers have worked very hard to improve the SWIG parser--you should report parsing errors to swig-dev@cs.uchicago.edu or to the SWIG bug tracker on www.swig.org.

4.7.2 The SWIG interface file

The preferred method of using SWIG is to generate separate interface file. Suppose you have the following C header file :

/* File : header.h */

#include <stdio.h>
#include <math.h>

extern int foo(double);
extern double bar(int, int);
extern void dump(FILE *f);

A typical SWIG interface file for this header file would look like the following :

/* File : interface.i */
%module mymodule
%{
#include "header.h"
%}
extern int foo(double);
extern double bar(int, int);
extern void dump(FILE *f);

Of course, in this case, our header file is pretty simple so we could have made an interface file like this as well:

/* File : interface.i */
%module mymodule
%include header.h

Naturally, your mileage may vary.

4.7.3 Why use separate interface files?

Although SWIG can parse many header files, it is more common to write a special .i file defining the interface to a package. There are several reasons why you might want to do this:

  • It is rarely necessary to access every single function in a large package. Many C functions might have little or no use in a scripted environment. Therfore, why wrap them?
  • Separate interface files provide an opportunity to provide more precise rules about how an interface is to be constructed.
  • Interface files can provide more structure and organization.
  • SWIG can't parse certain definitions that appear in header files. Having a separate file allows you to eliminate or work around these problems.
  • Interface files provide a more precise definition of what the interface is. Users wanting to extend the system can go to the interface file and immediately see what is available without having to dig it out of header files.

4.7.4 Getting the right header files

Sometimes, it is necessary to use certain header files in order for the code generated by SWIG to compile properly. Make sure you include certain header files by using a %{,%} block like this:
%module graphics
%{
#include <GL/gl.h>
#include <GL/glu.h>
%}

// Put rest of declarations here
...

4.7.5 What to do with main()

If your program defines a main() function, you may need to get rid of it or rename it in order to use a scripting language. Most scripting languages define their own main() procedure that is called instead. main() also makes no sense when working with dynamic loading. There are a few approaches to solving the main() conflict :

  • Get rid of main() entirely.
  • Rename main() to something else. You can do this by compiling your C program with an option like -Dmain=oldmain.
  • Use conditional compilation to only include main() when not using a scripting language.

Getting rid of main() may cause potential initialization problems of a program. To handle this problem, you may consider writing a special function called program_init() that initializes your program upon startup. This function could then be called either from the scripting language as the first operation, or when the SWIG generated module is loaded.

As a general note, many C programs only use the main() function to parse command line options and to set parameters. However, by using a scripting language, you are probably trying to create a program that is more interactive. In many cases, the old main() program can be completely replaced by a Perl, Python, or Tcl script.

Note: If some cases, you might be inclined to create a scripting language wrapper for main(). If you do this, the compilation will probably work and your module might even load correctly. The only trouble is that when you call your main() wrapper, you will find that it actually invokes the main() of the scripting language interpreter itself! This behavior is a side effect of the symbol binding mechanism used in the dynamic linker. The bottom line: don't do this.


SWIG 1.3 - Last Modified : August 7, 2003
cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/Documentation.html0000644000175000000620000000056312561312226023222 0ustar stevestaff Documentation System

5 Documentation System

The documentation system is under repair and disabled in SWIG1.3. It will return in a later release.


SWIG 1.3 - Last Modified : August 18, 2001
cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/SWIGPlus.html0000644000175000000620000032126712561312226022035 0ustar stevestaff SWIG and C++

5 SWIG and C++

This chapter describes SWIG's support for wrapping C++. As a prerequisite, you should first read the chapter SWIG Basics to see how SWIG wraps ANSI C. Support for C++ builds upon ANSI C wrapping and that material will be useful in understanding this chapter.

5.1 Comments on C++ Wrapping

Because of its complexity and the fact that C++ can be difficult to integrate with itself let alone other languages, SWIG only provides support for a subset of C++ features. Fortunately, this is now a rather large subset.

In part, the problem with C++ wrapping is that there is no semantically obvious (or automatic ) way to map many of its advanced features into other languages. As a simple example, consider the problem of wrapping C++ multiple inheritance to a target language with no such support. Similarly, the use of overloaded operators and overloaded functions can be problematic when no such capability exists in a target language.

A more subtle issue with C++ has to do with the way that some C++ programmers think about programming libraries. In the world of SWIG, you are really trying to create binary-level software components for use in other languages. In order for this to work, a "component" has to contain real executable instructions and there has to be some kind of binary linking mechanism for accessing its functionality. In contrast, C++ has increasingly relied upon generic programming and templates for much of its functionality. Although templates are a powerful feature, they are largely orthogonal to the whole notion of binary components and libraries. For example, an STL vector does not define any kind of binary object for which SWIG can just create a wrapper. To further complicate matters, these libraries often utilize a lot of behind the scenes magic in which the semantics of seemingly basic operations (e.g., pointer dereferencing, procedure call, etc.) can be changed in dramatic and sometimes non-obvious ways. Although this "magic" may present few problems in a C++-only universe, it greatly complicates the problem of crossing language boundaries and provides many opportunities to shoot yourself in the foot. You will just have to be careful.

5.2 Approach

To wrap C++, SWIG uses a layered approach to code generation. At the lowest level, SWIG generates a collection of procedural ANSI-C style wrappers. These wrappers take care of basic type conversion, type checking, error handling, and other low-level details of the C++ binding. These wrappers are also sufficient to bind C++ into any target language that supports built-in procedures. In some sense, you might view this layer of wrapping as providing a C library interface to C++. Optionally, SWIG can also generate proxy classes that provide a natural OO interface to the underlying code. These proxies are built on top of the low-level procedural wrappers and are typically written in the target language itself. For instance, in Python, a real Python class is used to provide a wrapper around the underlying C++ object.

It is important to emphasize that SWIG takes a deliberately conservative and non-intrusive approach to C++ wrapping. SWIG does not encapsulate C++ classes inside special C++ adaptor or proxy classes, it does not rely upon templates, nor does it use C++ inheritance when generating wrappers. The last thing that most C++ programs need is even more compiler magic. Therefore, SWIG tries to maintain a very strict and clean separation between the implementation of your C++ application and the resulting wrapper code. You might say that SWIG has been written to follow the principle of least surprise--it does not play sneaky tricks with the C++ type system, it doesn't mess with your class hierarchies, and it doesn't introduce new semantics. Although this approach might not provide the most seamless integration with C++, it is safe, simple, portable, and debuggable.

Most of this chapter focuses on the low-level procedural interface to C++ that is used as the foundation for all language modules. Keep in mind that most target languages also provide a high-level OO interface via proxy classes. A few general details about proxies can be found at the end of this chapter. However, more detailed coverage can be found in the documentation for each target language.

5.3 Supported C++ features

SWIG's currently supports the following C++ features :

  • Classes.
  • Constructors and destructors
  • Virtual functions
  • Public inheritance (including multiple inheritance)
  • Static functions
  • Function and method overloading.
  • Operator overloading for many standard operators
  • References
  • Templates (including specialization and member templates).
  • Pointers to members
  • Namespaces

The following C++ features are not currently supported :

  • Nested classes
  • Overloaded versions of certain operators (new, delete, etc.)

SWIG's C++ support is an ongoing project so some of these limitations may be lifted in future releases. However, we make no promises. Also, submitting a bug report is a very good way to get problems fixed (wink).

5.4 Command line options and compilation

When wrapping C++ code, it is critical that SWIG be called with the `-c++' option. This changes the way a number of critical features such as memory management are handled. It also enables the recognition of C++ keywords. Without the -c++ flag, SWIG will either issue a warning or a large number of syntax errors if it encounters C++ code in an interface file.

When compiling and linking the resulting wrapper file, it is normal to use the C++ compiler. For example:

$ swig -c++ -tcl example.i
$ c++ -c example_wrap.cxx 
$ c++ example_wrap.o $(OBJS) -o example.so
Unfortunately, the process varies slightly on each machine. Make sure you refer to the documentation on each target language for further details. The SWIG Wiki also has further details.

5.5 Simple C++ wrapping

The following code shows a SWIG interface file for a simple C++ class.

%module list
%{
#include "list.h"
%}

// Very simple C++ example for linked list

class List {
public:
  List();
  ~List();
  int  search(char *value);
  void insert(char *);
  void remove(char *);
  char *get(int n);
  int  length;
static void print(List *l);
};
To generate wrappers for this class, SWIG first reduces the class to a collection of low-level C-style accessor functions. The next few sections describe this process. Later parts of the chapter decribe a higher level interface based on proxy classes.

5.5.1 Constructors and destructors

C++ constructors and destructors are translated into accessor functions such as the following :

List * new_List(void) {
	return new List;
}
void delete_List(List *l) {
	delete l;
}

5.5.2 Default constructors

If a C++ class does not define any public constructors or destructors, SWIG will automatically create a default constructor or destructor. However, there are a few rules that define this behavior:
  • A default constructor is not created if a class already defines a constructor with arguments.

  • Default constructors are not generated for classes with pure virtual methods or for classes that inherit from an abstract class, but don't provide definitions for all of the pure methods.

  • A default constructor is not created unless all bases classes support a default constructor.

  • Default constructors and destructors are not created if a class defines constructors or destructors in a private or protected section.

  • Default constructors and destructors are not created if any base class defines a private default constructor or a private destructor.
SWIG should never generate a constructor or destructor for a class in which it is illegal to do so. However, if it is necessary to disable the default constructor/destructor creation, the %nodefault directive can be used:
%nodefault;   // Disable creation of constructor/destructor
class Foo {
...
};
%makedefault;
%nodefault can also take a class name. For example:
%nodefault Foo;     // Disable for class Foo only.
Compatibility Note: The generation of default constructors/destructors was made the default behavior in SWIG 1.3.7. This may break certain older modules, but the old behavior can be easily restored using %nodefault or the -nodefault command line option. Furthermore, in order for SWIG to properly generate (or not generate) default constructors, it must be able to gather information from both the private and protected sections (specifically, it needs to know if a private or protected constructor/destructor is defined). In older versions of SWIG, it was fairly common to simply remove or comment out the private and protected sections of a class due to parser limitations. However, this removal may now cause SWIG to erroneously generate constructors for classes that define a constructor in those sections. Consider restoring those sections in the interface or using %nodefault to fix the problem.

5.5.3 When constructor wrappers aren't created

If a class defines a constructor, SWIG normally tries to generate a wrapper for it. However, SWIG will not generate a constructor wrapper if it thinks that it will result in illegal wrapper code. There are really two cases where this might show up.

First, SWIG won't generate wrappers for protected or private constructors. For example:

class Foo {
protected:
     Foo();         // Not wrapped.
public:
      ...
};

Next, SWIG won't generate wrappers for a class if it appears to be abstract--that is, it has undefined pure virtual methods. Here are some examples:

class Bar {
public:
     Bar();               // Not wrappped.  Bar is abstract.
     virtual void spam(void) = 0; 
};

class Grok : public Bar {
public:
      Grok();            // Not wrapped. No implementation of abstract spam().
};
Some users are surprised (or confused) to find missing constructor wrappers in their interfaces. In almost all cases, this is caused when classes are determined to be abstract. To see if this is the case, run SWIG with all of its warnings turned on:
% swig -Wall -python module.i
In this mode, SWIG will issue a warning for all abstract classes. It is possible to force a class to be non-abstract using this:
%feature("notabstract") Foo;

class Foo : public Bar {
public:
     Foo();    // Generated no matter what---not abstract. 
     ...
};
More information about %feature can be found in the Customization features chapter.

5.5.4 Copy constructors

If a class defines more than one constructor, its behavior depends on the capabilities of the target language. If overloading is supported, the copy constructor is accessible using the normal constructor function. For example, if you have this:
class List {
public:
    List();    
    List(const List &);      // Copy constructor
    ...
};
then the copy constructor can be used as follows:
x = new_List()               # Create a list
y = new_List(x)              # Copy list x
If the target language does not support overloading, then the copy constructor is available through a special function like this:
List *copy_List(List *f) {
    return new List(*f);
}

Note: For a class X, SWIG only treats a constructor as a copy constructor if it can be applied to an object of type X or X *. If more than one copy constructor is defined, only the first definition that appears is used as the copy constructor--other definitions will result in a name-clash. Constructors such as X(const X &), X(X &), and X(X *) are handled as copy constructors in SWIG.

Note: SWIG does not generate a copy constructor wrapper unless one is explicitly declared in the class. This differs from the treatment of default constructors and destructors.

Compatibility note: Special support for copy constructors was not added until SWIG-1.3.12. In previous versions, copy constructors could be wrapped, but they had to be renamed. For example:

class Foo {
public:
    Foo();
  %name(CopyFoo) Foo(const Foo &);
    ...
};
For backwards compatibility, SWIG does not perform any special copy-constructor handling if the constructor has been manually renamed. For instance, in the above example, the name of the constructor is set to new_CopyFoo(). This is the same as in older versions.

5.5.5 Member functions

All member functions are roughly translated into accessor functions like this :

int List_search(List *obj, char *value) {
	return obj->search(value);
}

This translation is the same even if the member function has been declared as virtual.

It should be noted that SWIG does not actually create a C accessor function in the code it generates. Instead, member access such as obj->search(value) is directly inlined into the generated wrapper functions. However, the name and calling convention of the wrappers match the accessor function prototype described above.

5.5.6 Static members

Static member functions are called directly without making any special transformations. For example, the static member function print(List *l) directly invokes List::print(List *l) in the generated wrapper code.

Usually, static members are accessed as functions with names in which the class name has been prepended with an underscore. For example, List_print.

5.5.7 Member functions and default arguments

SWIG allows member functions to accept default arguments. For example:
class Foo {
public:
    void bar(int x, int y = 3);
};
However, the implementation restricts the use of default arguments to values that are public. The following example illustrates a very subtle semantic incompatibility between SWIG and C++:
class Foo {
private:
   int  spam;
public:
   void bar(int x, int y = spam);   // Illegal in SWIG. Private default value
};
When this occurs, you will get a couple of warning messages like this:
example.i:15. Warning 'spam' is private in this context.
example.i:15. Warning. Can't set default argument (ignored)
This incompatibility arises because default values in C++ are evaluated in the same scope as the member function whereas SWIG evaluates them in the scope of a wrapper function (meaning that the values have to be public). The full set of arguments are needed in the wrappers in order to support a number of advanced customization features and the use of default arguments in ANSI C (which is not part of the ANSI standard).

There are several somewhat clumsy ways to work around this problem (which are not discussed here). However, a simpler solution may be to reconsider your design--is it really that critical to make the default argument private?

5.5.8 Member data

Member data is handled in exactly the same manner as for C structures. A pair of accessor functions are created. For example :

int List_length_get(List *obj) {
	return obj->length;
}
int List_length_set(List *obj, int value) {
	obj->length = value;
	return value;
}

A read-only member can be created using the %immutable and %mutable directives. For example, we probably wouldn't want the user to change the length of a list so we could do the following to make the value available, but read-only.

class List {
public:
...
%immutable;
	int length;
%mutable;
...
};
Alternatively, you can specify an immutable member in advance like this:
%immutable List::length;
...
class List {
   ...
   int length;         // Immutable by above directive
   ...
};
Similarly, all data attributes declared as const are wrapped as read-only members.

There are some subtle issues when wrapping data members that are themselves classes. For instance, if you had another class like this,

class Foo {
public:
    List items;
    ...
then access to the items member actually uses pointers. For example:
List *Foo_items_get(Foo *self) {
    return &self->items;
}
void Foo_items_set(Foo *self, List *value) {
    self->items = *value;
}
More information about this can be found in the "Structure data members" section of the SWIG Basics chapter.

Compatibility note: Read-only access used to be controlled by a pair of directives %readonly and %readwrite. Although these directives still work, they generate a warning message. Simply change the directives to %immutable; and %mutable; to silence the warning. Don't forget the extra semicolon!

Compatibility note: Prior to SWIG-1.3.12, all members of unknown type were wrapped into accessor functions using pointers. For example, if you had a structure like this

struct Foo {
   size_t  len;
};
and nothing was known about size_t, then accessors would be written to work with size_t *. Starting in SWIG-1.3.12, this behavior has been modified. Specifically, pointers will only be used if SWIG knows that a datatype corresponds to a structure or class. Therefore, the above code would be wrapped into accessors involving size_t. This change is subtle, but it smooths over a few problems related to structure wrapping and some of SWIG's customization features.

5.6 Protection

SWIG can only wrap class members that are declared public. Anything specified in a private or protected section will simply be ignored (although the internal code generator sometimes looks at the contents of the private and protected sections so that it can properly generate code for default constructors and destructors).

By default, members of a class definition are assumed to be private until you explicitly give a `public:' declaration (This is the same convention used by C++).

A subtle access problem relates to default values of member functions. Specifically, default values must be public. Please go back to the section on default arguments for further details.

5.7 Enums and constants

Enumerations and constants placed in a class definition are mapped into constants with the classname as a prefix. For example :

class Swig {
public:
	enum {ALE, LAGER, PORTER, STOUT};
};

Generates the following set of constants in the target scripting language :

Swig_ALE = Swig::ALE
Swig_LAGER = Swig::LAGER
Swig_PORTER = Swig::PORTER
Swig_STOUT = Swig::STOUT

Members declared as const are wrapped as read-only members and do not create constants.

5.8 Friends

Friend declarations are ignored by SWIG. For example, if you have this code:
class Foo {
public:
     ...
     friend void blah(Foo *f);
     ...
};
then the friend declaration does not result in any wrapper code. On the other hand, a declaration of the function itself will work fine. For instance:
class Foo {
public:
    ...
    friend void blah(Foo *f);       // Ignored
    ...
};

void blah(Foo *f);       // Generates wrappers
Unlike normal member functions or static member functions, a friend declaration does not define a method that operates on an instance of an object nor does it define a declaration in the scope of the class. Therefore, it would make no sense for SWIG to create wrappers as such.

5.9 References and pointers

C++ references are supported, but SWIG transforms them back into pointers. For example, a declaration like this :

class Foo {
public:
	double bar(double &a);
}

is accessed using a function similar to this:

double Foo_bar(Foo *obj, double *a) {
	obj->bar(*a);
}
As a special case, most language modules pass const references to primitive datatypes (int, short, float, etc.) by value instead of pointers. For example, if you have a function like this,
void foo(const int &x);
it is called from a script as follows:
foo(3)              # Notice pass by value
Functions that return a reference are remapped to return a pointer instead. For example:
class Bar {
public:
     Foo &spam();
};
Generates code like this:
Foo *Bar_spam(Bar *obj) {
   Foo &result = obj->spam();
   return &result;
}
However, functions that return const references to primitive datatypes (int, short, etc.) normally return the result as a value rather than a pointer. For example, a function like this,
const int &bar();
will return integers such as 37 or 42 in the target scripting language rather than a pointer to an integer.

Don't return references to objects allocated as local variables on the stack. SWIG doesn't make a copy of the objects so this will probably cause your program to crash.

Note: The special treatment for references to primitive datatypes is necessary to provide more seamless integration with more advanced C++ wrapping applications---especially related to templates and the STL. This was first added in SWIG-1.3.12.

5.10 Pass and return by value

Occasionally, a C++ program will pass and return class objects by value. For example, a function like this might appear:
Vector cross_product(Vector a, Vector b);
If no information is supplied about Vector, SWIG creates a wrapper function similar to the following:
Vector *wrap_cross_product(Vector *a, Vector *b) {
   Vector x = *a;
   Vector y = *b;
   Vector r = cross_product(x,y);
   return new Vector(r);
}
In order for the wrapper code to compile, Vector must define a copy constructor and a default constructor.

If Vector is defined as class in the interface, but it does not support a default constructor, SWIG changes the wrapper code by encapsulating the arguments inside a special C++ template wrapper class. This produces a wrapper that looks like this:

Vector cross_product(Vector *a, Vector *b) {
   SwigValueWrapper<Vector> x = *a;
   SwigValueWrapper<Vector> y = *b;
   SwigValueWrapper<Vector> r = cross_product(x,y);
   return new Vector(r);
}
This transformation is a little sneaky, but it provides support for pass-by-value even when a class does not provide a default constructor and it makes it possible to properly support a number of SWIG's customization options. The definition of SwigValueWrapper can be found by reading the SWIG wrapper code. This class is really nothing more than a thin wrapper around a pointer.

Note: this transformation has no effect on typemaps or any other part of SWIG---it should be transparent except that you may see this code when reading the SWIG output file.

Note: This template transformation is new in SWIG-1.3.11 and may be refined in future SWIG releases. In practice, it is only necessary to do this for classes that don't define a default constructor.

Note: The use of this template only occurs when objects are passed or returned by value. It is not used for C++ pointers or references.

Note: The performance of pass-by-value is especially bad for large objects and should be avoided if possible (consider using references instead).

5.11 Inheritance

SWIG supports C++ public inheritance of classes and allows both single and multiple inheritance. The SWIG type-checker knows about the relationship between base and derived classes and allows pointers to any object of a derived class to be used in functions of a base class. The type-checker properly casts pointer values and is safe to use with multiple inheritance.

SWIG does not support private or protected inheritance (it is parsed, but it has no effect on the generated code). Note: private and protected inheritance do not define an "isa" relationship between classes so it would have no effect on type-checking anyways.

The following example shows how SWIG handles inheritance. For clarity, the full C++ code has been omitted.

// shapes.i
%module shapes
%{
#include "shapes.h"
%}

class Shape {
public:
        double x,y;
	virtual double area() = 0;
	virtual double perimeter() = 0;
	void    set_location(double x, double y);
};
class Circle : public Shape {
public:
	Circle(double radius);
	~Circle();
	double area();
	double perimeter();
};
class Square : public Shape {
public:
	Square(double size);
	~Square();
	double area();
	double perimeter();
}

When wrapped into Python, we can now perform the following operations :

$ python
>>> import shapes
>>> circle = shapes.new_Circle(7)
>>> square = shapes.new_Square(10)
>>> print shapes.Circle_area(circle)
153.93804004599999757
>>> print shapes.Shape_area(circle)
153.93804004599999757
>>> print shapes.Shape_area(square)
100.00000000000000000
>>> shapes.Shape_set_location(square,2,-3)
>>> print shapes.Shape_perimeter(square)
40.00000000000000000
>>>
In this example, Circle and Square objects have been created. Member functions can be invoked on each object by making calls to Circle_area, Square_area, and so on. However, the same results can be accomplished by simply using the Shape_area function on either object.

One important point concerning inheritance is that the low-level accessor functions are only generated for classes in which they are actually declared. For instance, in the above example, the method set_location() is only accessible as Shape_set_location() and not as Circle_set_location() or Square_set_location(). Of course, the Shape_set_location() function will accept any kind of object derived from Shape. Similarly, accessor functions for the attributes x and y are generated as Shape_x_get(), Shape_x_set(), Shape_y_get(), and Shape_y_set(). Functions such as Circle_x_get() are not available--instead you should use Shape_x_get().

Although the low-level C-like interface is functional, most language modules also produce a higher level OO interface using proxy classes. This approach is described later and can be used to provide a more natural C++ interface.

Note: For the best results, SWIG requires all base classes to be defined in an interface. Otherwise, you may get an warning message like this:

example:18. Nothing known about class 'Foo'. Ignored.
If any base class is undefined, SWIG still generates correct type relationships. For instance, a function accepting a Foo * will accept any object derived from Foo regardless of whether or not SWIG actually wrapped the Foo class. If you really don't want to generate wrappers for the base class, but you want to silence the warning, you might consider using the %import directive to include the file that defines Foo. %import simply gathers type information, but doesn't generate wrappers. Alternatively, you could just define Foo as an empty class in the SWIG interface.

Note: typedef-names can be used as base classes. For example:

class Foo {
...
};

typedef Foo FooObj;
class Bar : public FooObj {     // Ok.  Base class is Foo
...
};
Similarly, typedef allows unnamed structures to be used as base classes. For example:
typedef struct {
   ...
} Foo;

class Bar : public Foo {    // Ok. 
...
};

Compatibility Note: Starting in version 1.3.7, SWIG only generates low-level accessor wrappers for the declarations that are actually defined in each class. This differs from SWIG1.1 which used to inherit all of the declarations defined in base classes and regenerate specialized accessor functions such as Circle_x_get(), Square_x_get(), Circle_set_location(), and Square_set_location(). This behavior resulted in huge amounts of replicated code for large class hierarchies and made it awkward to build applications spread across multiple modules (since accessor functions are duplicated in every single module). It is also unnecessary to have such wrappers when advanced features like proxy classes are used. Future versions of SWIG may apply further optimizations such as not regenerating wrapper functions for virtual members that are already defined in a base class.

5.12 A brief discussion of multiple inheritance, pointers, and type checking

When a target scripting language refers to a C++ object, it normally uses a tagged pointer object that contains both the value of the pointer and a type string. For example, in Tcl, a C++ pointer might be encoded as a string like this:
_808fea88_p_Circle
A somewhat common question is whether or not the type-tag could be safely removed from the pointer. For instance, to get better performance, could you strip all type tags and just use simple integers instead?

In general, the answer to this question is no. In the wrappers, all pointers are converted into a common data representation in the target language. Typically this is the equivalent of casting a pointer to void *. This means that any C++ type information associated with the pointer is lost in the conversion.

The problem with losing type information is that it is needed to properly support many advanced C++ features--especially multiple inheritance. For example, suppose you had code like this:

class A {
public:
   int x;
};

class B {
public:
   int y;
};

class C : public A, public B {
};

int A_function(A *a) {
   return a->x;
}

int B_function(B *b) {
   return b->y;
}
Now, consider the following code that uses void *.
C *c = new C();
void *p = (void *) c;
...
int x = A_function((A *) p);
int y = B_function((B *) p);
In this code, both A_function() and B_function() may legally accept an object of type C * (via inheritance). However, one of the functions will always return the wrong result when used as shown. The reason for this is that even though p points to an object of type C, the casting operation doesn't work like you would expect. Internally, this has to do with the data representation of C. With multiple inheritance, the data from each base class is stacked together. For example:
             ------------    <--- (C *),  (A *)
            |     A      |
            |------------|   <--- (B *)
            |     B      |
             ------------   
Because of this stacking, a pointer of type C * may change value when it is converted to a A * or B *. However, this adjustment does not occur if you are converting from a void *.

The use of type tags marks all pointers with the real type of the underlying object. This extra information is then used by SWIG generated wrappers to correctly cast pointer values under inheritance (avoiding the above problem).

One might be inclined to fix this problem using some variation of dynamic_cast<>. The only problem is that it doesn't work with void pointers, it requires RTTI support, and it only works with polymorphic classes (i.e., classes that define one or more virtual functions).

The bottom line: learn to live with type-tagged pointers.

5.13 Renaming

C++ member functions and data can be renamed with the %name directive. The %name directive only replaces the member function name. For example :

class List {
public:
  List();
%name(ListSize) List(int maxsize);
  ~List();
  int  search(char *value); 
%name(find)    void insert(char *); 
%name(delete)  void remove(char *); 
  char *get(int n);
  int  length;
static void print(List *l);
};

This will create the functions List_find, List_delete, and a function named new_ListSize for the overloaded constructor.

The %name directive can be applied to all members including constructors, destructors, static functions, data members, and enumeration values.

The class name prefix can also be changed by specifying

%name(newname) class List {
...
}
Although the %name() directive can be used to help deal with overloaded methods, it really doesn't work very well because it requires a lot of additional markup in your interface. Keep reading for a better solution.

5.14 Wrapping Overloaded Functions and Methods

In many language modules, SWIG provides partial support for overloaded functions, methods, and constructors. For example, if you supply SWIG with overloaded functions like this:
void foo(int x) {
   printf("x is %d\n", x);
}
void foo(char *x) {
   printf("x is '%s'\n", x);
}
The function is used in a completely natural way. For example:
>>> foo(3)
x is 3
>>> foo("hello")
x is 'hello'
>>>
Overloading works in a similar manner for methods and constructors. For example if you have this code,
class Foo {
public:
     Foo();
     Foo(const Foo &);   // Copy constructor
     void bar(int x);
     void bar(char *s, int y);
};
it might be used like this
>>> f = Foo()          # Create a Foo
>>> f.bar(3)
>>> g = Foo(f)         # Copy Foo
>>> f.bar("hello",2)

5.14.1 Dispatch function generation

The implementation of overloaded functions and methods is somewhat complicated due to the dynamic nature of scripting languages. Unlike C++, which binds overloaded methods at compile time, SWIG must determine the proper function as a runtime check for scripting language targets. This check is further complicated by the typeless nature of certain scripting languages. For instance, in Tcl, all types are simply strings. Therefore, if you have two overloaded functions like this,
void foo(char *x);
void foo(int x);
the order in which the arguments are checked plays a rather critical role.

For statically typed languages, SWIG uses the language's method overloading mechanism. To implement overloading for the scripting languages, SWIG generates a dispatch function that checks the number of passed arguments and their types. To create this function, SWIG first examines all of the overloaded methods and ranks them according to the following rules:

  1. Number of required arguments. Methods are sorted by increasing number of required arguments.

  2. Argument type precedence. All C++ datatypes are assigned a numeric type precedence value (which is determined by the language module).
    Type              Precedence
    ----------------  ----------
    TYPE *            0     (High)
    void *            20
    Integers          40
    Floating point    60
    char              80
    Strings           100   (Low)
    
    Using these precedence values, overloaded methods with the same number of required arguments are sorted in increased order of precedence values.

This may sound very confusing, but an example will help. Consider the following collection of overloaded methods:

void foo(double);
void foo(int);
void foo(Bar *);
void foo();
void foo(int x, int y, int z, int w);
void foo(int x, int y, int z = 3);
void foo(double x, double y);
void foo(double x, Bar *z);
The first rule simply ranks the functions by required argument count. This would produce the following list:
rank
-----
[0]   foo()
[1]   foo(double);
[2]   foo(int);
[3]   foo(Bar *);
[4]   foo(int x, int y, int z = 3);
[5]   foo(double x, double y)
[6]   foo(double x, Bar *z)
[7]   foo(int x, int y, int z, int w);
The second rule, simply refines the ranking by looking at argument type precedence values.
rank
-----
[0]   foo()
[1]   foo(Bar *);
[2]   foo(int);
[3]   foo(double);
[4]   foo(int x, int y, int z = 3);
[5]   foo(double x, Bar *z)
[6]   foo(double x, double y)
[7]   foo(int x, int y, int z, int w);
Finally, to generate the dispatch function, the arguments passed to an overloaded method are simply checked in the same order as they appear in this ranking.

If you're still confused, don't worry about it---SWIG is probably doing the right thing.

5.14.2 Ambiguity in Overloading

Regrettably, SWIG is not able to support every possible use of valid C++ overloading. Consider the following example:
void foo(int x);
void foo(long x);
In C++, this is perfectly legal. However, in a scripting language, there is generally only one kind of integer object. Therefore, which one of these functions do you pick? Clearly, there is no way to truly make a distinction just by looking at the value of the integer itself (int and long may even be the same precision). Therefore, when SWIG encounters this situation, it may generate a warning message like this for scripting languages:
example.i:4: Warning(509): Overloaded foo(long) is shadowed by foo(int) at example.i:3.
or for statically typed languages like Java:
example.i:4: Warning(516): Overloaded method foo(long) ignored. Method foo(int) at example.i:3 used.
This means that the second overloaded function will be inaccessible from a scripting interface or the method won't be wrapped at all. This is done as SWIG does not know how to disambiguate it from an earlier method.

Ambiguity problems are known to arise in the following situations:

  • Integer conversions. Datatypes such as int, long, and short cannot be disambiguated in some languages. Shown above.

  • Floating point conversion. float and double can not be disambiguated in some languages.

  • Pointers and references. For example, Foo * and Foo &.

  • Pointers and arrays. For example, Foo * and Foo [4].

  • Pointers and instances. For example, Foo and Foo *. Note: SWIG converts all instances to pointers.

  • Qualifiers. For example, const Foo * and Foo *.

  • Default vs. non default arguments. For example, foo(int a, int b) and foo(int a, int b = 3).
When an ambiguity arises, methods are checked in the same order as they appear in the interface file. Therefore, earlier methods will shadow methods that appear later.

When wrapping an overloaded function, there is a chance that you will get an error message like this:

example.i:3: Warning(467): Overloaded foo(int) not supported (no type checking rule for 'int').
This error means that the target language module supports overloading, but for some reason there is no type-checking rule that can be used to generate a working dispatch function. The resulting behavior is then undefined. You should report this as a bug to swig-dev@cs.uchicago.edu.

If you get an error message such as the following,

foo.i:6. Overloaded declaration ignored.  Spam::foo(double )
foo.i:5. Previous declaration is Spam::foo(int )
foo.i:7. Overloaded declaration ignored.  Spam::foo(Bar *,Spam *,int )
foo.i:5. Previous declaration is Spam::foo(int )
it means that the target language module has not yet implemented support for overloaded functions and methods. The only way to fix the problem is to read the next section.

5.14.3 Ambiguity resolution and renaming

If an ambiguity in overload resolution occurs or if a module doesn't allow overloading, there are a few strategies for dealing with the problem. First, you can tell SWIG to ignore one of the methods. This is easy---simply use the %ignore directive. For example:
%ignore foo(long);

void foo(int);
void foo(long);       // Ignored.  Oh well.
The other alternative is to rename one of the methods. This can be done using %rename. For example:
%rename(foo_long) foo(long);

void foo(int);
void foo(long);       // Accessed as foo_long()
The %ignore and %rename directives are both rather powerful in their ability to match declarations. When used in their simple form, they apply to both global functions and methods. For example:
/* Forward renaming declarations */
%rename(foo_i) foo(int); 
%rename(foo_d) foo(double);
...
void foo(int);           // Becomes 'foo_i'
void foo(char *c);       // Stays 'foo' (not renamed)

class Spam {
public:
   void foo(int);      // Becomes 'foo_i'
   void foo(double);   // Becomes 'foo_d'
   ...
};
If you only want the renaming to apply to a certain scope, the C++ scope resolution operator (::) can be used. For example:
%rename(foo_i) ::foo(int);      // Only rename foo(int) in the global scope.
                                // (will not rename class members)

%rename(foo_i) Spam::foo(int);  // Only rename foo(int) in class Spam
When a renaming operator is applied to a class as in Spam::foo(int), it is applied to that class and all derived classes. This can be used to apply a consistent renaming across an entire class hierarchy with only a few declarations. For example:
%rename(foo_i) Spam::foo(int);
%rename(foo_d) Spam::foo(double);

class Spam {
public:
   virtual void foo(int);      // Renamed to foo_i
   virtual void foo(double);   // Renamed to foo_d
   ...
};

class Bar : public Spam {
public:
   virtual void foo(int);      // Renamed to foo_i
   virtual void foo(double);   // Renamed to foo_d
...
};

class Grok : public Bar {
public:
   virtual void foo(int);      // Renamed to foo_i
   virtual void foo(double);   // Renamed to foo_d
...
};
It is also possible to include %rename specifications in the class definition itself. For example:
class Spam {
   %rename(foo_i) foo(int);
   %rename(foo_d) foo(double);
public:
   virtual void foo(int);      // Renamed to foo_i
   virtual void foo(double);   // Renamed to foo_d
   ...
};

class Bar : public Spam {
public:
   virtual void foo(int);      // Renamed to foo_i
   virtual void foo(double);   // Renamed to foo_d
...
};
In this case, the %rename directives still get applied across the entire inheritance hierarchy, but it's no longer necessary to explicitly specify the class prefix Spam::.

A special form of %rename can be used to apply a renaming just to class members (of all classes):

%rename(foo_i) *::foo(int);   // Only rename foo(int) if it appears in a class.
Note: the *:: syntax is non-standard C++, but the '*' is meant to be a wildcard that matches any class name (we couldn't think of a better alternative so if you have a better idea, send email to swig-dev@cs.uchicago.edu).

Although this discussion has primarily focused on %rename all of the same rules also apply to %ignore. For example:

%ignore foo(double);          // Ignore all foo(double)
%ignore Spam::foo;            // Ignore foo in class Spam
%ignore Spam::foo(double);    // Ignore foo(double) in class Spam
%ignore *::foo(double);       // Ignore foo(double) in all classes
When applied to a base class, %ignore forces all definitions in derived clases to disappear. For example, %ignore Spam::foo(double) will eliminate foo(double) in Spam and all classes derived from Spam.

Notes on %rename and %ignore:

  • Since, the %rename declaration is used to declare a renaming in advance, it can be placed at the start of an interface file. This makes it possible to apply a consistent name resolution without having to modify header files. For example:
    %module foo
    
    /* Rename these overloaded functions */
    %rename(foo_i) foo(int); 
    %rename(foo_d) foo(double);
    
    %include "header.h"
    

  • The scope qualifier (::) can also be used on simple names. For example:
    %rename(bar) ::foo;       // Rename foo to bar in global scope only
    %rename(bar) Spam::foo;   // Rename foo to bar in class Spam only
    %rename(bar) *::foo;      // Rename foo in classes only
    

  • Name matching tries to find the most specific match that is defined. A qualified name such as Spam::foo always has higher precedence than an unqualified name foo. Spam::foo has higher precedence than *::foo and *::foo has higher precedence than foo. A parameterized name has higher precedence than an unparameterized name within the same scope level. However, an unparameterized name with a scope qualifier has higher precedence than a parameterized name in global scope (e.g., a renaming of Spam::foo takes precedence over a renaming of foo(int)).

  • The order in which %rename directives are defined does not matter as long as they appear before the declarations to be renamed. Thus, there is no difference between saying:
    %rename(bar) foo;
    %rename(foo_i) Spam::foo(int);
    %rename(Foo) Spam::foo;
    
    and this
    %rename(Foo) Spam::foo;
    %rename(bar) foo;
    %rename(foo_i) Spam::foo(int);
    
    (the declarations are not stored in a linked list and order has no importance). Of course, a repeated %rename directive will change the setting for a previous %rename directive if exactly the same name, scope, and parameters are supplied.

  • For multiple inheritance where renaming rules are defined for multiple base classes, the first renaming rule found on a depth-first traversal of the class hierarchy is used.

  • The name matching rules strictly follow member qualification rules. For example, if you have a class like this:
    class Foo {
    public:
       ...
       void bar();
       ...
    };
    
    the declaration %rename(name) Foo::bar() only applies to the unqualified member bar(). However, an often overlooked C++ feature is that classes can define two different overloaded members that differ only in their qualifiers, like this:
    class Foo {
    public:
       ...
       void bar();         // Unqualified member
       void bar() const;   // Qualified member (OK)
       ...
    };
    
    In this case, the renaming operator would only apply to the first method. If you wanted to rename the qualified member function, use %rename(name) Foo::bar() const instead. Similarly, if you merely wanted to ignore one of the declarations, use %ignore with the full qualification. For example, the following directive would tell SWIG to ignore the const version of bar() above:
    %ignore Foo::bar() const;   // Ignore bar() const, but leave other bar() alone
    

5.14.4 Comments on overloading

Support for overloaded methods was first added in SWIG-1.3.14. The implementation is somewhat unusual when compared to similar tools. For instance, the order in which declarations appear is largely irrelevant in SWIG. Furthermore, SWIG does not rely upon trial execution or exception handling to figure out which method to invoke.

Internally, the overloading mechanism is completely configurable by the target language module. Therefore, the degree of overloading support may vary from language to language. As a general rule, statically typed languages like Java are able to provide more support than dynamically typed languages like Perl, Python, Ruby, and Tcl.

5.15 Wrapping overloaded operators

Starting in SWIG-1.3.10, C++ overloaded operator declarations can be wrapped. For example, consider a class like this:
class Complex {
private:
  double rpart, ipart;
public:
  Complex(double r = 0, double i = 0) : rpart(r), ipart(i) { }
  Complex(const Complex &c) : rpart(c.rpart), ipart(c.ipart) { }
  Complex &operator=(const Complex &c) {
    rpart = c.rpart;
    ipart = c.ipart;
    return *this;
  }
  Complex operator+(const Complex &c) const {
    return Complex(rpart+c.rpart, ipart+c.ipart);
  }
  Complex operator-(const Complex &c) const {
    return Complex(rpart-c.rpart, ipart-c.ipart);
  }
  Complex operator*(const Complex &c) const {
    return Complex(rpart*c.rpart - ipart*c.ipart,
		   rpart*c.ipart + c.rpart*ipart);
  }
  Complex operator-() const {
    return Complex(-rpart, -ipart);
  }
  double re() const { return rpart; }
  double im() const { return ipart; }
};
When operator declarations appear, they are handled in exactly the same manner as regular methods. However, the names of these methods are set to strings like "operator +" or "operator -". The problem with these names is that they are illegal identifiers in most scripting languages. For instance, you can't just create a method called "operator +" in Python--there won't be any way to call it.

Some language modules already know how to automatically handle certain operators (mapping them into operators in the target language). However, the underlying implementation of this is really managed in a very general way using the %rename directive. For example, in Python a declaration similar to this is used:

%rename(__add__) Complex::operator+;
This binds the + operator to a method called __add__ (which is conveniently the same name used to implement the Python + operator). Internally, the generated wrapper code for a wrapped operator will look something like this pseudocode:
_wrap_Complex___add__(args) {
   ... get args ...
   obj->operator+(args);
   ...
}
When used in the target language, it may now be possible to use the overloaded operator normally. For example:
>>> a = Complex(3,4)
>>> b = Complex(5,2)
>>> c = a + b           # Invokes __add__ method
It is important to realize that there is nothing magical happening here. The %rename directive really only picks a valid method name. If you wrote this:
%rename(add) operator+;
The resulting scripting interface might work like this:
a = Complex(3,4)
b = Complex(5,2)
c = a.add(b)      # Call a.operator+(b)
All of the techniques described to deal with overloaded functions also apply to operators. For example:
%ignore Complex::operator=;             // Ignore = in class Complex
%ignore *::operator=;                   // Ignore = in all classes
%ignore operator=;                      // Ignore = everywhere.

%rename(__sub__) Complex::operator-; 
%rename(__neg__) Complex::operator-();  // Unary - 
The last part of this example illustrates how multiple definitions of the operator- method might be handled.

Handling operators in this manner is mostly straightforward. However, there are a few subtle issues to keep in mind:

  • In C++, it is fairly common to define different versions of the operators to account for different types. For example, a class might also include a friend function like this:
    class Complex {
    public:
      friend Complex operator+(Complex &, double);
    };
    Complex operator+(Complex &, double);
    
    SWIG simply ignores all friend declarations. Furthermore, it doesn't know how to associate the associated operator+ with the class (because it's not a member of the class).

    It's still possible to make a wrapper for this operator, but you'll have to handle it like a normal function. For example:

    %rename(add_complex_double) operator+(Complex &, double);
    

  • Certain operators are ignored by default. For instance, new and delete operators are ignored as well as conversion operators.

  • The semantics of certain C++ operators may not match those in the target language.

5.16 Class extension

New methods can be added to a class using the %extend directive. This directive is primarily used in conjunction with proxy classes to add additional functionality to an existing class. For example :

%module vector
%{
#include "vector.h"
%}

class Vector {
public:
	double x,y,z;
	Vector();
	~Vector();
	... bunch of C++ methods ...
	%extend {
		char *__str__() {
			static char temp[256];
			sprintf(temp,"[ %g, %g, %g ]", v->x,v->y,v->z);
			return &temp[0];
		}
	}
};

This code adds a __str__ method to our class for producing a string representation of the object. In Python, such a method would allow us to print the value of an object using the print command.

>>>
>>> v = Vector();
>>> v.x = 3
>>> v.y = 4
>>> v.z = 0
>>> print(v)
[ 3.0, 4.0, 0.0 ]
>>>

The %extend directive follows all of the same conventions as its use with C structures. Please refer to the SWIG Basics chapter for further details.

Compatibility note: The %extend directive is a new name for the %addmethods directive. Since %addmethods could be used to extend a structure with more than just methods, a more suitable directive name has been chosen.

5.17 Templates

In all versions of SWIG, template type names may appear anywhere a type is expected in an interface file. For example:
void foo(vector<int> *a, int n);
void bar(list<int,100> *x);
There are some restrictions on the use of non-type arguments. Specifically, they have to be simple literals and not expressions. For example:
void bar(list<int,100> *x);    // OK
void bar(list<int,2*50> *x);   // Illegal
The type system is smart enough to figure out clever games you might try to play with typedef. For instance, consider this code:
typedef int Integer;
void foo(vector<int> *x, vector<Integer> *y);
In this case, vector<Integer> is exactly the same type as vector<int>. The wrapper for foo() will accept either variant.

Starting with SWIG-1.3.7, simple C++ template declarations can also be wrapped. SWIG-1.3.12 greatly expands upon the earlier implementation. Before discussing this any further, there are a few things you need to know about template wrapping. First, a bare C++ template does not define any sort of runnable object-code for which SWIG can normally create a wrapper. Therefore, in order to wrap a template, you need to give SWIG information about a particular template instantiation (e.g., vector<int>, array<double>, etc.). Second, an instantiation name such as vector<int> is generally not a valid identifier name in most target languages. Thus, you will need to give the template instantiation a more suitable name such as intvector when creating a wrapper.

To illustrate, consider the following template definition:

template<class T> class List {
private:
    T *data;
    int nitems;
    int maxitems;
public:
    List(int max) {
      data = new T [max];
      nitems = 0;
      maxitems = max;
    }
    ~List() {
      delete [] data;
    };
    void append(T obj) {
      if (nitems < maxitems) {
        data[nitems++] = obj;
      }
    }
    int length() {
      return nitems;
    }
    T get(int n) {
      return data[n];
    }
};
By itself, this template declaration is useless--SWIG simply ignores it because it doesn't know how to generate any code until unless a definition of T is provided.

One way to create wrappers for a specific template instantiation is to simply provide an expanded version of the class directly like this:

%rename(intList) List<int>;       // Rename to a suitable identifier
class List<int> {
private:
    int *data;
    int nitems;
    int maxitems;
public:
    List(int max);
    ~List();
    void append(int obj);
    int length();
    int get(int n);
};
The %rename directive is needed to give the template class an appropriate identifier name in the target language (most languages would not recognize C++ template syntax as a valid class name). The rest of the code is the same as what would appear in a normal class definition.

Since manual expansion of templates gets old in a hurry, the %template directive can be used to create instantiations of a template class. Semantically, %template is simply a shortcut---it expands template code in exactly the same way as shown above. Here are some examples:

/* Instantiate a few different versions of the template */
%template(intList) List<int>;
%template(doubleList) List<double>;
The argument to %template() is the name of the instantiation in the target language. The name you choose should not conflict with any other declarations in the interface file with one exception---it is okay for the template name to match that of a typedef declaration. For example:
%template(intList) List<int>;
...
typedef List<int> intList;    // OK
SWIG can also generate wrappers for function templates using a similar technique. For example:
// Function template
template<class T> T max(T a, T b) { return a > b ? a : b; }

// Make some different versions of this function
%template(maxint) max<int>;
%template(maxdouble) max<double>;
In this case, maxint and maxdouble become unique names for specific instantiations of the function.

The number of arguments supplied to %template should match that in the original template definition. Template default arguments are supported. For example:

template vector<typename T, int max=100> class vector {
...
};

%template(intvec) vector<int>;           // OK
%template(vec1000) vector<int,1000>;     // OK

The %template directive should not be used to wrap the same template instantiation more than once in the same scope. This will generate an error. For example:

%template(intList) List<int>;
%template(Listint) List<int>;    // Error.   Template already wrapped.

This error is caused because the template expansion results in two identical classes with the same name. This generates a symbol table conflict. Besides, it probably more efficient to only wrap a specific instantiation only once in order to reduce the potential for code bloat.

Since the type system knows how to handle typedef, it is generally not necessary to instantiate different versions of a template for typenames that are equivalent. For instance, consider this code:

%template(intList) vector<int>;
typedef int Integer;
...
void foo(vector<Integer> *x);
In this case, vector<Integer> is exactly the same type as vector<int>. Any use of Vector<Integer> is mapped back to the instantiation of vector<int> created earlier. Therefore, it is not necessary to instantiate a new class for the type Integer (doing so is redundant and will simply result in code bloat).

When a template is instantiated using %template, information about that class is saved by SWIG and used elsewhere in the program. For example, if you wrote code like this,

...
%template(intList) List<int>;
...
class UltraList : public List<int> {
   ...
};
then SWIG knows that List<int> was already wrapped as a class called intList and arranges to handle the inheritance correctly. If, on the other hand, nothing is known about List<int>, you will get a warning message similar to this:
example.h:42. Nothing known about class 'List<int >' (ignored). 
example.h:42. Maybe you forgot to instantiate 'List<int >' using %template. 

If a template class inherits from another template class, you need to make sure that base classes are instantiated before derived classes. For example:

template<class T> class Foo {
...
};

template<class T> class Bar : public Foo<T> {
...
};

// Instantiate base classes first 
%template(intFoo) Foo<int>;
%template(doubleFoo) Foo<double>;

// Now instantiate derived classes
%template(intBar) Bar<int>;
%template(doubleBar) Bar<double>;
The order is important since SWIG uses the instantiation names to properly set up the inheritance hierarchy in the resulting wrapper code (and base classes need to be wrapped before derived classes). Don't worry--if you get the order wrong, SWIG should generate an warning message.

Occassionally, you may need to tell SWIG about base classes that are defined by templates, but which aren't supposed to be wrapped. Since SWIG is not able to automatically instantiate templates for this purpose, you must do it manually. To do this, simply use %template with no name. For example:

// Instantiate traits<double,double>, but don't wrap it.
%template() traits<double,double>;

If you have to instantiate a lot of different classes for many different types, you might consider writing a SWIG macro. For example:

%define TEMPLATE_WRAP(T,prefix) 
%template(prefix ## Foo) Foo<T>;
%template(prefix ## Bar) Bar<T>;
...
%enddef

TEMPLATE_WRAP(int, int)
TEMPLATE_WRAP(double, double)
TEMPLATE_WRAP(char *, String)
...

The SWIG template mechanism does support specialization. For instance, if you define a class like this,

template<> class List<int> {
private:
    int *data;
    int nitems;
    int maxitems;
public:
    List(int max);
    ~List();
    void append(int obj);
    int length();
    int get(int n);
};
then SWIG will use this code whenever the user expands List<int>. In practice, this may have very little effect on the underlying wrapper code since specialization is often used to provide slightly modified method bodies (which are ignored by SWIG). However, special SWIG directives such as %typemap, %extend, and so forth can be attached to a specialization to provide customization for specific types.

Partial template specialization is partially supported by SWIG. For example, this code defines a template that is applied when the template argument is a pointer.

template<class T> class List<T*> {
private:
    T *data;
    int nitems;
    int maxitems;
public:
    List(int max);
    ~List();
    void append(int obj);
    int length();
    T get(int n);
};
SWIG should be able to handle most simple uses of partial specialization. However, it may fail to match templates properly in more complicated cases. For example, if you have this code,
template<class T1, class T2> class Foo<T1, T2 *> { };
SWIG isn't able to match it properly for instantiations like Foo<int *, int *>. This problem is not due to parsing, but due to the fact that SWIG does not currently implement all of the C++ argument deduction rules.

Member function templates are supported. The underlying principle is the same as for normal templates--SWIG can't create a wrapper unless you provide more information about types. For example, a class with a member template might look like this:

class Foo {
public:
     template<class T> void bar(T x, T y) { ... };
     ...
};
To expand the template, simply use %template inside the class.
class Foo {
public:
     template<class T> void bar(T x, T y) { ... };
     ...
     %template(barint)    bar<int>;
     %template(bardouble) bar<double>;
};
Or, if you want to leave the original class definition alone, just do this:
class Foo {
public:
     template<class T> void bar(T x, T y) { ... };
     ...
};
...
%extend Foo {
     %template(barint)    bar<int>;
     %template(bardouble) bar<double>;
};
Note: because of the way that templates are handled, the %template directive must always appear after the definition of the template to be expanded.

When used with members, the %template directive may be placed in another template class. Here is a slightly perverse example:

// A template
template<class T> class Foo {
public:
     // A member template
     template<class S> T bar(S x, S y) { ... };
     ...
};

// Expand a few member templates
%extend Foo {
     %template(bari) bar<int>;
     %template(bard) bar<double>;
};

// Create some wrappers for the template
%template(Fooi) Foo<int>;
%template(Food) Foo<double>;
Miraculously, you will find that each expansion of Foo has member functions bari() and bard() added.

A common use of member templates is to define constructors for copies and conversions. For example:

template<class T1, class T2> struct pair {
   T1 first;
   T2 second;
   pair() : first(T1()), second(T2()) { }
   pair(const T1 &x, const T2 &y) : first(x), second(y) { }
   template<class U1, class U2> pair(const pair<U1,U2> &x) : first(x.first),second(x.second) { }
};
This declaration is perfectly acceptable to SWIG, but the constructor template will be ignored unless you explicitly expand it. To do that, you could expand a few versions of the constructor in the template class itself. For example:
%extend pair {
   %template(pair) pair<T1,T2>;        // Generate default copy constructor
};
When using %extend in this manner, notice how you can still use the template parameters in the original template definition.

Alternatively, you could expand the constructor template in selected instantiations. For example:

// Instantiate a few versions
%template(pairii) pair<int,int>;
%template(pairdd) pair<double,double>;

// Create a conversion constructor from int to double
%extend pair<double,double> {
   %template(pairdd_from_pairii) pair<int,int>;   // Conversion constructor
};
Admittedly, this isn't very pretty or automatic. However, it's probably better than nothing--well, maybe.

If all of this isn't quite enough and you really want to make someone's head explode, SWIG directives such as %rename, %extend, and %typemap can be included directly in template definitions. For example:

// File : list.h
template<class T> class List {
   ...
public:
    %rename(__getitem__) get(int);
    List(int max);
    ~List();
    ...
    T get(int index);
    %extend {
        char *__str__() {
            /* Make a string representation */
            ...
        }
    }
};
In this example, the extra SWIG directives are propagated to every template instantiation.

It is also possible to separate these declarations from the template class. For example:

%rename(__getitem__) List::get;
%extend List {
    char *__str__() {
        /* Make a string representation */
        ...
    }
    /* Make a copy */
    T *__copy__() {
       return new List<T>(*self);
    }
};

...
template<class T> class List {
   ...
   public:
   List() { };
   ...
};

When %extend is decoupled from the class definition, it is legal to use the same template parameters as provided in the class definition. These are replaced when the template is expanded. In addition, the %extend directive can be used to add additional methods to a specific instantiation. For example:

%template(intList) List<int>;

%extend List<int> {
    void blah() {
          printf("Hey, I'm an List<int>!\n");
    }
};

Needless to say, SWIG's template support provides plenty of opportunities to break the universe. That said, an important final point is that SWIG does not perform extensive error checking of templates! Specifically, SWIG does not perform type checking nor does it check to see if the actual contents of the template declaration make any sense. Since the C++ compiler will hopefully check this when it compiles the resulting wrapper file, there is no practical reason for SWIG to duplicate this functionality (besides, none of the SWIG developers are masochistic enough to want to implement this right now).

Finally, there are a few limitations in SWIG's current support for templates:

  • SWIG does not support overloaded versions of a template. Some C++ programs might do this to define overloaded functions. For example:
    template<class T> void foo(T x) { };
    template<class T> void foo(T x, T y) { };     // Error. foo already defined.
    
    This will generate a name conflict error message in SWIG. To silence the error message, use %ignore:
    %ignore foo(T,T);
    
    In this case, %template will only work with the first definition. To create a wrapper for the second definition, just do it manually:
    %name(foo2int) void foo<int>(int x, int y);
    

Compatibility Note: The first implementation of template support relied heavily on macro expansion in the preprocessor. Templates have been more tightly integrated into the parser and type system in SWIG-1.3.12 and the preprocessor is no longer used. Code that relied on preprocessing features in template expansion will no longer work. However, SWIG still allows the # operator to be used to generate a string from a template argument.

Compatibility Note: In earlier versions of SWIG, the %template directive introduced a new class name. This name could then be used with other directives. For example:

%template(vectori) vector<int>;
%extend vectori {
    void somemethod() { }
};
This behavior is no longer supported. Instead, you should use the original template name as the class name. For example:
%template(vectori) vector<int>;
%extend vector<int> {
    void somemethod() { }
};
Similar changes apply to typemaps and other customization features.

5.18 Namespaces

Support for C++ namespaces is a relatively late addition to SWIG, first appearing in SWIG-1.3.12. Before describing the implementation, it is worth nothing 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 encapsulate common functionality. For example:
namespace math {
   double sin(double);
   double cos(double);

   class Complex {
      double im,re;
   public:
      ...
   };
   ...
};
Members of the namespace are accessed in C++ by prepending the namespace prefix to names. For example:
double x = math::sin(1.0);
double magitude(math::Complex *c);
math::Complex c;
...
At this level, namespaces are relatively easy to manage. However, things start to get very ugly when you throw in the other ways a namespace can be used. For example, selective symbols can be exported from a namespace with using.
using math::Complex;
double magnitude(Complex *c);       // Namespace prefix stripped
Similarly, the contents of an entire namespace can be made available like this:
using namespace math;
double x = sin(1.0);
double magnitude(Complex *c);
Alternatively, a namespace can be aliased:
namespace M = math;
double x = M::sin(1.0);
double magnitude(M::Complex *c);
Using combinations of these features, it is possible to write head-exploding code like this:
namespace A {
  class Foo {
  };
}

namespace B {
   namespace C {
      using namespace A;
   }
   typedef C::Foo FooClass;
}

namespace BIGB = B;

namespace D {
   using BIGB::FooClass;
   class Bar : public FooClass {
   }
};

class Spam : public D::Bar {
};

void evil(A::Foo *a, B::FooClass *b, B::C::Foo *c, BIGB::FooClass *d,
          BIGB::C::Foo *e, D::FooClass *f);

Given the possibility for such perversion, it's hard to imagine how every C++ programmer might want such code wrapped into the target language. Clearly this code defines three different classes. However, one of those classes is accessible under at least six different class names!

SWIG fully supports C++ namespaces in its internal type system and class handling code. If you feed SWIG the above code, it will be parsed correctly, it will generate compilable wrapper code, and it will produce a working scripting language module. However, the default wrapping behavior is to flatten namespaces in the target language. This means that the contents of all namespaces are merged together in the resulting scripting language module. For example, if you have code like this,

%module foo
namespace foo {
   void bar(int);
   void spam();
}

namespace bar {
   void blah();
}

then SWIG simply creates three wrapper functions bar(), spam(), and blah() in the target language. SWIG does not prepend the names with a namespace prefix nor are the functions packaged in any kind of nested scope.

There is some rationale for taking this approach. Since C++ namespaces are often used to define modules in C++, there is a natural correlation between the likely contents of a SWIG module and the contents of a namespace. For instance, it would not be unreasonable to assume that a programmer might make a separate extension module for each C++ namespace. In this case, it would be redundant to prepend everything with an additional namespace prefix when the module itself already serves as a namespace in the target language. Or put another way, if you want SWIG to keep namespaces separate, simply wrap each namespace with its own SWIG interface.

Because namespaces are flattened, it is possible for symbols defined in different namespaces to generate a name conflict in the target language. For example:

namespace A {
   void foo(int);
}
namespace B {
   void foo(double);
}
When this conflict occurs, you will get an error message that resembles this:
example.i:26. Error. 'foo' is multiply defined in the generated module.
example.i:23. Previous declaration of 'foo'
To resolve this error, simply use %rename to disambiguate the declarations. For example:
%rename(B_foo) B::foo;
...
namespace A {
   void foo(int);
}
namespace B {
   void foo(double);     // Gets renamed to B_foo
}
Similarly, %ignore can be used to ignore declarations.

using declarations do not have any effect on the generated wrapper code. They are ignored by SWIG language modules and they do not result in any code. However, these declarations are used by the internal type system to track type-names. Therefore, if you have code like this:

namespace A {
   typedef int Integer;
}
using namespace A;
void foo(Integer x);
SWIG knows that Integer is the same as A::Integer which is the same as int.

Namespaces may be combined with templates. If necessary, the %template directive can be used to expand a template defined in a different namespace. For example:

namespace foo {
    template<typename T> max(T a, T b) { return a > b ? a : b; }
}

using foo::max;

%template(maxint)   max<int>            // Okay.
%template(maxfloat) foo::max<float>;    // Okay (qualified name).

namespace bar {
    using namespace foo;
    %template(maxdouble)  max<double>;    // Okay.
}
The combination of namespaces and other SWIG directives may introduce subtle scope-related problems. The key thing to keep in mind is that all SWIG generated wrappers are produced in the global namespace. Symbols from other namespaces are always accessed using fully qualified names---names are never imported into the global space unless the interface happens to do so with a using declaration. In almost all cases, SWIG adjusts typenames and symbols to be fully qualified. However, this is not done in code fragments such as function bodies, typemaps, exception handlers, and so forth. For example, consider the following:
namespace foo {
    typedef int Integer;
    class bar {
    public:
       ...
    };
}

%extend foo::bar {
   Integer add(Integer x, Integer y) {
       Integer r = x + y;        // Error. Integer not defined in this scope
       return r;
   }
};
In this case, SWIG correctly resolves the added method parameters and return type to foo::Integer. However, since function bodies aren't parsed and such code is emitted in the global namespace, this code produces a compiler error about Integer. To fix the problem, make sure you use fully qualified names. For example:
%extend foo::bar {
   Integer add(Integer x, Integer y) {
       foo::Integer r = x + y;        // Ok.
       return r;
   }
};

Note: SWIG does not propagate using declarations to the resulting wrapper code. If these declarations appear in an interface, they should also appear in any header files that might have been included in a %{ ... %} section. In other words, don't insert extra using declarations into a SWIG interface unless they also appear in the underlying C++ code.

Note: Code inclusion directives such as %{ ... %} or %inline %{ ... %} should not be placed inside a namespace declaration. The code emitted by these directives will not be enclosed in a namespace and you may get very strange results. If you need to use namespaces with these directives, consider the following:

// Good version
%inline %{
namespace foo {
     void bar(int) { ... }
     ...
}
%}

// Bad version.  Emitted code not placed in namespace.
namespace foo {
%inline %{
     void bar(int) { ... }   /* I'm bad */
     ...
%}
}

Note: When the %extend directive is used inside a namespace, the namespace name is included in the generated functions. For example, if you have code like this,

namespace foo {
   class bar {
   public:
        %extend {
           int blah(int x);
        };
   };
}
the added method blah() is mapped to a function int foo_bar_blah(foo::bar *self, int x). This function resides in the global namespace.

Note: Although namespaces are flattened in the target language, the SWIG generated wrapper code observes the same namespace conventions as used in the input file. Thus, if there are no symbol conflicts in the input, there will be no conflicts in the generated code.

Note: Namespaces have a subtle effect on the wrapping of conversion operators. For instance, suppose you had an interface like this:

namespace foo {
   class bar;
   class spam {
   public;
        ...
        operator bar();      // Conversion of spam -> bar
        ...
   };
}
To wrap the conversion function, you might be inclined to write this:
%rename(tofoo) foo::spam::operator bar();
The only problem is that it doesn't work. The reason it doesn't work is that bar is not defined in the global scope. Therefore, to make it work, do this instead:
%rename(tofoo) foo::spam::operator foo::bar();

Note: The flattening of namespaces is only intended to serve as a basic namespace implementation. Since namespaces are a new addition to SWIG, none of the target language modules are currently programmed with any namespace awareness. In the future, language modules may or may not provide more advanced namespace support.

5.19 Exception specifiers

When C++ programs utilize exceptions, exceptional behavior is sometimes specified as part of a function or method declaration. For example:
class Error { };

class Foo {
public:
    ...
    void blah() throw(Error);
    ...
};
If an exception specification is used, SWIG automatically generates wrapper code for catching the indicated exception and converting it into an error in the target language. In certain language modules, wrapped exception classes themselves can be used to catch errors. For example, in Python, you can write code like this:
f = Foo()
try:
    f.blah()
except Error,e:
     # e is a wrapped instance of "Error"
Obviously, the exact details of how exceptions are handled depend on the target language module.

Since exception specifiers 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 "Customization features" chapter for details.

5.20 Pointers to Members

Starting with SWIG1.3.7, there is limited parsing support for pointers to C++ class members. For example:
double do_op(Object *o, double (Object::*callback)(double,double));
extern double (Object::*fooptr)(double,double);
%constant double (Object::*FOO)(double,double) = &Object::foo;
Although these kinds of pointers can be parsed and represented by the SWIG type system, few language modules know how to handle them due to implementation differences from standard C pointers. Readers are strongly advised to consult an advanced text such as the "The Annotated C++ Manual" for specific details.

When pointers to members are supported, the pointer value might appear as a special string like this:

>>> print example.FOO
_ff0d54a800000000_m_Object__f_double_double__double
>>>
In this case, the hexadecimal digits represent the entire value of the pointer which is usually the contents of a small C++ structure on most machines.

SWIG's type-checking mechanism is also more limited when working with member pointers. Normally SWIG tries to keep track of inheritance when checking types. However, no such support is currently provided for member pointers.

5.21 Smart pointers and operator->()

In some C++ programs, objects are often encapsulated by smart-pointers or proxy classes. This is sometimes done to implement automatic memory management (reference counting) or persistence. Typically a smart-pointer is defined by a template class where the -> operator has been overloaded. This class is then wrapped around some other class. For example:
// Smart-pointer class
template<class T> class SmartPtr {
    T *pointee;
public:
    ...
    T *operator->() {
        return pointee;
    }
    ...
};

// Ordinary class
class Foo_Impl {
public:
    int x;
    virtual void bar();
    ...
};

// Smart-pointer wrapper
typedef SmartPtr<Foo_Impl> Foo;

// Create smart pointer Foo
Foo make_Foo() {
    return SmartPtr(new Foo_Impl());
}

// Do something with smart pointer Foo
void do_something(Foo f) {
    printf("x = %d\n", f->x);
    f->bar();
}
A key feature of this approach is that by defining operator-> the methods and attributes of the object wrapped by a smart pointer are transparently accessible. For example, expressions such as these (from the previous example),
f->x
f->bar()
are transparently mapped to the following
(f.operator->())->x;
(f.operator->())->bar();
When generating wrappers, SWIG tries to emulate this functionality to the extent that it is possible. To do this, whenever operator->() is encountered in a class, SWIG looks at its returned type and uses it to generate wrappers for accessing attributes of the underlying object. For example, wrapping the above code produces wrappers like this:
int Foo_x_get(Foo *f) {
   return (*f)->x;
}
void Foo_x_set(Foo *f, int value) {
   (*f)->x = value;
}
void Foo_bar(Foo *f) {
   (*f)->bar();
}
These wrappers take a smart-pointer instance as an argument, but dereference it in a way to gain access to the object returned by operator->(). You should carefully compare these wrappers to those in the first part of this chapter (they are slightly different).

The end result is that access looks very similar to C++. For example, you could do this in Python:

>>> f = make_Foo()
>>> print f.x
0
>>> f.bar()
>>>
When generating wrappers through a smart-pointer, SWIG tries to generate wrappers for all methods and attributes that might be accessible through operator->(). This includes any methods that might be accessible through inheritance. However, there are a number of restrictions:
  • Only member variables and methods are wrapped through a smart pointer. Static members, enumerations, constructors, and destructors are not wrapped.

  • If the smart-pointer class and the underlying object both define a method or variable of the same name, then the smart-pointer version has precedence. For example, if you have this code
    class Foo {
    public:
        int x;
    };
    
    class Bar {
    public:
        int x;       
        Foo *operator->();
    };
    
    then the wrapper for Bar::x accesses the x defined in Bar, and not the x defined in Foo.
If your intent is to only expose the smart-pointer class in the interface, it is not necessary to wrap both the smart-pointer class and the class for the underlying object. However, you must still tell SWIG about both classes if you want the technique described in this section to work. To only generate wrappers for the smart-pointer class, you can use the %ignore directive. For example:
%ignore Foo;
class Foo {       // Ignored
};

class Bar {
public:
   Foo *operator->();
   ...
};
Alternatively, you can import the definition of Foo from a separate file using %import.

Note: When a class defines operator->(), the operator itself is wrapped as a method __deref__(). For example:

f = Foo()               # Smart-pointer
p = f.__deref__()       # Raw pointer from operator->

Note: To disable the smart-pointer behavior, use %ignore to ignore operator->(). For example:

%ignore Bar::operator->;

Note: Smart pointer support was first added in SWIG-1.3.14.

5.22 Using declarations and inheritance

using declarations are sometimes used to adjust access to members of base classes. For example:
class Foo {
public:
      int  blah(int x);
};

class Bar {
public:
      double blah(double x);
};

class FooBar : public Foo, public Bar {
public:
      using Foo::blah;  
      using Bar::blah;
      char *blah(const char *x);
};
In this example, the using declarations make different versions of the overloaded blah() method accessible from the derived class. For example:
FooBar *f;
f->blah(3);         // Ok. Invokes Foo::blah(int)
f->blah(3.5);       // Ok. Invokes Bar::blah(double)
f->blah("hello");   // Ok. Invokes FooBar::blah(const char *);
SWIG emulates the same functionality when creating wrappers. For example, if you wrap this code in Python, the module works just like you would expect:
>>> import example
>>> f = example.FooBar()
>>> f.blah(3)
>>> f.blah(3.5)
>>> f.blah("hello")
using declarations can also be used to change access when applicable. For example:
class Foo {
protected:
    int x;
    int blah(int x);
};

class Bar : public Foo {
public:
    using Foo::x;       // Make x public
    using Foo::blah;    // Make blah public
};
This also works in SWIG---the exposed declarations will be wrapped normally.

When using declarations are used as shown in these examples, declarations from the base classes are copied into the derived class and wrapped normally. When copied, the declarations retain any properties that might have been attached using %rename, %ignore, or %feature. Thus, if a method is ignored in a base class, it will also be ignored by a using declaration.

Because a using declaration does not provide fine-grained control over the declarations that get imported, it may be difficult to manage such declarations in applications that make heavy use of SWIG customization features. If you can't get using to work correctly, you can always change the interface to the following:


class FooBar : public Foo, public Bar {
public:
#ifndef SWIG
      using Foo::blah;  
      using Bar::blah;
#else
      int blah(int x);         // explicitly tell SWIG about other declarations
      double blah(double x);
#endif

      char *blah(const char *x);
};
Notes:
  • If a derived class redefines a method defined in a base class, then a using declaration won't cause a conflict. For example:
    class Foo {
    public:
           int blah(int );
           double blah(double);
    };
    
    class Bar : public Foo {
    public:
           using Foo::blah;    // Only imports blah(double);
           int blah(int);
    };
    
  • Resolving ambiguity in overloading may prevent declarations from being imported by using. For example:
    %rename(blah_long) Foo::blah(long);
    class Foo {
    public:
         int blah(int);
         long blah(long);  // Renamed to blah_long
    };
    
    class Bar : public Foo {
    public:
         using Foo::blah;     // Only imports blah(int)
         double blah(double x);
    };
    

5.23 Partial class definitions

Since SWIG is still limited in its support of C++, it may be necessary to use partial class information in an interface file. However, since SWIG does not need the entire class specification to work, conditional compilation can be used to comment out problematic parts. For example, if you had a nested class definition, you might do this:
class Foo {
public:
#ifndef SWIG
   class Bar {
   public:
     ...
   };
#endif
   Foo();
  ~Foo();
   ...
};

Also, as a rule of thumb, SWIG should not be used on raw C++ source files.

5.24 A brief rant about const-correctness

A common issue when working with C++ programs is dealing with all possible ways in which the const qualifier (or lack thereof) will break your program, all programs linked against your program, and all programs linked against those programs.

Although SWIG knows how to correctly deal with const in its internal type system and it knows how to generate wrappers that are free of const-related warnings, SWIG does not make any attempt to preserve const-correctness in the target language. Thus, it is possible to pass const qualified objects to non-const methods and functions. For example, consider the following code in C++:

const Object * foo();
void bar(Object *);

...
// C++ code
void blah() {
   bar(foo());         // Error: bar discards const
};
Now, consider the behavior when wrapped into a Python module:
>>> bar(foo())         # Okay
>>> 
Although this is clearly a violation of the C++ type-system, fixing the problem doesn't seem to be worth the added implementation complexity that would be required to support it in the SWIG run-time type system. There are no plans to change this in future releases (although we'll never rule anything out entirely).

The bottom line is that this particular issue does not appear to be a problem for most SWIG projects. Of course, you might want to consider using another tool if maintaining constness is the most important part of your project.

5.25 Proxy classes

In order to provide a more natural API, many of SWIG's target languages also wrap C++ classes with special proxy classes. These proxy classes are typically implemented in the target language itself. For example, if you're building a Python module, each C++ class is wrapped with Python class. Or if you're building a Java module, each C++ class is wrapped by a Java class.

5.25.1 Construction of proxy classes

Proxy classes are always constructed as an extra layer of wrapping that uses the low-level accessor functions described in the previous section. To illustrate, suppose you had a C++ class like this:
class Foo {
public:
      Foo();
     ~Foo();
      int  bar(int x);
      int  x;
};
Using C++ as pseudocode, a proxy class looks something like this:
class FooProxy {
private:
      Foo    *self;
public:
      FooProxy() {
            self = new_Foo();
      }
     ~FooProxy() {
            delete_Foo(self);
      }
      int bar(int x) {
            return Foo_bar(self,x);
      }
      int x_get() {
            return Foo_x_get(self);
      }
      void x_set(int x) {
            Foo_x_set(self,x);
      }
};
Of course, always keep in mind that the real proxy class is written in the target language. For example, in Python, the proxy might look roughly like this:
class Foo:
    def __init__(self):
         self.this = new_Foo()
    def __del__(self):
         delete_Foo(self.this)
    def bar(self,x):
         return Foo_bar(self.this,x)
    def __getattr__(self,name):
         if name == 'x':
              return Foo_x_get(self.this)
         ...
    def __setattr__(self,name,value):
         if name == 'x':
              Foo_x_set(self.this,value)
         ...
Again, it's important to emphasize that the low-level accessor functions are always used to construct the proxy classes.

Whenever possible, proxies try to take advantage of language features that are similar to C++. This might include operator overloading, exception handling, and other features.

5.25.2 Resource management in proxies

A major issue with proxies concerns the memory management of wrapped objects. Consider the following C++ code:
class Foo {
public:
      Foo();
     ~Foo();
      int bar(int x);
      int x;
};

class Spam {
public:
      Foo *value;
      ...
};
Now, consider some script code that uses these classes:
f = Foo()               # Creates a new Foo
s = Spam()              # Creates a new Spam
s.value = f             # Stores a reference to f inside s
g = s.value             # Returns stored reference
g = 4                   # Reassign g to some other value
del f                   # Destroy f 
Now, ponder the resulting memory management issues. When objects are created in the script, the objects are wrapped by newly created proxy classes. That is, there is both a new proxy class instance and a new instance of the underlying C++ class. In this example, both f and s are created in this way. However, the statement s.value is rather curious---when executed, a pointer to f is stored inside another object. This means that the scripting proxy class AND another C++ class share a reference to the same object. To make matters even more interesting, consider the statement g = s.value. When executed, this creates a new proxy class g that provides a wrapper around the C++ object stored in s.value. In general, there is no way to know where this object came from---it could have been created by the script, but it could also have been generated internally. In this particular example, the assignment of g results in a second proxy class for f. In other words, a reference to f is now shared by two proxy classes and a C++ class.

Finally, consider what happens when objects are destroyed. In the statement, g=4, the variable g is reassigned. In many languages, this makes the old value of g available for garbage collection. Therefore, this causes one of the proxy classes to be destroyed. Later on, the statement del f destroys the other proxy class. Of course, there is still a reference to the original object stored inside another C++ object. What happens to it? Is it the object still valid?

To deal with memory management problems, proxy classes always provide an API for controlling ownership. In C++ pseudocode, ownership control might look roughly like this:

class FooProxy {
public:
      Foo    *self;
      int     thisown;

      FooProxy() {
            self = new_Foo();
            thisown = 1;       // Newly created object
      }
     ~FooProxy() {
            if (thisown) delete_Foo(self);
      }
      ...
      // Ownership control API
      void disown() {
           thisown = 0;
      }
      void acquire() {
           thisown = 1;
      }
};

class FooPtrProxy: public FooProxy {
public:
      FooPtrProxy(Foo *s) {
          self = s;
          thisown = 0;
      }
};

class SpamProxy {
     ...
     FooProxy *value_get() {
          return FooPtrProxy(Spam_value_get(self));
     }
     void value_set(FooProxy *v) {
          Spam_value_set(self,v->self);
          v->disown();
     }
     ...
};
Looking at this code, there are a few central features:
  • Each proxy class keeps an extra flag to indicate ownership. C++ objects are only destroyed if the ownership flag is set.

  • When new objects are created in the target language, the ownership flag is set.

  • When a reference to an internal C++ object is returned, it is wrapped by a proxy class, but the proxy class does not have ownership.

  • In certain cases, ownership is adjusted. For instance, when a value is assigned to the member of a class, ownership is lost.

  • Manual ownership control is provided by special disown() and acquire() methods.
Given the tricky nature of C++ memory management, it is impossible for proxy classes to automatically handle every possible memory management problem. However, proxies do provide a mechanism for manual control that can be used (if necessary) to address some of the more tricky memory management problems.

5.25.3 Language specific details

Language specific details on proxy classes are contained the chapters describing each target language. This chapter has merely introduced the topic in a very general way.

5.26 Where to go for more information

If you're wrapping serious C++ code, you might want to pick up a copy of "The Annotated C++ Reference Manual" by Ellis and Stroustrup. This is the reference document we use to guide a lot of SWIG's C++ support.


SWIG 1.3 - Last Modified : April 3, 2003
cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/Perl5.html0000644000175000000620000021334412561312226021403 0ustar stevestaff SWIG and Perl5

19 SWIG and Perl5

Caution: This chapter is under repair!

This chapter describes SWIG's support of Perl5. Although the Perl5 module is one of the earliest SWIG modules, it has continued to evolve and has been improved greatly with the help of SWIG users. For the best results, it is recommended that SWIG be used with Perl5.003 or later. Earlier versions are problematic and SWIG generated extensions may not compile or run correctly.

19.1 Overview

To build Perl extension modules, SWIG uses a layered approach. At the lowest level, simple procedural wrappers are generated for functions, classes, methods, and other declarations in the input file. Then, for structures and classes, an optional collection of Perl proxy classes can be generated in order to provide a more natural object oriented Perl interface. These proxy classes simply build upon the low-level interface.

In describing the Perl interface, this chapter begins by covering the essentials. First, the problem of configuration, compiling, and installing Perl modules is discussed. Next, the low-level procedural interface is presented. Finally, proxy classes are described. Advanced customization features, typemaps, and other options are found near the end of the chapter.

19.2 Preliminaries

To build a Perl5 module, run Swig using the -perl option as follows :

swig -perl example.i

This produces two files. The first file, example_wrap.c contains all of the C code needed to build a Perl5 module. The second file, example.pm contains supporting Perl code needed to properly load the module.

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

19.2.1 Getting the right header files

In order to compile, SWIG extensions need the following Perl5 header files :

#include "Extern.h"
#include "perl.h"
#include "XSUB.h"

These are typically located in a directory like this

/usr/lib/perl5/5.00503/i386-linux/CORE

The SWIG configuration script automatically tries to locate this directory so that it can compile examples. However, if you need to find out where the directory is loaded, an easy way to find out is to run Perl itself.

% perl -e 'use Config; print $Config{archlib};'
/usr/lib/perl5/5.00503/i386-linux

19.2.2 Compiling a dynamic module

The preferred approach to building an extension module is to compile it into a shared object file or DLL. To do this, you will need to compile your program using comands like this (shown for Linux):
$ swig -perl example.i
% gcc example.c
% gcc -c example_wrap.c -I/usr/lib/perl5/5.00503/i386-linux/CORE -Dbool=char
% gcc -shared example.o example_wrap.o -o example.so
The exact compiler options vary from platform to platform. SWIG tries to guess the right options when it is installed. Therefore, you may want to start with one of the examples in the SWIG/Examples/perl5 directory. If that doesn't work, you will need to read the man-pages for your compiler and linker to get the right set of options. You might also check the SWIG Wiki for additional information.

When linking the module, the name of the shared object file must match the module name used in the SWIG interface file. If you used `%module example', then the target should be named `example.so', `example.sl', or the appropriate dynamic module name on your system.

19.2.3 Building a dynamic module with MakeMaker

It is also possible to use Perl to build dynamically loadable modules for you using the MakeMaker utility. To do this, write a Perl script such as the following :

# File : Makefile.PL
use ExtUtils::MakeMaker;
WriteMakefile(
	`NAME'    => `example',                  # Name of package
	`LIBS'    => [`-lm'],                    # Name of custom libraries
	`OBJECT'  => `example.o example_wrap.o'  # Object files
);

Now, to build a module, simply follow these steps :

% perl Makefile.PL
% make
% make install

If you are planning to distribute a SWIG-generated module, this is 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.

19.2.4 Building a static version of Perl

If you machine does not support dynamic loading or if you've tried to use it without success, you can build a new version of the Perl interpreter with your SWIG extensions added to it. To build a static extension, you first need to invoke SWIG as follows :

% swig -perl -static example.i

By default SWIG includes code for dynamic loading, but the -static option takes it out.

Next, you will need to supply a main() function that initializes your extension and starts the Perl interpreter. While, this may sound daunting, SWIG can do this for you automatically as follows :

%module example

extern double My_variable;
extern int fact(int);

// Include code for rebuilding Perl
%include perlmain.i

The same thing can be accomplished by running SWIG as follows :

% swig -perl -static -lperlmain.i example.i

The permain.i file inserts Perl's main() function into the wrapper code and automatically initializes the SWIG generated module. If you just want to make a quick a dirty module, this may be the easiest way. By default, the perlmain.i code does not initialize any other Perl extensions. If you need to use other packages, you will need to modify it appropriately. You can do this by just copying perlmain.i out of the SWIG library, placing it in your own directory, and modifying it to suit your purposes.

To build your new Perl executable, follow the exact same procedure as for a dynamic module, but change the link line to something like this:

% gcc example.o example_wrap.o -L/usr/lib/perl5/5.00503/i386-linux/CORE \
	-lperl -lsocket -lnsl -lm -o myperl

This will produce a new version of Perl called myperl. It should be functionality identical to Perl with your C/C++ extension added to it. Depending on your machine, you may need to link with additional libraries such as -lsocket, -lnsl, -ldl, etc.

19.2.5 Using the module

To use the module, simply use the Perl use statement. If all goes well, you will be able to do this:

$ perl
use example;
print example::fact(4),"\n";
24
A common error received by first-time users is the following:
use example;
Can't locate example.pm in @INC (@INC contains: /usr/lib/perl5/5.00503/i386-linux /usr/lib/perl5/5.00503 /usr/lib/perl5/site_perl/5.005/i386-linux /usr/lib/perl5/site_perl/5.005 .) at - line 1.
BEGIN failed--compilation aborted at - line 1.
This error is almost caused when the name of the shared object file you created doesn't match the module name you specified with the %module directive.

A somewhat related, but slightly different error is this:

use example;
Can't find 'boot_example' symbol in ./example.so
 at - line 1
BEGIN failed--compilation aborted at - line 1.
This error is generated because Perl can't locate the module bootstrap function in the SWIG extension module. This could be caused by a mismatch between the module name and the shared library name. However, another possible cause is forgetting to link the SWIG-generated wrapper code with the rest of your application when you linked the extension module.

Another common error is the following:

use example;
Can't load './example.so' for module example: ./example.so: 
undefined symbol: Foo at /usr/lib/perl5/5.00503/i386-linux/DynaLoader.pm line 169.

 at - line 1
BEGIN failed--compilation aborted at - line 1.
This error usually indicates that you forgot to include some object files or libraries in the linking of the shared library file. Make sure you compile both the SWIG wrapper file and your original program into a shared library file. Make sure you pass all of the required libraries to the linker.

Sometimes unresolved symbols occur because a wrapper has been created for a function that doesn't actually exist in a library. This usually occurs when a header file includes a declaration for a function that was never actually implemented or it was removed from a library without updating the header file. To fix this, you can either edit the SWIG input file to remove the offending declaration or you can use the %ignore directive to ignore the declaration. Better yet, update the header file so that it doesn't have an undefined declaration.

Finally, suppose that your extension module is linked with another library like this:

$ gcc -shared example.o example_wrap.o -L/home/beazley/projects/lib -lfoo \
      -o example.so
If the foo library is compiled as a shared library, you might get the following error when you try to use your module:
use example;
Can't load './example.so' for module example: libfoo.so: cannot open shared object file: 
No such file or directory at /usr/lib/perl5/5.00503/i386-linux/DynaLoader.pm line 169.

 at - line 1
BEGIN failed--compilation aborted at - line 1.
>>>                 
This error is generated because the dynamic linker can't locate the libfoo.so library. When shared libraries are loaded, the system normally only checks a few standard locations such as /usr/lib and /usr/local/lib. To get the loader to look in other locations, there are several things you can do. First, you can recompile your extension module with extra path information. For example, on Linux you can do this:
$ gcc -shared example.o example_wrap.o -L/home/beazley/projects/lib -lfoo \
      -Xlinker -rpath /home/beazley/projects/lib \
      -o example.so
Alternatively, you can set the LD_LIBRARY_PATH environment variable to include the directory with your shared libraries. If setting LD_LIBRARY_PATH, be aware that setting this variable can introduce a noticeable performance impact on all other applications that you run. To set it only for Perl, you might want to do this instead:
$ env LD_LIBRARY_PATH=/home/beazley/projects/lib perl
Finally, you can use a command such as ldconfig (Linux) or crle (Solaris) to add additional search paths to the default system configuration (this requires root access and you will need to read the man pages).

19.2.6 Compilation problems and compiling with C++

Compilation of C++ extensions has traditionally been a tricky problem. Since the Perl interpreter is written in C, you need to take steps to make sure C++ is properly initialized and that modules are compiled correctly.

On most machines, C++ extension modules should be linked using the C++ compiler. For example:

% swig -c++ -perl example.i
% g++ -c example.cxx
% g++ -c example_wrap.cxx -I/usr/lib/perl5/5.00503/i386-linux/CORE
% g++ -shared example.o example_wrap.o -o example.so
In addition to this, you may need to include additional library files to make it work. For example, if you are using the Sun C++ compiler on Solaris, you often need to add an extra library -lCrun like this:

% swig -c++ -perl example.i
% g++ -c example.cxx
% g++ -c example_wrap.cxx -I/usr/lib/perl5/5.00503/i386-linux/CORE
% g++ -shared example.o example_wrap.o -o example.so -lCrun
Of course, the names of the extra libraries are completely non-portable---you will probably need to do some experimentation.

Another possible compile problem comes from recent versions of Perl (5.8.0) and the GNU tools. If you see errors having to do with _crypt_struct, that means _GNU_SOURCE is not defined and it needs to be. So you should compile the wrapper like:

% g++ -c example_wrap.cxx -I/usr/lib/perl/5.8.0/CORE -D_GNU_SOURCE
-D_GNU_SOURCE is also included in the Perl ccflags, which can be found by running
% perl -e 'use Config; print $Config{ccflags};'
So you could also compile the wrapper like
% g++ -c example_wrap.cxx -I/usr/lib/perl/5.8.0/CORE `perl -e 'use Config; print $Config{ccflags}'`

Sometimes people have suggested that it is necessary to relink the Perl interpreter using the C++ compiler to make C++ extension modules work. In the experience of this author, this has never actually appeared to be necessary on most platforms. Relinking the interpreter with C++ really only includes the special run-time libraries described above---as long as you link your extension modules with these libraries, it should not be necessary to rebuild Perl.

If you aren't entirely sure about the linking of a C++ extension, you might look at an existing C++ program. On many Unix machines, the ldd command will list library dependencies. This should give you some clues about what you might have to include when you link your extension module. For example, notice the first line of output here:

$ ldd swig
        libstdc++-libc6.1-1.so.2 => /usr/lib/libstdc++-libc6.1-1.so.2 (0x40019000)
        libm.so.6 => /lib/libm.so.6 (0x4005b000)
        libc.so.6 => /lib/libc.so.6 (0x40077000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
$

If linking wasn't enough of a problem, another major complication of C++ is that it does not define any sort of standard for binary linking of libraries. This means that C++ code compiled by different compilers will not link together properly as libraries nor is the memory layout of classes and data structures implemented in any kind of portable manner. In a monolithic C++ program, this problem may be unnoticed. However, in Perl, it is possible for different extension modules to be compiled with different C++ compilers. As long as these modules are self-contained, this probably won't matter. However, if these modules start sharing data, you will need to take steps to avoid segmentation faults and other erratic program behavior. Also, be aware that certain C++ features, especially RTTI, can behave strangely when working with multiple modules.

It should be noted that you may get alot of error messages about the `bool' datatype when compiling a C++ Perl module. If you experience this problem, you can try the following :

  • Use -DHAS_BOOL when compiling the SWIG wrapper code
  • Or use -Dbool=char when compiling.

Finally, recent versions of Perl (5.8.0) have namespace conflict problems. Perl defines a bunch of short macros to make the Perl API function names shorter. For example, in /usr/lib/perl/5.8.0/CORE/embed.h there is a line:

#define do_open Perl_do_open
The problem is, in the <iostream> header from GNU libstdc++v3 there is a private function named do_open. If <iostream> is included after the perl headers, then the Perl macro causes the iostream do_open to be renamed, which causes compile errors. Hopefully in the future Perl will support a PERL_NO_SHORT_NAMES flag, but for now the only solution is to undef the macros that conflict. Lib/perl5/noembed.h in the SWIG source has a list of macros that are known to conflict with either standard headers or other headers. But if you get macro type conflicts from other macros not included in Lib/perl5/noembed.h while compiling the wrapper, you will have to find the macro that conflicts and add an #undef into the .i file. Please report any conflicting macros you find to swig@cs.uchicago.edu.

19.2.7 Compiling for 64-bit platforms

On platforms that support 64-bit applications (Solaris, Irix, etc.), special care is required when building extension modules. On these machines, 64-bit applications are compiled and linked using a different set of compiler/linker options. In addition, it is not generally possible to mix 32-bit and 64-bit code together in the same application.

To utilize 64-bits, the Perl executable will need to be recompiled as a 64-bit application. In addition, all libraries, wrapper code, and every other part of your application will need to be compiled for 64-bits. If you plan to use other third-party extension modules, they will also have to be recompiled as 64-bit extensions.

If you are wrapping commercial software for which you have no source code, you will be forced to use the same linking standard as used by that software. This may prevent the use of 64-bit extensions. It may also introduce problems on platforms that support more than one linking standard (e.g., -o32 and -n32 on Irix).

19.3 Building Perl Extensions under Windows

Building a SWIG extension to Perl under Windows is roughly similar to the process used with Unix. Normally, you will want to produce a DLL that can be loaded into the Perl interpreter. This section assumes you are using SWIG with Microsoft Visual C++ although the procedure may be similar with other compilers.

19.3.1 Running SWIG from Developer Studio

If you are developing your application within Microsoft developer studio, SWIG can be invoked as a custom build option. The process roughly requires these steps :

  • Open up a new workspace and use the AppWizard to select a DLL project.
  • Add both the SWIG interface file (the .i file), any supporting C files, and the name of the wrapper file that will be created by SWIG (ie. example_wrap.c). Note : If using C++, choose a different suffix for the wrapper file such as example_wrap.cxx. Don't worry if the wrapper file doesn't exist yet--Developer studio will keep a reference to it around.
  • Select the SWIG interface file and go to the settings menu. Under settings, select the "Custom Build" option.
  • Enter "SWIG" in the description field.
  • Enter "swig -perl5 -o $(ProjDir)\$(InputName)_wrap.cxx $(InputPath)" in the "Build command(s) field"
  • Enter "$(ProjDir)\$(InputName)_wrap.cxx" in the "Output files(s) field".
  • Next, select the settings for the entire project and go to "C++:Preprocessor". Add the include directories for your Perl 5 installation under "Additional include directories".
  • Define the symbols WIN32 and MSWIN32 under preprocessor options. If using the ActiveWare port, also define the symbol PERL_OBJECT. Note that all extensions to the ActiveWare port must be compiled with the C++ compiler since Perl has been encapsulated in a C++ class.
  • Finally, select the settings for the entire project and go to "Link Options". Add the Perl library file to your link libraries. For example "perl.lib". Also, set the name of the output file to match the name of your Perl module (ie. example.dll).
  • Build your project.

Now, assuming you made it this far, SWIG will be automatically invoked when you build your project. Any changes made to the interface file will result in SWIG being automatically invoked to produce a new version of the wrapper file. To run your new Perl extension, simply run Perl and use the use command as normal. For example :

DOS > perl
use example;
$a = example::fact(4);
print "$a\n";

19.3.2 Using other compilers

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.

19.4 The low-level interface

At its core, the Perl module uses a simple low-level interface to C function, variables, constants, and classes. This low-level interface 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.

19.4.1 Functions

C functions are converted into new Perl built-in commands (or subroutines). For example:

%module example
int fact(int a);
...

Now, in Perl:

use example;
$a = &example::fact(2);

19.4.2 Global variables

Global variables are handled using Perl's magic variable mechanism. SWIG generates a pair of functions that intercept read/write operations and attaches them to a Perl variable with the same name as the C global variable. Thus, an interface like this

%module example;
...
double Spam;
...

is accessed as follows :

use example;
print $example::Spam,"\n";
$example::Spam = $example::Spam + 4
# ... etc ...

If a variable is declared as const, it is wrapped as a read-only variable. Attempts to modify its value will result in an error.

To make ordinary variables read-only, you can also use the %immutable directive. For example:

%immutable;
extern char *path;
%mutable;
The %immutable directive stays in effect until it is explicitly disabled using %mutable. It is also possible to tag a specific variable as read-only like this:
%immutable path; 
...
...
extern char *path;       // Declared later in the input

19.4.3 Constants

Constants are wrapped as read-only Perl variables. For example:
%module example

#define FOO 42
In Perl:
use example;
print $example::FOO,"\n";    # OK
$example::FOO = 2;           # Error

19.4.4 Pointers

SWIG represents pointers as blessed references. A blessed reference is the same as a Perl reference except that it has additional information attached to it indicating what kind of reference it is. That is, if you have a C declaration like this :

Matrix *new_Matrix(int n, int m);

The module returns a value generated as follows:

$ptr = new_Matrix(int n, int m);     # Save pointer return result
bless $ptr, "p_Matrix";              # Bless it as a pointer to Matrix

SWIG uses the "blessing" to check the datatype of various pointers. In the event of a mismatch, an error or warning message is generated.

To check to see if a value is the NULL pointer, use the defined() command :

if (defined($ptr)) {
	print "Not a NULL pointer.";
} else {
	print "Is a NULL pointer.";
}

To create a NULL pointer, you should pass the undef value to a function.

The "value" of a Perl reference is not the same as the underlying C pointer that SWIG wrapper functions return. Suppose that $a and $b are two references that point to the same C object. In general, $a and $b will be different--since they are different references. Thus, it is a mistake to check the equality of $a and $b to check the equality of two C pointers. The correct method to check equality of C pointers is to dereference them as follows :

if ($$a == $$b) {
	print "a and b point to the same thing in C";
} else {
	print "a and b point to different objects.";
}

As much as you might be inclined to modify a pointer value directly from Perl, don't. Manipulating pointer values is architecture dependent and could cause your program to crash. Similarly, don't try to manually cast a pointer to a new type by reblessing a pointer. This may not work like you expect and it is particularly dangerous when casting C++ objects. If you need to cast a pointer or change its value, consider writing some helper functions instead. For example:
%inline %{
/* C-style cast */
Bar *FooToBar(Foo *f) {
   return (Bar *) f;
}

/* C++-style cast */
Foo *BarToFoo(Bar *b) {
   return dynamic_cast<Foo*>(b);
}

Foo *IncrFoo(Foo *f, int i) {
    return f+i;
}
%}
Also, if working with C++, you should always try to use the new C++ style casts. For example, in the above code, the C-style cast may return a bogus result whereas as the C++-style cast will return NULL if the conversion can't be performed.

Compatibility Note: In earlier versions, SWIG tried to preserve the same pointer naming conventions as XS and xsubpp. Given the advancement of the SWIG typesystem and the growing differences between SWIG and XS, this is no longer supported.

19.4.5 Structures

Access to the contents of a structure are provided through a set of low-level accessor functions as described in the "SWIG Basics" chapter. For example,

struct Vector {
	double x,y,z;
};

gets mapped into the following collection of accessor functions:

struct Vector *new_Vector();
void           delete_Vector(Vector *v);
double         Vector_x_get(Vector *obj)
void           Vector_x_set(Vector *obj, double x)
double         Vector_y_get(Vector *obj)
void           Vector_y_set(Vector *obj, double y)
double         Vector_z_get(Vector *obj)
void           Vector_z_set(Vector *obj, double z)

These functions are then used to access structure data from Perl as follows:

$v = example::new_Vector();
print example::Vector_x_get($v),"\n";    # Get x component
example::Vector_x_set($v,7.8);          # Change x component

Similar access is provided for unions and the data members of C++ classes.

const members of a structure are read-only. Data members can also be forced to be read-only using the %immutable directive. For example:

struct Foo {
   ...
   %immutable;
   int x;        /* Read-only members */
   char *name;
   %mutable;
   ...
};

When char * members of a structure are wrapped, the contents are assumed to be dynamically allocated using malloc or new (depending on whether or not SWIG is run with the -c++ option). When the structure member is set, the old contents will be released and a new value created. If this is not the behavior you want, you will have to use a typemap (described later).

Array members are normally wrapped as read-only. For example,

struct Foo {
   int  x[50];
};
produces a single accessor function like this:
int *Foo_x_get(Foo *self) {
    return self->x;
};
If you want to set an array member, you will need to supply a "memberin" typemap described later in this chapter. As a special case, SWIG does generate code to set array members of type char (allowing you to store a Python string in the structure).

When structure members are wrapped, they are handled as pointers. For example,

struct Foo {
   ...
};

struct Bar {
   Foo f;
};
generates accessor functions such as this:
Foo *Bar_f_get(Bar *b) {
    return &b->f;
}

void Bar_f_set(Bar *b, Foo *val) {
    b->f = *val;
}

19.4.6 C++ classes

C++ classes are wrapped by building a set of low level accessor functions. Consider the following class :

class List {
public:
  List();
  ~List();
  int  search(char *item);
  void insert(char *item);
  void remove(char *item);
  char *get(int n);
  int  length;
static void print(List *l);
};

When wrapped by SWIG, the following functions are created :

List    *new_List();
void     delete_List(List *l);
int      List_search(List *l, char *item);
void     List_insert(List *l, char *item);
void     List_remove(List *l, char *item);
char    *List_get(List *l, int n);
int      List_length_get(List *l);
void     List_length_set(List *l, int n);
void     List_print(List *l);

In Perl, these functions are used in a straightforward manner:
use example;
$l = example::new_List();
example::List_insert($l,"Ale");
example::List_insert($l,"Stout");
example::List_insert($l,"Lager")
example::List_print($l)
Lager
Stout
Ale
print example::List_length_get($l),"\n";
3
At this low level, C++ objects are really just typed pointers. Member functions are accessed by calling a C-like wrapper with an instance pointer as the first argument. Although this interface is fairly primitive, it provides direct access to C++ objects. A higher level interface using Perl proxy classes can be built using these low-level accessors. This is described shortly.

19.4.7 C++ classes and type-checking

The SWIG type-checker is fully aware of C++ inheritance. Therefore, if you have classes like this
class Foo {
...
};

class Bar : public Foo {
...
};
and a function
void spam(Foo *f);
then the function spam() accepts Foo * or a pointer to any class derived from Foo. If necesssary, the type-checker also adjusts the value of the pointer (as is necessary when multiple inheritance is used).

19.4.8 C++ overloaded functions

If you have a C++ program with overloaded functions or methods, you will need to disambiguate those methods using %rename. For example:
/* Forward renaming declarations */
%rename(foo_i) foo(int); 
%rename(foo_d) foo(double);
...
void foo(int);           // Becomes 'foo_i'
void foo(char *c);       // Stays 'foo' (not renamed)

class Spam {
public:
   void foo(int);      // Becomes 'foo_i'
   void foo(double);   // Becomes 'foo_d'
   ...
};
Now, in Perl, the methods are accessed as follows:
use example;
example::foo_i(3);
$s = example::new_Spam();
example::Spam_foo_i($s,3);
example::Spam_foo_d($s,3.14);
Please refer to the "SWIG Basics" chapter for more information.

19.4.9 Operators

C++ operators can also be wrapped using the %rename directive. All you need to do is give the operator the name of a valid Perl identifier. For example:
%rename(add_complex) operator+(Complex &, Complex &);
...
Complex operator+(Complex &, Complex &);
Now, in Perl, you can do this:
use example;
$a = example::new_Complex(2,3);
$b = example::new_Complex(4,-1);
$c = example::add_complex($a,$b);
Some preliminary work on mapping C++ operators into Perl operators has been completed. This is covered later.

19.4.10 Modules and packages

When you create a SWIG extension, everything gets placed into a single Perl module. The name of the module is determined by the %module directive. To use the module, do the following :

% perl5
use example;                      # load the example module
print example::fact(4),"\n"       # Call a function in it
24

Usually, a module consists of a collection of code that is contained within a single file. A package, on the other hand, is the Perl equivalent of a namespace. A package is alot like a module, except that it is independent of files. Any number of files may be part of the same package--or a package may be broken up into a collection of modules if you prefer to think about it in this way.

SWIG installs its functions into a package with the same name as the module.

Incompatible Change: previous versions of SWIG enabled you to change the name of the package by using the -package option, this feature has been removed in order to properly support modules that used nested namespaces, e.g. Foo::Bar::Baz. To give your module a nested namespace simply provide the fully qualified name in your %module directive:

%module "Foo::Bar::Baz"

NOTE: the double quotes are necessary.

19.5 Input and output parameters

A common problem in some C programs is handling parameters passed as simple pointers. For example:
void add(int x, int y, int *result) {
   *result = x + y;
}
or perhaps
int sub(int *x, int *y) {
   return *x+*y;
}
The easiest way to handle these situations is to use the typemaps.i file. For example:
%module example
%include "typemaps.i"

void add(int, int, int *OUTPUT);
int  sub(int *INPUT, int *INPUT);
In Perl, this allows you to pass simple values. For example:
$a = example::add(3,4);
print "$a\n";
7
$b = example::sub(7,4);
print "$b\n";
3
Notice how the INPUT parameters allow integer values to be passed instead of pointers and how the OUTPUT parameter creates a return result.

If you don't want to use the names INPUT or OUTPUT, use the %apply directive. For example:

%module example
%include "typemaps.i"

%apply int *OUTPUT { int *result };
%apply int *INPUT  { int *x, int *y};

void add(int x, int y, int *result);
int  sub(int *x, int *y);

If a function mutates one of its parameters like this,

void negate(int *x) {
   *x = -(*x);
}
you can use INOUT like this:
%include "typemaps.i"
...
void negate(int *INOUT);
In Perl, a mutated parameter shows up as a return value. For example:
$a = example::negate(3);
print "$a\n";
-3

The most common use of these special typemap rules is to handle functions that return more than one value. For example, sometimes a function returns a result as well as a special error code:

/* send message, return number of bytes sent, along with success code */
int send_message(char *text, int len, int *success);
To wrap such a function, simply use the OUTPUT rule above. For example:
%module example
%include "typemaps.i"
%apply int *OUTPUT { int *success };
...
int send_message(char *text, int *success);
When used in Perl, the function will return multiple values.
($bytes, $success) = example::send_message("Hello World");
Another common use of multiple return values are in query functions. For example:
void get_dimensions(Matrix *m, int *rows, int *columns);
To wrap this, you might use the following:
%module example
%include "typemaps.i"
%apply int *OUTPUT { int *rows, int *columns };
...
void get_dimensions(Matrix *m, int *rows, *columns);
Now, in Perl:
($r,$c) = example::get_dimensions($m);
In certain cases, it is possible to treat Perl references as C pointers. To do this, use the REFERENCE typemap. For example:
%module example
%include typemaps.i

void add(int x, int y, int *REFERENCE);
In Perl:
use example;
$c = 0.0;
example::add(3,4,\$c);
print "$c\n";
7
Note: The REFERENCE feature is only currently supported for numeric types (integers and floating point).

19.6 Exception handling

The SWIG %exception directive can be used to create a user-definable exception handler for converting exceptions in your C/C++ program into Perl exceptions. The chapter on customization features contains more details, but suppose you have a C++ class like the following :

class RangeError {};   // Used for an exception

class DoubleArray {
  private:
    int n;
    double *ptr;
  public:
    // Create a new array of fixed size
    DoubleArray(int size) {
      ptr = new double[size];
      n = size;
    }
    // Destroy an array
    ~DoubleArray() {
       delete ptr;
    }
    // Return the length of the array
    int   length() {
      return n;
    }

    // Get an item from the array and perform bounds checking.
    double getitem(int i) {
      if ((i >= 0) && (i < n))
        return ptr[i];
      else
        throw RangeError();
    }

    // Set an item in the array and perform bounds checking.
    void setitem(int i, double val) {
      if ((i >= 0) && (i < n))
        ptr[i] = val;
      else {
        throw RangeError();
      }
    }
  };
Since several methods in this class can throw an exception for an out-of-bounds access, you might want to catch this in the Perl extension by writing the following in an interface file:

%exception {
  try {
    $action
  }
  catch (RangeError) {
    croak("Array index out-of-bounds");
  }
}

class DoubleArray {
...
};
The exception handling code is inserted directly into generated wrapper functions. The $action variable is replaced with the C/C++ code being executed by the wrapper. When an exception handler is defined, errors can be caught and used to gracefully generate a Perl error instead of forcing the entire program to terminate with an uncaught error.

As shown, the exception handling code will be added to every wrapper function. Since this is somewhat inefficient. You might consider refining the exception handler to only apply to specific methods like this:

%exception getitem {
  try {
    $action
  }
  catch (RangeError) {
    croak("Array index out-of-bounds");
  }
}

%exception setitem {
  try {
    $action
  }
  catch (RangeError) {
    croak("Array index out-of-bounds");
  }
}
In this case, the exception handler is only attached to methods and functions named getitem and setitem.

If you had a lot of different methods, you can avoid extra typing by using a macro. For example:

%define RANGE_ERROR
{
  try {
    $action
  }
  catch (RangeError) {
    croak("Array index out-of-bounds");
  }
}
%enddef

%exception getitem RANGE_ERROR;
%exception setitem RANGE_ERROR;
Since SWIG's exception handling is user-definable, you are not limited to C++ exception handling. See the chapter on "Customization features" for more examples.

Compatibility note: In SWIG1.1, exceptions were defined using the older %except directive:

%except(python) {
  try {
    $function
  }
  catch (RangeError) {
    croak("Array index out-of-bounds");
  }
}
This is still supported, but it is deprecated. The newer %exception directive provides the same functionality, but it has additional capabilities that make it more powerful.

19.7 Remapping datatypes with 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 Perl C API as well as the material in the "Typemaps" chapter.

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 primitive C-Perl interface.

19.7.1 A simple typemap example

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

%module example

%typemap(in) int {
	$1 = (int) SvIV($input);
	printf("Received an integer : %d\n", $1);
}
...
extern int fact(int n);

Typemaps are always associated with some specific aspect of code generation. In this case, the "in" method refers to the conversion of input arguments to C/C++. The datatype int is the datatype to which the typemap will be applied. The supplied C code is used to convert values. In this code a number of special variable prefaced by a $ are used. The $1 variable is placeholder for a local variable of type int. The $input variable is the input object (usually a SV *).

When this example is used in Perl5, it will operate as follows :

use example;
$n = example::fact(6);
print "$n\n";
...

Output :
Received an integer : 6
720

The application of a typemap to specific datatypes and argument names involves more than simple text-matching--typemaps are fully integrated into the SWIG type-system. When you define a typemap for int, that typemap applies to int and qualified variations such as const int. In addition, the typemap system follows typedef declarations. For example:

%typemap(in) int n {
	$1 = (int) SvIV($input);
	printf("n = %d\n",$1);
}
typedef int Integer;
extern int fact(Integer n);    // Above typemap is applied
It should be noted that the matching of typedef only occurs in one direction. If you defined a typemap for Integer, it is not applied to arguments of type int.

Typemaps can also be defined for groups of consecutive arguments. For example:

%typemap(in) (char *str, unsigned len) {
    $1 = SvPV($input,$2);
};

int count(char c, char *str, unsigned len);
When a multi-argument typemap is defined, the arguments are always handled as a single Perl object. This allows the function to be used like this (notice how the length parameter is ommitted):
example::count("e","Hello World");
1
>>>

19.7.2 Perl5 typemaps

The previous section illustrated an "in" typemap for converting Perl objects to C. A variety of different typemap methods are defined by the Perl module. For example, to convert a C integer back into a Perl object, you might define an "out" typemap like this:
%typemap(out) int {
    $result = sv_newmortal();
    set_setiv($result, (IV) $1);
    argvi++;
}
The following typemap methods are available:

%typemap(in)

Converts Perl5 object to input function arguments.

%typemap(out)

Converts function return value to a Perl5 value.

%typemap(varin)

Converts a Perl5 object to a global variable.

%typemap(varout)

Converts a global variable to a Perl5 object.

%typemap(freearg)

Cleans up a function argument after a function call

%typemap(argout)

Output argument handling

%typemap(ret)

Clean up return value from a function.

%typemap(memberin)

Setting of C++ member data (all languages).

%typemap(memberout)

Return of C++ member data (all languages).

%typemap(check)

Check value of input parameter.

19.7.3 Typemap variables

Within typemap code, a number of special variables prefaced with a $ may appear. A full list of variables can be found in the "Typemaps" chapter. This is a list of the most common variables:

$1

A C local variable corresponding to the actual type specified in the %typemap directive. For input values, this is a C local variable that's supposed to hold an argument value. For output values, this is the raw result that's supposed to be returned to Perl.

$input

A Perl object holding the value of an argument of variable value.

$result

A Perl object that holds the result to be returned to Perl.

$1_name

The parameter name that was matched.

$1_type

The actual C datatype matched by the typemap.

$1_ltype

An assignable version of the datatype matched by the typemap (a type that can appear on the left-hand-side of a C assignment operation). This type is stripped of qualifiers and may be an altered version of $1_type. All arguments and local variables in wrapper functions are declared using this type so that their values can be properly assigned.
$symname
The Perl name of the wrapper function being created.

19.7.4 Useful functions

When writing typemaps, it is necessary to work directly with Perl5 objects. This, unfortunately, can be a daunting task. Consult the "perlguts" man-page for all of the really ugly details. A short summary of commonly used functions is provided here for reference. It should be stressed that SWIG can be usef quite effectively without knowing any of these details--especially now that there are typemap libraries that can already been written.

Perl Integer Functions

int   SvIV(SV *);
void  sv_setiv(SV *sv, IV value);
SV   *newSViv(IV value);
int   SvIOK(SV *);
Perl Floating Point Functions
double SvNV(SV *);
void   sv_setnv(SV *, double value);
SV    *newSVnv(double value);
int    SvNOK(SV *);
Perl String Functions
char     *SvPV(SV *, STRLEN len);
void      sv_setpv(SV *, char *val);
void      sv_setpvn(SV *, char *val, STRLEN len);
SV       *newSVpv(char *value, STRLEN len);
int       SvPOK(SV *);
void      sv_catpv(SV *, char *);
void      sv_catpvn(SV *, char *, STRLEN);
Perl References
void      sv_setref_pv(SV *, char *, void *ptr);
int       sv_isobject(SV *);
SV       *SvRV(SV *);
int       sv_isa(SV *, char *0;

19.8 Typemap Examples

This section includes a few examples of typemaps. For more examples, you might look at the files "perl5.swg" and "typemaps.i" in the SWIG library.

19.8.1 Converting a Perl5 array to a char **

A common problem in many C programs is the processing of command line arguments, which are usually passed in an array of NULL terminated strings. The following SWIG interface file allows a Perl5 array reference to be used as a char ** datatype.

%module argv

// This tells SWIG to treat char ** as a special case
%typemap(in) char ** {
	AV *tempav;
	I32 len;
	int i;
	SV  **tv;
	if (!SvROK($input))
	    croak("Argument $argnum is not a reference.");
        if (SvTYPE(SvRV($input)) != SVt_PVAV)
	    croak("Argument $argnum is not an array.");
        tempav = (AV*)SvRV($input);
	len = av_len(tempav);
	$1 = (char **) malloc((len+2)*sizeof(char *));
	for (i = 0; i <= len; i++) {
	    tv = av_fetch(tempav, i, 0);	
	    $1[i] = (char *) SvPV(*tv,PL_na);
        }
	$1[i] = NULL;
};

// This cleans up the char ** array after the function call
%typemap(freearg) char ** {
	free($1);
}

// Creates a new Perl array and places a NULL-terminated char ** into it
%typemap(out) char ** {
	AV *myav;
	SV **svs;
	int i = 0,len = 0;
	/* Figure out how many elements we have */
	while ($1[len])
	   len++;
	svs = (SV **) malloc(len*sizeof(SV *));
	for (i = 0; i < len ; i++) {
	    svs[i] = sv_newmortal();
	    sv_setpv((SV*)svs[i],$1[i]);
	};
	myav =	av_make(len,svs);
	free(svs);
        $result = newRV((SV*)myav);
        sv_2mortal($result);
        argvi++;
}

// Now a few test functions
%inline %{
int print_args(char **argv) {
    int i = 0;
    while (argv[i]) {
         printf("argv[%d] = %s\n", i,argv[i]);
         i++;
    }
    return i;
}

// Returns a char ** list 
char **get_args() {
    static char *values[] = { "Dave", "Mike", "Susan", "John", "Michelle", 0};
    return &values[0];
}
%}

When this module is compiled, the wrapped C functions can be used in a Perl script as follows :

use argv;
@a = ("Dave", "Mike", "John", "Mary");           # Create an array of strings
argv::print_args(\@a);                           # Pass it to our C function
$b = argv::get_args();                           # Get array of strings from C
print @$b,"\n";                                  # Print it out

19.8.2 Return values

Return values are placed on the argument stack of each wrapper function. The current value of the argument stack pointer is contained in a variable argvi. Whenever a new output value is added, it is critical that this value be incremented. For multiple output values, the final value of argvi should be the total number of output values.

The total number of return values should not exceed the number of input values unless you explicitly extend the argument stack. This can be done using the EXTEND() macro as in :

%typemap(argout) int *OUTPUT {
	if (argvi >= items) {            
		EXTEND(sp,1);              /* Extend the stack by 1 object */
	}
	$result = sv_newmortal();
	sv_setiv($target,(IV) *($1));
	argvi++;
}

19.8.3 Returning values from arguments

Sometimes it is desirable for a function to return a value in one of its arguments. This example describes the implementation of the OUTPUT typemap.

%module return

// This tells SWIG to treat an double * argument with name 'OutDouble' as
// an output value.  

%typemap(argout) double *OUTPUT {
	$result = sv_newmortal();
	sv_setnv($result, *$input);
	argvi++;                     /* Increment return count -- important! */
}

// We don't care what the input value is. Ignore, but set to a temporary variable

%typemap(in,numinputs=0) double *OUTPUT(double junk) {
	$1 = &junk;
}

// Now a function to test it
%{
/* Returns the first two input arguments */
int multout(double a, double b, double *out1, double *out2) {
	*out1 = a;
	*out2 = b;
	return 0;
};
%}

// If we name both parameters OutDouble both will be output

int multout(double a, double b, double *OUTPUT, double *OUTPUT);
...

When this function is called, the output arguments are appended to the stack used to return results. This shows up an array in Perl. For example :

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

19.8.4 Accessing array structure members

Consider the following data structure :

#define SIZE  8
typedef struct {
    int   values[SIZE];
    ...
} Foo;

By default, SWIG doesn't know how to the handle the values structure member it's an array, not a pointer. In this case, SWIG makes the array member read-only. Reading will simply return a pointer to the first item in the array. To make the member writable, a "memberin" typemap can be used.

%typemap(memberin) int [SIZE] {
    int i;
    for (i = 0; i < SIZE; i++) {
        $1[i] = $input[i];
    }
}

Whenever a int [SIZE] member is encountered in a structure or class, this typemap provides a safe mechanism for setting its value.

As in the previous example, the typemap can be generalized for any dimension. For example:

%typemap(memberin) int [ANY] {
   int i;
   for (i = 0; i < $1_dim0; i++) {
      $1[i] = $input[i];
   }
}
When setting structure members, the input object is always assumed to be a C array of values that have already been converted from the target language. Because of this, the memberin typemap is almost always combined with the use of an "in" typemap. For example, the "in" typemap in the previous section would be used to convert an int[] array to C whereas the "memberin" typemap would be used to copy the converted array into a C data structure.

19.8.5 Turning Perl references into C pointers

A frequent confusion on the SWIG mailing list is errors caused by the mixing of Perl references and C pointers. For example, suppose you have a C function that modifies its arguments like this :

void add(double a, double b, double *c) {
	*c = a + b;
}

A common misinterpretation of this function is the following Perl script :

# Perl script
$a = 3.5;
$b = 7.5;
$c = 0.0;          # Output value
add($a,$b,\$c);    # Place result in c (Except that it doesn't work)

To make this work with a reference, you can use a typemap such as this:

%typemap(in) double * (double dvalue) {
  SV* tempsv;
  if (!SvROK($input)) {
    croak("expected a reference\n");
  }
  tempsv = SvRV($input);
  if ((!SvNOK(tempsv)) && (!SvIOK(tempsv))) {
    croak("expected a double reference\n");
  }
  dvalue = SvNV(tempsv);
  $1 = &dvalue;
}

%typemap(argout) double * {
  SV *tempsv;
  tempsv = SvRV($input);
  sv_setnv(tempsv, *$input);
}

Now, if you place this before the add function, you can do this :

$a = 3.5;
$b = 7.5;
$c = 0.0;
add($a,$b,\$c);            # Now it works!
print "$c\n";

19.8.6 Pointer handling

Occasionally, it might be necessary to convert pointer values that have been stored using the SWIG typed-pointer representation. To convert a pointer from Perl to C, the following function is used:

int SWIG_ConvertPtr(SV *obj, void **ptr, swig_type_info *ty, int flags)

Converts a Perl object obj to a C pointer. The result of the conversion is placed into the pointer located at ptr. ty is a SWIG type descriptor structure. flags is used to handle error checking and other aspects of conversion. flags is currently undefined and reserved for future expansion. Returns 0 on success and -1 on error.

void *SWIG_MakePtr(SV *obj, void *ptr, swig_type_info *ty, int flags)

Creates a new Perl pointer object. obj is a Perl SV that has been initialized to hold the result, ptrty is the SWIG type descriptor structure that describes the type, and flags is a flag that controls properties of the conversion. flags is currently undefined and reserved.
Both of these functions require the use of a special SWIG type-descriptor structure. This structure contains information about the mangled name of the datatype, type-equivalence information, as well as information about converting pointer values under C++ inheritance. For a type of Foo *, the type descriptor structure is usually accessed as follows:
Foo *f;
if (SWIG_ConvertPtr($input, (void **) &f, SWIGTYPE_p_Foo, 0) == -1) return NULL;

SV *sv = sv_newmortal();
SWIG_MakePtr(sv, f, SWIGTYPE_p_Foo, 0);
In a typemap, the type descriptor should always be accessed using the special typemap variable $1_descriptor. For example:
%typemap(in) Foo * {
   if ((SWIG_ConvertPtr($input,(void **) &$1, $1_descriptor,0)) == -1) return NULL;
}
If necessary, the descriptor for any type can be obtained using the $descriptor() macro in a typemap. For example:
%typemap(in) Foo * {
   if ((SWIG_ConvertPtr($input,(void **) &$1, $descriptor(Foo *), 0)) == -1) return NULL;
}

19.9 Proxy classes

Out of date. Needs update.

Using the low-level procedural interface, SWIG can also construct a high-level object oriented interface to C structures and C++ classes. This is done by constructing a Perl proxy class that provides an OO wrapper to the underlying code. This section describes the implementation details of the proxy interface.

19.9.1 Preliminaries

To generate proxy classes, you need to use the -proxy command line option. For example:
$ swig -c++ -perl -proxy example.i
When proxy classes are used, SWIG moves all of the low-level procedural wrappers to another package name. By default, this package is named 'modulec' where 'module' is the name of the module you provided with the %module directive. Then, in place of the original module, SWIG creates a collection of high-level Perl wrappers. In your scripts, you will use these high level wrappers. The wrappers, in turn, interact with the low-level procedural module.

Structure and class wrappers

Suppose you have the following SWIG interface file :

%module example
struct Vector {
	Vector(double x, double y, double z);
	~Vector();
	double x,y,z;
};

When wrapped, SWIG creates the following set of low-level accessor functions as described in previous sections.

Vector *new_Vector(double x, double y, double z);
void    delete_Vector(Vector *v);
double  Vector_x_get(Vector *v);
double  Vector_x_set(Vector *v, double value);
double  Vector_y_get(Vector *v);
double  Vector_y_set(Vector *v, double value);
double  Vector_z_get(Vector *v);
double  Vector_z_set(Vector *v, double value);

However, when proxy classes are enabled, these accessor functions are wrapped inside a Perl class like this:

package example::Vector;
@ISA = qw( example );
%OWNER = ();
%BLESSEDMEMBERS = ();

sub new () {
    my $self = shift;
    my @args = @_;
    $self = vectorc::new_Vector(@args);
    return undef if (!defined($self));
    bless $self, "example::Vector";
    $OWNER{$self} = 1;
    my %retval;
    tie %retval, "example::Vector", $self;
    return bless \%retval,"Vector";
}

sub DESTROY {
    return unless $_[0]->isa('HASH');
    my $self = tied(%{$_[0]});
    delete $ITERATORS{$self};
    if (exists $OWNER{$self}) {
	 examplec::delete_Vector($self));
	 delete $OWNER{$self};
}

sub FETCH {
    my ($self,$field) = @_;
    my $member_func = "vectorc::Vector_${field}_get";
    my $val = &$member_func($self);
    if (exists $BLESSEDMEMBERS{$field}) {
        return undef if (!defined($val));
        my %retval;
        tie %retval,$BLESSEDMEMBERS{$field},$val;
        return bless \%retval, $BLESSEDMEMBERS{$field};
    }
    return $val;
}

sub STORE {
    my ($self,$field,$newval) = @_;
    my $member_func = "vectorc::Vector_${field}_set";
    if (exists $BLESSEDMEMBERS{$field}) {
        &$member_func($self,tied(%{$newval}));
    } else {
        &$member_func($self,$newval);
    }
}

Each structure or class is mapped into a Perl package of the same name. The C++ constructors and destructors are mapped into constructors and destructors for the package and are always named "new" and "DESTROY". The constructor always returns a tied hash table. This hash table is used to access the member variables of a structure in addition to being able to invoke member functions. The %OWNER and %BLESSEDMEMBERS hash tables are used internally and described shortly.

To use our new shadow class we can simply do the following:

# Perl code using Vector class
$v = new Vector(2,3,4);
$w = Vector->new(-1,-2,-3);

# Assignment of a single member
$v->{x} = 7.5;

# Assignment of all members
%$v = ( x=>3,
	 y=>9,
	 z=>-2);

# Reading members
$x = $v->{x};

# Destruction
$v->DESTROY();

19.9.2 Object Ownership

In order for shadow classes to work properly, it is necessary for Perl to manage some mechanism of object ownership. Here's the crux of the problem---suppose you had a function like this :

Vector *Vector_get(Vector *v, int index) {
	return &v[i];
}

This function takes a Vector pointer and returns a pointer to another Vector. Such a function might be used to manage arrays or lists of vectors (in C). Now contrast this function with the constructor for a Vector object :

Vector *new_Vector(double x, double y, double z) {
	Vector *v;
	v = new Vector(x,y,z);        // Call C++ constructor
	return v;
}

Both functions return a Vector, but the constructor is returning a brand-new Vector while the other function is returning a Vector that was already created (hopefully). In Perl, both vectors will be indistinguishable---clearly a problem considering that we would probably like the newly created Vector to be destroyed when we are done with it.

To manage these problems, each class contains two methods that access an internal hash table called %OWNER. This hash keeps a list of all of the objects that Perl knows that it has created. This happens in two cases: (1) when the constructor has been called, and (2) when a function implicitly creates a new object (as is done when SWIG needs to return a complex datatype by value). When the destructor is invoked, the Perl shadow class module checks the %OWNER hash to see if Perl created the object. If so, the C/C++ destructor is invoked. If not, we simply destroy the Perl object and leave the underlying C object alone (under the assumption that someone else must have created it).

This scheme works remarkably well in practice but it isn't foolproof. In fact, it will fail if you create a new C object in Perl, pass it on to a C function that remembers the object, and then destroy the corresponding Perl object (this situation turns out to come up frequently when constructing objects like linked lists and trees). When C takes possession of an object, you can change Perl's owership by simply deleting the object from the %OWNER hash. This is done using the DISOWN method.

# Perl code to change ownership of an object
$v = new Vector(x,y,z);
$v->DISOWN();     

To acquire ownership of an object, the ACQUIRE method can be used.

# Given Perl ownership of a file
$u = Vector_get($v);
$u->ACQUIRE();

As always, a little care is in order. SWIG does not provide reference counting, garbage collection, or advanced features one might find in sophisticated languages.

19.9.3 Nested Objects

Suppose that we have a new object that looks like this :

struct Particle {
	Vector r;
	Vector v;
	Vector f;
	int	type;
}

In this case, the members of the structure are complex objects that have already been encapsulated in a Perl shadow class. To handle these correctly, we use the %BLESSEDMEMBERS hash which would look like this (along with some supporting code) :

package Particle;
...
%BLESSEDMEMBERS = (
	r => `Vector',
	v => `Vector',
	f => `Vector',
);

When fetching members from the structure, %BLESSEDMEMBERS is checked. If the requested field is present, we create a tied-hash table and return it. If not, we just return the corresponding member unmodified.

This implementation allows us to operate on nested structures as follows :

# Perl access of nested structure
$p = new Particle();
$p->{f}->{x} = 0.0;
%${$p->{v}} = ( x=>0, y=>0, z=>0);         

19.9.4 Shadow Functions

When functions take arguments involving a complex object, it is sometimes necessary to write a shadow function. For example :

double dot_product(Vector *v1, Vector *v2);

Since Vector is an object already wrapped into a shadow class, we need to modify this function to accept arguments that are given in the form of tied hash tables. This is done by creating a Perl function like this :

sub dot_product {
    my @args = @_;
    $args[0] = tied(%{$args[0]});         # Get the real pointer values
    $args[1] = tied(%{$args[1]});
    my $result = vectorc::dot_product(@args);
    return $result;
}

This function replaces the original function, but operates in an identical manner.

19.9.5 Inheritance

Simple C++ inheritance is handled using the Perl @ISA array in each class package. For example, if you have the following interface file :

// shapes.i
// SWIG interface file for shapes class
%module shapes
%{
#include "shapes.h"
%}

class Shape {
public:
	virtual double area() = 0;
	virtual double perimeter() = 0;
	void    set_location(double x, double y);
};
class Circle : public Shape {
public:
	Circle(double radius);
	~Circle();
	double area();
	double perimeter();
};
class Square : public Shape {
public:
	Square(double size);
	~Square();
	double area();
	double perimeter();
}

The resulting, Perl wrapper class will create the following code :

Package Shape;
@ISA = (shapes);
...
Package Circle;
@ISA = (shapes Shape);
...
Package Square;
@ISA = (shapes Shape);

The @ISA array determines where to look for methods of a particular class. In this case, both the Circle and Square classes inherit functions from Shape so we'll want to look in the Shape base class for them. All classes also inherit from the top-level module shapes. This is because certain common operations needed to implement shadow classes are implemented only once and reused in the wrapper code for various classes and structures.

Since SWIG shadow classes are implemented in Perl, it is easy to subclass from any SWIG generated class. To do this, simply put the name of a SWIG class in the @ISA array for your new class. However, be forewarned that this is not a trivial problem. In particular, inheritance of data members is extremely tricky (and I'm not even sure if it really works).


SWIG 1.3 - Last Modified : Feb 13, 2003
cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/Preprocessor.html0000644000175000000620000002254712561312226023105 0ustar stevestaff SWIG Preprocessor

6 Preprocessing

SWIG includes its own enhanced version of the C preprocessor. The preprocessor supports the standard preprocessor directives and macro expansion rules. However, a number of modifications and enhancements have been made. This chapter describes some of these modifications.

6.1 File inclusion

To include another file into a SWIG interface, use the %include directive like this:
%include "pointer.i"
Unlike, #include, %include includes each file once (and will not reload the file on subsequent %include declarations). Therefore, it is not necessary to use include-guards in SWIG interfaces.

By default, the #include is ignored unless you run SWIG with the -includeall option. The reason for ignoring traditional includes is that you often don't want SWIG to try and wrap everything included in standard header system headers and auxilliary files.

6.2 File imports

SWIG provides another file inclusion directive with the %import directive. For example:
%import "foo.i"
The purpose of %import is to collect certain information from another SWIG interface file or a header file without actually generating any wrapper code. Such information generally includes type declarations (e.g., typedef) as well as 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 advanced topic and is described in a later chapter.

The -importall directive tells SWIG to follow all #include statements as imports. This might be useful if you want to extract type definitions from system header files without generating any wrappers.

6.3 Conditional Compilation

SWIG fully supports the use of #if, #ifdef, #ifndef, #else, #endif to conditionally include parts of an interface. The following symbols are predefined by SWIG when it is parsing the interface:

SWIG                            Always defined when SWIG is processing a file
SWIGMAC                         Defined when running SWIG on the Macintosh
SWIGWIN                         Defined when running SWIG under Windows

SWIGCHICKEN                     Defined when using CHICKEN
SWIGCSHARP                      Defined when using C#
SWIGGUILE                       Defined when using Guile
SWIGJAVA                        Defined when using Java
SWIGMZSCHEME                    Defined when using Mzscheme        
SWIGOCAML                       Defined when using Ocaml
SWIGPERL                        Defined when using Perl
SWIGPERL5                       Defined when using Perl5
SWIGPHP                         Defined when using PHP
SWIGPHP4                        Defined when using PHP4
SWIGPYTHON                      Defined when using Python
SWIGRUBY                        Defined when using Ruby
SWIGSEXP                        Defined when using S-expressions
SWIGTCL                         Defined when using Tcl
SWIGTCL8                        Defined when using Tcl8.0
SWIGXML                         Defined when using XML
In addition, SWIG defines the following set of standard C/C++ macros:
__LINE__                        Current line number
__FILE__                        Current file name
__STDC__                        Defined to indicate ANSI C
__cplusplus                     Defined when -c++ option used
Interface files can look at these symbols as necessary to change the way in which an interface is generated or to mix SWIG directives with C code. These symbols are also defined within the C code generated by SWIG (except for the symbol `SWIG' which is only defined within the SWIG compiler).

6.4 Macro Expansion

Traditional preprocessor macros can be used in SWIG interfaces. Be aware that the #define statement is also used to try and detect constants. Therefore, if you have something like this in your file,
#ifndef _FOO_H 1
#define _FOO_H 1
...
#endif
you may get some extra constants such as _FOO_H showing up in the scripting interface.

More complex macros can be defined in the standard way. For example:

#define EXTERN extern
#ifdef __STDC__
#define _ANSI(args)   (args)
#else
#define _ANSI(args) ()
#endif
The following operators can appear in macro definitions:
  • #x
    Converts macro argument x to a string surrounded by double quotes ("x").

  • x ## y
    Concatenates x and y together to form xy.

  • `x`
    If x is a string surrounded by double quotes, do nothing. Otherwise, turn into a string like #x. This is a non-standard SWIG extension.

6.5 SWIG Macros

SWIG provides an enhanced macro capability with the %define and %enddef directives. For example:
%define ARRAYHELPER(type,name)
%inline %{
type *new_ ## name (int nitems) {
   return (type *) malloc(sizeof(type)*nitems);
}
void delete_ ## name(type *t) {
   free(t);
}
type name ## _get(type *t, int index) {
   return t[index];
}
void name ## _set(type *t, int index, type val) {
   t[index] = val;
}
%}
%enddef

ARRAYHELPER(int, IntArray)
ARRAYHELPER(double, DoubleArray)
The primary purpose of %define is to define large macros of code. Unlike normal C preprocessor macros, it is not necessary to terminate each line with a continuation character (\)--the macro definition extends to the first occurrence of %enddef. Furthermore, when such macros are expanded, they are reparsed through the C preprocessor. Thus, SWIG macros can contain all other preprocessor directives except for nested %define statements.

The SWIG macro capability is a very quick and easy way to generate large amounts of code. In fact, many of SWIG's advanced features and libraries are built using this mechanism (such as C++ template support).

6.6 C99 and GNU Extensions

SWIG-1.3.12 and newer releases support variadic preprocessor macros. For example:
#define DEBUGF(fmt,...)   fprintf(stderr,fmt,__VA_ARGS__)
When used, any extra arguments to ... are placed into the special variable __VA_ARGS__. This also works with special SWIG macros defined using %define.

SWIG allows a variable number of arguments to be empty. However, this often results in an extra comma (,) and syntax error in the resulting expansion. For example:

DEBUGF("hello");   --> fprintf(stderr,"hello",);
To get rid of the extra comma, use ## like this:
#define DEBUGF(fmt,...)   fprintf(stderr,fmt, ##__VA_ARGS__)

SWIG also supports GNU-style variadic macros. For example:

#define DEBUGF(fmt, args...)  fprintf(stdout,fmt,args)
Comment: It's not entirely clear how variadic macros might be useful to interface building. However, they are used internally to implement a number of SWIG directives and are provided to make SWIG more compatible with C99 code.

6.7 Preprocessing and %{ ... %} blocks

The SWIG preprocessor does not process any text enclosed in a code block %{ ... %}. Therefore, if you write code like this,
%{
#ifdef NEED_BLAH
int blah() {
   ...
}
#endif
%}
the contents of the %{ ... %} block are copied without modification to the output (including all preprocessor directives).

6.8 Preprocessing and { ... }

SWIG always runs the preprocessor on text appearing inside { ... }. However, sometimes it is desirable to make a preprocessor directive pass through to the output file. For example:
%extend Foo {
   void bar() {
      #ifdef DEBUG
       printf("I'm in bar\n");
      #endif
   }
}
By default, SWIG will interpret the #ifdef DEBUG statement. However, if you really wanted that code to actually go into the wrapper file, prefix the preprocessor directives with % like this:
%extend Foo {
   void bar() {
      %#ifdef DEBUG
       printf("I'm in bar\n");
      %#endif
   }
}
SWIG will strip the extra % and leave the preprocessor directive in the code.


SWIG 1.3 - Last Modified : March 9, 2003
cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/ch12.1.png0000644000175000000620000000702512561312226021125 0ustar stevestaff‰PNG  IHDR\¯†¹–PLTEÿÿÿÌffîîîff™ÿÿfÿ™™ÿ3™ÌÿfÌ™™Ì3ÌÌfÿÿf™ff™3™ÿ33fÌ33ÌÝÝÝ3ÿ333ÿ™fÿ3fÌÿ3Ì™fÌ3™™ÿÿfÿÌf™3ff3™Ì33Ì3™»»»f33f™ÿ™3ÿ33ÌÿÌ™3Ì3f™ÿÌfÿ™f™f33™™3ÿ™ÿ3fDDDUÿÿ3ÿ™ÿ3ÌÌÿÌ™Ì33™ÿ™fÿfffÿf3™f3Ì™Ì33"""Ì™ÌÿÌÿÿfÿÿÌÌÌ™ÌfÿÌ3™ÿffÿ3ffÌ3ÿÿ3™33™™™3fÌfÿfÿfÌ33™f3fÌfÌ™3f3ÿf™™™3Ì3™3fÿ3Ìf3ÿˆˆˆ33ÿÿÌÌÿf™ÿ™ÌÌf3Ìÿ™ÿ3™Ìf™fÿÿ™™ÿîf333f̪f3™f3ÿÿÌ™™ÌÌÌÌffU™f™"3Ìffff™Ì33Ì3fÿ™™3ÿÿ™ÿÿ33ÿ3™ÌÌ݈D™Ìff3ÌÌ»™ÿ™3ÿ3ÿ™™Ì™fÌÿÿÿ™f™™3̙̙»w"™Ìÿ3ÌÿÌf™ªfÿ33Ì3f3ÌfˆD™™™Ìf3ª3ÌÌfÌ™™fªªªˆf3Ìwwwf™ÌÌ3ÿw"ÌfÿÿÌÌ™fÌ™™™Ìff™ÿ3wÿÿÌ3Ý™3™3™fÌ™ÿîÌÿÌf™ÿÌÿÿffÌÌ33ÿffUÿf3ÿ»Ìÿ™™33f3™fÿfÌfÌ3ÿÌf™33™3fÌÿ™ÌÿÌfÌÌÿÿ3ÿ™ffÌ3ÿfUUU3Ì3™™ÿÿÌ3îÿf3fÌD™3™ÿÌ™ÿÿ™3ÿ™Ì™™fÌÌÿÌ™ffÿfÿÝÿÌf3ffÌ™fÌm|Ú ÐIDATxÚb`4ÿÿE4ÿÿE4ÿÿE4ÿÿE4ÿÿE4ÿÿE4ÿÿE4ÿÿèÿ°Ø|ÿÿ \.ÿÿ;r6Qÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿ^ƒôñ±÷ôiêì†ÿÿf±þ‰Ä.GO?ÿÿÂÿDh#+XþœÀÿÿ"ìˆÿ¤©QGÃÀE-"þ#sÿ3üGÑ0pÿÿÀýO»À…®""CÁ*þS31c÷ÿÿÂá<,…FJÿÿ3™°X@‹”û™÷Ÿ9pá\Z ÿÿ".å¢;æNdwÿ'-qý§uàÂ"Õ‘.ê6S°‰ÿÿ">pÿ#Š- ÷þÇZO93B»”‹‘2þ£ùÆÅÿÿ"-å2 ¹]œ””ûŸ>û=›!åB.ÿÿ"¹X@vç,LBCÛN¬T`@§ò´.ÿÿ"Xßü‡UU(ª{ÿ30JÓ mpu„ÿÿwа)6¸ÿÿî¾ ÿÿ"ºÁ4:*Fºÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿ$ƒ ÃsÙ>ÿÿuúÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿ®’ÆÞ)«ÿÿ"èuÚ8ed ÿÿ¨ÀýO~–úOjæ"¼®þ?mÿÿ"ääó6PNØ@œqrÖвÿDÙAB8ýG%HÑöŸ¦i »ÿÿ"\"2À¸Bs-üd!¸$’2¼!€ºIƒäÀýONà2 @àÿÿ"!p‘C†ý$!”ÃÒ0Ž,Ä·†ÄÀý8u~^ ÃÄYw'ß!Ÿ(?¶ îHÄn0‹.òÿÿ"9pQO6úœšÐt*'’”‘‚õ?Ò¹\¨!Ì€8ùŽé\9¤C„ C> &IbîÀîÿÿ"œOÐlC”8Š¢‹2Z H‹rèÚ\˜Çu¡;ˆv<ŽCó( \ÿÿ"\µþG=³ q*jzA@G°>#¿BC$J¤òKà¢$÷5PÃ{à’ØØÇ®ÿÿ¢¼'ðŸœâŸÜsÅþc?[Êe ,p©Q,ÿÿ À%Ûaÿ1 þÿÿñ†jàþ'6p©Ræÿÿb ªµ„'õQ¾ï•ÌÀýqrª«PÎÎ…Û„Ôc—º ÿÿ˜F!Y§í¸(÷±¹XR/Õÿÿ-nÍï˜g$¸ÿ±Eý” ÿÿ"²¹4z7ˆÊ ùlÿÿ ˆCþ1ÏE;f©lC*âþ#‰â8“”L?ÿÿ¸¡¡ÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿu ýÿÿ®{ÿÿ \.ÿÿE4ÿÿE4ÿÿE4ÿÿE4ÿÿE4ÿÿE4ÿÿÜÙψ œøIEND®B`‚cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/index.html0000644000175000000620000000600412561312226021514 0ustar stevestaff SWIG1.3 Documentation

SWIG1.3 Development Documentation

Last update : SWIG-1.3.19 (28 March 2003)

Authors:

  • David Beazley (beazley@cs.uchicago.edu)
  • William Fulton (wsf@fultondesigns.co.uk)
  • Matthias Köppe (mkoeppe@mail.math.uni-magdeburg.de)
  • Lyle Johnson (lyle@users.sourceforge.net)
  • Richard Palmer (richard@magicality.org)
  • Craig Files (cfiles@ftc.agilent.com)
  • Art Yerkes (ayerkes@users.sourceforge.net)
  • Jonah Beckford (beckford@usermail.com)

The SWIG documentation is currently being updated to reflect new SWIG features and enhancements. However,this update process is currently unfinished--there is a lot of old SWIG-1.1 documentation and it's going to take some time to update all of it. Please pardon our dust (or volunteer to help!).

Detailed table of contents

SWIG Core Documentation

Language Module Documentation

Developer Documentation

Documentation that has not yet been updated

This documentation has not been updated, 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.

Documentation not yet written (volunteers needed)

  • Mzscheme module
cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/Contents.html0000644000175000000620000012104612561312226022206 0ustar stevestaff SWIG Users Manual

SWIG Users Manual

0 Preface

1 Introduction

2 Getting started on Windows

3 Scripting Languages

4 SWIG Basics

5 SWIG and C++

6 Preprocessing

7 Argument Handling

8 Typemaps

9 Customization Features

10 Contracts

11 Variable Length Arguments

12 Warning Messages

13 SWIG library

14 Working with Modules

15 Advanced Topics

16 SWIG and Guile

17 SWIG and Java

18 SWIG and Ocaml

19 SWIG and Perl5

20 SWIG and PHP4

21 SWIG and Python

22 SWIG and Ruby

23 SWIG and Tcl

24 SWIG and Chicken

25 Extending SWIG

cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/About.html0000644000175000000620000000334412561312226021463 0ustar stevestaff About this manual

About This Manual

The HTML version of the SWIG Users Manual is a direct translation of the printed version which is produced using Framemaker 5. The conversion process was roughly as follows :

  • Raw HTML was produced using Framemaker 5 and Quadralay WebWorks Lite.
  • Tables and figures were converted into GIF images.
  • All of this output was fed into a magic Python script that cleaned up the HTML source and merged the GIF figures into the text.
  • A table of contents and alphabetized topic index were produced from HTML heading tags by the same script.
  • Each .html file was manually prefixed with the " While the conversion process is mostly complete, there are a few things to keep in mind :
    • Some sections of preformatted text may have weird formatting problems.
    • Framemaker tables were converted into GIF images instead of HTML tables--this is a little weird, but the easiest approach for now.
    • There may be a few minor formatting problems throughout due to minor "glitches" that slipped through the conversion process (although I've tried to correct as many as these as possible).
    • The printed version of the SWIG manual is more than 300 pages long--resulting in about 670 Kbytes of HTML. The HTML version is broken up into chapters. Each chapter is fairly well-contained, but some may contain as many as 50 pages of printed text.
    Please report any problems with the documentation to beazley@cs.utah.edu.
    Last Modified : August 3, 1997
    cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/Contract.html0000644000175000000620000001402612561312226022165 0ustar stevestaff Contract Checking

    10 Contracts

    A common problem that arises when wrapping C libraries is that of maintaining reliability and checking for errors. The fact of the matter is that many C programs are notorious for not providing error checks. Not only that, when you expose the internals of an application as a library, it often becomes possible to crash it simply by providing bad inputs or using it in a way that wasn't intended.

    This chapter describes SWIG's support for software contracts. In the context of SWIG, a contract can be viewed as a runtime constraint that is attached to a declaration. For example, you can easily attach argument checking rules, check the output values of a function and more. When one of the rules is violated by a script, a runtime exception is generated rather than having the program continue to execute.

    10.1 The %contract directive

    Contracts are added to a declaration using the %contract directive. Here is a simple example:
    %contract sqrt(double x) {
    require:
        x >= 0;
    ensure:
        sqrt >= 0;
    }
    
    ...
    double sqrt(double);
    
    In this case, a contract is being added to the sqrt() function. The %contract directive must always appear before the declaration in question. Within the contract there are two sections, both of which are optional. The require: section specifies conditions that must hold before the function is called. Typically, this is used to check argument values. The ensure: section specifies conditions that must hold after the function is called. This is often used to check return values or the state of the program. In both cases, the conditions that must hold must be specified as boolean expressions.

    In the above example, we're simply making sure that sqrt() returns a non-negative number (if it didn't, then it would be broken in some way).

    Once a contract has been specified, it modifies the behavior of the resulting module. For example:

    >>> example.sqrt(2)
    1.4142135623730951
    >>> example.sqrt(-2)
    Traceback (most recent call last):
      File "", line 1, in ?
    RuntimeError: Contract violation: require: (arg1>=0)
    >>>
    

    10.2 %contract and classes

    The %contract directive can also be applied to class methods and constructors. For example:
    %contract Foo::bar(int x, int y) {
    require:
       x > 0;
    ensure:
       bar > 0;
    }
    
    %contract Foo::Foo(int a) {
    require:
       a > 0;
    }
    
    class Foo {
    public:
        Foo(int);
        int bar(int, int);
    };
    
    The way in which %contract is applied is exactly the same as the %feature directive. Thus, any contract that you specified for a base class will also be attached to inherited methods. For example:
    class Spam : public Foo {
    public:
       int bar(int,int);    // Gets contract defined for Foo::bar(int,int)
    };
    
    In addition to this, separate contracts can be applied to both the base class and a derived class. For example:
    %contract Foo::bar(int x, int) {
    require:
        x > 0;
    }
    
    %contract Spam::bar(int, int y) {
    require:
        y > 0;
    }
    
    class Foo {
    public:
        int bar(int,int);   // Gets Foo::bar contract.
    };
    
    class Spam : public Foo {
    public:
         int bar(int,int);   // Gets Foo::bar and Spam::bar contract
    };
    
    When more than one contract is applied, the conditions specified in a "require:" section are combined together using a logical-AND operation. In other words conditions specified for the base class and conditions specified for the derived class all must hold. In the above example, this means that both the arguments to Spam::bar must be positive.

    10.3 Constant aggregation and %aggregate_check

    Consider an interface file that contains the following code:
    #define  UP     1
    #define  DOWN   2
    #define  RIGHT  3
    #define  LEFT   4
    
    void move(SomeObject *, int direction, int distance);
    
    One thing you might want to do is impose a constraint on the direction parameter to make sure it's one of a few accepted values. To do that, SWIG provides an easy to use macro %aggregate_check() that works like this:
    %aggregate_check(int, check_direction, UP, DOWN, LEFT, RIGHT);
    
    This merely defines a utility function of the form
    int check_direction(int x);
    
    That checks the argument x to see if it is one of the values listed. This utility function can be used in contracts. For example:
    %aggregate_check(int, check_direction, UP, DOWN, RIGHT, LEFT);
    
    %contract move(SomeObject *, int direction, in) {
    require:
         check_direction(direction);
    }
    
    #define  UP     1
    #define  DOWN   2
    #define  RIGHT  3
    #define  LEFT   4
    
    void move(SomeObject *, int direction, int distance);
    
    Alternatively, it can be used in typemaps and other directives. For example:
    %aggregate_check(int, check_direction, UP, DOWN, RIGHT, LEFT);
    
    %typemap(check) int direction {
        if (!check_direction($1)) SWIG_exception(SWIG_ValueError, "Bad direction");
    }
    
    #define  UP     1
    #define  DOWN   2
    #define  RIGHT  3
    #define  LEFT   4
    
    void move(SomeObject *, int direction, int distance);
    
    Regrettably, there is no automatic way to perform similar checks with enums values. Maybe in a future release.

    10.4 Notes

    Contract support was implemented by Songyan (Tiger) Feng and first appeared in SWIG-1.3.20.


    SWIG 1.3 - Last Modified : November 12, 2003
    cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/CSharp.html0000644000175000000620000001100412561312226021561 0ustar stevestaff SWIG and C#

    15 SWIG and C#

    The purpose of the C# module is to offer an automated way of accessing existing C/C++ code from .NET languages. The wrapper code implementation uses the Platform Invoke (PINVOKE) interface to access natively compiled C/C++ code. The PINVOKE interface has been chosen over Microsoft's Managed C++ interface as it is portable to both Microsoft Windows and non-Microsoft platforms. PINVOKE is part of the ECMA/ISO C# specification.

    The C# module is one of the more recently added language modules to SWIG and consequently is missing some functionality available in some other SWIG modules. The C# module is very similar to the Java module, so until some documentation has been written, please use the Java documentation as a guide to using SWIG with C#. The rest of this chapter should be read in conjunction with the Java documentation as it lists the main differences.

    Director support (virtual method callbacks into C#) has not yet been implemented and is the main missing feature compared to Java. The other missing feature is the lack of typemaps for wrapping STL code as well as a few minor utility typemaps in the various.i library.

    Currently enums are wrapped with C# integers. Be warned that this will change in a forthcoming release. C# enums will be generated instead.

    The most noteable differences to Java are the following:

    • When invoking SWIG use the -csharp command line option instead of -java.
    • C/C++ variables are wrapped with C# properties and not JavaBean style getters and setters.
    • Typemap equivalent names:
      jni                         -> ctype
      jtype                       -> imtype
      jstype                      -> cstype
      javain                      -> csin
      javaout                     -> csout
      javainterfaces              -> csinterfaces
      javabase                    -> csbase
      javaclassmodifiers          -> csclassmodifiers
      javacode                    -> cscode
      javaimports                 -> csimports
      javaptrconstructormodifiers -> csptrconstructormodifiers
      javagetcptr                 -> csgetcptr
      javafinalize                -> csfinalize
      javadestruct                -> csdestruct
      javadestruct_derived        -> csdestruct_derived
      
    • Additional typemaps:
      csvarin                     C# code property set typemap
      csvarout                    C# code property get typemap
      
    • Feature equivalent names:
      javaconst                   -> csconst
      javamethodmodifiers         -> csmethodmodifiers
      
    • Pragma equivalent names:
      pragma(java)                -> pragma(csharp)
      jniclassbase                -> imclassbase
      jniclassclassmodifiers      -> imclassclassmodifiers
      jniclasscode                -> imclasscode
      jniclassimports             -> imclassimports
      jniclassinterfaces          -> imclassinterfaces
      
    • Special variable equivalent names:
      $javaclassname              -> $csclassname
      $javainput                  -> $csinput
      $jnicall                    -> $imcall
      
    An additional special variable, $module, is replaced by the module name, as specified in the %module directive or -module command line option. The intermediary classname has PINVOKE appended after the module name instead of JNI, for example modulenamePINVOKE.

    The directory Examples/csharp has a number of simple examples. Visual Studio .NET 2003 solution and project files are available for compiling with the Microsoft .NET C# compiler on Windows. If your SWIG installation went well on a Unix environment and your C# compiler was detected, you should be able to type make in each example directory, then ilrun runme (Portable.NET C# compiler) or mono runme (Mono C# compiler) to run the examples. Windows users can also get the examples working using a Cygwin or MinGW environment for automatic configuration of the example makefiles. Any one of the three C# compilers (Portable.NET, Mono or Microsoft) can be detected from within a Cygwin or Mingw environment if installed in your path. cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/Varargs.html0000644000175000000620000006471612561312226022030 0ustar stevestaff Variable Length Arguments

    11 Variable Length Arguments

    (a.k.a, "The horror. The horror.")

    This chapter describes the problem of wrapping functions that take a variable number of arguments. For instance, generating wrappers for the C printf() family of functions.

    This topic is sufficiently advanced to merit its own chapter. In fact, support for varargs is an often requested feature that was first added in SWIG-1.3.12. Most other wrapper generation tools have wisely chosen to avoid this issue.

    11.1 Introduction

    Some C and C++ programs may include functions that accept a variable number of arguments. For example, most programmers are familiar with functions from the C library such as the following:
    int printf(const char *fmt, ...)
    int fprintf(FILE *, const char *fmt, ...);
    int sprintf(char *s, const char *fmt, ...);
    
    Although there is probably little practical purpose in wrapping these specific C library functions in a scripting language (what would be the point?), a library may include its own set of special functions based on a similar API. For example:
    int  traceprintf(const char *fmt, ...);
    
    In this case, you may want to have some kind of access from the target language.

    Before describing the SWIG implementation, it is important to discuss the common uses of varargs that you are likely to encounter in real programs. Obviously, there are the printf() style output functions as shown. Closely related to this would be scanf() style input functions that accept a format string and a list of pointers into which return values are placed. However, variable length arguments are also sometimes used to write functions that accept a NULL-terminated list of pointers. A good example of this would be a function like this:

    int execlp(const char *path, const char *arg1, ...);
    ...
    
    /* Example */
    execlp("ls","ls","-l",NULL);
    
    In addition, varargs is sometimes used to fake default arguments in older C libraries. For instance, the low level open() system call is often declared as a varargs function so that it will accept two or three arguments:
    int open(const char *path, int oflag, ...);
    ...
    
    /* Examples */
    f = open("foo", O_RDONLY);
    g = open("bar", O_WRONLY | O_CREAT, 0644);
    
    Finally, to implement a varargs function, recall that you have to use the C library functions defined in <stdarg.h>. For example:
    List make_list(const char *s, ...) {
        va_list ap;
        List    *x = new List();
        ...
        va_start(ap, s);
        while (s) {
           x.append(s);
           s = va_arg(ap, const char *);
        }
        va_end(ap);
        return x;
    }
    

    11.2 The Problem

    Generating wrappers for a variable length argument function presents a number of special challenges. Although C provides support for implementing functions that receive variable length arguments, there are no functions that can go in the other direction. Specifically, you can't write a function that dynamically creates a list of arguments and which invokes a varargs function on your behalf.

    Although it is possible to write functions that accept the special type va_list, this is something entirely different. You can't take a va_list structure and pass it in place of the variable length arguments to another varargs function. It just doesn't work.

    The reason this doesn't work has to do with the way that function calls get compiled. For example, suppose that your program has a function call like this:

    printf("Hello %s. Your number is %d\n", name, num);
    
    When the compiler looks at this, it knows that you are calling printf() with exactly three arguments. Furthermore, it knows that the number of arguments as well are their types and sizes is never going to change during program execution. Therefore, this gets turned to machine code that sets up a three-argument stack frame followed by a call to printf().

    In contrast, suppose you attempted to make some kind of wrapper around printf() using code like this:

    int wrap_printf(const char *fmt, ...) {
       va_list ap;
       va_start(ap,fmt);
       ...
       printf(fmt,ap);
       ...
       va_end(ap);
    };
    
    Athough this code might compile, it won't do what you expect. This is because the call to printf() is compiled as a procedure call involving only two arguments. However, clearly a two-argument configuration of the call stack is completely wrong if your intent is to pass an arbitrary number of arguments to the real printf(). Needless to say, it won't work.

    Unfortunately, the situation just described is exactly the problem faced by wrapper generation tools. In general, the number of passed arguments will not be known until run-time. To make matters even worse, you won't know the types and sizes of arguments until run-time as well. Needless to say, there is no obvious way to make the C compiler generate code for a function call involving an unknown number of arguments of unknown types.

    In theory, it is possible to write a wrapper that does the right thing. However, this involves knowing the underlying ABI for the target platform and language as well as writing special purpose code that manually constructed the call stack before making a procedure call. Unfortunately, both of these tasks require the use of inline assembly code. Clearly, that's the kind of solution you would much rather avoid.

    With this nastiness in mind, SWIG provides a number of solutions to the varargs wrapping problem. Most of these solutions are compromises that provide limited varargs support without having to resort to assembly language. However, SWIG can also support real varargs wrapping (with stack-frame manipulation) if you are willing to get hands dirty. Keep reading.

    11.3 Default varargs support

    When variable length arguments appear in an interface, the default behavior is to drop the variable argument list entirely, replacing them with a single NULL pointer. For example, if you had this function,
    void traceprintf(const char *fmt, ...);
    
    it would be wrapped as if it had been declared as follows:
    void traceprintf(const char *fmt);
    
    When the function is called inside the wrappers, it is called as follows:
    traceprintf(arg1, NULL);
    
    Arguably, this approach seems to defeat the whole point of variable length arguments. However, this actually provides enough support for many simple kinds of varargs functions to still be useful. For instance, you could make function calls like this (in Python):
    >>> traceprintf("Hello World")
    >>> traceprintf("Hello %s. Your number is %d\n" % (name, num))
    
    Notice how string formatting is being done in Python instead of C.

    11.4 Argument replacement using %varargs

    Instead of dropping the variable length arguments, an alternative approach is to replace (...) with a set of suitable arguments. SWIG provides a special %varargs directive that can be used to do this. For example,
    %varargs(int mode = 0) open;
    ...
    int open(const char *path, int oflags, ...);
    
    is equivalent to this:
    int open(const char *path, int oflags, int mode = 0);
    
    In this case, %varargs is simply providing more specific information about the extra arguments that might be passed to a function. If the parameters to a varargs function are of uniform type, %varargs can also accept a numerical argument count as follows:
    %varargs(10,char *arg = NULL) execlp;
    ...
    int execlp(const char *path, const char *arg1, ...);
    
    This would wrap execlp() as a function that accepted up to 10 optional arguments. Depending on the application, this may be more than enough for practical purposes.

    Argument replacement is most appropriate in cases where the types of the extra arguments is uniform and the maximum number of arguments is known. When replicated argument replacement is used, at least one extra argument is added to the end of the arguments when making the function call. This argument serves as a sentinel to make sure the list is properly terminated. It has the same value as that supplied to the %varargs directive.

    Argument replacement is not as useful when working with functions that accept mixed argument types such as printf(). Providing general purpose wrappers to such functions presents special problems (covered shortly).

    11.5 Varargs and typemaps

    Variable length arguments may be used in typemap specifications. For example:
    %typemap(in) (...) {
        // Get variable length arguments (somehow)
        ...
    }
    
    %typemap(in) (const char *fmt, ...) {
        // Multi-argument typemap
    }
    
    However, this immediately raises the question of what "type" is actually used to represent (...). For lack of a better alternative, the type of (...) is set to void *. Since there is no way to dynamically pass arguments to a varargs function (as previously described), the void * argument value is intended to serve as a place holder for storing some kind of information about the extra arguments (if any). In addition, the default behavior of SWIG is to pass the void * value as an argument to the function. Therefore, you could use the pointer to hold a valid argument value if you wanted.

    To illustrate, here is a safer version of wrapping printf() in Python:

    %typemap(in) (const char *fmt, ...) {
        $1 = "%s";                                /* Fix format string to %s */
        $2 = (void *) PyString_AsString($input);  /* Get string argument */
    };
    ...
    int printf(const char *fmt, ...);
    
    In this example, the format string is implicitly set to "%s". This prevents a program from passing a bogus format string to the extension. Then, the passed input object is decoded and placed in the void * argument defined for the (...) argument. When the actual function call is made, the underlying wrapper code will look roughly like this:
    wrap_printf() {
       char *arg1;
       void *arg2;
       int   result;
    
       arg1 = "%s";
       arg2 = (void *) PyString_AsString(arg2obj);
       ...
       result = printf(arg1,arg2);
       ...
    }
    
    Notice how both arguments are passed to the function and it does what you would expect.

    The next example illustrates a more advanced kind of varargs typemap. Disclaimer: this requires special support in the target language module and is not guaranteed to work with all SWIG modules at this time. It also starts to illustrate some of the more fundamental problems with supporting varargs in more generality.

    If a typemap is defined for any form of (...), many SWIG modules will generate wrappers that accept a variable number of arguments as input and will make these arguments available in some form. The precise details of this depends on the language module being used (consult the appropriate chapter for more details). However, suppose that you wanted to create a Python wrapper for the execlp() function shown earlier. To do this using a typemap instead of using %varargs, you might first write a typemap like this:

    %typemap(in) (...)(char *args[10]) {
        int i;
        int argc;
        for (i = 0; i < 10; i++) args[i] = 0;
        argc = PyTuple_Size(varargs);
        if (argc > 10) {
           PyErr_SetString(PyExc_ValueError,"Too many arguments");
           return NULL;
        }
        for (i = 0; i < argc; i++) {
           PyObject *o = PyTuple_GetItem(varargs,i);
           if (!PyString_Check(o)) {
               PyErr_SetString(PyExc_ValueError,"Expected a string");
               return NULL;
           }
           args[i] = PyString_AsString(o);
        }
        $1 = (void *) args;
    }
    
    In this typemap, the special variable varargs is a tuple holding all of the extra arguments passed (this is specific to the Python module). The typemap then pulls this apart and sticks the values into the array of strings args. Then, the array is assigned to $1 (recall that this is the void * variable corresponding to (...)). However, this assignment is only half of the picture----clearly this alone is not enough to make the function work. To patch everything up, you have to rewrite the underlying action code using the %feature directive like this:
    %feature("action") execlp {
       char *args = (char **) arg3;
       result = execlp(arg1, arg2, args[0], args[1], args[2], args[3], args[4],
                       args[5],args[6],args[7],args[8],args[9], NULL);
    }
    
    int execlp(const char *path, const char *arg, ...);
    

    This patches everything up and creates a function that more or less works. However, don't try explaining this to your coworkers unless you know for certain that they've had several cups of coffee. If you really want to elevate your guru status and increase your job security, continue to the next section.

    11.6 Varargs wrapping with libffi

    All of the previous examples have relied on features of SWIG that are portable and which don't rely upon any low-level machine-level details. In many ways, they have all dodged the real issue of variable length arguments by recasting a varargs function into some weaker variation with a fixed number of arguments of known types. In many cases, this works perfectly fine. However, if you want more generality than this, you need to bring out some bigger guns.

    One way to do this is to use a special purpose library such as libffi (http://sources.redhat.com/libffi). libffi is a library that allows you to dynamically construct call-stacks and invoke procedures in a relatively platform independent manner. Details about the library can be found in the libffi distribution and are not repeated here.

    To illustrate the use of libffi, suppose that you really wanted to create a wrapper for execlp() that accepted any number of arguments. To do this, you might make a few adjustments to the previous example. For example:

    /* Take an arbitrary number of extra arguments and place into an array
       of strings */
    
    %typemap(in) (...) {
       char **argv;
       int    argc;
       int    i;
    
       argc = PyTuple_Size(varargs);
       argv = (char **) malloc(sizeof(char *)*(argc+1));
       for (i = 0; i < argc; i++) {
          PyObject *o = PyTuple_GetItem(varargs,i);
          if (!PyString_Check(o)) {
              PyErr_SetString(PyExc_ValueError,"Expected a string");
    	  free(argv);
              return NULL;
          }
          argv[i] = PyString_AsString(o);
       }
       argv[i] = NULL;
       $1 = (void *) argv;
    }
    
    /* Rewrite the function call, using libffi */    
    
    %feature("action") execlp {
      int       i, vc;
      ffi_cif   cif;
      ffi_type  **types;
      void      **values;
      char      **args;
    
      vc = PyTuple_Size(varargs);
      types  = (ffi_type **) malloc((vc+3)*sizeof(ffi_type *));
      values = (void **) malloc((vc+3)*sizeof(void *));
      args   = (char **) arg3;
    
      /* Set up path parameter */
      types[0] = &ffi_type_pointer;
      values[0] = &arg1;
      
      /* Set up first argument */
      types[1] = &ffi_type_pointer;
      values[1] = &arg2;
    
      /* Set up rest of parameters */
      for (i = 0; i <= vc; i++) {
        types[2+i] = &ffi_type_pointer;
        values[2+i] = &args[i];
      }
      if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, vc+3,
                       &ffi_type_uint, types) == FFI_OK) {
        ffi_call(&cif, (void (*)()) execlp, &result, values);
      } else {
        PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
        free(types);
        free(values);
        free(arg3);
        return NULL;
      }
      free(types);
      free(values);
      free(arg3);
    }
    
    /* Declare the function. Whew! */
    int execlp(const char *path, const char *arg1, ...);
    
    Looking at this example, you may start to wonder if SWIG is making life any easier. Given the amount of code involved, you might also wonder why you didn't just write a hand-crafted wrapper! Either that or you're wondering "why in the hell am I trying to wrap this varargs function in the first place?!?" Obviously, those are questions you'll have to answer for yourself.

    As a more extreme example of libffi, here is some code that attempts to wrap printf(),

    /* A wrapper for printf() using libffi */
    
    %{
    /* Structure for holding passed arguments after conversion */
      typedef struct {
        int type;
        union {
          int    ivalue;
          double dvalue;
          void   *pvalue;
        } val;
      } vtype;
      enum { VT_INT, VT_DOUBLE, VT_POINTER };
    %}
    
    %typemap(in) (const char *fmt, ...) {
      vtype *argv;
      int    argc;
      int    i;
    
      /* Format string */
      $1 = PyString_AsString($input);
    
      /* Variable length arguments */
      argc = PyTuple_Size(varargs);
      argv = (vtype *) malloc(argc*sizeof(vtype));
      for (i = 0; i < argc; i++) {
        PyObject *o = PyTuple_GetItem(varargs,i);
        if (PyInt_Check(o)) {
          argv[i].type = VT_INT;
          argv[i].val.ivalue = PyInt_AsLong(o);
        } else if (PyFloat_Check(o)) {
          argv[i].type = VT_DOUBLE;
          argv[i].val.dvalue = PyFloat_AsDouble(o);
        } else if (PyString_Check(o)) {
          argv[i].type = VT_POINTER;
          argv[i].val.pvalue = (void *) PyString_AsString(o);
        } else {
          PyErr_SetString(PyExc_ValueError,"Unsupported argument type");
          free(argv);
          return NULL;
        }
      }
      $2 = (void *) argv;
    }
    
    /* Rewrite the function call using libffi */    
    %feature("action") printf {
      int       i, vc;
      ffi_cif   cif;
      ffi_type  **types;
      void      **values;
      vtype     *args;
    
      vc = PyTuple_Size(varargs);
      types  = (ffi_type **) malloc((vc+1)*sizeof(ffi_type *));
      values = (void **) malloc((vc+1)*sizeof(void *));
      args   = (vtype *) arg2;
    
      /* Set up fmt parameter */
      types[0] = &ffi_type_pointer;
      values[0] = &arg1;
    
      /* Set up rest of parameters */
      for (i = 0; i < vc; i++) {
        switch(args[i].type) {
        case VT_INT:
          types[1+i] = &ffi_type_uint;
          values[1+i] = &args[i].val.ivalue;
          break;
        case VT_DOUBLE:
          types[1+i] = &ffi_type_double;
          values[1+i] = &args[i].val.dvalue;
          break;
        case VT_POINTER:
          types[1+i] = &ffi_type_pointer;
          values[1+i] = &args[i].val.pvalue;
          break;
        default:
          abort();    /* Whoa! We're seriously hosed */
          break;   
        }
      }
      if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, vc+1,
                       &ffi_type_uint, types) == FFI_OK) {
        ffi_call(&cif, (void (*)()) printf, &result, values);
      } else {
        PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
        free(types);
        free(values);
        free(args);
        return NULL;
      }
      free(types);
      free(values);
      free(args);
    }
    
    /* The function */
    int printf(const char *fmt, ...);
    
    Much to your amazement, it even seems to work if you try it:
    >>> import example
    >>> example.printf("Grade: %s   %d/60 = %0.2f%%\n", "Dave", 47, 47.0*100/60)
    Grade: Dave   47/60 = 78.33%
    >>>
    
    Of course, there are still some limitations to consider:
    >>> example.printf("la de da de da %s", 42)
    Segmentation fault (core dumped)
    
    And, on this note, we leave further exploration of libffi to the reader as an exercise. Although Python has been used as an example, most of the techniques in this section can be extrapolated to other language modules with a bit of work. The only details you need to know is how the extra arguments are accessed in each target language. For example, in the Python module, we used the special varargs variable to get these arguments. Modules such as Tcl8 and Perl5 simply provide an argument number for the first extra argument. This can be used to index into an array of passed arguments to get values. Please consult the chapter on each language module for more details.

    11.7 Wrapping of va_list

    Closely related to variable length argument wrapping, you may encounter functions that accept a parameter of type va_list. For example:
    int vfprintf(FILE *f, const char *fmt, va_list ap);
    
    As far as we know, there is no obvious way to wrap these functions with SWIG. This is because there is no documented way to assemble the proper va_list structure (there are no C library functions to do it and the contents of va_list are opaque). Not only that, the contents of a va_list structure are closely tied to the underlying call-stack. It's not clear that exporting a va_list would have any use or that it would work at all.

    11.8 C++ Issues

    Wrapping of C++ member functions that accept a variable number of arguments presents a number of challenges. By far, the easiest way to handle this is to use the %varargs directive. This is portable and it fully supports classes much like the %rename directive. For example:
    %varargs (10, char * = NULL) Foo::bar;
    
    class Foo {
    public:
         virtual void bar(char *arg, ...);   // gets varargs above
    };
    
    class Spam: public Foo {
    public:
         virtual void bar(char *arg, ...);   // gets varargs above
    };
    
    %varargs also works with constructors, operators, and any other C++ programming construct that accepts variable arguments.

    Doing anything more advanced than this is likely to involve a serious world of pain. In order to use a library like libffi, you will need to know the underlying calling conventions and details of the C++ ABI. For instance, the details of how this is passed to member functions as well as any hidden arguments that might be used to pass additional information. These details are implementation specific and may differ between compilers and even different versions of the same compiler. Also, be aware that invoking a member function is further complicated if it is a virtual method. In this case, invocation might require a table lookup to obtain the proper function address (although you might be able to obtain an address by casting a bound pointer to a pointer to function as described in the C++ ARM section 18.3.4).

    If you do decide to change the underlying action code, be aware that SWIG always places the this pointer in arg1. Other arguments are placed in arg2, arg3, and so forth. For example:

    %feature("action") Foo::bar {
       ...
       result = arg1->bar(arg2, arg3, etc.);
       ...
    }
    
    Given the potential to shoot yourself in the foot, it is probably easier to reconsider your design or to provide an alternative interface using a helper function than it is to create a fully general wrapper to a varargs C++ member function.

    11.9 Discussion

    This chapter has provided a number of techniques that can be used to address the problem of variable length argument wrapping. If you care about portability and ease of use, the %varargs directive is probably the easiest way to tackle the problem. However, using typemaps, it is possible to do some very advanced kinds of wrapping.

    One point of discussion concerns the structure of the libffi examples in the previous section. Looking at that code, it is not at all clear that this is the easiest way to solve the problem. However, there are a number of subtle aspects of the solution to consider--mostly concerning the way in which the problem has been decomposed. First, the example is structured in a way that tries to maintain separation between wrapper-specific information and the declaration of the function itself. The idea here is that you might structure your interface like this:

    %typemap(const char *fmt, ...) {
       ...
    }
    %feature("action") traceprintf {
       ...
    }
    
    /* Include some header file with traceprintf in it */
    %include "someheader.h"
    
    Second, careful scrutiny will reveal that the typemaps involving (...) have nothing whatsoever to do with the libffi library. In fact, they are generic with respect to the way in which the function is actually called. This decoupling means that it will be much easier to consider other library alternatives for making the function call. For instance, if libffi wasn't supported on a certain platform, you might be able to use something else instead. You could use conditional compilation to control this:
    #ifdef USE_LIBFFI
    %feature("action") printf {
       ...
    }
    #endif
    #ifdef USE_OTHERFFI
    %feature("action") printf {
    ...
    }
    #endif
    
    Finally, even though you might be inclined to just write a hand-written wrapper for varargs functions, the techniques used in the previous section have the advantage of being compatible with all other features of SWIG such as exception handling.

    As a final word, some C programmers seem to have the assumption that the wrapping of variable length argument functions is an easily solved problem. However, this section has hopefully dispelled some of these myths. All things being equal, you are better off avoiding variable length arguments if you can. If you can't avoid them, please consider some of the simple solutions first. If you can't live with a simple solution, proceed with caution. At the very least, make sure you carefully read the section "A7.3.2 Function Calls" in Kernighan and Ritchie and make sure you fully understand the parameter passing conventions used for varargs. Also, be aware of the platform dependencies and reliability issues that this will introduce. Good luck.


    SWIG 1.3 - Last Modified : March 24, 2002
    cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/Extending.html0000644000175000000620000026241612561312226022345 0ustar stevestaff Extending SWIG

    25 Extending SWIG

    Caution: This chapter is being rewritten! (11/25/01)

    25.1 Introduction

    This chapter describes SWIG's internal organization and the process by which new target languages can be developed. First, a brief word of warning---SWIG has been undergoing a massive redevelopment effort that has focused extensively on its internal organization. The information in this chapter is mostly up to date, but changes are ongoing. Expect a few inconsistencies.

    Also, this chapter is not meant to be a hand-holding tutorial. As a starting point, you should probably look at one of SWIG's existing modules.

    25.2 Prerequisites

    In order to extend SWIG, it is useful to have the following background:

    • An understanding of the C API for the target language.
    • A good grasp of the C++ type system.
    • An understanding of typemaps and some of SWIG's advanced features.
    • Some familiarity with writing C++ (language modules are currently written in C++).
    Since SWIG is essentially a specialized C++ compiler, it may be useful to have some prior experience with compiler design (perhaps even a compilers course) to better understand certain parts of the system. A number of books will also be useful. For example, "The C Programming Language" by Kernighan and Ritchie (a.k.a, "K&R") and the "C++ Annotated Reference Manual" by Stroustrup (a.k.a, the "ARM") will be of great use.

    Also, it is useful to keep in mind that SWIG primarily operates as an extension of the C++ type system. At first glance, this might not be obvious, but almost all SWIG directives as well as the low-level generation of wrapper code are driven by C++ datatypes.

    25.3 The Big Picture

    SWIG is a special purpose compiler that parses C++ declarations to generate wrapper code. To make this conversion possible, SWIG makes three fundamental extensions to the C++ language:
    • Typemaps. Typemaps are used to define the conversion/marshalling behavior of specific C++ datatypes. All type conversion in SWIG is based on typemaps. Furthermore, the association of typemaps to datatypes utilizes an advanced pattern matching mechanism that is fully integrated with the C++ type system.

    • Declaration Annotation. To customize wrapper code generation, most declarations can be annotated with special features. For example, you can make a variable read-only, you can ignore a declaration, you can rename a member function, you can add exception handling, and so forth. Virtually all of these customizations are built on top of a low-level declaration annotator that can attach arbitrary attributes to any declaration. Code generation modules can look for these attributes to guide the wrapping process.

    • Class extension. SWIG allows classes and structures to be extended with new methods and attributes (the %extend directive). This has the effect of altering the API in the target language and can be used to generate OO interfaces to C libraries.
    It is important to emphasize that virtually all SWIG features reduce to one of these three fundamental concepts. The type system and pattern matching rules also play a critical role in making the system work. For example, both typemaps and declaration annotation are based on pattern matching and interact heavily with the underlying type system.

    25.4 Execution Model

    When you run SWIG on an interface, processing is handled in stages by a series of system components:
    • An integrated C preprocessor reads a collection of configuration files and the specified interface file into memory. The preprocessor performs the usual functions including macro expansion and file inclusion. However, the preprocessor also performs some transformations of the interface. For instance, #define statements are sometimes transformed into %constant declarations. In addition, information related to file/line number tracking is inserted.

    • A C/C++ parser reads the preprocessed input and generates a full parse tree of all of the SWIG directives and C declarations found. The parser is responsible for many aspects of the system including renaming, declaration annotation, and template expansion. However, the parser does not produce any output nor does it interact with the target language module as it runs. SWIG is not a one-pass compiler.

    • A type-checking pass is made. This adjusts all of the C++ typenames to properly handle namespaces, typedefs, nested classes, and other issues related to type scoping.

    • A semantic pass is made on the parse tree to collect information related to properties of the C++ interface. For example, this pass would determine whether or not a class allows a default constructor.

    • A code generation pass is made using a specific target language module. This phase is responsible for generating the actual wrapper code. All of SWIG's user-defined modules are invoked during this stage of compilation.
    The next few sections briefly describe some of these stages.

    25.4.1 Preprocessing

    The preprocessor plays a critical role in the SWIG implementation. This is because a lot of SWIG's processing and internal configuration is managed not by code written in C, but by configuration files in the SWIG library. In fact, when you run SWIG, parsing starts with a small interface file like this (note: this explains the cryptic error messages that new users sometimes get when SWIG is misconfigured or installed incorrectly):
    %include "swig.swg"             // Global SWIG configuration
    %include "langconfig.swg"       // Language specific configuration
    %include "yourinterface.i"      // Your interface file
    
    The swig.swg file contains global configuration information. In addition, this file defines many of SWIG's standard directives as macros. For instance, part of of swig.swg looks like this:
    ...
    /* Code insertion directives such as %wrapper %{ ... %} */
    
    #define %init        %insert("init")
    #define %wrapper     %insert("wrapper")
    #define %header      %insert("header")
    #define %runtime     %insert("runtime")
    
    /* Access control directives */
    
    #define %immutable   %feature("immutable","1")
    #define %mutable     %feature("immutable")
    
    /* Directives for callback functions */
    
    #define %callback(x) %feature("callback") `x`;
    #define %nocallback  %feature("callback");
    
    /* %ignore directive */
    
    #define %ignore         %rename($ignore)
    #define %ignorewarn(x)  %rename("$ignore:" x)
    ...
    
    The fact that most of the standard SWIG directives are macros is intended to simplify the implementation of the internals. For instance, rather than having to support dozens of special directives, it is easier to have a few basic primitives such as %feature or %insert.

    The langconfig.swg file is supplied by the target language. This file contains language-specific configuration information. More often than not, this file provides run-time wrapper support code (e.g., the type-checker) as well as a collection of typemaps that define the default wrapping behavior. Note: the name of this file depends on the target language and is usually something like python.swg or perl5.swg.

    As a debugging aide, the text that SWIG feeds to its C++ parser can be obtained by running swig -E interface.i. This output probably isn't too useful in general, but it will show how macros have been expanded as well as everything else that goes into the low-level construction of the wrapper code.

    25.4.2 Parsing

    The current C++ parser handles a subset of C++. Most incompatibilities with C are due to subtle aspects of how SWIG parses declarations. Specifically, SWIG expects all C/C++ declarations to follow this general form:
    storage type declarator initializer;
    
    storage is a keyword such as extern, static, typedef, or virtual. type is a primitive datatype such as int or void. type may be optionally qualified with a qualifier such as const or volatile. declarator is a name with additional type-construction modifiers attached to it (pointers, arrays, references, functions, etc.). Examples of declarators include *x, **x, x[20], and (*x)(int,double). The initializer may be a value assigned using = or body of code enclosed in braces { ... }.

    This declaration format covers most common C++ declarations. However, the C++ standard is somewhat more flexible in the placement of the parts. For example, it is technically legal, although uncommon to write something like int typedef const a in your program. SWIG simply doesn't bother to deal with this case.

    The other significant difference between C++ and SWIG is in the treatment of typenames. In C++, if you have a declaration like this,

    int blah(Foo *x, Bar *y);
    
    it won't parse correctly unless Foo and Bar have been previously defined as types either using a class definition or a typedef. The reasons for this are subtle, but this treatment of typenames is normally integrated at the level of the C tokenizer---when a typename appears, a different token is returned to the parser instead of an identifier.

    SWIG does not operate in this manner--any legal identifier can be used as a type name. The reason for this is primarily motivated by the use of SWIG with partially defined data. Specifically, SWIG is supposed to be easy to use on interfaces with missing type information.

    Because of the different treatment of typenames, the most serious limitation of the SWIG parser is that it can't process type declarations where an extra (and unnecessary) grouping operator is used. For example:

    int (x);         /* A variable x */
    int (y)(int);    /* A function y */
    
    The placing of extra parentheses in type declarations like this is already recognized by the C++ community as a potential source of strange programming errors. For example, Scott Meyers "Effective STL" discusses this problem in a section on avoiding C++'s "most vexing parse."

    The parser is also unable to handle declarations with no return type or bare argument names. For example, in an old C program, you might see things like this:

    foo(a,b) {
    ...
    }
    
    In this case, the return type as well as the types of the arguments are taken by the C compiler to be an int. However, SWIG interprets the above code as an abstract declarator for a function returning a foo and taking types a and b as arguments).

    25.4.3 Parse Trees

    The SWIG parser produces a complete parse tree of the input file before any wrapper code is actually generated. Each item in the tree is known as a "Node". Each node is identified by a symbolic tag. Furthermore, a node may have an arbitrary number of children. The parse tree structure and tag names of an interface can be displayed using swig -dump_tags. For example:
    $ swig -c++ -python -dump_tags example.i
     . top (example.i:1)
     . top . include (example.i:1)
     . top . include . typemap (/r0/beazley/Projects/lib/swig1.3/swig.swg:71)
     . top . include . typemap . typemapitem (/r0/beazley/Projects/lib/swig1.3/swig.swg:71)
     . top . include . typemap (/r0/beazley/Projects/lib/swig1.3/swig.swg:83)
     . top . include . typemap . typemapitem (/r0/beazley/Projects/lib/swig1.3/swig.swg:83)
     . top . include (example.i:4)
     . top . include . insert (/r0/beazley/Projects/lib/swig1.3/python/python.swg:7)
     . top . include . insert (/r0/beazley/Projects/lib/swig1.3/python/python.swg:8)
     . top . include . typemap (/r0/beazley/Projects/lib/swig1.3/python/python.swg:19)
     . top . include . typemap . typemapitem (/r0/beazley/Projects/lib/swig1.3/python/python.swg:19)
     . top . include . typemap . typemapitem (/r0/beazley/Projects/lib/swig1.3/python/python.swg:19)
    ...
     . top . include (example.i:6)
     . top . include . module (example.i:2)
     . top . include . insert (example.i:6)
     . top . include . include (example.i:9)
     . top . include . include . class (example.h:3)
     . top . include . include . class . access (example.h:4)
     . top . include . include . class . constructor (example.h:7)
     . top . include . include . class . destructor (example.h:10)
     . top . include . include . class . cdecl (example.h:11)
     . top . include . include . class . cdecl (example.h:11)
     . top . include . include . class . cdecl (example.h:12)
     . top . include . include . class . cdecl (example.h:13)
     . top . include . include . class . cdecl (example.h:14)
     . top . include . include . class . cdecl (example.h:15)
     . top . include . include . class (example.h:18)
     . top . include . include . class . access (example.h:19)
     . top . include . include . class . cdecl (example.h:20)
     . top . include . include . class . access (example.h:21)
     . top . include . include . class . constructor (example.h:22)
     . top . include . include . class . cdecl (example.h:23)
     . top . include . include . class . cdecl (example.h:24)
     . top . include . include . class (example.h:27)
     . top . include . include . class . access (example.h:28)
     . top . include . include . class . cdecl (example.h:29)
     . top . include . include . class . access (example.h:30)
     . top . include . include . class . constructor (example.h:31)
     . top . include . include . class . cdecl (example.h:32)
     . top . include . include . class . cdecl (example.h:33)
    
    Even for the most simple interface, the parse tree structure is larger than you might expect. For example, in the above output, a substantial number of nodes are actually generated by the python.swg configuration file which defines typemaps and other directives. The contents of the user-supplied input file don't appear until the end of the output.

    The contents of each parse tree node consist of a collection of attribute/value pairs. Internally, the nodes are simply represented by hash tables. A display of the parse-tree structure can be obtained using swig -dump_tree. For example:

    $ swig -c++ -python -dump_tree example.i
    ...
          +++ include ----------------------------------------
          | name         - "example.i"
    
                +++ module ----------------------------------------
                | name         - "example"
                | 
                +++ insert ----------------------------------------
                | code         - "\n#include \"example.h\"\n"
                | 
                +++ include ----------------------------------------
                | name         - "example.h"
    
                      +++ class ----------------------------------------
                      | abstract     - "1"
                      | sym:name     - "Shape"
                      | name         - "Shape"
                      | kind         - "class"
                      | symtab       - 0x40194140
                      | sym:symtab   - 0x40191078
    
                            +++ access ----------------------------------------
                            | kind         - "public"
                            | 
                            +++ constructor ----------------------------------------
                            | sym:name     - "Shape"
                            | name         - "Shape"
                            | decl         - "f()."
                            | code         - "{\n    nshapes++;\n  }"
                            | sym:symtab   - 0x40194140
                            | 
                            +++ destructor ----------------------------------------
                            | sym:name     - "~Shape"
                            | name         - "~Shape"
                            | storage      - "virtual"
                            | code         - "{\n    nshapes--;\n  }"
                            | sym:symtab   - 0x40194140
                            | 
                            +++ cdecl ----------------------------------------
                            | sym:name     - "x"
                            | name         - "x"
                            | decl         - ""
                            | type         - "double"
                            | sym:symtab   - 0x40194140
                            | 
                            +++ cdecl ----------------------------------------
                            | sym:name     - "y"
                            | name         - "y"
                            | decl         - ""
                            | type         - "double"
                            | sym:symtab   - 0x40194140
                            | 
                            +++ cdecl ----------------------------------------
                            | sym:name     - "move"
                            | name         - "move"
                            | decl         - "f(double,double)."
                            | parms        - double ,double 
                            | type         - "void"
                            | sym:symtab   - 0x40194140
                            | 
                            +++ cdecl ----------------------------------------
                            | sym:name     - "area"
                            | name         - "area"
                            | decl         - "f(void)."
                            | parms        - void 
                            | storage      - "virtual"
                            | value        - "0"
                            | type         - "double"
                            | sym:symtab   - 0x40194140
                            | 
                            +++ cdecl ----------------------------------------
                            | sym:name     - "perimeter"
                            | name         - "perimeter"
                            | decl         - "f(void)."
                            | parms        - void 
                            | storage      - "virtual"
                            | value        - "0"
                            | type         - "double"
                            | sym:symtab   - 0x40194140
                            | 
                            +++ cdecl ----------------------------------------
                            | sym:name     - "nshapes"
                            | name         - "nshapes"
                            | decl         - ""
                            | storage      - "static"
                            | type         - "int"
                            | sym:symtab   - 0x40194140
                            | 
                      +++ class ----------------------------------------
                      | sym:name     - "Circle"
                      | name         - "Circle"
                      | kind         - "class"
                      | bases        - 0x40194510
                      | symtab       - 0x40194538
                      | sym:symtab   - 0x40191078
    
                            +++ access ----------------------------------------
                            | kind         - "private"
                            | 
                            +++ cdecl ----------------------------------------
                            | name         - "radius"
                            | decl         - ""
                            | type         - "double"
                            | 
                            +++ access ----------------------------------------
                            | kind         - "public"
                            | 
                            +++ constructor ----------------------------------------
                            | sym:name     - "Circle"
                            | name         - "Circle"
                            | parms        - double 
                            | decl         - "f(double)."
                            | code         - "{ }"
                            | sym:symtab   - 0x40194538
                            | 
                            +++ cdecl ----------------------------------------
                            | sym:name     - "area"
                            | name         - "area"
                            | decl         - "f(void)."
                            | parms        - void 
                            | storage      - "virtual"
                            | type         - "double"
                            | sym:symtab   - 0x40194538
                            | 
                            +++ cdecl ----------------------------------------
                            | sym:name     - "perimeter"
                            | name         - "perimeter"
                            | decl         - "f(void)."
                            | parms        - void 
                            | storage      - "virtual"
                            | type         - "double"
                            | sym:symtab   - 0x40194538
                            | 
                      +++ class ----------------------------------------
                      | sym:name     - "Square"
                      | name         - "Square"
                      | kind         - "class"
                      | bases        - 0x40194760
                      | symtab       - 0x40194788
                      | sym:symtab   - 0x40191078
    
                            +++ access ----------------------------------------
                            | kind         - "private"
                            | 
                            +++ cdecl ----------------------------------------
                            | name         - "width"
                            | decl         - ""
                            | type         - "double"
                            | 
                            +++ access ----------------------------------------
                            | kind         - "public"
                            | 
                            +++ constructor ----------------------------------------
                            | sym:name     - "Square"
                            | name         - "Square"
                            | parms        - double 
                            | decl         - "f(double)."
                            | code         - "{ }"
                            | sym:symtab   - 0x40194788
                            | 
                            +++ cdecl ----------------------------------------
                            | sym:name     - "area"
                            | name         - "area"
                            | decl         - "f(void)."
                            | parms        - void 
                            | storage      - "virtual"
                            | type         - "double"
                            | sym:symtab   - 0x40194788
                            | 
                            +++ cdecl ----------------------------------------
                            | sym:name     - "perimeter"
                            | name         - "perimeter"
                            | decl         - "f(void)."
                            | parms        - void 
                            | storage      - "virtual"
                            | type         - "double"
                            | sym:symtab   - 0x40194788
    

    25.4.4 Attribute namespaces

    Attributes of parse tree nodes are often prepended with a namespace qualifier. For example, the attributes sym:name and sym:symtab are attributes related to symbol table management and are prefixed with sym:. As a general rule, only those attributes which are directly related to the raw declaration appear without a prefix (type, name, declarator, etc.).

    Target language modules may add additional attributes to nodes to assist the generation of wrapper code. The convention for doing this is to place these attributes in a namespace that matches the name of the target language. For example, python:foo or perl:foo.

    25.4.5 Symbol Tables

    During parsing, all symbols are managed in the space of the target language. The sym:name attribute of each node contains the symbol name selected by the parser. Normally, sym:name and name are the same. However, the %rename directive can be used to change the value of sym:name. You can see the effect of %rename by trying it on a simple interface and dumping the parse tree. For example:
    %rename(foo_i) foo(int);
    %rename(foo_d) foo(double);
    
    void foo(int);
    void foo(double);
    void foo(Bar *b);
    
    Now, running SWIG:
    $ swig -dump_tree example.i
    ...
                +++ cdecl ----------------------------------------
                | sym:name     - "foo_i"
                | name         - "foo"
                | decl         - "f(int)."
                | parms        - int 
                | type         - "void"
                | sym:symtab   - 0x40165078
                | 
                +++ cdecl ----------------------------------------
                | sym:name     - "foo_d"
                | name         - "foo"
                | decl         - "f(double)."
                | parms        - double 
                | type         - "void"
                | sym:symtab   - 0x40165078
                | 
                +++ cdecl ----------------------------------------
                | sym:name     - "foo"
                | name         - "foo"
                | decl         - "f(p.Bar)."
                | parms        - Bar *
                | type         - "void"
                | sym:symtab   - 0x40165078
    
    All symbol-related conflicts and complaints about overloading are based on sym:name values. For instance, the following example uses %rename in reverse to generate a name clash.
    %rename(foo) foo_i(int);
    %rename(foo) foo_d(double;
    
    void foo_i(int);
    void foo_d(double);
    void foo(Bar *b);
    
    When you run SWIG on this you now get:
    $ ./swig example.i
    example.i:6. Overloaded declaration ignored.  foo_d(double )
    example.i:5. Previous declaration is foo_i(int )
    example.i:7. Overloaded declaration ignored.  foo(Bar *)
    example.i:5. Previous declaration is foo_i(int )
    

    25.4.6 The %feature directive

    A number of SWIG directives such as %exception are implemented using the low-level %feature directive. For example:
    %feature("except") getitem(int) {
      try {
         $action
      } catch (badindex) {
         ...
      }
    }
    
    ...
    class Foo {
    public:
        Object *getitem(int index) throws(badindex);
        ...
    };
    
    The behavior of %feature is very easy to describe--it simply attaches a new attribute to any parse tree node that matches the given prototype. When a feature is added, it shows up as an attribute in the feature: namespace. You can see this when running with the -dump_tree option. For example:
     +++ cdecl ----------------------------------------
     | sym:name     - "getitem"
     | name         - "getitem"
     | decl         - "f(int).p."
     | parms        - int 
     | type         - "Object"
     | feature:except - "{\n    try {\n       $action\n    } catc..."
     | sym:symtab   - 0x40168ac8
     | 
    
    Feature names are completely arbitrary and a target language module can be programmed to respond to any feature name that it wants to recognized. The data stored in a feature attribute is usually just a raw unparsed string. For example, the exception code above is simply stored without any modifications.

    25.4.7 Code Generation

    Language modules work by defining handler functions that know how to respond to different types of parse-tree nodes. These handlers simply look at the attributes of each node in order to produce low-level code.

    In reality, the generation of code is somewhat more subtle than simply invoking handler functions. This is because parse-tree nodes might be transformed. For example, suppose you are wrapping a class like this:

    class Foo {
    public:
        virtual int *bar(int x);
    };
    
    When the parser constructs a node for the member bar, it creates a raw "cdecl" node with the following attributes:
    nodeType    : cdecl
    name        : bar
    type        : int
    decl        : f(int).p
    parms       : int x
    storage     : virtual
    sym:name    : bar
    
    To produce wrapper code, this "cdecl" node undergoes a number of transformations. First, the node is recognized as a function declaration. This adjusts some of the type information--specifically, the declarator is joined with the base datatype to produce this:
    nodeType    : cdecl
    name        : bar
    type        : p.int        <-- Notice change in return type
    decl        : f(int).p
    parms       : int x
    storage     : virtual
    sym:name    : bar
    
    Next, the context of the node indicates that the node is really a member function. This produces a transformation to a low-level accessor function like this:
    nodeType    : cdecl
    name        : bar
    type        : int.p
    decl        : f(int).p
    parms       : Foo *self, int x            <-- Added parameter
    storage     : virtual
    wrap:action : result = (arg1)->bar(arg2)  <-- Action code added
    sym:name    : Foo_bar                     <-- Symbol name changed
    
    In this transformation, notice how an additional parameter was added to the parameter list and how the symbol name of the node has suddenly changed into an accessor using the naming scheme described in the "SWIG Basics" chapter. A small fragment of "action" code has also been generated--notice how the wrap:action attribute defines the access to the underlying method. The data in this transformed node is then used to generate a wrapper.

    Language modules work by registering handler functions for dealing with various types of nodes at different stages of transformation. This is done by inheriting from a special Language class and defining a collection of virtual methods. For example, the Python module defines a class as follows:

    class PYTHON : public Language {
    protected:
    public :
      virtual void main(int, char *argv[]);
      virtual int  top(Node *); 
      virtual int  functionWrapper(Node *);
      virtual int  constantWrapper(Node *);
      virtual int  variableWrapper(Node *);
      virtual int  nativeWrapper(Node *);
      virtual int  membervariableHandler(Node *);
      virtual int  memberconstantHandler(Node *);
      virtual int  memberfunctionHandler(Node *);
      virtual int  constructorHandler(Node *);
      virtual int  destructorHandler(Node *);
      virtual int  classHandler(Node *);
      virtual int  classforwardDeclaration(Node *);
      virtual int  insertDirective(Node *);
      virtual int  importDirective(Node *);
    };
    
    The role of these functions is described shortly.

    25.4.8 SWIG and XML

    Much of SWIG's current parser design was originally motivated by interest in using XML to represent SWIG parse trees. Although XML is not currently used in any direct manner, the parse tree structure, use of node tags, attributes, and attribute namespaces are all influenced by aspects of XML parsing. Therefore, in trying to understand SWIG's internal data structures, it may be useful keep XML in the back of your mind as a model.

    25.5 Primitive Data Structures

    Most of SWIG is constructed using three basic data structures: strings, hashes, and lists. These data structures are dynamic in same way as similar structures found in many scripting languages. For instance, you can have containers (lists and hash tables) of mixed types and certain operations are polymorphic.

    This section briefly describes the basic structures so that later sections of this chapter make more sense.

    When describing the low-level API, the following type name conventions are used:

    • String. A string object.
    • Hash. A hash object.
    • List. A list object.
    • String_or_char. A string object or a char *.
    • Object_or_char. An object or a char *.
    • Object. Any object (string, hash, list, etc.)
    In most cases, other typenames in the source are aliases for one of these primitive types. Specifically:
    typedef String SwigType;
    typedef Hash   Parm;
    typedef Hash   ParmList;
    typedef Hash   Node;
    typedef Hash   Symtab;
    typedef Hash   Typetab;
    

    25.5.1 Strings

    String *NewString(const String_or_char *val)

    Creates a new string with initial value val. val may be a char * or another String object. If you want to create an empty string, use "" for val.

    String *NewStringf(const char *fmt, ...)

    Creates a new string whose initial value is set according to a C printf style format string in fmt. Additional arguments follow depending on fmt.

    String *Copy(String *s)

    Make a copy of the string s.

    void Delete(String *s)

    Deletes s.

    int Len(String_or_char *s)

    Returns the length of the string.

    char *Char(String_or_char *s)

    Returns a pointer to the first character in a string.

    void Append(String *s, String_or_char *t)

    Appends t to the end of string s.

    void Insert(String *s, int pos, String_or_char *t)

    Inserts t into s at position pos. The contents of s are shifted accordingly. The special value DOH_END can be used for pos to indicate insertion at the end of the string (appending).

    int Strcmp(const String_or_char *s, const String_or_char *t)

    Compare strings s and t. Same as the C strcmp() function.

    int Strncmp(const String_or_char *s, const String_or_char *t, int len)

    Compare the first len characters of strings s and t. Same as the C strncmp() function.

    char *Strstr(const String_or_char *s, const String_or_char *pat)

    Returns a pointer to the first occurrence of pat in s. Same as the C strstr() function.

    char *Strchr(const String_or_char *s, char ch)

    Returns a pointer to the first occurrence of character ch in s. Same as the C strchr() function.

    void Chop(String *s)

    Chops trailing whitespace off the end of s.

    int Replace(String *s, const String_or_char *pat, const String_or_char *rep, int flags)

    Replaces the pattern pat with rep in string s. flags is a combination of the following flags:
    DOH_REPLACE_ANY       - Replace all occurrences
    DOH_REPLACE_ID        - Valid C identifiers only
    DOH_REPLACE_NOQUOTE   - Don't replace in quoted strings
    DOH_REPLACE_FIRST     - Replace first occurrence only.
    
    Returns the number of replacements made (if any).

    25.5.2 Hashes

    Hash *NewHash()

    Creates a new empty hash table.

    Hash *Copy(Hash *h)

    Make a shallow copy of the hash h.

    void Delete(Hash *h)

    Deletes h.

    int Len(Hash *h)

    Returns the number of items in h.

    Object *Getattr(Hash *h, String_or_char *key)

    Gets an object from h. key may be a string or a simple char * string. Returns NULL if not found.

    int Setattr(Hash *h, String_or_char *key, Object_or_char *val)

    Stores val in h. key may be a string or a simple char *. If val is not a standard object (String, Hash, or List) it is assumed to be a char * in which case it is used to construct a String that is stored in the hash. If val is NULL, the object is deleted. Increases the reference count of val. Returns 1 if this operation replaced an existing hash entry, 0 otherwise.

    int Delattr(Hash *h, String_or_char *key)

    Deletes the hash item referenced by key. Decreases the reference count on the corresponding object (if any). Returns 1 if an object was removed, 0 otherwise.

    List *Keys(Hash *h)

    Returns the list of hash table keys.

    25.5.3 Lists

    List *NewList()

    Creates a new empty list.

    List *Copy(List *x)

    Make a shallow copy of the List x.

    void Delete(List *x)

    Deletes x.

    int Len(List *x)

    Returns the number of items in x.

    Object *Getitem(List *x, int n)

    Returns an object from x with index n. If n is beyond the end of the list, the last item is returned. If n is negative, the first item is returned.

    int *Setitem(List *x, int n, Object_or_char *val)

    Stores val in x. If val is not a standard object (String, Hash, or List) it is assumed to be a char * in which case it is used to construct a String that is stored in the list. n must be in range. Otherwise, an assertion will be raised.

    int *Delitem(List *x, int n)

    Deletes item n from the list, shifting items down if necessary. To delete the last item in the list, use the special value DOH_END for n.

    void Append(List *x, Object_or_char *t)

    Appends t to the end of x. If t is not a standard object, it is assumed to be a char * and is used to create a String object.

    void Insert(String *s, int pos, Object_or_char *t)

    Inserts t into s at position pos. The contents of s are shifted accordingly. The special value DOH_END can be used for pos to indicate insertion at the end of the list (appending). If t is not a standard object, it is assumed to be a char * and is used to create a String object.

    25.5.4 Common operations

    The following operations are applicable to all datatypes.

    Object *Copy(Object *x)

    Make a copy of the object x.

    void Delete(Object *x)

    Deletes x.

    void Setfile(Object *x, String_or_char *f)

    Sets the filename associated with x. Used to track objects and report errors.

    String *Getfile(Object *x)

    Gets the filename associated with x.

    void Setline(Object *x, int n)

    Sets the line number associated with x. Used to track objects and report errors.

    int Getline(Object *x)

    Gets the line number associated with x.

    25.5.5 Iterating over Lists and Hashes

    To iterate over the elements of a list or a hash table, the following functions are used:

    Iterator First(Object *x)

    Returns an iterator object that points to the first item in a list or hash table. The item attribute of the Iterator object is a pointer to the item. For hash tables, the key attribute of the Iterator object additionally points to the corresponding Hash table key. The item and key attributes are NULL if the object contains no items or if there are no more items.

    Iterator Next(Iterator i)

    Returns an iterator that points to the next item in a list or hash table.
    Here are two examples of iteration:
    List *l = (some list);
    Iterator i;
    
    for (i = First(l); i.item; i = Next(i)) {
        Printf(stdout,"%s\n", i.item);
    }
    
    Hash *h = (some hash);
    Iterator j;
    
    for (j = First(j); j.item; j= Next(j)) {
        Printf(stdout,"%s : %s\n", j.key, j.item);
    }
    

    25.5.6 I/O

    Special I/O functions are used for all internal I/O. These operations work on C FILE * objects, String objects, and special File objects (which are merely a wrapper around FILE *).

    int Printf(String_or_FILE *f, const char *fmt, ...)

    Formatted I/O. Same as the C fprintf() function except that output can also be directed to a string object. Note: the %s format specifier works with both strings and char *. All other format operators have the same meaning.

    int Printv(String_or_FILE *f, String_or_char *arg1,..., NULL)

    Prints a variable number of strings arguments to the output. The last argument to this function must be NULL. The other arguments can either be char * or string objects.

    int Putc(int ch, String_or_FILE *f)

    Same as the C fputc() function.

    int Write(String_or_FILE *f, void *buf, int len)

    Same as the C write() function.

    int Read(String_or_FILE *f, void *buf, int maxlen)

    Same as the C read() function.

    int Getc(String_or_FILE *f)

    Same as the C fgetc() function.

    int Ungetc(int ch, String_or_FILE *f)

    Same as the C ungetc() function.

    int Seek(String_or_FILE *f, int offset, int whence)

    Same as the C seek() function. offset is the number of bytes. whence is one of SEEK_SET,SEEK_CUR, or SEEK_END..

    long Tell(String_or_FILE *f)

    Same as the C tell() function.

    File *NewFile(const char *filename, const char *mode)

    Create a File object using the fopen() library call. This file differs from FILE * in that it can be placed in the standard SWIG containers (lists, hashes, etc.).

    File *NewFileFromFile(FILE *f)

    Create a File object wrapper around an existing FILE * object.

    int Close(String_or_FILE *f)

    Closes a file. Has no effect on strings.
    The use of the above I/O functions and strings play a critical role in SWIG. It is common to see small code fragments of code generated using code like this:
    /* Print into a string */
    String *s = NewString("");
    Printf(s,"Hello\n");
    for (i = 0; i < 10; i++) {
        Printf(s,"%d\n", i);
    }
    ...
    /* Print string into a file */
    Printf(f, "%s\n", s);
    
    Similarly, the preprocessor and parser all operate on string-files.

    25.6 Navigating and manipulating parse trees

    Parse trees are built as collections of hash tables. Each node is a hash table in which arbitrary attributes can be stored. Certain attributes in the hash table provide links to other parse tree nodes. The following macros can be used to move around the parse tree.

    String *nodeType(Node *n)

    Returns the node type tag as a string. The returned string indicates the type of parse tree node.

    Node *nextSibling(Node *n)

    Returns the next node in the parse tree. For example, the next C declaration.

    Node *previousSibling(Node *n)

    Returns the previous node in the parse tree. For example, the previous C declaration.

    Node *firstChild(Node *n)

    Returns the first child node. For example, if n was a C++ class node, this would return the node for the first class member.

    Node *lastChild(Node *n)

    Returns the last child node. You might use this if you wanted to append a new node to the of a class.

    Node *parentNode(Node *n)

    Returns the parent of node n. Use this to move up the pass tree.
    The following macros can be used to change all of the above attributes. Normally, these functions are only used by the parser. Changing them without knowing what you are doing is likely to be dangerous.

    void set_nodeType(Node *n, const String_or_char)

    Change the node type. tree node.

    void set_nextSibling(Node *n, Node *s)

    Set the next sibling.

    void set_previousSibling(Node *n, Node *s)

    Set the previous sibling.

    void set_firstChild(Node *n, Node *c)

    Set the first child node.

    void set_lastChild(Node *n, Node *c)

    Set the last child node.

    void set_parentNode(Node *n, Node *p)

    Set the parent node.
    The following utility functions are used to alter the parse tree (at your own risk)

    void appendChild(Node *parent, Node *child)

    Append a child to parent. The appended node becomes the last child.

    void deleteNode(Node *node)

    Deletes a node from the parse tree. Deletion reconnects siblings and properly updates the parent so that sibling nodes are unaffected.

    25.7 Working with attributes

    Since parse tree nodes are just hash tables, attributes are accessed using the Getattr(), Setattr(), and Delattr() operations. For example:
    int functionHandler(Node *n) {
        String *name    = Getattr(n,"name");
        String *symname = Getattr(n,"sym:name");
        SwigType *type  = Getattr(n,"type");
        ...
    }
    
    New attributes can be freely attached to a node as needed. However, when new attributes are attached during code generation, they should be prepended with a namespace prefix. For example:
    ...
    Setattr(n,"python:docstring", doc);     /* Store docstring */
    ...
    

    A quick way to check the value of an attribute is to use the checkAttribute() function like this:

    if (checkAttribute(n,"storage","virtual")) {
       /* n is virtual */
       ...
    }
    

    Changing the values of existing attributes is allowed and is sometimes done to implement node transformations. However, if a function/method modifies a node, it is required to restore modified attributes to their original values. To simplify the task of saving/restoring attributes, the following functions are used:

    int Swig_save(const char *ns, Node *n, const char *name1, const char *name2, ..., NIL)

    Saves a copy of attributes name1, name2, etc. from node n. Copies of the attributes are actually resaved in the node in a different namespace which is set by the ns argument. For example, if you call Swig_save("foo",n,"type",NIL), then the "type" attribute will be copied and saved as "foo:type". The namespace name itself is stored in the "view" attribute of the node. If necessary, this can be examined to find out where previous values of attributes might have been saved.

    int Swig_restore(Node *n)

    Restores the attributes saved by the previous call to Swig_save(). Those attributes that were supplied to Swig_save() will be restored to their original values.
    The Swig_save() and Swig_restore() functions must always be used as a pair. That is, every call to Swig_save() must have a matching call to Swig_restore(). Calls can be nested if necessary. Here is an example that shows how the functions might be used:
    int variableHandler(Node *n) {
        Swig_save("variableHandler",n,"type","sym:name",NIL);
        String *symname = Getattr(n,"sym:name");
        SwigType *type  = Getattr(n,"type");
        ...
        Append(symname,"_global");         // Change symbol name
        SwigType_add_pointer(type);        // Add pointer
        ...
        generate wrappers
        ...
        Swig_restore(n);                  // Restore original values
        return SWIG_OK;
    }
    

    int Swig_require(const char *ns, Node *n, const char *name1, const char *name2, ..., NIL)

    This is an enhanced version of Swig_save() that adds error checking. If an attribute name is not present in n, a failed assertion results and SWIG terminates with a fatal error. Optionally, if an attribute name is specified as "*name", a copy of the attribute is saved as with Swig_save(). If an attribute is specified as "?name", the attribute is optional. Swig_restore() must always be called after using this function.

    25.8 Type system

    SWIG implements the complete C++ type system including typedef, inheritance, pointers, references, and pointers to members. A detailed discussion of type theory is impossible here. However, let's cover the highlights.

    25.8.1 String encoding of types

    All types in SWIG consist of a base datatype and a collection of type operators that are applied to the base. A base datatype is almost always some kind of primitive type such as int or double. The operators consist of things like pointers, references, arrays, and so forth. Internally, types are represented as strings that are constructed in a very precise manner. Here are some examples:

    C datatype                     SWIG encoding (strings)
    -----------------------------  --------------------------
    int                            "int"
    int *                          "p.int"
    const int *                    "p.q(const).int"
    int (*x)(int,double)           "p.f(int,double).int"
    int [20][30]                   "a(20).a(30).int"
    int (F::*)(int)                "m(F).f(int).int"
    vector<int> *                  "p.vector<(int)>"
    
    Reading the SWIG encoding is often easier than figuring out the C code---just read it from left to right. For a type of "p.f(int,double).int" is a "pointer to a function(int,double) that returns int".

    The following operator encodings are used in type strings:

    Operator              Meaning
    -------------------   -------------------------------
    p.                    Pointer to
    a(n).                 Array of dimension n
    r.                    C++ reference
    m(class).             Member pointer to class
    f(args).              Function.
    q(qlist).             Qualifiers
    
    In addition, type names may be parameterized by templates. This is represented by enclosing the template parameters in <( ... )>. Variable length arguments are represented by the special base type of v(...).

    If you want to experiment with type encodings, the raw type strings can be inserted into an interface file using backticks `` wherever a type is expected. For instance, here is an extremely perverted example:

    `p.a(10).p.f(int,p.f(int).int)` foo(int, int (*x)(int));
    
    This corresponds to the immediately obvious C declaration:
    (*(*foo(int,int (*)(int)))[10])(int,int (*)(int));
    
    Aside from the potential use of this declaration on a C programming quiz, it motivates the use of the special SWIG encoding of types. The SWIG encoding is much easier to work with because types can be easily examined, modified, and constructed using simple string operations (comparison, substrings, concatenation, etc.). For example, in the parser, a declaration like this
    int *a[30];
    
    is processed in a few pieces. In this case, you have the base type "int" and the declarator of type "a(30).p.". To make the final type, the two parts are just joined together using string concatenation.

    25.8.2 Type construction

    The following functions are used to construct types. You should use these functions instead of trying to build the type strings yourself.

    void SwigType_add_pointer(SwigType *ty)

    Adds a pointer to ty.

    void SwigType_del_pointer(SwigType *ty)

    Removes a single pointer from ty.

    void SwigType_add_reference(SwigType *ty)

    Adds a reference to ty.

    void SwigType_add_array(SwigType *ty, String_or_char *dim)

    Adds an array with dimension dim to ty.

    void SwigType_add_qualifier(SwigType *ty, String_or_char *q)

    Adds a type qualifier q to ty. q is typically "const" or "volatile".

    void SwigType_add_memberpointer(SwigType *ty, String_or_char *cls)

    Adds a pointer to a member of class cls to ty.

    void SwigType_add_function(SwigType *ty, ParmList *p)

    Adds a function to ty. p is a linked-list of parameter nodes as generated by the parser. See the section on parameter lists for details about the representation.

    void SwigType_add_template(SwigType *ty, ParmList *p)

    Adds a template to ty. p is a linked-list of parameter nodes as generated by the parser. See the section on parameter lists for details about the representation.

    SwigType *SwigType_pop(SwigType *ty)

    Removes the last type constructor from ty and returns it. ty is modified.

    void SwigType_push(SwigType *ty, SwigType *op)

    Pushes the type operators in op onto type ty. The opposite of SwigType_pop().

    SwigType *SwigType_pop_arrays(SwigType *ty)

    Removes all leading array operators from ty and returns them. ty is modified. For example, if ty is "a(20).a(10).p.int", then this function would return "a(20).a(10)." and modify ty so that it has the value "p.int".

    SwigType *SwigType_pop_function(SwigType *ty)

    Removes a function operator from ty including any qualification. ty is modified. For example, if ty is "f(int).int", then this function would return "f(int)." and modify ty so that it has the value "int".

    SwigType *SwigType_base(SwigType *ty)

    Returns the base type of a type. For example, if ty is "p.a(20).int", this function would return "int". ty is unmodified.

    SwigType *SwigType_prefix(SwigType *ty)

    Returns the prefix of a type. For example, if ty is "p.a(20).int", this function would return "p.a(20).". ty is unmodified.

    25.8.3 Type tests

    The following functions can be used to test properties of a datatype.

    int SwigType_ispointer(SwigType *ty)

    Checks if ty is a standard pointer.

    int SwigType_ismemberpointer(SwigType *ty)

    Checks if ty is a member pointer.

    int SwigType_isreference(SwigType *ty)

    Checks if ty is a C++ reference.

    int SwigType_isarray(SwigType *ty)

    Checks if ty is an array.

    int SwigType_isfunction(SwigType *ty)

    Checks if ty is a function.

    int SwigType_isqualifier(SwigType *ty)

    Checks if ty is a qualifier.

    int SwigType_issimple(SwigType *ty)

    Checks if ty is a simple type. No operators applied.

    int SwigType_isconst(SwigType *ty)

    Checks if ty is a const type.

    int SwigType_isvarargs(SwigType *ty)

    Checks if ty is a varargs type.

    int SwigType_istemplate(SwigType *ty)

    Checks if ty is a templatized type.

    25.8.4 Typedef and inheritance

    The behavior of typedef declaration is to introduce a type alias. For instance, typedef int Integer makes the identifier Integer an alias for int. The treatment of typedef in SWIG is somewhat complicated due to the pattern matching rules that get applied in typemaps and the fact that SWIG prefers to generate wrapper code that closely matches the input to simplify debugging (a user will see the typedef names used in their program instead of the low-level primitive C datatypes).

    To handle typedef, SWIG builds a collection of trees containing typedef relations. For example,

    typedef int Integer;
    typedef Integer *IntegerPtr;
    typedef int Number;
    typedef int Size;
    
    produces two trees like this:
                     int               p.Integer
                   ^  ^  ^                 ^ 
                  /   |   \                |
                 /    |    \               |
            Integer  Size   Number    IntegerPtr
    
    To resolve a single typedef relationship, the following function is used:

    SwigType *SwigType_typedef_resolve(SwigType *ty)

    Checks if ty can be reduced to a new type via typedef. If so, returns the new type. If not, returns NULL.
    Typedefs are only resolved in simple typenames that appear in a type. For example, the type base name and in function parameters. When resolving types, the process starts in the leaf nodes and moves up the tree towards the root. Here are a few examples that show how it works:
    Original type            After typedef_resolve()
    ------------------------ -----------------------
    Integer                  int
    a(30).Integer            int
    p.IntegerPtr             p.p.Integer
    p.p.Integer              p.p.int
    
    For complicated types, the process can be quite involved. Here is the reduction of a function pointer:
    p.f(Integer, p.IntegerPtr, Size).Integer          : Start
    p.f(Integer, p.IntegerPtr, Size).int
    p.f(int, p.IntegerPtr, Size).int
    p.f(int, p.p.Integer, Size).int
    p.f(int, p.p.int, Size).int
    p.f(int, p.p.int, int).int                        : End
    
    Two types are equivalent if their full type reductions are the same. The following function will fully reduce a datatype:

    SwigType *SwigType_typedef_resolve_all(SwigType *ty)

    Fully reduces ty according to typedef rules. Resulting datatype will consist only of primitive typenames.

    25.8.5 Lvalues

    When generating wrapper code, it is necessary to emit datatypes that can be used on the left-hand side of an assignment operator (an lvalue). However, not all C datatypes can be used in this way---especially arrays and const-qualified types. To generate a type that can be used as an lvalue, use the following function:

    SwigType *SwigType_ltype(SwigType *ty)

    Converts type ty to a type that can be used as an lvalue in assignment. The resulting type is stripped of qualifiers and arrays are converted to a pointers.
    The creation of lvalues is fully aware of typedef and other aspects of the type system. Therefore, the creation of an lvalue may result in unexpected results. Here are a few examples:
    typedef double Matrix4[4][4];
    Matrix4 x;    // type = 'Matrix4', ltype='p.a(4).double'
    
    typedef const char * Literal;
    Literal y;    // type = 'Literal', ltype='p.char'
    

    25.8.6 Output functions

    The following functions produce strings that are suitable for output.

    String *SwigType_str(SwigType *ty, String_or_char *id = 0)

    Generates a C string for a datatype. id is an optional declarator. For example, if ty is "p.f(int).int" and id is "foo", then this function produces "int (*foo)(int)". This function is used to convert string-encoded types back into a form that is valid C syntax.

    String *SwigType_lstr(SwigType *ty, String_or_char *id = 0)

    This is the same as SwigType_str() except that the result is generated from the type's lvalue (as generated from SwigType_ltype).

    String *SwigType_lcaststr(SwigType *ty, String_or_char *id = 0)

    Generates a casting operation that converts from type ty to its lvalue. id is an optional name to include in the cast. For example, if ty is "q(const).p.char" and id is "foo", this function produces the string "(char *) foo".

    String *SwigType_rcaststr(SwigType *ty, String_or_char *id = 0)

    Generates a casting operation that converts from a type's lvalue to a type equivalent to ty. id is an optional name to include in the cast. For example, if ty is "q(const).p.char" and id is "foo", this function produces the string "(const char *) foo".

    String *SwigType_manglestr(SwigType *ty)

    Generates a mangled string encoding of type ty. The mangled string only contains characters that are part of a valid C identifier. The resulting string is used in various parts of SWIG, but is most commonly associated with type-descriptor objects that appear in wrappers (e.g., SWIGTYPE_p_double).

    25.9 Parameters

    Several type-related functions involve parameter lists. These include functions and templates. Parameter list are represented as a list of nodes with the following attributes:
    "type"        -  Parameter type  (required)
    "name"        -  Parameter name  (optional)
    "value"       -  Initializer     (optional)
    
    Typically parameters are denoted in the source by using a typename of Parm * or ParmList *. To walk a parameter list, simply use code like this:
    Parm *parms;
    Parm *p;
    for (p = parms; p; p = nextSibling(p)) {
        SwigType *type  = Getattr(p,"type");
        String   *name  = Getattr(p,"name");
        String   *value = Getattr(p,"value");
        ...
    }
    
    Note: this code is exactly the same as what you would use to walk parse tree nodes.

    An empty list of parameters is denoted by a NULL pointer.

    Since parameter lists are fairly common, the following utility functions are provided to manipulate them:

    Parm *CopyParm(Parm *p);

    Copies a single parameter.

    ParmList *CopyParmList(ParmList *p);

    Copies an entire list of parameters.

    int ParmList_len(ParmList *p);

    Returns the number of parameters in a parameter list.

    String *ParmList_str(ParmList *p);

    Converts a parameter list into a C string. For example, produces a string like "(int *p, int n, double x);".

    String *ParmList_protostr(ParmList *p);

    The same as ParmList_str() except that parameter names are not included. Used to emit prototypes.

    int ParmList_numrequired(ParmList *p);

    Returns the number of required (non-optional) arguments in p.

    25.10 Writing a Language Module

    This section briefly outlines the steps needed to create a bare-bones language module. For more advanced techniques, you should look at the implementation of existing modules. Since the code is relatively easy to read, this section describes the creation of a minimal Python module. You should be able to extrapolate this to other languages.

    25.10.1 Execution model

    Code generation modules are defined by inheriting from the Language class, currently defined in the Source/Modules1.1 directory of SWIG. Starting from the parsing of command line options, all aspects of code generation are controlled by different methods of the Language that must be defined by your module.

    25.10.2 Starting out

    To define a new language module, first create a minimal implementation using this example as a guide:
    #include "swigmod.h"
    
    #ifndef MACSWIG
    #include "swigconfig.h"
    #endif
    
    class PYTHON : public Language {
    public:
    
      virtual void main(int argc, char *argv[]) {
        printf("I'm the Python module.\n");
      }
    
      virtual int top(Node *n) {
        printf("Generating code.\n");
        return SWIG_OK;
      }
      
    };
    
    extern "C" Language *
    swig_python(void) {
      return new PYTHON();
    }
    
    The "swigmod.h" header file contains, among other things, the declaration of the Language base class and so you should include it at the top of your language module's source file. Similarly, the "swigconfig.h" header file contains some other useful definitions that you may need. Note that you should not include any header files that are installed with the target language. That is to say, the implementation of the SWIG Python module shouldn't have any dependencies on the Python header files. The wrapper code generated by SWIG will almost always depend on some language-specific C/C++ header files, but SWIG itself does not.

    Give your language class a reasonable name, usually the same as the target language. By convention, these class names are all uppercase (e.g. "PYTHON" for the Python language module) but this is not a requirement. This class will ultimately consist of a number of overrides of the virtual functions declared in the Language base class, in addition to any language-specific member functions and data you need. For now, just use the dummy implementations shown above.

    The language module ends with a factory function, swig_python(), that simply returns a new instance of the language class. As shown, it should be declared with the extern "C" storage qualifier so that it can be called from C code. It should also return a pointer to the base class (Language) so that only the interface (and not the implementation) of your language module is exposed to the rest of SWIG.

    Save the code for your language module in a file named "python.cxx" and. place this file in the Source/Modules1.1 directory of the SWIG distribution. To ensure that your module is compiled into SWIG along with the other language modules, modify the file Source/Modules1.1/Makefile.in to include the additional source files. Look for the lines that define the SRCS and OBJS variables and add entries for your language. In addition, modify the file Source/Modules1.1/swigmain.cxx with an additional command line option that activates the module. Read the source---it's straightforward.

    Next, at the top level of the SWIG distribution, re-run the autogen.sh script to regenerate the various build files:

    $ sh autogen.sh
    
    Next re-run configure to regenerate all of the Makefiles:
    $ ./configure
    
    Finally, rebuild SWIG with your module added:
    $ make
    
    Once it finishes compiling, try running SWIG with the command-line option that activates your module. For example, swig -python foo.i. The messages from your new module should appear.

    25.10.3 Command line options

    When SWIG starts, the command line options are passed to your language module. This occurs before any other processing occurs (preprocessing, parsing, etc.). To capture the command line options, simply use code similar to this:
    void Language::main(int argc, char *argv[]) {
      for (int i = 1; i < argc; i++) {
          if (argv[i]) {
              if(strcmp(argv[i],"-interface") == 0) {
                if (argv[i+1]) {
                  interface = NewString(argv[i+1]);
                  Swig_mark_arg(i);
                  Swig_mark_arg(i+1);
                  i++;
                } else {
                  Swig_arg_error();
                }
    	  } else if (strcmp(argv[i],"-globals") == 0) {
    	    if (argv[i+1]) {
    	      global_name = NewString(argv[i+1]);
    	      Swig_mark_arg(i);
    	      Swig_mark_arg(i+1);
    	      i++;
    	    } else {
    	      Swig_arg_error();
    	    }
    	  } else if ((strcmp(argv[i],"-shadow") == 0) || ((strcmp(argv[i],"-proxy") == 0))) {
    	    shadow = 1;
    	    Swig_mark_arg(i);
    	  } else if (strcmp(argv[i],"-keyword") == 0) {
    	    use_kw = 1;
    	    Swig_mark_arg(i);
    	  } else if (strcmp(argv[i],"-help") == 0) {
    	    fputs(usage,stderr);
    	  }
              ...
          }
      }
    }
    
    The exact set of options depends on what you want to do in your module. Generally, you would use the options to change code generation modes or to print diagnostic information.

    If a module recognizes an option, it should always call Swig_mark_arg() to mark the option as valid. If you forget to do this, SWIG will terminate with an unrecognized command line option error.

    25.10.4 Configuration and preprocessing

    In addition to looking at command line options, the main() method is responsible for some initial configuration of the SWIG library and preprocessor. To do this, insert some code like this:
    void main(int argc, char *argv[]) {
       ... command line options ...
    
       /* Set language-specific subdirectory in SWIG library */
       SWIG_library_directory("python"); 
    
       /* Set language-specific preprocessing symbol */
       Preprocessor_define("SWIGPYTHON 1", 0);
       
       /* Set language-specific configuration file */
       SWIG_config_file("python.swg");
    
       /* Set typemap language (historical) */
       SWIG_typemap_lang("python");
    }
    
    The above code does several things--it registers the name of the language module with the core, it supplies some preprocessor macro definitions for use in input files (so that they can determine the target language), and it registers a start-up file. In this case, the file python.swg will be parsed before any part of the user-supplied input file.

    Before proceeding any further, create a directory for your module in the SWIG library (The Lib directory). Now, create a configuration file in the directory. For example, python.swg.

    Just to review, your language module should now consist of two files-- an implementation file python.cxx and a configuration file python.swg.

    25.10.5 Entry point to code generation

    SWIG is a multi-pass compiler. Once the main() method has been invoked, the language module does not execute again until preprocessing, parsing, and a variety of semantic analysis passes have been performed. When the core is ready to start generating wrappers, it invokes the top() method of your language class. The argument to top is a single parse tree node that corresponds to the top of the entire parse tree.

    To get the code generation process started, the top() procedure needs to do several things:

    • Initialize the wrapper code output.
    • Set the module name.
    • Emit common initialization code.
    • Emit code for all of the child nodes.
    • Finalize the wrapper module and cleanup.

    An outline of top() might be as follows:

    int Python::top(Node *n) {
    
       /* Get the module name */
       String *module = Getattr(n,"name");  
    
       /* Get the output file name */
       String *outfile = Getattr(n,"outfile");
    
       /* Initialize I/O (see next section) */
       ...
    
       /* Output module initialization code */
       ...
    
       /* Emit code for children */
       Language::top(n); 
    
       ...
       /* Cleanup files */
       ...
    
       return SWIG_OK;
    }
    

    25.10.6 Module I/O and wrapper skeleton

    25.10.7 Low-level code generators

    25.10.8 Configuration files

    At the time of this writing, SWIG supports nearly a dozen languages, which means that for continued sanity in maintaining the configuration files, the language modules need to follow some conventions. These are outlined here along with the admission that, yes it is ok to violate these conventions in minor ways, as long as you know where to apply the proper kludge to keep the overall system regular and running. Engineering is the art of compromise, see...

    Much of the maintenance regularity depends on choosing a suitable nickname for your language module (and then using it in a controlled way). Nicknames should be all lower case letters with an optional numeric suffix (no underscores, no dashes, no spaces). Some examples are: foo, bar, qux99.

    The numeric suffix variant, as in the last example, is somewhat tricky to work with because sometimes people expect to refer to the language without this number but sometimes that number is extremely relevant (especially when it corresponds to langauge implementation versions with incompatible interfaces). New language modules that unavoidably require a numeric suffix in their nickname should include that number in all uses, or be prepared to kludge.

    The nickname is used in four places:
    usagetransform
    "skip" tag(none)
    Examples/ subdir name(none)
    Examples/GIFPlot/ subdir name capitalize (upcase first letter)
    Examples/test-suite/ subdir name(none)

    As you can see, most usages are direct.

    configure.in
    This file is processed by autoconf to generate the configure script. This is where you need to add shell script fragments and autoconf macros to detect the presence of whatever development support your language module requires, typically directories where headers and libraries can be found, and/or utility programs useful for integrating the generated wrapper code.

    Use the AC_ARG_WITH, AC_MSG_CHECKING, AC_SUBST macros and so forth (see other languages for examples). Avoid using the [ and ] character in shell script fragments. The variable names passed to AC_SUBST should begin with the nickname, entirely upcased.

    At the end of the new section is the place to put the aforementioned nickname kludges (should they be needed). See Perl5 and Php4 for examples of what to do. [If this is still unclear after you've read the code, ping me and I'll expand on this further. --ttn]

    Makefile.in
    Some of the variables AC_SUBSTitutued are essential to the support of your language module. Fashion these into a shell script "test" clause and assign that to a skip tag using "-z" and "-o":

    skip-qux99 = [ -z "@QUX99INCLUDE@" -o -z "@QUX99LIBS" ]

    This means if those vars should ever be empty, qux99 support should be considered absent and so it would be a good idea to skip actions that might rely on it.

    Here is where you may also define an alias (but then you'll need to kludge --- don't do this):

    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). 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 these kinds of problems.

    Examples/Makefile.in
    Nothing special here; see comments at top the of this file and look to the existing languages for examples.

    Examples/qux99/check.list
    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 all *.i and *.swg files from the language-specific subdirectory of Lib. Use (optional) file extra-install.list in that directory to name additional files to install (see ruby for example).

    Runtime/Makefile.in
    Add another make invocation to all, and a section for your language module.

    Source/Modules1.1/Makefile.in
    Add appropriate entries for vars OBJS and SRCS. That's it!

    At some point it would be a good idea to use automake to handle some of these configuration tasks, but that point is now long past. If you are interested in working on that, feel free to raise the issue in the context of a next-generation clean-slate SWIG.

    25.10.9 Runtime support

    Discuss the kinds of functions typically needed for SWIG runtime support (e.g. SWIG_ConvertPtr() and SWIG_NewPointerObj()) and the names of the SWIG files that implement those functions.

    25.10.10 Standard library files

    Discuss the standard library files that most language modules provide, e.g.
    • typemaps.i
    • std_string.i
    • std_vector.i
    • stl.i

    25.10.11 Examples and test cases

    Each of the language modules provides one or more examples. These examples are used to demonstrate different features of the language module to SWIG end-users, but you'll find that they're useful during development and testing of your language module as well. You can use examples from the existing SWIG language modules for inspiration.

    Each example is self-contained and consists of (at least) a Makefile, a SWIG interface file for the example module, and a script that demonstrates the functionality for that module. All of these files are stored in the same subdirectory, and that directory should be nested under Examples/python. For example, the files for the Python "simple" example are found in Examples/python/simple.

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

    25.10.12 Documentation

    Don't forget to write end-user documentation for your language module. Currently, each language module has a dedicated chapter (although this structure may change in the future). You shouldn't rehash things that are already covered in sufficient detail in the SWIG Basics and SWIG and C++ chapters. There is no fixed format for what, exactly, you should document about your language module, but you'll obviously want to cover issues that are unique to your language.

    Some topics that you'll want to be sure to address include:

    • Command line options unique to your language module.
    • Non-obvious mappings between C/C++ and scripting language concepts. For example, if your scripting language provides a single floating point type, it should be no big surprise to find that C/C++ float and double types are mapped to it. On the other hand, if your scripting language doesn't provide support for "classes" or something similar, you'd want to discuss how C++ classes are handled.
    • How to compile the SWIG-generated wrapper code into shared libraries that can actually be used. For some languages, there are well-defined procedures for doing this, but for others it's an ad hoc process. Provide as much detail as appropriate, and links to other resources if available.

    25.11 Typemaps

    25.11.1 Proxy classes

    25.12 Guide to parse tree nodes

    This section describes the different parse tree nodes and their attributes.

    cdecl

    Describes general C declarations including variables, functions, and typedefs. A declaration is parsed as "storage T D" where storage is a storage class, T is a base type, and D is a declarator.
    "name"          - Declarator name
    "type"          - Base type T
    "decl"          - Declarator type (abstract)
    "storage"       - Storage class (static, extern, typedef, etc.)
    "parms"         - Function parameters (if a function)
    "code"          - Function body code (if supplied)
    "value"         - Default value (if supplied)
    

    constructor

    C++ constructor declaration.
    "name"          - Name of constructor
    "parms"         - Parameters
    "decl"          - Declarator (function with parameters)
    "code"          - Function body code (if any)
    "feature:new"   - Set to indicate return of new object.
    

    destructor

    C++ destructor declaration.
    "name"          - Name of destructor
    "code"          - Function body code (if any)
    "storage"       - Storage class (set if virtual)
    "value"         - Default value (set if pure virtual).
    

    access

    C++ access change.
    "kind"          - public, protected, private
    

    constant

    Constant created by %constant or #define.
    "name"          - Name of constant.
    "type"          - Base type.
    "value"         - Value.
    "storage"       - Set to %constant
    "feature:immutable" - Set to indicate read-only
    

    class

    C++ class definition or C structure definition.
    "name"          - Name of the class.
    "kind"          - Class kind ("struct", "union", "class")
    "symtab"        - Enclosing symbol table.
    "tdname"        - Typedef name. Use for typedef struct { ... } A.
    "abstract"      - Set if class has pure virtual methods.
    "baselist"      - List of base class names.
    "storage"       - Storage class (if any)
    "unnamed"       - Set if class is unnamed.
    

    enum

    Enumeration.
    "name"          - Name of the enum (if supplied).
    "storage"       - Storage class (if any)
    "tdname"        - Typedef name (typedef enum { ... } name).
    "unnamed"       - Set if enum is unnamed.
    

    enumitem

    Enumeration value.
    "name"          - Name of the enum value.
    "type"          - Type (integer or char)
    "value"         - Enum value (if given)
    "feature:immutable" - Set to indicate read-only
    

    namespace

    C++ namespace.
    "name"          - Name of the namespace.
    "symtab"        - Symbol table for enclosed scope.
    "unnamed"       - Set if unnamed namespace
    "alias"         - Alias name. Set for namespace A = B;
    

    using

    C++ using directive.
    "name"          - Name of the object being referred to.
    "uname"         - Qualified name actually given to using.
    "node"          - Node being referenced.
    "namespace"     - Namespace name being reference (using namespace name)
    

    classforward

    A forward C++ class declaration.
    "name"          - Name of the class.
    "kind"          - Class kind ("union", "struct", "class")
    

    insert

    Code insertion directive. For example, %{ ... %} or %insert(section).
    "code"          - Inserted code
    "section"       - Section name ("header", "wrapper", etc.)
    

    top

    Top of the parse tree.
    "module"        - Module name
    

    extend

    %extend directive.
    "name"          - Module name
    "symtab"        - Symbol table of enclosed scope.
    

    apply

    %apply pattern { patternlist }.
    "pattern"       - Source pattern.
    "symtab"        - Symbol table of enclosed scope.
    

    clear

    %clear patternlist;
    "firstChild"    - Patterns to clear
    

    include

    %include directive.
    "name"         - Filename
    "firstChild"   - Children
    

    import

    %import directive.
    "name"         - Filename
    "firstChild"   - Children
    

    module

    %module directive.
    "name"         - Name of the module
    

    typemap

    %typemap directive.
    "method"       - Typemap method name.
    "code"         - Typemap code.
    "kwargs"       - Keyword arguments (if any)
    "firstChild"   - Typemap patterns
    

    typemapcopy

    %typemap directive with copy.
    "method"       - Typemap method name.
    "pattern"      - Typemap source pattern.
    "firstChild"   - Typemap patterns
    

    typemapitem

    %typemap pattern. Used with %apply, %clear, %typemap.
    "pattern"      - Typemap pattern (a parameter list)
    "parms"        - Typemap parameters.
    

    types

    %types directive.
    "parms"        - List of parameter types.
    

    extern

    extern "X" { ... } declaration.
    "name"       - Name "C", "Fortran", etc.
    

    SWIG 1.3 - Last Modified : January 22, 2002
    cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/Guile.html0000644000175000000620000010401012561312226021446 0ustar stevestaff SWIG and Guile

    16 SWIG and Guile

    This section details guile-specific support in SWIG.

    16.1 Meaning of "Module"

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

    16.2 Using the SCM or GH Guile API

    The guile module can currently export wrapper files that use the guile GH interface or the SCM interface. This is controlled by an argument passed to swig. The "-gh" argument causes swig to output GH code, and the "-scm" argument causes swig to output SCM code. Right now the "-gh" argument is the default. The "-scm" wrapper generation assumes a guile version >= 1.6 and has several advantages over the "-gh" wrapper generation including garbage collection and GOOPS support. The "-gh" wrapper generation can be used for older versions of guile. Thus eventually the guile GH wrapper code generation will be depreciated (as guile 1.6 and above become more common) and the SCM interface will become the default. The SCM and GH interface differ greatly in how they store pointers and have completely different run-time code. See below for more info. make runtime will now produce two libraries, libguile (with the GH interface) and libguilescm (with the SCM interface)

    The GH interface to guile is deprecated. Read more about why in the 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 using a high level API. So even though the GH interface is depreciated, SWIG will continue to use the GH interface and provide mappings from the GH interface to whatever API we need. We can maintain this mapping where guile failed because SWIG uses a small subset of all the GH functions which map easily. All the guile typemaps like typemaps.i and std_vector.i will continue to use the GH functions to do things like create lists of values, convert strings to integers, etc. Then every language module will define a mapping between the GH interface and whatever custom API the language uses. This is currently implemented by the guile module to use the SCM guile API rather than the GH guile API. For example, here are some of the current mapping file for the SCM API

    
    #define gh_append2(a, b) scm_append(scm_listify(a, b, SCM_UNDEFINED)) 
    #define gh_apply(a, b) scm_apply(a, b, SCM_EOL) 
    #define gh_bool2scm SCM_BOOL 
    #define gh_boolean_p SCM_BOOLP 
    #define gh_car SCM_CAR 
    #define gh_cdr SCM_CDR 
    #define gh_cons scm_cons 
    #define gh_double2scm scm_make_real 
    ...
    

    This file is parsed by SWIG at wrapper generation time, so every reference to a gh_ function is replaced by a scm_ function in the wrapper file. Thus the gh_ function calls will never be seen in the wrapper; the wrapper will look exactly like it was generated for the specific API. Currently only the guile language module has created a mapping policy from gh_ to scm_, 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.

    16.3 Linkage

    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.

    16.3.1 Simple Linkage

    The default linkage is the simplest; nothing special is done. In this case the function SWIG_init() is exported. Simple linkage can be used in several ways:
    • Embedded Guile, no modules. You want to embed a Guile interpreter into your program; all bindings made by SWIG shall show up in the root module. Then call SWIG_init() in the inner_main() function. See the "simple" and "matrix" examples under Examples/guile.
    • Dynamic module mix-in. You want to create a Guile module using define-module, containing both Scheme code and bindings made by SWIG; you want to load the SWIG modules as shared libraries into Guile.
      (define-module (my module))
      (define my-so (dynamic-link "./example.so"))
      (dynamic-call "SWIG_init" my-so) ; make SWIG bindings
      ;; Scheme definitions can go here
      
      Newer Guile versions provide a shorthand for dynamic-link and dynamic-call:
      (load-extension "./example.so" "SWIG_init")
      
      You need to explicitly export those bindings made by SWIG that you want to import into other modules:
      (export foo bar)
      
      In this example, the procedures foo and bar would be exported. Alternatively, you can export all bindings with the following module-system hack:
      (module-map (lambda (sym var)
      	      (module-export! (current-module) (list sym)))
      	    (current-module))
      

      SWIG can also generate this Scheme stub (from define-module up to export) semi-automagically if you pass it the command-line argument -scmstub. The code will be exported in a file called module.scm in the directory specified by -outdir or the current directory if -outdir is not specified. Since SWIG doesn't know how to load your extension module (with dynamic-link or load-extension), you need to supply this information by including a directive like this in the interface file:

      %scheme %{ (load-extension "./example.so" "SWIG_init") %}
      
      (The %scheme directive allows to insert arbitrary Scheme code into the generated file module.scm; it is placed between the define-module form and the export form.)

    If you want to include several SWIG modules, you would need to rename SWIG_init via a preprocessor define to avoid symbol clashes. For this case, however, passive linkage is available.

    16.3.2 Passive Linkage

    Passive linkage is just like simple linkage, but it generates an initialization function whose name is derived from the module and package name (see below).

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

    16.3.3 Native Guile Module Linkage

    SWIG can also generate wrapper code that does all the Guile module declarations on its own if you pass it the -Linkage module command-line option. This requires Guile 1.5.0 or later.

    The module name is set with the -package and -module command-line options. Suppose you want to define a module with name (my lib foo); then you would have to pass the options -package my/lib -module foo. Note that the last part of the name can also be set via the SWIG directive %module.

    You can use this linkage in several ways:

    • Embedded Guile with SWIG modules. You want to embed a Guile interpreter into your program; the SWIG bindings shall be put into different modules. Simply call the function scm_init_my_modules_foo_module in the inner_main() function.
    • Dynamic Guile modules. You want to load the SWIG modules as shared libraries into Guile; all bindings are automatically put in newly created Guile modules.
      (define my-so (dynamic-link "./foo.so"))
      ;; create new module and put bindings there:
      (dynamic-call "scm_init_my_modules_foo_module" my-so) 
      
      Newer Guile versions have a shorthand procedure for this:
      (load-extension "./foo.so" "scm_init_my_modules_foo_module")
      

    16.3.4 Old Auto-Loading Guile Module Linkage

    Guile used to support an autoloading facility for object-code modules. This support has been marked deprecated in version 1.4.1 and is going to disappear sooner or later. SWIG still supports building auto-loading modules if you pass it the -Linkage ltdlmod command-line option.

    Auto-loading worked like this: Suppose a module with name (my lib foo) is required and not loaded yet. Guile will then search all directories in its search path for a Scheme file my/modules/foo.scm or a shared library my/modules/libfoo.so (or my/modules/libfoo.la; see the GNU libtool documentation). If a shared library is found that contains the symbol scm_init_my_modules_foo_module, the library is loaded, and the function at that symbol is called with no arguments in order to initialize the module.

    When invoked with the -Linkage ltdlmod command-line option, SWIG generates an exported module initialization function with an appropriate name.

    16.3.5 Hobbit4D Linkage

    The only other linkage supported at this time creates shared object libraries suitable for use by hobbit's (hobbit4d link) guile module. This is called the "hobbit" linkage, and requires also using the "-package" command line option to set the part of the module name before the last symbol. For example, both command lines:

    swig -guile -package my/lib foo.i
    swig -guile -package my/lib -module foo foo.i
    
    would create module (my lib foo) (assuming in the first case foo.i declares the module to be "foo"). The installed files are my/lib/libfoo.so.X.Y.Z and friends. This scheme is still very experimental; the (hobbit4d link) conventions are not well understood.

    16.3.6 General Remarks on Multiple SWIG Modules

    If you want to use multiple SWIG modules, they have to share some run-time data for the typing system. You have two options:
    • Either generate all but one wrapper module with the -c command-line argument. Compile all wrapper files with the C compiler switch -DSWIG_GLOBAL.
    • Or generate all wrapper modules with the -c command-line argument and compile all wrapper files with the C compiler switch -DSWIG_GLOBAL. Then link against the runtime library libswigguile or libswigguilescm, which is built by make runtime. The needed linker flags are reported by SWIG if you invoke it with the -guile -ldflags command-line arguments.

    16.4 Underscore Folding

    Underscores are converted to dashes in identifiers. Guile support may grow an option to inhibit this folding in the future, but no one has complained so far.

    You can use the SWIG directives %name and %rename to specify the Guile name of the wrapped functions and variables (see CHANGES).

    16.5 Typemaps

    The Guile module handles all types via typemaps. This information is read from Lib/guile/typemaps.i. Some non-standard typemap substitutions are supported:

    • $descriptor expands to a type descriptor for use with the SWIG_NewPointerObj() and SWIG_ConvertPtr functions.
    • For pointer types, $*descriptor expands to a descriptor for the direct base type (i.e., one pointer is stripped), whereas $basedescriptor expands to a descriptor for the base type (i.e., all pointers are stripped).

    A function returning void (more precisely, a function whose out typemap returns SCM_UNSPECIFIED) is treated as returning no values. In argout typemaps, one can use the macro GUILE_APPEND_RESULT in order to append a value to the list of function return values.

    Multiple values can be passed up to Scheme in one of three ways:

    • Multiple values as lists. By default, if more than one value is to be returned, a list of the values is created and returned; to switch back to this behavior, use
      %values_as_list;
    • Multiple values as vectors. By issuing
      %values_as_vector;
      vectors instead of lists will be used.
    • Multiple values for multiple-value continuations. This is the most elegant way. By issuing
      %multiple_values;
      multiple values are passed to the multiple-value continuation, as created by call-with-values or the convenience macro receive. The latter is available if you issue (use-modules (srfi srfi-8)). Assuming that your divide function wants to return two values, a quotient and a remainder, you can write:
      (receive (quotient remainder)
          (divide 35 17)
        body...)
      
      In body, the first result of divide will be bound to the variable quotient, and the second result to remainder.
    See also the "multivalue" example.

    16.6 Representation of pointers as smobs

    For pointer types, SWIG uses Guile smobs. SWIG smobs print like this: #<swig struct xyzzy * 0x1234affe> Two of them are equal? if and only if they have the same type and value.

    To construct a Scheme object from a C pointer, the wrapper code calls the function SWIG_NewPointerObj(), passing a pointer to a struct representing the pointer type. The type index to store in the upper half of the CAR is read from this struct. To get the pointer represented by a smob, the wrapper code calls the function SWIG_ConvertPtr(), passing a pointer to a struct representing the expected pointer type. See also Section 8.8 The run-time type checker. If the Scheme object passed was not a SWIG smob representing a compatible pointer, a wrong-type-arg exception is raised.

    16.6.1 GH Smobs

    In earlier versions of SWIG, C pointers were represented as Scheme strings containing a hexadecimal rendering of the pointer value and a mangled type name. As Guile allows registering user types, so-called "smobs" (small objects), a much cleaner representation has been implemented now. The details will be discussed in the following.

    A smob is a cons cell where the lower half of the CAR contains the smob type tag, while the upper half of the CAR and the whole CDR are available. SWIG_Guile_Init() registers a smob type named "swig" with Guile; its type tag is stored in the variable swig_tag. The upper half of the CAR store an index into a table of all C pointer types seen so far, to which new types seen are appended. The CDR stores the pointer value.

    16.6.2 SCM Smobs

    The SCM interface (using the "-scm" argument to swig) uses common.swg. The whole type system, when it is first initialized, creates two smobs named "swig" and "collected_swig". The swig smob is used for non-garbage collected smobs, while the collected_swig smob is used as described below. Each smob has the same format, which is a double cell created by SCM_NEWSMOB2() The first word of data is the pointer to the object and the second word of data is the swig_type_info * structure describing this type. This is a lot easier than the GH interface above because we can store a pointer to the type info structure right in the type. With the GH interface, there was not enough room in the smob to store two whole words of data so we needed to store part of the "swig_type_info address" in the smob tag. If a generated GOOPS module has been loaded, smobs will be wrapped by the corresponding GOOPS class.

    16.6.3 Garbage Collection

    Garbage collection is a feature of the new SCM interface, and it is automatically included if you pass the "-scm" flag to swig. Thus the swig garbage collection support requires guile >1.6. Garbage collection works like this. Every swig_type_info structure stores in its clientdata field a pointer to the destructor for this type. The destructor is the generated wrapper around the delete function. 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 Section 9.2 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.

    16.7 Exception Handling

    SWIG code calls scm_error on exception, using the following mapping:

          MAP(SWIG_MemoryError,	"swig-memory-error");
          MAP(SWIG_IOError,		"swig-io-error");
          MAP(SWIG_RuntimeError,	"swig-runtime-error");
          MAP(SWIG_IndexError,	"swig-index-error");
          MAP(SWIG_TypeError,	"swig-type-error");
          MAP(SWIG_DivisionByZero,	"swig-division-by-zero");
          MAP(SWIG_OverflowError,	"swig-overflow-error");
          MAP(SWIG_SyntaxError,	"swig-syntax-error");
          MAP(SWIG_ValueError,	"swig-value-error");
          MAP(SWIG_SystemError,	"swig-system-error");
    

    The default when not specified here is to use "swig-error". See Lib/exception.i for details.

    16.8 Procedure documentation

    If invoked with the command-line option -procdoc file, SWIG creates documentation strings for the generated wrapper functions, describing the procedure signature and return value, and writes them to file. You need Guile 1.4 or later to make use of the documentation files.

    SWIG can generate documentation strings in three formats, which are selected via the command-line option -procdocformat format:

    • guile-1.4 (default): Generates a format suitable for Guile 1.4.
    • plain: Generates a format suitable for Guile 1.4.1 and later.
    • texinfo: Generates texinfo source, which must be run through texinfo in order to get a format suitable for Guile 1.4.1 and later.

    You need to register the generated documentation file with Guile like this:

    (use-modules (ice-9 documentation))
    (set! documentation-files 
          (cons "file" documentation-files))
    

    Documentation strings can be configured using the Guile-specific typemap argument doc. See Lib/guile/typemaps.i for details.

    16.9 Procedures with setters

    For global variables, SWIG creates a single wrapper procedure (variable :optional value), which is used for both getting and setting the value. For struct members, SWIG creates two wrapper procedures (struct-member-get pointer) and (struct-member-set pointer value).

    If invoked with the command-line option -emit-setters (recommended), SWIG will additionally create procedures with setters. For global variables, the procedure-with-setter variable is created, so you can use (variable) to get the value and (set! (variable) value) to set it. For struct members, the procedure-with-setter struct-member is created, so you can use (struct-member pointer) to get the value and (set! (struct-member pointer) value) to set it.

    If invoked with the command-line option -only-setters, SWIG will only create procedures with setters, i.e., for struct members, the procedures (struct-member-get pointer) and (struct-member-set pointer value) are not generated.

    16.10 GOOPS Shadow Classes

    SWIG can also generate classes and generic functions for use with Guile's Object-Oriented Programming System (GOOPS). GOOPS is a sophisticated object system in the spirit of the Common Lisp Object System (CLOS).

    GOOPS support is only available with the new SCM interface (enabled with the -scm command-line option of SWIG). To enable GOOPS support, pass the -shadow argument to swig. This will export the GOOPS wrapper definitions into the module.scm file in the directory specified by -outdir or the current directory. GOOPS support requires either passive or module linkage.

    The generated file will contain definitions of GOOPS classes mimicking the C++ class hierarchy.

    Enabling GOOPS support implies -emit-setters.

    If -emit-slot-accessors is also passed as an argument, then the generated file will contain accessor methods for all the slots in the classes and for global variables. The input class

      class Foo {
        public:
          Foo(int i) : a(i) {}
          int a;
          int getMultBy(int i) { return a * i; }
          Foo getFooMultBy(int i) { return Foo(a * i); }
      }; 
      Foo getFooPlus(int i) { return Foo(a + i); }
    
    will produce (if -emit-slot-accessors is not passed as a parameter)
    (define-class <Foo> (<swig>)
      (a #:allocation #:swig-virtual 
         #:slot-ref primitive:Foo-a-get 
         #:slot-set! primitive:Foo-a-set)
      #:metaclass <swig-metaclass>
      #:new-function primitive:new-Foo
    )
    (define-method (getMultBy (swig_smob <Foo>) i)
      (primitive:Foo-getMultBy  (slot-ref swig_smob 'smob) i))
    (define-method (getFooMultBy (swig_smob <Foo>) i)
      (make <Foo> #:init-smob (primitive:Foo-getFooMultBy  (slot-ref swig_smob 'smob) i)))
    
    (define-method (getFooPlus i)
      (make <Foo> #:init-smob (primitive:getFooPlus i)))
    
    (export <Foo> getMultBy getFooMultBy getFooPlus )
    
    and will produce (if -emit-slot-accessors is passed as a parameter)
    (define-class <Foo> (<swig>)
      (a #:allocation #:swig-virtual 
         #:slot-ref primitive:Foo-a-get 
         #:slot-set! primitive:Foo-a-set 
         #:accessor a)
      #:metaclass <swig-metaclass>
      #:new-function primitive:new-Foo
    )
    (define-method (getMultBy (swig_smob <Foo>) i)
      (primitive:Foo-getMultBy  (slot-ref swig_smob 'smob) i))
    (define-method (getFooMultBy (swig_smob <Foo>) i)
      (make <Foo> #:init-smob (primitive:Foo-getFooMultBy  (slot-ref swig_smob 'smob) i)))
    
    (define-method (getFooPlus i)
      (make <Foo> #:init-smob (primitive:getFooPlus i)))
    
    (export <Foo> a getMultBy getFooMultBy getFooPlus )
    
    which can then be used by this code
    ;; not using getters and setters
    (define foo (make <Foo> #:args '(45)))
    (slot-ref foo 'a)
    (slot-set! foo 'a 3)
    (getMultBy foo 4)
    (define foo2 (getFooMultBy foo 7))
    (slot-ref foo 'a)
    (slot-ref (getFooPlus foo 4) 'a)
    
    ;; using getters and setters
    (define foo (make <Foo> #:args '(45)))
    (a foo)
    (set! (a foo) 5)
    (getMultBy foo 4)
    (a (getFooMultBy foo 7))
    

    Notice that constructor arguments are passed as a list after the #:args keyword. Hopefully in the future the following will be valid (make <Foo> #:a 5 #:b 4)

    Also note that the order the declarations occur in the .i file make a difference. For example,

    %module test
    
    %{ #include "foo.h" %}
    
    %inline %{
      int someFunc(Foo &a) {
        ...
      }
    %}
    
    %include "foo.h"
    
    This is a valid SWIG file it will work as you think it will for primitive support, but the generated GOOPS file will be broken. Since the someFunc definition is parsed by SWIG before all the declarations in foo.h, the generated GOOPS file will contain the definition of someFunc() before the definition of <Foo>. The generated GOOPS file would look like
    ;;...
    
    (define-method (someFunc (swig_smob <Foo>))
      (primitive:someFunc (slot-ref swig_smob 'smob)))
    
    ;;...
    
    (define-class <Foo> (<swig>)
      ;;...
    )
    
    ;;...
    
    Notice that <Foo> is used before it is defined. The fix is to just put the %import "foo.h" before the %inline block.

    16.10.1 Naming Issues

    As you can see in the example above, there are potential naming conflicts. The default exported accessor for the Foo::a variable is named a. The name of the wrapper global function is getFooPlus. If the -useclassprefix option is passed to swig, the name of all accessors and member functions will be prepended with the class name. So the accessor will be called Foo-a and the member functions will be called Foo-getMultBy. Also, if the -goopsprefix goops: argument is passed to swig, every identifier will be prefixed by goops:

    Two guile-modules are created by SWIG. The first module contains the primitive definitions of all the wrapped functions and variables, and is located either in the _wrap.cxx file (with -Linkage module) or in the scmstub file (if -Linkage passive -scmstub). The name of this guile-module is the swig-module name (given on the command line with the -module argument or with the %module directive) concatenated with the string "-primitive". For example, if %module Test is set in the swig interface file, the name of the guile-module in the scmstub or -Linkage module will be Test-primitive. Also, the scmstub file will be named Test-primitive.scm. The string "primitive" can be changed by the -primsuffix swig argument. So the same interface, with the -primsuffix base will produce a module called Test-base. The second generated guile-module contains all the GOOPS class definitions and is located in a file named module.scm in the directory specified with -outdir or the current directory. The name of this guile-module is the name of the swig-module (given on the command line or with the %module directive). In the previous example, the GOOPS definitions will be in a file named Test.scm.

    Because of the naming conflicts, you can't in general use both the -primitive and the GOOPS guile-modules at the same time. To do this, you need to rename the exported symbols from one or both guile-modules. For example,

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

    TODO: Renaming class name prefixes?

    16.10.2 Linking

    The guile-modules generated above all need to be linked together. GOOPS support requires either passive or module linkage. The exported GOOPS guile-module will be the name of the swig-module and should be located in a file called Module.scm. This should be installed on the autoload path for guile, so that (use-modules (Package Module)) will load everything needed. Thus, the top of the GOOPS guile-module will contain code to load everything needed by the interface (the shared library, the scmstub module, etc.). The %goops directive inserts arbitrary code into the generated GOOPS guile-module, and should be used to load the dependent libraries.

    This breaks up into three cases

    • Passive Linkage without -scmstub: Note that this linkage style has the potential for naming conflicts, since the primitive exported function and variable names are not wrapped in a guile-module and might conflict with names from the GOOPS guile-module (see above). Pass the -goopsprefix argument to solve this problem. If the -exportprimitive option is passed to SWIG the (export ...) code that would be exported into the scmstub file is exported at the bottom of the generated GOOPS guile-module. The %goops directive should contain code to load the .so library.
    • %goops %{ (load-extension "./foo.so" "scm_init_my_modules_foo_module") %}
      
      Produces the following code at the top of the generated GOOPS guile-module (with the -package my/modules -module foo command line arguments)
      (define-module (my modules foo))
      
      ;; %goops directive goes here
      (load-extension "./foo.so" "scm_init_my_modules_foo_module") 
      
      (use-modules (oop goops) (Swig common))
      
    • Passive Linkage with -scmstub: Here, the name of the scmstub file should be Module-primitive.scm (with primitive replaced with whatever is given with the -primsuffix argument. The code to load the .so library should be located in the %scheme directive, which will then be added to the scmstub file. Swig will automatically generate the line (use-modules (Package Module-primitive)) into the GOOPS guile-module. So if Module-primitive.scm is on the autoload path for guile, the %goops directive can be empty. Otherwise, the %goops directive should contain whatever code is needed to load the Module-primitive.scm file into guile.
    • %scheme %{ (load-extension "./foo.so" "scm_init_my_modules_foo_module") %}
      // only include the following definition if (my modules foo) can not be loaded automatically
      %goops %{ 
        (primitive-load "/path/to/foo-primitive.scm") 
        (primitive-load "/path/to/Swig/common.scm")
      %}
      
      Produces the following code at the top of the generated GOOPS guile-module
      (define-module (my modules foo))
      
      ;; %goops directive goes here (if any)
      (primitive-load "/path/to/foo-primitive.scm")
      (primitive-load "/path/to/Swig/common.scm")
      
      (use-modules (oop goops) (Swig common))
      (use-modules ((my modules foo-primitive) :renamer (symbol-prefix-proc 'primitive:)))
      
      
    • Module Linkage: This is very similar to passive linkage with a scmstub file. Swig will also automatically generate the line (use-modules (Package Module-primitive)) into the GOOPS guile-module. Again the %goops directive should contain whatever code is needed to get that module loaded into guile.
    • %goops %{ (load-extension "./foo.so" "scm_init_my_modules_foo_module") %}
      
      Produces the following code at the top of the generated GOOPS guile-module
      (define-module (my modules foo))
      
      ;; %goops directive goes here (if any)
      (load-extension "./foo.so" "scm_init_my_modules_foo_module") 
      
      (use-modules (oop goops) (Swig common))
      (use-modules ((my modules foo-primitive) :renamer (symbol-prefix-proc 'primitive:)))
      
      

    (Swig common): The generated GOOPS guile-module also imports definitions from the (Swig common) guile-module. This module is included with SWIG and should be installed by SWIG into the autoload path for guile (based on the configure script and whatever arguments are passed). If it is not, then the %goops directive also needs to contain code to load the common.scm file into guile. Also note that if you are trying to install the generated wrappers on a computer without SWIG installed, you will need to include the common.swg file along with the install.

    Multiple Modules: Type dependencies between modules is supported. For example, if mod1 includes definitions of some classes, and mod2 includes some classes derived from classes in mod1, the generated GOOPS file for mod2 will declare the correct superclasses. The only problem is that since mod2 uses symbols from mod1, the mod2 GOOPS file must include a (use-modules (mod2)). Currently, SWIG does not automatically export this line; it must be included in the %goops directive of mod2. Maybe in the future SWIG can detect dependencies and export this line. (how do other language modules handle this problem?)

    cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/makechap.py0000755000175000000620000000717612561312226021660 0ustar stevestaff#!/usr/local/bin/python # Takes a chapter as input and adds internal links and numbering to all # of the h1, h2, h3, h4 sections and so forth. # import sys import re if len(sys.argv) != 3: print "usage: makechap.py filename num" sys.exit(1) filename = sys.argv[1] num = int(sys.argv[2]) section = 0 subsection = 0 subsubsection = 0 nameindex = 0 name = "" # Regexs for

    ,...

    sections h1 = re.compile(r".*?

    [\d\.\s]*(.*?)

    ", re.IGNORECASE) h2 = re.compile(r".*?

    [\d\.\s]*(.*?)

    ", re.IGNORECASE) h3 = re.compile(r".*?

    [\d\.\s]*(.*?)

    ", re.IGNORECASE) h4 = re.compile(r".*?

    [\d\.\s]*(.*?)

    ", re.IGNORECASE) h5 = re.compile(r".*?
    [\d\.\s]*(.*?)
    ", re.IGNORECASE) data = open(filename).read() # Read data open(filename+".bak","w").write(data) # Make backup lines = data.splitlines() result = [ ] index = "\n
      \n" skip = 0 skipspace = 0 for s in lines: if s == "": if not skip: skip = 1 else: skip = 0 continue; if skip: continue if not s and skipspace: continue if skipspace: result.append("") result.append("") skipspace = 0 m = h1.match(s) if m: nameindex += 1 result.append("""

      %d %s

      """ % (nameindex,num,m.group(1))) result.append("@INDEX@") section = 0 subsection = 0 subsubsection = 0 subsubsubsection = 0 name = m.group(1) skipspace = 1 continue m = h2.match(s) if m: nameindex += 1 section += 1 result.append("""

      %d.%d %s

      """ % (nameindex,num,section, m.group(1))) if subsubsection: index += "
    \n" if subsection: index += "
\n" index += """
  • %s\n""" % (nameindex,m.group(1)) subsection = 0 subsubsection = 0 subsubsubsection = 0 skipspace = 1 continue m = h3.match(s) if m: nameindex += 1 subsection += 1 result.append("""

    %d.%d.%d %s

    """ % (nameindex,num,section, subsection, m.group(1))) if subsubsection: index += "\n" if subsection == 1: index += "
      \n" index += """
    • %s\n""" % (nameindex,m.group(1)) subsubsection = 0 skipspace = 1 continue m = h4.match(s) if m: nameindex += 1 subsubsection += 1 subsubsubsection = 0 result.append("""

      %d.%d.%d.%d %s

      """ % (nameindex,num,section, subsection, subsubsection, m.group(1))) if subsubsection == 1: index += "
        \n" index += """
      • %s\n""" % (nameindex,m.group(1)) skipspace = 1 continue m = h5.match(s) if m: nameindex += 1 subsubsubsection += 1 result.append("""
        %d.%d.%d.%d.%d %s
        """ % (nameindex,num,second,subsection,subsubsection,subsubsubsection, m.group(1))) skipspace = 1 continue result.append(s) if subsubsection: index += "
      \n" if subsection: index += "
    \n" if section: index += "\n" index += "\n" data = "\n".join(result) data = data.replace("@INDEX@",index); # Write the file back out open(filename,"w").write(data) # Print the TOC data index = index.replace("#n","%s#n" % filename) print """

    %d %s

    \n""" % (filename,num,name) print index cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/README0000644000175000000620000000032712561312226020401 0ustar stevestaffThis directory contains the HTML for the SWIG users manual. All of this HTML is hand-written. However, section numbering, indices, and the table of contents is generated automatically by the 'maketoc.py' script. cableswig-0.1.0+git20150808.orig/SWIG/Doc/Manual/chapters0000644000175000000620000000052512561312226021255 0ustar stevestaffPreface.html Introduction.html Windows.html Scripting.html SWIG.html SWIGPlus.html Preprocessor.html Arguments.html Typemaps.html Customization.html Contract.html Varargs.html Warnings.html Library.html Modules.html Advanced.html Guile.html Java.html Ocaml.html Perl5.html Php.html Python.html Ruby.html Tcl.html Chicken.html Extending.html cableswig-0.1.0+git20150808.orig/SWIG/Doc/README0000644000175000000620000000026512561312226017165 0ustar stevestaffDoc/Manual - Latest version of the SWIG user manual Doc/Devel - Developer documentation concerning SWIG internals. (not necessarily up to date) cableswig-0.1.0+git20150808.orig/SWIG/CHANGES.current0000644000175000000620000001012212561312226020245 0ustar stevestaffVersion 1.3.22 (in progress) ================================== 02/12/2004: cheetah (William Fulton) [Java, C#] Patch submitted by Bill Hoffman which prevents SWIG from crashing when a file for the typewrapper class cannot be opened. 02/11/2004: cheetah (William Fulton) [Java, C#] Overloading changes: - Methods which are overloaded in const only no longer generate Java code that won't compile - the first method parsed is used and a warning is displayed. Note that this behaviour is slightly different to the scripting languages which always uses the non-const method. - Warning messages 509 and 512 replaced by new warning number 516, which is more relevant to these statically typed languages as the overloaded methods aren't 'shadowed', they are ignored. 01/23/2004: mkoeppe (Matthias Koeppe) [Guile] Replace the "known_classes" hash table by a node attribute. Methods of classes in C++ namespaces now get the proper specializer in the GOOPS declaration. Reported by rm@mh-freiburg.de. 01/23/2004: mkoeppe (Matthias Koeppe) [Guile] Uniquify the argument names in GOOPS shadow method declarations. Reported by rm@mh-freiburg.de. 01/21/2004: sunshine (Eric Sunshine) Revived the NextStep port of SWIG. Fixed fatal problem in DohStrstr() caused by difference in strstr() implementation which made %apply become entirely dysfunctional. On NextStep, strstr("foo","") evaluates to NULL; whereas, on modern platforms, it evaluates to "foo". %apply relies extensively upon strstr("foo","") evaluating to non-NULL, therefore it failed catastrophically when faced with NextStep's strstr(). Added `bool' check to configure.in since NextStep's C++ compiler does not supply this type. swig.h now fakes up `bool' if needed. Worked around NextStep C++ compiler bug in which C++ code is disallowed inside extern "C" functions. This problem affected all language modules, since they publish hook functions of the form: extern "C" Language *swig_foo(void) { return new FOO(); } Fixed by creating a C++ wrapper: static Language *new_swig_foo() { return new FOO(); } extern "C" Language *swig_foo(void) { return new_swig_foo(); } Ensured that Swig_copy_string() is used in place of strdup() since NextStep does not supply strdup(). Fixed detection of Ruby library name and location in configure.in. Problem 1: Assumed that library always resided in Ruby's "archdir", which was correct for Ruby 1.6.x, but which is incorrect for Ruby 1.8.x, in which case the library normally resides in Ruby's "libdir". Problem 2: Assumed that the library could always be linked via "-l"+RUBY_INSTALL_NAME (where RUBY_INSTALL_NAME typically is "ruby"), however this failed for platforms, such as NextStep, which do not support shared libraries. In this case, the static library name in 1.8.x is libruby-static.a, thus -lruby-static is required. The new logic works correctly for static and shared libraries for 1.6.x and 1.8.x. Fixed detection of Perl CFLAGS in configure.in for NextStep. Detection code extracted CFLAGS from Perl's %Config hash but neglected to add a newline to the value before passing it through `sed'. NextStep's ancient `sed' discards input which is not terminated with a newline, thus Perl CFLAGS always evaluated to the empty string. 01/16/2004: cheetah (William Fulton) Tidy up in the exception handling code that is generated when C++ exception specifications are wrapped with the throws typemap. This redundant code is no longer generated: catch(...) { throw; } cableswig-0.1.0+git20150808.orig/SWIG/Runtime/0002755000175000000620000000000012561312227017223 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Runtime/swigpy.dsp0000644000175000000620000001221312561312227021252 0ustar stevestaff# Microsoft Developer Studio Project File - Name="swigpy" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=swigpy - Win32 Release !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "swigpy.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "swigpy.mak" CFG="swigpy - Win32 Release" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "swigpy - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "swigpy - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "swigpy - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SWIGPY_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(PYTHON_INCLUDE)" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SWIGPY_EXPORTS" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "_DEBUG" # ADD RSC /l 0x809 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "$(PYTHON_LIB)" /nologo /dll /debug /machine:I386 /pdbtype:sept !ELSEIF "$(CFG)" == "swigpy - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SWIGPY_EXPORTS" /YX /FD /c # ADD CPP /nologo /MT /W3 /GX /O2 /I "$(PYTHON_INCLUDE)" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SWIGPY_EXPORTS" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "NDEBUG" # ADD RSC /l 0x809 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "$(PYTHON_LIB)" /nologo /dll /machine:I386 !ENDIF # Begin Target # Name "swigpy - Win32 Debug" # Name "swigpy - Win32 Release" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=.\libpy.c # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # End Group # Begin Source File SOURCE=..\Lib\common.swg # End Source File # Begin Source File SOURCE=..\Lib\python\pyrun.swg !IF "$(CFG)" == "swigpy - Win32 Debug" USERDEP__PYRUN="..\Lib\common.swg" "..\Lib\swigrun.i" # Begin Custom Build ProjDir=. InputPath=..\Lib\python\pyrun.swg "$(ProjDir)/libpy.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" echo In order to function correctly, please ensure the following environment variables are correctly set: echo PYTHON_INCLUDE: %PYTHON_INCLUDE% echo PYTHON_LIB: %PYTHON_LIB% echo on ..\swig -python -runtime -o libpy.c swigrun.i # End Custom Build !ELSEIF "$(CFG)" == "swigpy - Win32 Release" USERDEP__PYRUN="..\Lib\common.swg" "..\Lib\swigrun.i" # Begin Custom Build ProjDir=. InputPath=..\Lib\python\pyrun.swg "$(ProjDir)/libpy.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" echo In order to function correctly, please ensure the following environment variables are correctly set: echo PYTHON_INCLUDE: %PYTHON_INCLUDE% echo PYTHON_LIB: %PYTHON_LIB% echo on ..\swig -python -runtime -o libpy.c swigrun.i # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\Lib\swigrun.i # End Source File # End Target # End Project cableswig-0.1.0+git20150808.orig/SWIG/Runtime/swigpl.dsp0000644000175000000620000001217612561312227021245 0ustar stevestaff# Microsoft Developer Studio Project File - Name="swigpl" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=swigpl - Win32 Release !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "swigpl.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "swigpl.mak" CFG="swigpl - Win32 Release" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "swigpl - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "swigpl - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "swigpl - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SWIGPL_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(PERL5_INCLUDE)" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SWIGPL_EXPORTS" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "_DEBUG" # ADD RSC /l 0x809 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "$(PERL5_LIB)" /nologo /dll /debug /machine:I386 /pdbtype:sept !ELSEIF "$(CFG)" == "swigpl - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SWIGPL_EXPORTS" /YX /FD /c # ADD CPP /nologo /MT /W3 /GX /O2 /I "$(PERL5_INCLUDE)" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SWIGPL_EXPORTS" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "NDEBUG" # ADD RSC /l 0x809 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "$(PERL5_LIB)" /nologo /dll /machine:I386 !ENDIF # Begin Target # Name "swigpl - Win32 Debug" # Name "swigpl - Win32 Release" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=.\libpl.c # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # End Group # Begin Source File SOURCE=..\Lib\common.swg # End Source File # Begin Source File SOURCE=..\Lib\perl5\perlrun.swg !IF "$(CFG)" == "swigpl - Win32 Debug" USERDEP__PERLR="..\Lib\common.swg" "..\Lib\swigrun.i" # Begin Custom Build ProjDir=. InputPath=..\Lib\perl5\perlrun.swg "$(ProjDir)/libpl.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" echo In order to function correctly, please ensure the following environment variables are correctly set: echo PERL5_INCLUDE: %PERL5_INCLUDE% echo PERL5_LIB: %PERL5_LIB% echo on ..\swig -perl -runtime -o libpl.c swigrun.i # End Custom Build !ELSEIF "$(CFG)" == "swigpl - Win32 Release" USERDEP__PERLR="..\Lib\common.swg" "..\Lib\swigrun.i" # Begin Custom Build ProjDir=. InputPath=..\Lib\perl5\perlrun.swg "$(ProjDir)/libpl.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" echo In order to function correctly, please ensure the following environment variables are correctly set: echo PERL5_INCLUDE: %PERL5_INCLUDE% echo PERL5_LIB: %PERL5_LIB% echo on ..\swig -perl -runtime -o libpl.c swigrun.i # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\Lib\swigrun.i # End Source File # End Target # End Project cableswig-0.1.0+git20150808.orig/SWIG/Runtime/.cvsignore0000644000175000000620000000025612561312227021224 0ustar stevestaff.deps .libs Debug Makefile Makefile.in Release lib*.c lib*.la lib*.lo swig*.dll swig*.dsw swig*.exp swig*.lib swig*.ncb swig*.opt swig*.plg swigrun.pm swigrun.py swigrun.scm cableswig-0.1.0+git20150808.orig/SWIG/Runtime/swigrb.dsp0000644000175000000620000001252212561312227021230 0ustar stevestaff# Microsoft Developer Studio Project File - Name="swigrb" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=swigrb - Win32 Release !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "swigrb.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "swigrb.mak" CFG="swigrb - Win32 Release" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "swigrb - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "swigrb - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "swigrb - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SWIGRB_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(RUBY_INCLUDE)" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SWIGRB_EXPORTS" /D NT=1 /D "IMPORT" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "_DEBUG" # ADD RSC /l 0x809 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "$(RUBY_LIB)" /nologo /dll /debug /machine:I386 /pdbtype:sept # SUBTRACT LINK32 /pdb:none !ELSEIF "$(CFG)" == "swigrb - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SWIGRB_EXPORTS" /YX /FD /c # ADD CPP /nologo /MT /W3 /GX /O2 /I "$(RUBY_INCLUDE)" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SWIGRB_EXPORTS" /D NT=1 /D "IMPORT" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "NDEBUG" # ADD RSC /l 0x809 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "$(RUBY_LIB)" /nologo /dll /machine:I386 # SUBTRACT LINK32 /pdb:none !ENDIF # Begin Target # Name "swigrb - Win32 Debug" # Name "swigrb - Win32 Release" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=.\librb.c # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # End Group # Begin Source File SOURCE=..\Lib\common.swg # End Source File # Begin Source File SOURCE=..\Lib\ruby\rubydef.swg !IF "$(CFG)" == "swigrb - Win32 Debug" USERDEP__RUBYD="..\Lib\common.swg" "..\Lib\ruby\rubyhead.swg" "..\Lib\swigrun.i" # Begin Custom Build ProjDir=. InputPath=..\Lib\ruby\rubydef.swg "$(ProjDir)/librb.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" echo In order to function correctly, please ensure the following environment variables are correctly set: echo RUBY_INCLUDE: %RUBY_INCLUDE% echo RUBY_LIB: %RUBY_LIB% echo on ..\swig -ruby -runtime -o librb.c swigrun.i # End Custom Build !ELSEIF "$(CFG)" == "swigrb - Win32 Release" USERDEP__RUBYD="..\Lib\common.swg" "..\Lib\ruby\rubyhead.swg" "..\Lib\swigrun.i" # Begin Custom Build ProjDir=. InputPath=..\Lib\ruby\rubydef.swg "$(ProjDir)/librb.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" echo In order to function correctly, please ensure the following environment variables are correctly set: echo RUBY_INCLUDE: %RUBY_INCLUDE% echo RUBY_LIB: %RUBY_LIB% echo on ..\swig -ruby -runtime -o librb.c swigrun.i # End Custom Build !ENDIF # End Source File # Begin Source File SOURCE=..\Lib\ruby\rubyhead.swg # End Source File # Begin Source File SOURCE=..\Lib\swigrun.i # End Source File # End Target # End Project cableswig-0.1.0+git20150808.orig/SWIG/Runtime/swigtcl8.dsp0000644000175000000620000001221512561312227021476 0ustar stevestaff# Microsoft Developer Studio Project File - Name="swigtcl8" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=swigtcl8 - Win32 Release !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "swigtcl8.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "swigtcl8.mak" CFG="swigtcl8 - Win32 Release" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "swigtcl8 - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "swigtcl8 - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "swigtcl8 - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SWIGTCL8_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(TCL_INCLUDE)" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SWIGTCL8_EXPORTS" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "_DEBUG" # ADD RSC /l 0x809 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "$(TCL_LIB)" /nologo /dll /debug /machine:I386 /pdbtype:sept !ELSEIF "$(CFG)" == "swigtcl8 - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SWIGTCL8_EXPORTS" /YX /FD /c # ADD CPP /nologo /MT /W3 /GX /O2 /I "$(TCL_INCLUDE)" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SWIGTCL8_EXPORTS" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "NDEBUG" # ADD RSC /l 0x809 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "$(TCL_LIB)" /nologo /dll /machine:I386 !ENDIF # Begin Target # Name "swigtcl8 - Win32 Debug" # Name "swigtcl8 - Win32 Release" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=.\libtcl8.c # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # End Group # Begin Source File SOURCE=..\Lib\common.swg # End Source File # Begin Source File SOURCE=..\Lib\swigrun.i # End Source File # Begin Source File SOURCE=..\Lib\tcl\swigtcl8.swg !IF "$(CFG)" == "swigtcl8 - Win32 Debug" USERDEP__SWIGT="..\Lib\common.swg" "..\Lib\swigrun.i" # Begin Custom Build ProjDir=. InputPath=..\Lib\tcl\swigtcl8.swg "$(ProjDir)/libtcl8.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" echo In order to function correctly, please ensure the following environment variables are correctly set: echo TCL_INCLUDE: %TCL_INCLUDE% echo TCL_LIB: %TCL_LIB% echo on ..\swig -tcl -runtime -o libtcl8.c swigrun.i # End Custom Build !ELSEIF "$(CFG)" == "swigtcl8 - Win32 Release" USERDEP__SWIGT="..\Lib\common.swg" "..\Lib\swigrun.i" # Begin Custom Build ProjDir=. InputPath=..\Lib\tcl\swigtcl8.swg "$(ProjDir)/libtcl8.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" echo In order to function correctly, please ensure the following environment variables are correctly set: echo TCL_INCLUDE: %TCL_INCLUDE% echo TCL_LIB: %TCL_LIB% echo on ..\swig -tcl -runtime -o libtcl8.c swigrun.i # End Custom Build !ENDIF # End Source File # End Target # End Project cableswig-0.1.0+git20150808.orig/SWIG/Runtime/Makefile.am0000644000175000000620000001634012561312227021261 0ustar stevestaff## Process this file with automake to produce Makefile.in SWIGLIB = @top_srcdir@/Lib SWIG_TYPECHECK = $(SWIGLIB)/common.swg RELEASE_SUFFIX_LIBTOOL = @release_suffix_libtool@ # Additional clean clean-local: rm -f *.c # List of runtime libraries to be built lib_LTLIBRARIES = if !SKIP_TCL lib_LTLIBRARIES += libswigtcl8.la endif if !SKIP_PERL5 lib_LTLIBRARIES += libswigpl.la endif if !SKIP_PYTHON lib_LTLIBRARIES += libswigpy.la endif if !SKIP_GUILE lib_LTLIBRARIES += libswigguile.la endif if !SKIP_GUILESCM lib_LTLIBRARIES += libswigguilescm.la endif if !SKIP_RUBY lib_LTLIBRARIES += libswigrb.la endif if !SKIP_PHP4 lib_LTLIBRARIES += libswigphp4.la endif if !SKIP_PIKE lib_LTLIBRARIES += libswigpike.la endif if !SKIP_CHICKEN lib_LTLIBRARIES += libswigchicken.la endif # ---------------------------------------------------------------------- # Tcl run-time library # ---------------------------------------------------------------------- TCL_INCLUDE = @TCLINCLUDE@ TCL_RUNTIME = $(SWIGLIB)/tcl/swigtcl8.swg TCL_PRECOMMON = $(SWIGLIB)/tcl/precommon.swg TCL_DLNK = @TCLDYNAMICLINKING@ libswigtcl8_la_SOURCES = libtcl8.c libswigtcl8_la_LDFLAGS = @LIBTOOL_NO_UNDEFINED@ $(RELEASE_SUFFIX_LIBTOOL) $(TCL_DLNK) libswigtcl8_la_CFLAGS = $(TCL_INCLUDE) libtcl8.c: $(TCL_PRECOMMON) $(SWIG_TYPECHECK) $(TCL_RUNTIME) ../preinst-swig -tcl -runtime -o libtcl8.c swigrun.i # ---------------------------------------------------------------------- # Perl run-time library # ---------------------------------------------------------------------- PERL5_INCLUDE = -I@PERL5EXT@ PERL5_RUNTIME = $(SWIGLIB)/perl5/perlrun.swg PERL5_PRECOMMON = $(SWIGLIB)/perl5/precommon.swg PERL5_DLNK = @PERL5DYNAMICLINKING@ PERL5_CCFLAGS = @PERL5CCFLAGS@ libswigpl_la_SOURCES = libpl.c libswigpl_la_LDFLAGS = @LIBTOOL_NO_UNDEFINED@ $(RELEASE_SUFFIX_LIBTOOL) $(PERL5_DLNK) libswigpl_la_CFLAGS = $(PERL5_INCLUDE) -Dbool=char -Dexplicit=$(PERL5_CCFLAGS) libpl.c: $(PERL5_PRECOMMON) $(SWIG_TYPECHECK) $(PERL5_RUNTIME) ../preinst-swig -perl5 -runtime -o libpl.c swigrun.i # ---------------------------------------------------------------------- # Python run-time library # ---------------------------------------------------------------------- PYTHON_INCLUDE = -DHAVE_CONFIG_H @PYINCLUDE@ PYTHON_RUNTIME = $(SWIGLIB)/python/pyrun.swg PYTHON_PRECOMMON = $(SWIGLIB)/python/precommon.swg PYTHON_DLNK = @PYTHONDYNAMICLINKING@ libswigpy_la_SOURCES = libpy.c libswigpy_la_LDFLAGS = @LIBTOOL_NO_UNDEFINED@ $(RELEASE_SUFFIX_LIBTOOL) $(PYTHON_DLNK) libswigpy_la_CFLAGS = $(PYTHON_INCLUDE) libpy.c: $(PYTHON_PRECOMMON) $(SWIG_TYPECHECK) $(PYTHON_RUNTIME) ../preinst-swig -python -runtime -o libpy.c swigrun.i # ---------------------------------------------------------------------- # Guile run-time library # ---------------------------------------------------------------------- GUILE_INCLUDE = @GUILEINCLUDE@ GUILE_GH_RUNTIME = $(SWIGLIB)/guile/guile_gh_run.swg GUILE_SCM_RUNTIME = $(SWIGLIB)/guile/guile_scm_run.swg GUILE_SCM_PRECOMMON = $(SWIGLIB)/guile/precommon.swg GUILE_DLNK = $(GUILELINK) libswigguile_la_SOURCES = libguile_gh.c libswigguile_la_LDFLAGS = @LIBTOOL_NO_UNDEFINED@ $(RELEASE_SUFFIX_LIBTOOL) $(GUILE_DLNK) libswigguile_la_CFLAGS = -DSWIG_GLOBAL $(GUILE_INCLUDE) libguile_gh.c: $(GUILE_GH_RUNTIME) ../preinst-swig -guile -gh -runtime -o libguile_gh.c swigrun.i libswigguilescm_la_SOURCES = libguile_scm.c libswigguilescm_la_LDFLAGS = @LIBTOOL_NO_UNDEFINED@ $(RELEASE_SUFFIX_LIBTOOL) $(GUILE_DLNK) libswigguilescm_la_CFLAGS = -DSWIG_GLOBAL $(GUILE_INCLUDE) libguile_scm.c: $(GUILE_SCM_PRECOMMON) $(SWIG_TYPECHECK) $(GUILE_SCM_RUNTIME) ../preinst-swig -guile -scm -runtime -o libguile_scm.c swigrun.i # ---------------------------------------------------------------------- # Ruby run-time library # ---------------------------------------------------------------------- RUBY_INCLUDE = @RUBYINCLUDE@ RUBY_RUNTIME = $(SWIGLIB)/ruby/rubyhead.swg $(SWIGLIB)/ruby/rubydef.swg RUBY_PRECOMMON = $(SWIGLIB)/ruby/precommon.swg RUBY_DLNK = @RUBYDYNAMICLINKING@ RUBY_CFLAGS = @RUBYCCDLFLAGS@ -DHAVE_CONFIG_H libswigrb_la_SOURCES = librb.c libswigrb_la_LDFLAGS = @LIBTOOL_NO_UNDEFINED@ $(RELEASE_SUFFIX_LIBTOOL) $(RUBY_DLNK) libswigrb_la_CFLAGS = $(RUBY_INCLUDE) $(RUBY_CFLAGS) librb.c: $(RUBY_PRECOMMON) $(SWIG_TYPECHECK) $(RUBY_RUNTIME) ../preinst-swig -ruby -runtime -o librb.c swigrun.i # ---------------------------------------------------------------------- # PHP4 run-time library # ---------------------------------------------------------------------- PHP4_INCLUDE = @PHP4INC@ PHP4_RUNTIME = $(SWIGLIB)/php4/php4run.swg PHP4_PRECOMMON = $(SWIGLIB)/php4/precommon.swg PHP4_DLNK = libswigphp4_la_SOURCES = libphp4.c libswigphp4_la_LDFLAGS = @LIBTOOL_NO_UNDEFINED@ $(RELEASE_SUFFIX_LIBTOOL) $(PHP4_DLNK) libswigphp4_la_CFLAGS = $(PHP4_INCLUDE) libphp4.c: $(PHP4_PRECOMMON) $(SWIG_TYPECHECK) $(PHP4_RUNTIME) ../preinst-swig -php -runtime -o libphp4.c swigrun.i # ---------------------------------------------------------------------- # Pike run-time library # ---------------------------------------------------------------------- PIKE_INCLUDE = -DHAVE_CONFIG_H @PIKEINCLUDE@ PIKE_RUNTIME = $(SWIGLIB)/pike/pikerun.swg PIKE_PRECOMMON = $(SWIGLIB)/pike/precommon.swg PIKE_DLNK = libswigpike_la_SOURCES = libpike.c libswigpike_la_LDFLAGS = @LIBTOOL_NO_UNDEFINED@ $(RELEASE_SUFFIX_LIBTOOL) $(PIKE_DLNK) libswigpike_la_CFLAGS = -DSWIG_GLOBAL $(PIKE_INCLUDE) libpike.c: $(PIKE_PRECOMMON) $(SWIG_TYPECHECK) $(PIKE_RUNTIME) cat $(PIKE_PRECOMMON) $(SWIG_TYPECHECK) $(PIKE_RUNTIME) > libpike.c # ---------------------------------------------------------------------- # CHICKEN run-time library # ---------------------------------------------------------------------- CHICKENOPTS = @CHICKENOPTS@ CHICKEN_RUNTIME = $(SWIGLIB)/chicken/chickenrun.swg CHICKEN_PRECOMMON = $(SWIGLIB)/chicken/precommon.swg CHICKEN_DLNK = @CHICKENSHAREDLIB@ libswigchicken_la_SOURCES = libchicken.c libswigchicken_la_LDFLAGS = @LIBTOOL_NO_UNDEFINED@ $(RELEASE_SUFFIX_LIBTOOL) $(CHICKEN_DLNK) libswigchicken_la_CFLAGS = $(CHICKEN_INCLUDE) libchicken.c: $(CHICKEN_PRECOMMON) $(SWIG_TYPECHECK) $(CHICKEN_RUNTIME) ../preinst-swig -chicken -runtime -o libchicken.c swigrun.i # ---------------------------------------------------------------------- # The following do not use Libtool # There are no install and uninstall targets. These could be implemented # with Automake's install-exec-local and uninstall-local targets. # ---------------------------------------------------------------------- # ---------------------------------------------------------------------- # MzScheme run-time library # ---------------------------------------------------------------------- MZSCHEME_RUNTIME = $(SWIGLIB)/mzscheme/precommon.swg $(SWIG_TYPECHECK) $(SWIGLIB)/mzscheme/mzrun.swg MZC = @MZC@ SO = @MZSCHEME_SO@ RELEASESUFFIX = @release_suffix@ # Add in non Libtool targets if !SKIP_MZSCHEME all-local: .libs/libswigmz$(RELEASESUFFIX)$(SO) else all-local: endif .libs/libswigmz$(RELEASESUFFIX)$(SO): $(MZSCHEME_RUNTIME) ../preinst-swig -mzscheme -runtime -o libmz.c swigrun.i $(MZC) ++ccf "-DSWIG_GLOBAL" --cc libmz.c if [ ! -d .libs ] ; then mkdir .libs; fi $(MZC) --ld .libs/libswigmz$(RELEASESUFFIX)$(SO) libmz.o cableswig-0.1.0+git20150808.orig/SWIG/Runtime/README0000644000175000000620000000076012561312227020104 0ustar stevestaffRuntime Libraries ----------------- The SWIG runtime libraries are built in this directory. Unix ---- Run make. This can also be done from the top level directory by running 'make runtime' and is automatically done when building the swig executable. Windows ------- See Doc\Manual\Windows.html for environment variables to set and further information. Choose which runtime library needs building and load the Visual Studio 6 project file and build it. For example, use swigpy.dsp for Python. cableswig-0.1.0+git20150808.orig/SWIG/Misc/0002755000175000000620000000000012561312227016473 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Misc/fileheader0000644000175000000620000000062612561312227020510 0ustar stevestaff/* ----------------------------------------------------------------------------- * file.c * * This file does a bunch of stuff. * * Author(s) : David Beazley (beazley@cs.uchicago.edu) * * Copyright (C) 1999-2000. The University of Chicago * See the file LICENSE for information on usage and redistribution. * ----------------------------------------------------------------------------- */ cableswig-0.1.0+git20150808.orig/SWIG/CMake/0002755000175000000620000000000012561312226016557 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/CMake/Macros.cmake0000644000175000000620000000237412561312226021011 0ustar stevestaffMACRO(BUILD_RUNTIME LANGUAGE RUNTIME_NAME LANGUAGE_RUNTIME RUNTIME_LINK_LIBRARIES) # Prepare output directory SET(__temp_EXECUTABLE_OUTPUT_PATH "${EXECUTABLE_OUTPUT_PATH}") SET(__temp_LIBRARY_OUTPUT_PATH "${LIBRARY_OUTPUT_PATH}") SET(EXECUTABLE_OUTPUT_PATH "${SWIG_BINARY_DIR}/Runtime") SET(LIBRARY_OUTPUT_PATH "${SWIG_BINARY_DIR}/Runtime") SET(RUNTIME_SRC "${SWIG_BINARY_DIR}/Runtime/lib${RUNTIME_NAME}.c") ADD_DEFINITIONS(-DSWIG_GLOBAL -DHAVE_CONFIG_H) SET(SWIG_CONTENT "") FOREACH(file ${LANGUAGE_RUNTIME}) FILE(READ "${SWIG_SOURCE_DIR}/Lib/${file}" LANGUAGE_RUNTIME_SWIG) SET(SWIG_CONTENT "${SWIG_CONTENT}${LANGUAGE_RUNTIME_SWIG}") ENDFOREACH(file ${LANGUAGE_RUNTIME}) CONFIGURE_FILE("${SWIG_SOURCE_DIR}/Runtime/empty.c.in" "${RUNTIME_SRC}" @ONLY) SET_SOURCE_FILES_PROPERTIES(${RUNTIME_SRC} PROPERTIES GENERATED 1) ADD_LIBRARY(swig${RUNTIME_NAME} SHARED "${RUNTIME_SRC}") TARGET_LINK_LIBRARIES(swig${RUNTIME_NAME} "${RUNTIME_LINK_LIBRARIES}") # Test if ok #ADD_EXECUTABLE(tmp ${SWIG_SOURCE_DIR}/Runtime/tmp.c) #TARGET_LINK_LIBRARIES(tmp swig${RUNTIME_NAME}) # Cleanup SET(${EXECUTABLE_OUTPUT_PATH} "${__temp_EXECUTABLE_OUTPUT_PATH}") SET(${LIBRARY_OUTPUT_PATH} "${__temp_LIBRARY_OUTPUT_PATH}") ENDMACRO(BUILD_RUNTIME) cableswig-0.1.0+git20150808.orig/SWIG/CMake/FindRuby.cmake0000644000175000000620000000135412561312226021304 0ustar stevestaff# # This module finds if RUBY is installed and determines where the include files # and libraries are. It also determines what the name of the library is. This # code sets the following variables: # # RUBY_INCLUDE_PATH = path to where object.h can be found # RUBY_EXECUTABLE = full path to the ruby binary # SET(RUBY_POSSIBLE_INCLUDE_PATHS /usr/lib/ruby/1.8/i386-linux ) SET(RUBY_POSSIBLE_LIB_PATHS /usr/lib ) FIND_PATH(RUBY_INCLUDE_PATH ruby.h ${RUBY_POSSIBLE_INCLUDE_PATHS}) FIND_LIBRARY(RUBY_LIBRARY NAMES ruby1.8 PATHS ${RUBY_POSSIBLE_LIB_PATHS} ) FIND_PROGRAM(RUBY_EXECUTABLE NAMES ruby1.8 PATHS /usr/bin /usr/local/bin ) MARK_AS_ADVANCED( RUBY_EXECUTABLE RUBY_LIBRARY RUBY_INCLUDE_PATH ) cableswig-0.1.0+git20150808.orig/SWIG/CMake/FindGuile.cmake0000644000175000000620000000135712561312226021433 0ustar stevestaff# # This module finds if GUILE is installed and determines where the include files # and libraries are. It also determines what the name of the library is. This # code sets the following variables: # # GUILE_INCLUDE_PATH = path to where object.h can be found # GUILE_EXECUTABLE = full path to the guile binary # SET(GUILE_POSSIBLE_INCLUDE_PATHS /usr/include ) SET(GUILE_POSSIBLE_LIB_PATHS /usr/lib ) FIND_PATH(GUILE_INCLUDE_PATH guile/gh.h ${GUILE_POSSIBLE_INCLUDE_PATHS}) FIND_LIBRARY(GUILE_LIBRARY NAMES guile PATHS ${GUILE_POSSIBLE_LIB_PATHS} ) FIND_PROGRAM(GUILE_EXECUTABLE NAMES guile1.4 PATHS /usr/bin /usr/local/bin ) MARK_AS_ADVANCED( GUILE_INCLUDE_PATH GUILE_LIBRARY GUILE_EXECUTABLE ) cableswig-0.1.0+git20150808.orig/SWIG/CMake/FindPerlLibs.cmake0000644000175000000620000000160012561312226022071 0ustar stevestaff# # This module finds if PERL is installed and determines where the include files # and libraries are. It also determines what the name of the library is. This # code sets the following variables: # # PERL_INCLUDE_PATH = path to where object.h can be found # PERL_EXECUTABLE = full path to the perl binary # SET(PERL_POSSIBLE_INCLUDE_PATHS c:/Perl/lib/CORE /Perl/lib/CORE /usr/lib/perl/5.8.0/CORE /usr/lib/perl/5.8.2/CORE ) SET(PERL_POSSIBLE_LIB_PATHS c:/Perl/lib/CORE /Perl/lib/CORE /Perl/lib /usr/lib ) FIND_PATH(PERL_INCLUDE_PATH perl.h ${PERL_POSSIBLE_INCLUDE_PATHS}) FIND_PROGRAM(PERL_EXECUTABLE NAMES perl PATHS c:/Perl/bin /Perl/bin /usr/bin /usr/local/bin ) FIND_LIBRARY(PERL_LIBRARY NAMES perl perl5.8.0 perl58 PATHS ${PERL_POSSIBLE_LIB_PATHS} ) MARK_AS_ADVANCED( PERL_INCLUDE_PATH PERL_EXECUTABLE PERL_LIBRARY ) cableswig-0.1.0+git20150808.orig/SWIG/CMake/FindPike.cmake0000644000175000000620000000124412561312226021251 0ustar stevestaff# # This module finds if PIKE is installed and determines where the include files # and libraries are. It also determines what the name of the library is. This # code sets the following variables: # # PIKE_INCLUDE_PATH = path to where object.h can be found # PIKE_EXECUTABLE = full path to the pike binary # SET(PIKE_POSSIBLE_INCLUDE_PATHS /usr/include /usr/include/pike /usr/include/pike/7.4.27 /usr/local/include/pike/7.4.27 ) FIND_PATH(PIKE_INCLUDE_PATH program.h ${PIKE_POSSIBLE_INCLUDE_PATHS}) FIND_PROGRAM(PIKE_EXECUTABLE NAMES pike7.4 PATHS /usr/bin /usr/local/bin ) MARK_AS_ADVANCED( PIKE_EXECUTABLE PIKE_INCLUDE_PATH ) cableswig-0.1.0+git20150808.orig/SWIG/CMake/FindPHP4.cmake0000644000175000000620000000351412561312226021076 0ustar stevestaff# # This module finds if PHP4 is installed and determines where the include files # and libraries are. It also determines what the name of the library is. This # code sets the following variables: # # PHP4_INCLUDE_PATH = path to where object.h can be found # PHP4_EXECUTABLE = full path to the php4 binary # SET(PHP4_POSSIBLE_INCLUDE_PATHS /usr/include/php4 /usr/local/include/php4 /usr/include/php /usr/local/include/php /usr/local/apache/php ) SET(PHP4_POSSIBLE_LIB_PATHS /usr/lib ) FIND_PATH(PHP4_FOUND_INCLUDE_PATH php_version.h ${PHP4_POSSIBLE_INCLUDE_PATHS}) IF(PHP4_FOUND_INCLUDE_PATH) SET(php4_paths "${PHP4_POSSIBLE_INCLUDE_PATHS}") FOREACH(php4_path Zend main TSRM) SET(php4_paths ${php4_paths} "${PHP4_FOUND_INCLUDE_PATH}/${php4_path}") ENDFOREACH(php4_path Zend main TSRM) SET(PHP4_INCLUDE_PATH "${php4_paths}" INTERNAL "PHP4 include paths") ENDIF(PHP4_FOUND_INCLUDE_PATH) FIND_PROGRAM(PHP4_EXECUTABLE NAMES php4 php PATHS /usr/bin /usr/local/bin ) MARK_AS_ADVANCED( PHP4_EXECUTABLE PHP4_FOUND_INCLUDE_PATH ) IF(APPLE) # this is a hack for now SET(CMAKE_SHARED_MODULE_CREATE_C_FLAGS "${CMAKE_SHARED_MODULE_CREATE_C_FLAGS} -Wl,-flat_namespace") FOREACH(symbol __efree __emalloc __estrdup __object_init_ex __zend_get_parameters_array_ex __zend_list_find __zval_copy_ctor _add_property_zval_ex _alloc_globals _compiler_globals _convert_to_double _convert_to_long _zend_error _zend_hash_find _zend_register_internal_class_ex _zend_register_list_destructors_ex _zend_register_resource _zend_rsrc_list_get_rsrc_type _zend_wrong_param_count _zval_used_for_init ) SET(CMAKE_SHARED_MODULE_CREATE_C_FLAGS "${CMAKE_SHARED_MODULE_CREATE_C_FLAGS},-U,${symbol}") ENDFOREACH(symbol) ENDIF(APPLE) cableswig-0.1.0+git20150808.orig/SWIG/CMake/UsingSwig.cmake0000644000175000000620000000677712561312226021517 0ustar stevestaff# set up mapping from language name to swig runtime library name # if SWIG_USE_SHARED_RUNTIME is set then the -c option will be used for swig MACRO(ADD_SWIG_SOURCE LANGUAGE INPUT SOURCE INCLUDES DEPENDS) SET(SWIG_CXX_FLAGS "-c++") IF(${SOURCE} MATCHES ".c$") SET(SWIG_CXX_FLAGS "") ENDIF(${SOURCE} MATCHES ".c$") IF(EXISTS ${INPUT}) SET(swig_infile "${INPUT}") ELSE(EXISTS ${INPUT}) SET(swig_infile "${CMAKE_CURRENT_SOURCE_DIR}/${INPUT}") ENDIF(EXISTS ${INPUT}) IF(EXISTS ${swig_infile}) ELSE(EXISTS ${swig_infile}) MESSAGE(FATAL_ERROR "Cannot find input file ${INPUT}") ENDIF(EXISTS ${swig_infile}) IF(${LANGUAGE} MATCHES "^perl$") SET(SWIG_LANGUAGE_LIB "perl5") ELSE(${LANGUAGE} MATCHES "^perl$") IF(${LANGUAGE} MATCHES "^php$") SET(SWIG_LANGUAGE_LIB "php4") ELSE(${LANGUAGE} MATCHES "^php$") SET(SWIG_LANGUAGE_LIB "${LANGUAGE}") ENDIF(${LANGUAGE} MATCHES "^php$") ENDIF(${LANGUAGE} MATCHES "^perl$") SET(SWIG_INCLUDES "") FOREACH(path ${INCLUDES} ${SWIG_COMMON_INCLUDES} ${SWIG_LIB_DIR}/${SWIG_LANGUAGE_LIB}) SET(SWIG_INCLUDES ${SWIG_INCLUDES} "-I${path}") ENDFOREACH(path ${INCLUDES} ${SWIG_COMMON_INCLUDES}) SET(swig_current_output_dir "${CMAKE_CURRENT_BINARY_DIR}") # if SWIG_SCRIPT_OUTPUT_DIR is set use it period IF(SWIG_SCRIPT_OUTPUT_DIR) SET(swig_current_output_dir "${SWIG_SCRIPT_OUTPUT_DIR}") ELSE(SWIG_SCRIPT_OUTPUT_DIR) # for python make sure the .py files go next to the libraries as they are needed # for loading IF(${LANGUAGE} MATCHES "^python$") SET(swig_current_output_dir "${LIBRARY_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}") ENDIF(${LANGUAGE} MATCHES "^python$") ENDIF(SWIG_SCRIPT_OUTPUT_DIR) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) IF(SWIG_USE_SHARED_RUNTIME) SET(SWIG_RUNTIME_FLAG "-noruntime") ELSE(SWIG_USE_SHARED_RUNTIME) SET(SWIG_RUNTIME_FLAG) ENDIF(SWIG_USE_SHARED_RUNTIME) ADD_CUSTOM_COMMAND( OUTPUT "${SOURCE}" DEPENDS "${swig_infile}" ${DEPENDS} MAIN_DEPENDENCY "${swig_infile}" COMMAND ${SWIG_EXECUTABLE} ARGS ${SWIG_CXX_FLAGS} ${SWIG_CMD_FLAGS} -${LANGUAGE} ${SWIG_INCLUDES} ${SWIG_RUNTIME_FLAG} -outdir "${swig_current_output_dir}" -o "${SOURCE}" "${swig_infile}" ) SET_SOURCE_FILES_PROPERTIES(${SOURCE} PROPERTIES GENERATED 1) ENDMACRO(ADD_SWIG_SOURCE) MACRO(GET_SWIG_LIBRARY_NAME LANGUAGE LIBNAME VAR) SET(${VAR} "${LIBNAME}") IF("${LANGUAGE}" MATCHES "^python$") SET(${VAR} "_${LIBNAME}") ENDIF("${LANGUAGE}" MATCHES "^python$") ENDMACRO(GET_SWIG_LIBRARY_NAME) MACRO(ADD_SWIG_LIBRARY LANGUAGE LIBNAME SOURCES) SET(SWIG_LIB_PREFIX "") IF("${LANGUAGE}" MATCHES "^python$") SET(SWIG_LIB_PREFIX "_") ENDIF("${LANGUAGE}" MATCHES "^python$") # tcl does not use MODULES IF("${LANGUAGE}" MATCHES "^tcl$") ADD_LIBRARY("${SWIG_LIB_PREFIX}${LIBNAME}" SHARED ${SOURCES}) ELSE("${LANGUAGE}" MATCHES "^tcl$") ADD_LIBRARY("${SWIG_LIB_PREFIX}${LIBNAME}" MODULE ${SOURCES}) ENDIF("${LANGUAGE}" MATCHES "^tcl$") IF(${LANGUAGE} MATCHES "java") ELSE(${LANGUAGE} MATCHES "java") SET_TARGET_PROPERTIES("${SWIG_LIB_PREFIX}${LIBNAME}" PROPERTIES PREFIX "") ENDIF(${LANGUAGE} MATCHES "java") IF(SWIG_SOURCE_DIR) IF(CMAKE_CONFIGURATION_TYPES) ADD_DEPENDENCIES("${SWIG_LIB_PREFIX}${LIBNAME}" swig) ENDIF(CMAKE_CONFIGURATION_TYPES) ENDIF(SWIG_SOURCE_DIR) ENDMACRO(ADD_SWIG_LIBRARY) cableswig-0.1.0+git20150808.orig/SWIG/CMake/FindPythonLibs.cmake0000644000175000000620000000106012561312226022450 0ustar stevestaffINCLUDE(${CMAKE_ROOT}/Modules/FindPythonLibs.cmake) IF(APPLE) SET(CMAKE_SHARED_MODULE_CREATE_C_FLAGS "${CMAKE_SHARED_MODULE_CREATE_C_FLAGS} -Wl,-flat_namespace,-U,_environ") SET(CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS "${CMAKE_SHARED_MODULE_CREATE_CXX_FLAGS} -Wl,-flat_namespace,-U,_environ") SET(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS} -Wl,-flat_namespace,-U,_environ") SET(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "${CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS} -Wl,-flat_namespace,-U,_environ") ENDIF(APPLE) cableswig-0.1.0+git20150808.orig/SWIG/CMake/swigTestBoolType.cxx0000644000175000000620000000020612561312226022566 0ustar stevestaff// Minimal test for existence of "bool" type. void TestBool(bool) {} int main() { TestBool(false); TestBool(true); return 0; } cableswig-0.1.0+git20150808.orig/SWIG/Examples/0002755000175000000620000000000012561312227017356 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Examples/python/0002755000175000000620000000000012561312227020677 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Examples/python/funcattr/0002755000175000000620000000000012561312227022525 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Examples/python/funcattr/runme.py0000644000175000000620000000040012561312227024215 0ustar stevestaff# file: runme.py import example # Create an object v = example.Vector() print "Setting some values" # Set some values (using functions instead of attributes) v.set_x(3.5) v.set_y(4.0) v.set_z(10.5) # Get some values print v print v.x(), v.y(), v.z() cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/funcattr/.cvsignore0000644000175000000620000000014312561312227024521 0ustar stevestaffexample.py example.pyc *_wrap.c *_wrap.cxx *.dll *.dsw *.exp *.lib *.ncb *.opt *.plg Release Debug cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/funcattr/Makefile0000644000175000000620000000101712561312227024162 0ustar stevestaffTOP = ../.. SWIG = $(TOP)/../swig CXXSRCS = TARGET = example INTERFACE = example.i LIBS = -lm SWIGOPT = all:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp static:: $(MAKE) -f $(TOP)/Makefile 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 cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/funcattr/example.i0000644000175000000620000000062212561312227024330 0ustar stevestaff/* File : example.i */ %module example /* Turn all data attributes into a pair of accessor functions. In this case, a data attribute foo is accessed using foo() and changed using set_foo(). The format strings in %attributefunc() can be used to precisely determine the format of the get/set functions */ %attributefunc(%s,set_%s) %inline %{ class Vector { public: double x,y,z; }; %} cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/funcattr/index.html0000644000175000000620000000060512561312227024521 0ustar stevestaff SWIG:Examples:python:funcattr SWIG/Examples/python/funcattr/

    Turning Attributes into Functions

    /cvsroot/SWIG/Examples/python/funcattr/index.html,v 1.3 2002/11/30 22:10:05 beazley Exp

    This example shows how you can turn data attributes into member functions.


    cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/import/0002755000175000000620000000000012561312227022211 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Examples/python/import/spam.i0000644000175000000620000000011012561312227023311 0ustar stevestaff%module spam %{ #include "spam.h" %} %import bar.i %include "spam.h" cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/import/foo.dsp0000644000175000000620000001176412561312227023513 0ustar stevestaff# Microsoft Developer Studio Project File - Name="foo" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=foo - Win32 Release !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "foo.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "foo.mak" CFG="foo - Win32 Release" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "foo - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "foo - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "foo - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FOO_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MTd /W3 /Gm /GR /GX /ZI /Od /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FOO_EXPORTS" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "_DEBUG" # ADD RSC /l 0x809 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "$(PYTHON_LIB)" ..\..\..\Runtime\swigpy.lib /nologo /dll /debug /machine:I386 /out:"_foo.dll" /pdbtype:sept !ELSEIF "$(CFG)" == "foo - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FOO_EXPORTS" /YX /FD /c # ADD CPP /nologo /MT /W3 /GR /GX /O2 /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FOO_EXPORTS" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "NDEBUG" # ADD RSC /l 0x809 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "$(PYTHON_LIB)" ..\..\..\Runtime\swigpy.lib /nologo /dll /machine:I386 /out:"_foo.dll" !ENDIF # Begin Target # Name "foo - Win32 Debug" # Name "foo - Win32 Release" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=.\foo_wrap.cxx # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=.\foo.h # End Source File # End Group # Begin Source File SOURCE=.\foo.i !IF "$(CFG)" == "foo - Win32 Debug" # Begin Custom Build InputPath=.\foo.i InputName=foo "$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" echo In order to function correctly, please ensure the following environment variables are correctly set: echo PYTHON_INCLUDE: %PYTHON_INCLUDE% echo PYTHON_LIB: %PYTHON_LIB% echo on ..\..\..\swig -noruntime -c++ -python $(InputPath) # End Custom Build !ELSEIF "$(CFG)" == "foo - Win32 Release" # Begin Custom Build InputPath=.\foo.i InputName=foo "$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" echo In order to function correctly, please ensure the following environment variables are correctly set: echo PYTHON_INCLUDE: %PYTHON_INCLUDE% echo PYTHON_LIB: %PYTHON_LIB% echo on ..\..\..\swig -noruntime -c++ -python $(InputPath) # End Custom Build !ENDIF # End Source File # End Target # End Project cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/import/bar.h0000644000175000000620000000050612561312227023125 0ustar stevestaff#include "base.h" class Bar : public Base { public: Bar() { } ~Bar() { } virtual void A() { printf("I'm Bar::A\n"); } void B() { printf("I'm Bar::B\n"); } virtual Base *toBase() { return static_cast(this); } static Bar *fromBase(Base *b) { return dynamic_cast(b); } }; cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/import/runme.py0000644000175000000620000000330312561312227023706 0ustar stevestaff# file: runme.py # Test various properties of classes defined in separate modules print "Testing the %import directive" import base import foo import bar import spam # Create some objects print "Creating some objects" a = base.Base() b = foo.Foo() c = bar.Bar() d = spam.Spam() # Try calling some methods print "Testing some methods" print "", print "Should see 'Base::A' ---> ", a.A() print "Should see 'Base::B' ---> ", a.B() print "Should see 'Foo::A' ---> ", b.A() print "Should see 'Foo::B' ---> ", b.B() print "Should see 'Bar::A' ---> ", c.A() print "Should see 'Bar::B' ---> ", c.B() print "Should see 'Spam::A' ---> ", d.A() print "Should see 'Spam::B' ---> ", d.B() # Try some casts print "\nTesting some casts\n" print "", x = a.toBase() print "Should see 'Base::A' ---> ", x.A() print "Should see 'Base::B' ---> ", x.B() x = b.toBase() print "Should see 'Foo::A' ---> ", x.A() print "Should see 'Base::B' ---> ", x.B() x = c.toBase() print "Should see 'Bar::A' ---> ", x.A() print "Should see 'Base::B' ---> ", x.B() x = d.toBase() print "Should see 'Spam::A' ---> ", x.A() print "Should see 'Base::B' ---> ", x.B() x = d.toBar() print "Should see 'Bar::B' ---> ", x.B() print "\nTesting some dynamic casts\n" x = d.toBase() print " Spam -> Base -> Foo : ", y = foo.Foo_fromBase(x) if y: print "bad swig" else: print "good swig" print " Spam -> Base -> Bar : ", y = bar.Bar_fromBase(x) if y: print "good swig" else: print "bad swig" print " Spam -> Base -> Spam : ", y = spam.Spam_fromBase(x) if y: print "good swig" else: print "bad swig" print " Foo -> Spam : ", y = spam.Spam_fromBase(b) if y: print "bad swig" else: print "good swig" cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/import/foo.i0000644000175000000620000000010512561312227023140 0ustar stevestaff%module foo %{ #include "foo.h" %} %import base.i %include "foo.h" cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/import/.cvsignore0000644000175000000620000000024412561312227024207 0ustar stevestaffbar.py base.py foo.py spam.py bar.pyc base.pyc foo.pyc spam.pyc *_wrap.c *_wrap.cxx *.dll example.dsw *.exp *.lib example.ncb example.opt example.plg Release Debug cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/import/bar.i0000644000175000000620000000010612561312227023122 0ustar stevestaff%module bar %{ #include "bar.h" %} %import base.i %include "bar.h" cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/import/spam.h0000644000175000000620000000061412561312227023321 0ustar stevestaff#include "bar.h" class Spam : public Bar { public: Spam() { } ~Spam() { } virtual void A() { printf("I'm Spam::A\n"); } void B() { printf("I'm Spam::B\n"); } virtual Base *toBase() { return static_cast(this); } virtual Bar *toBar() { return static_cast(this); } static Spam *fromBase(Base *b) { return dynamic_cast(b); } }; cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/import/base.h0000644000175000000620000000044012561312227023270 0ustar stevestaff#include class Base { public: Base() { }; ~Base() { }; virtual void A() { printf("I'm Base::A\n"); } void B() { printf("I'm Base::B\n"); } virtual Base *toBase() { return static_cast(this); } }; cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/import/bar.dsp0000644000175000000620000001176412561312227023474 0ustar stevestaff# Microsoft Developer Studio Project File - Name="bar" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=bar - Win32 Release !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "bar.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "bar.mak" CFG="bar - Win32 Release" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "bar - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "bar - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "bar - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BAR_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MTd /W3 /Gm /GR /GX /ZI /Od /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BAR_EXPORTS" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "_DEBUG" # ADD RSC /l 0x809 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "$(PYTHON_LIB)" ..\..\..\Runtime\swigpy.lib /nologo /dll /debug /machine:I386 /out:"_bar.dll" /pdbtype:sept !ELSEIF "$(CFG)" == "bar - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BAR_EXPORTS" /YX /FD /c # ADD CPP /nologo /MT /W3 /GR /GX /O2 /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BAR_EXPORTS" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "NDEBUG" # ADD RSC /l 0x809 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "$(PYTHON_LIB)" ..\..\..\Runtime\swigpy.lib /nologo /dll /machine:I386 /out:"_bar.dll" !ENDIF # Begin Target # Name "bar - Win32 Debug" # Name "bar - Win32 Release" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=.\bar_wrap.cxx # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=.\bar.h # End Source File # End Group # Begin Source File SOURCE=.\bar.i !IF "$(CFG)" == "bar - Win32 Debug" # Begin Custom Build InputPath=.\bar.i InputName=bar "$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" echo In order to function correctly, please ensure the following environment variables are correctly set: echo PYTHON_INCLUDE: %PYTHON_INCLUDE% echo PYTHON_LIB: %PYTHON_LIB% echo on ..\..\..\swig -noruntime -c++ -python $(InputPath) # End Custom Build !ELSEIF "$(CFG)" == "bar - Win32 Release" # Begin Custom Build InputPath=.\bar.i InputName=bar "$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" echo In order to function correctly, please ensure the following environment variables are correctly set: echo PYTHON_INCLUDE: %PYTHON_INCLUDE% echo PYTHON_LIB: %PYTHON_LIB% echo on ..\..\..\swig -noruntime -c++ -python $(InputPath) # End Custom Build !ENDIF # End Source File # End Target # End Project cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/import/base.i0000644000175000000620000000006612561312227023275 0ustar stevestaff%module base %{ #include "base.h" %} %include base.h cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/import/Makefile0000644000175000000620000000142412561312227023650 0ustar stevestaffTOP = ../.. SWIG = $(TOP)/../swig SWIGOPT = -noruntime RUNTIMEDIR = $(TOP)/../Runtime/.libs all:: $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ RUNTIMEDIR='$(RUNTIMEDIR)' TARGET='base' INTERFACE='base.i' python_multi_cpp $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ RUNTIMEDIR='$(RUNTIMEDIR)' TARGET='foo' INTERFACE='foo.i' python_multi_cpp $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ RUNTIMEDIR='$(RUNTIMEDIR)' TARGET='bar' INTERFACE='bar.i' python_multi_cpp $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ RUNTIMEDIR='$(RUNTIMEDIR)' TARGET='spam' INTERFACE='spam.i' python_multi_cpp clean:: $(MAKE) -f $(TOP)/Makefile python_clean @rm -f foo.py bar.py spam.py base.py check: all cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/import/foo.h0000644000175000000620000000050512561312227023143 0ustar stevestaff#include "base.h" class Foo : public Base { public: Foo() { } ~Foo() { } virtual void A() { printf("I'm Foo::A\n"); } void B() { printf("I'm Foo::B\n"); } virtual Base *toBase() { return static_cast(this); } static Foo *fromBase(Base *b) { return dynamic_cast(b); } }; cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/import/spam.dsp0000644000175000000620000001201612561312227023657 0ustar stevestaff# Microsoft Developer Studio Project File - Name="spam" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=spam - Win32 Release !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "spam.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "spam.mak" CFG="spam - Win32 Release" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "spam - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "spam - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "spam - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SPAM_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MTd /W3 /Gm /GR /GX /ZI /Od /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SPAM_EXPORTS" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "_DEBUG" # ADD RSC /l 0x809 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "$(PYTHON_LIB)" ..\..\..\Runtime\swigpy.lib /nologo /dll /debug /machine:I386 /out:"_spam.dll" /pdbtype:sept !ELSEIF "$(CFG)" == "spam - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SPAM_EXPORTS" /YX /FD /c # ADD CPP /nologo /MT /W3 /GR /GX /O2 /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SPAM_EXPORTS" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "NDEBUG" # ADD RSC /l 0x809 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "$(PYTHON_LIB)" ..\..\..\Runtime\swigpy.lib /nologo /dll /machine:I386 /out:"_spam.dll" !ENDIF # Begin Target # Name "spam - Win32 Debug" # Name "spam - Win32 Release" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=.\spam_wrap.cxx # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=.\spam.h # End Source File # End Group # Begin Source File SOURCE=.\spam.i !IF "$(CFG)" == "spam - Win32 Debug" # Begin Custom Build InputPath=.\spam.i InputName=spam "$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" echo In order to function correctly, please ensure the following environment variables are correctly set: echo PYTHON_INCLUDE: %PYTHON_INCLUDE% echo PYTHON_LIB: %PYTHON_LIB% echo on ..\..\..\swig -noruntime -c++ -python $(InputPath) # End Custom Build !ELSEIF "$(CFG)" == "spam - Win32 Release" # Begin Custom Build InputPath=.\spam.i InputName=spam "$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" echo In order to function correctly, please ensure the following environment variables are correctly set: echo PYTHON_INCLUDE: %PYTHON_INCLUDE% echo PYTHON_LIB: %PYTHON_LIB% echo on ..\..\..\swig -noruntime -c++ -python $(InputPath) # End Custom Build !ENDIF # End Source File # End Target # End Project cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/import/base.dsp0000644000175000000620000001201612561312227023631 0ustar stevestaff# Microsoft Developer Studio Project File - Name="base" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=base - Win32 Release !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "base.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "base.mak" CFG="base - Win32 Release" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "base - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "base - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "base - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BASE_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MTd /W3 /Gm /GR /GX /ZI /Od /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BASE_EXPORTS" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "_DEBUG" # ADD RSC /l 0x809 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "$(PYTHON_LIB)" ..\..\..\Runtime\swigpy.lib /nologo /dll /debug /machine:I386 /out:"_base.dll" /pdbtype:sept !ELSEIF "$(CFG)" == "base - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BASE_EXPORTS" /YX /FD /c # ADD CPP /nologo /MT /W3 /GR /GX /O2 /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "BASE_EXPORTS" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "NDEBUG" # ADD RSC /l 0x809 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "$(PYTHON_LIB)" ..\..\..\Runtime\swigpy.lib /nologo /dll /machine:I386 /out:"_base.dll" !ENDIF # Begin Target # Name "base - Win32 Debug" # Name "base - Win32 Release" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=.\base_wrap.cxx # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File SOURCE=.\base.h # End Source File # End Group # Begin Source File SOURCE=.\base.i !IF "$(CFG)" == "base - Win32 Debug" # Begin Custom Build InputPath=.\base.i InputName=base "$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" echo In order to function correctly, please ensure the following environment variables are correctly set: echo PYTHON_INCLUDE: %PYTHON_INCLUDE% echo PYTHON_LIB: %PYTHON_LIB% echo on ..\..\..\swig -noruntime -c++ -python $(InputPath) # End Custom Build !ELSEIF "$(CFG)" == "base - Win32 Release" # Begin Custom Build InputPath=.\base.i InputName=base "$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" echo In order to function correctly, please ensure the following environment variables are correctly set: echo PYTHON_INCLUDE: %PYTHON_INCLUDE% echo PYTHON_LIB: %PYTHON_LIB% echo on ..\..\..\swig -noruntime -c++ -python $(InputPath) # End Custom Build !ENDIF # End Source File # End Target # End Project cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/import/README0000644000175000000620000000243312561312227023071 0ustar stevestaffThis example tests the SWIG run-time libraries and use of the %import directive to work with multiple modules. Use 'python runme.py' to run a test. Overview: --------- The example defines 4 different extension modules--each wrapping a separate C++ class. base.i - Base class foo.i - Foo class derived from Base bar.i - Bar class derived from Base spam.i - Spam class derived from Bar Each module used %import to refer to another module. For example, the 'foo.i' module uses '%import base.i' to get definitions for its base class. If everything is working correctly, all of the modules will load correctly and type checking will work correctly. The example requires the use of the SWIG run-time libraries which must be built and properly installed. Unix: ----- - Make sure the SWIG runtime library is built and the path to it is in LD_LIBRARY_PATH - Run make - Run the test as described above Windows: -------- - Make sure the SWIG runtime library is built and in your path. See Windows.html. - Use the Visual C++ 6 workspace file (example.dsw). Build each project to create the 4 DLLs. The Batch build option in the Build menu is the easiest way to do this. Only use the Release builds not the Debug builds. - Run the test as described above cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/pointer/0002755000175000000620000000000012561312227022357 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Examples/python/pointer/runme.py0000644000175000000620000000163012561312227024055 0ustar stevestaff# file: example.py import example; # First create some objects using the pointer library. print "Testing the pointer library"; a = example.new_intp(); b = example.new_intp(); c = example.new_intp(); example.intp_assign(a,37); example.intp_assign(b,42); print " a =",a print " b =",b print " c =",c # Call the add() function with some pointers example.add(a,b,c) # Now get the result r = example.intp_value(c) print " 37 + 42 =",r # Clean up the pointers example.delete_intp(a) example.delete_intp(b) example.delete_intp(c) # Now try the typemap library # This should be much easier. Now how it is no longer # necessary to manufacture pointers. print "Trying the typemap library"; r = example.sub(37,42) print " 37 - 42 =",r # Now try the version with multiple return values print "Testing multiple return values"; q,r = example.divide(42,37) print " 42/37 = %d remainder %d" % (q,r) cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/pointer/.cvsignore0000644000175000000620000000014312561312227024353 0ustar stevestaffexample.py example.pyc *_wrap.c *_wrap.cxx *.dll *.dsw *.exp *.lib *.ncb *.opt *.plg Release Debug cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/pointer/Makefile0000644000175000000620000000067312561312227024023 0ustar stevestaffTOP = ../.. SWIG = $(TOP)/../swig SRCS = example.c TARGET = example INTERFACE = example.i all:: $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python static:: $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ TARGET='mypython' INTERFACE='$(INTERFACE)' python_static clean:: $(MAKE) -f $(TOP)/Makefile python_clean rm -f $(TARGET).py check: all cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/pointer/example.i0000644000175000000620000000100712561312227024160 0ustar stevestaff/* File : example.i */ %module example /* 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); cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/pointer/index.html0000644000175000000620000000674212561312227024363 0ustar stevestaff SWIG:Examples:python:pointer SWIG/Examples/python/pointer/

    Simple Pointer Handling

    /cvsroot/SWIG/Examples/python/pointer/index.html,v 1.1 2000/09/02 19:26:03 beazley Exp

    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. The only problem is how does one go about creating these objects from a script?

    Possible Solutions

    • Write some helper functions to explicitly create objects. For example:
      int *new_int(int ivalue) {
        int *i = (int *) malloc(sizeof(ivalue));
        *i = ivalue;
        return i;
      }
      int get_int(int *i) {
        return *i;
      }
      
      void delete_int(int *i) {
        free(i);
      }
      
      Now, in a script you would do this:
      a = new_int(37)
      b = new_int(42)
      c = new_int(0)
      add(a,b,c)
      r = get_int(c);
      print "Result =",r
      delete_int(a)
      delete_int(b)
      delete_int(c)
      

    • Use the SWIG pointer library. For example, in the interface file you would do this:
      %include "pointer.i"
      
      a = ptrcreate("int",37)
      b = ptrcreate("int",42)
      c = ptrcreate("int")
      add(a,b,c)
      r = ptrvalue(c)
      print "Result =",r
      ptrfree(a)
      ptrfree(b)
      ptrfree(c)
      
      The advantage to using the pointer library is that it unifies some of the helper functions behind a common set of names. For example, the same set of functions work with int, double, float, and other fundamental types.

    • 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 script:
      r = add(37,42)
      print "Result =",r
      
      Needless to say, this is substantially easier.

    • 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 pointer.i library files can be found in the SWIG user manual. The files also contain documentation.

    • The pointer.i library is designed primarily for convenience. If you are concerned about performance, you probably want to use a different approach.

    cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/pointer/example.c0000644000175000000620000000036112561312227024154 0ustar stevestaff/* 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; } cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/operator/0002755000175000000620000000000012561312227022532 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Examples/python/operator/example.h0000644000175000000620000000147312561312227024341 0ustar stevestaff/* File : example.h */ #include class Complex { private: double rpart, ipart; public: Complex(double r = 0, double i = 0) : rpart(r), ipart(i) { } Complex(const Complex &c) : rpart(c.rpart), ipart(c.ipart) { } Complex &operator=(const Complex &c) { rpart = c.rpart; ipart = c.ipart; return *this; } Complex operator+(const Complex &c) const { return Complex(rpart+c.rpart, ipart+c.ipart); } Complex operator-(const Complex &c) const { return Complex(rpart-c.rpart, ipart-c.ipart); } Complex operator*(const Complex &c) const { return Complex(rpart*c.rpart - ipart*c.ipart, rpart*c.ipart + c.rpart*ipart); } Complex operator-() const { return Complex(-rpart, -ipart); } double re() const { return rpart; } double im() const { return ipart; } }; cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/operator/runme.py0000644000175000000620000000045712561312227024236 0ustar stevestaff# Operator overloading example import example a = example.Complex(2,3) b = example.Complex(-5,10) print "a =",a print "b =",b c = a + b print "c =",c print "a*b =",a*b print "a-c =",a-c e = example.ComplexCopy(a-c) print "e =",e # Big expression f = ((a+b)*(c+b*e)) + (-a) print "f =",f cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/operator/.cvsignore0000644000175000000620000000014312561312227024526 0ustar stevestaffexample.py example.pyc *_wrap.c *_wrap.cxx *.dll *.dsw *.exp *.lib *.ncb *.opt *.plg Release Debug cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/operator/Makefile0000644000175000000620000000077212561312227024176 0ustar stevestaffTOP = ../.. SWIG = $(TOP)/../swig CXXSRCS = TARGET = example INTERFACE = example.i LIBS = -lm SWIGOPT = all:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp static:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static clean:: $(MAKE) -f $(TOP)/Makefile python_clean rm -f $(TARGET).py check: all cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/operator/example.i0000644000175000000620000000123712561312227024340 0ustar stevestaff/* File : example.i */ %module example #pragma SWIG nowarn=362 %{ #include "example.h" %} /* This header file is a little tough to handle because it has overloaded operators and constructors. We're going to try and deal with that here */ /* This turns the copy constructor in a function ComplexCopy() that can be called */ %rename(ComplexCopy) Complex::Complex(Complex const &); /* Now grab the original header file */ %include "example.h" /* An output method that turns a complex into a short string */ %extend Complex { char *__str__() { static char temp[512]; sprintf(temp,"(%g,%g)", self->re(), self->im()); return temp; } }; cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/functor/0002755000175000000620000000000012561312227022357 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Examples/python/functor/runme.py0000644000175000000620000000053112561312227024054 0ustar stevestaff# Operator overloading example import example import math a = example.intSum(0) b = example.doubleSum(100.0) # Use the objects. They should be callable just like a normal # python function. for i in range(0,100): a(i) # Note: function call b(math.sqrt(i)) # Note: function call print a.result() print b.result() cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/functor/.cvsignore0000644000175000000620000000014312561312227024353 0ustar stevestaffexample.py example.pyc *_wrap.c *_wrap.cxx *.dll *.dsw *.exp *.lib *.ncb *.opt *.plg Release Debug cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/functor/Makefile0000644000175000000620000000077212561312227024023 0ustar stevestaffTOP = ../.. SWIG = $(TOP)/../swig CXXSRCS = TARGET = example INTERFACE = example.i LIBS = -lm SWIGOPT = all:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp static:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static clean:: $(MAKE) -f $(TOP)/Makefile python_clean rm -f $(TARGET).py check: all cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/functor/example.i0000644000175000000620000000111312561312227024156 0ustar stevestaff/* File : example.i */ %module example %inline %{ // From B. Strousjoup, "The C++ Programming Language, Third Edition", p. 514 template class Sum { T res; public: Sum(T i = 0) : res(i) { } void operator() (T x) { res += x; } T result() const { return res; } }; %} // Rename the application operator to __call__ for python. // Note: this is normally automatic, but if you had to do it yourself // you would use this directive: // // %rename(__call__) *::operator(); // Instantiate a few versions %template(intSum) Sum; %template(doubleSum) Sum; cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/callback/0002755000175000000620000000000012561312227022433 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Examples/python/callback/example.h0000644000175000000620000000103712561312227024236 0ustar stevestaff/* 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() { if (_callback) delete _callback; _callback = 0; } void setCallback(Callback *cb) { delCallback(); _callback = cb; } void call() { if (_callback) _callback->run(); } }; cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/callback/runme.py0000644000175000000620000000302612561312227024132 0ustar stevestaff# file: runme.py # This file illustrates the cross language polymorphism using directors. import example # CEO class, which overrides Employee::getPosition(). class PyCallback(example.Callback): def __init__(self): example.Callback.__init__(self) def run(self): print "PyCallback.run()" def __del__(self): print "PyCallback.__del__()" # for shadow class extensions that are not "disowned" and # define a __del__ method, it is very important to call the # base class __del__. otherwise the c++ objects will never # be deleted. example.Callback.__del__(self) # Create an Caller instance caller = example.Caller() # Add a simple C++ callback (caller owns the callback, so # we disown it first by clearing the .thisown flag). print "Adding and calling a normal C++ callback" print "----------------------------------------" callback = example.Callback() callback.thisown = 0 caller.setCallback(callback) caller.call() caller.delCallback(); print print "Adding and calling a Python callback" print "------------------------------------" # Add a Python callback (caller owns the callback, so we # disown it first by calling __disown__). caller.setCallback(PyCallback().__disown__()) caller.call() caller.delCallback() print print "Adding and calling another Python callback" print "------------------------------------------" # Lets do the same but use the weak reference this time. callback = PyCallback().__disown__() caller.setCallback(callback) caller.call() caller.delCallback() # All done. print print "python exit" cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/callback/.cvsignore0000644000175000000620000000015412561312227024431 0ustar stevestaffexample.py example.pyc *_wrap.c *_wrap.cxx *_wrap.h *.dll *.dsw *.exp *.lib *.ncb *.opt *.plg Release Debug cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/callback/Makefile0000644000175000000620000000106012561312227024066 0ustar stevestaffTOP = ../.. SWIG = $(TOP)/../swig CXXSRCS = example.cxx 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 cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/callback/example.i0000644000175000000620000000031212561312227024232 0ustar stevestaff/* 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" cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/callback/index.html0000644000175000000620000000061412561312227024427 0ustar stevestaff SWIG:Examples:python:callback SWIG/Examples/python/extend/

    Implementing C++ callbacks in Python

    /cvsroot/SWIG/Examples/python/callback/index.html,v 1.1 2003/03/07 10:26:55 mrose Exp

    This example illustrates how to use directors to implement C++ callbacks in Python.


    cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/callback/example.cxx0000644000175000000620000000006012561312227024604 0ustar stevestaff/* File : example.cxx */ #include "example.h" cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/contract/0002755000175000000620000000000012561312227022514 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Examples/python/contract/runme.py0000644000175000000620000000056012561312227024213 0ustar stevestaff# file: example.py import example # Call our gcd() function x = 42 y = 105 g = example.gcd(x,y) print "The gcd of %d and %d is %d" % (x,y,g) # Manipulate the Foo global variable # Output its current value print "Foo = ", example.cvar.Foo # Change its value example.cvar.Foo = 3.1415926 # See if the change took effect print "Foo = ", example.cvar.Foo cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/contract/.cvsignore0000644000175000000620000000014312561312227024510 0ustar stevestaffexample.py example.pyc *_wrap.c *_wrap.cxx *.dll *.dsw *.exp *.lib *.ncb *.opt *.plg Release Debug cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/contract/Makefile0000644000175000000620000000076212561312227024157 0ustar stevestaffTOP = ../.. SWIG = $(TOP)/../swig SRCS = example.c TARGET = example INTERFACE = example.i SWIGOPT = all:: $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python static:: $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ TARGET='mypython' INTERFACE='$(INTERFACE)' python_static clean:: $(MAKE) -f $(TOP)/Makefile python_clean rm -f $(TARGET).py check: all cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/contract/example.i0000644000175000000620000000036412561312227024322 0ustar stevestaff/* File : example.i */ %module example %contract gcd(int x, int y) { require: x >= 0; y >= 0; } %contract fact(int n) { require: n >= 0; ensure: fact >= 1; } extern int gcd(int x, int y); extern int fact(int n); extern double Foo; cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/contract/example.c0000644000175000000620000000047212561312227024314 0ustar stevestaff/* 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; } int fact(int n) { if (n <= 0) return 1; return n*fact(n-1); } cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/contract/example.dsp0000644000175000000620000001215712561312227024663 0ustar stevestaff# Microsoft Developer Studio Project File - Name="example" - Package Owner=<4> # Microsoft Developer Studio Generated Build File, Format Version 6.00 # ** DO NOT EDIT ** # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 CFG=example - Win32 Release !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE !MESSAGE NMAKE /f "example.mak". !MESSAGE !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE !MESSAGE NMAKE /f "example.mak" CFG="example - Win32 Release" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "example - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE "example - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" CPP=cl.exe MTL=midl.exe RSC=rc.exe !IF "$(CFG)" == "example - Win32 Debug" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 # PROP BASE Output_Dir "Debug" # PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 # PROP Output_Dir "Debug" # PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /GZ /c # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "_DEBUG" # ADD RSC /l 0x809 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "$(PYTHON_LIB)" /nologo /dll /debug /machine:I386 /out:"_example.dll" /pdbtype:sept !ELSEIF "$(CFG)" == "example - Win32 Release" # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 # PROP BASE Output_Dir "Release" # PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 # PROP Output_Dir "Release" # PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c # ADD CPP /nologo /MT /W3 /GX /O2 /I "$(PYTHON_INCLUDE)" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "EXAMPLE_EXPORTS" /YX /FD /c # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE RSC /l 0x809 /d "NDEBUG" # ADD RSC /l 0x809 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib "$(PYTHON_LIB)" /nologo /dll /machine:I386 /out:"_example.dll" !ENDIF # Begin Target # Name "example - Win32 Debug" # Name "example - Win32 Release" # Begin Group "Source Files" # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" # Begin Source File SOURCE=.\example.c # End Source File # Begin Source File SOURCE=.\example_wrap.c # End Source File # End Group # Begin Group "Header Files" # PROP Default_Filter "h;hpp;hxx;hm;inl" # End Group # Begin Group "Resource Files" # PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" # End Group # Begin Source File SOURCE=.\example.i !IF "$(CFG)" == "example - Win32 Debug" # Begin Custom Build InputPath=.\example.i InputName=example "$(InputName)_wrap.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" echo In order to function correctly, please ensure the following environment variables are correctly set: echo PYTHON_INCLUDE: %PYTHON_INCLUDE% echo PYTHON_LIB: %PYTHON_LIB% echo on ..\..\..\swig -python $(InputPath) # End Custom Build !ELSEIF "$(CFG)" == "example - Win32 Release" # Begin Custom Build InputPath=.\example.i InputName=example "$(InputName)_wrap.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" echo In order to function correctly, please ensure the following environment variables are correctly set: echo PYTHON_INCLUDE: %PYTHON_INCLUDE% echo PYTHON_LIB: %PYTHON_LIB% echo on ..\..\..\swig -python $(InputPath) # End Custom Build !ENDIF # End Source File # End Target # End Project cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/class/0002755000175000000620000000000012561312227022004 5ustar stevestaffcableswig-0.1.0+git20150808.orig/SWIG/Examples/python/class/example.h0000644000175000000620000000114312561312227023605 0ustar stevestaff/* 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); }; cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/class/runme.py0000644000175000000620000000175412561312227023511 0ustar stevestaff# file: runme.py # This file illustrates the shadow-class C++ interface generated # by SWIG. import example # ----- Object creation ----- print "Creating some objects:" c = example.Circle(10) print " Created circle", c s = example.Square(10) print " Created square", s # ----- Access a static member ----- print "\nA total of", example.cvar.Shape_nshapes,"shapes were created" # ----- Member data access ----- # Set the location of the object c.x = 20 c.y = 30 s.x = -10 s.y = 5 print "\nHere is their current position:" print " Circle = (%f, %f)" % (c.x,c.y) print " Square = (%f, %f)" % (s.x,s.y) # ----- Call some methods ----- print "\nHere are some properties of the shapes:" for o in [c,s]: print " ", o print " area = ", o.area() print " perimeter = ", o.perimeter() print "\nGuess I'll clean up now" # Note: this invokes the virtual destructor del c del s s = 3 print example.cvar.Shape_nshapes,"shapes remain" print "Goodbye" cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/class/.cvsignore0000644000175000000620000000014312561312227024000 0ustar stevestaffexample.py example.pyc *_wrap.c *_wrap.cxx *.dll *.dsw *.exp *.lib *.ncb *.opt *.plg Release Debug cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/class/Makefile0000644000175000000620000000074212561312227023445 0ustar stevestaffTOP = ../.. SWIG = $(TOP)/../swig CXXSRCS = example.cxx TARGET = example INTERFACE = example.i LIBS = -lm all:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' python_cpp static:: $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ TARGET='mypython' INTERFACE='$(INTERFACE)' python_cpp_static clean:: $(MAKE) -f $(TOP)/Makefile python_clean rm -f $(TARGET).py check: all cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/class/example.i0000644000175000000620000000021612561312227023606 0ustar stevestaff/* File : example.i */ %module example %{ #include "example.h" %} /* Let's just grab the original header file here */ %include "example.h" cableswig-0.1.0+git20150808.orig/SWIG/Examples/python/class/index.html0000644000175000000620000001103012561312227023772 0ustar stevestaff SWIG:Examples:python:class SWIG/Examples/python/class/

    Wrapping a simple C++ class

    /cvsroot/SWIG/Examples/python/class/index.html,v 1.3 2002/11/30 22:10:04 beazley Exp

    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++ -python example.i
    

    A sample Python script

    Click here to see a script that calls the C++ functions from Python.

    Key points

    • To create a new object, you call a constructor like this:
      c = example.new_Circle(10.0)
      

    • To access member data, a pair of accessor functions are used. For example:
      example.Shape_x_set(c,15)    # Set member data
      x = example.Shape_x_get(c)    # Get member data
      
      Note: when accessing member data, the name of the class in which the member data was must be used. In this case, Shape_x_get() and Shape_x_set() are used since 'x' was defined in Shape.

    • To invoke a member function, you simply do this
      print "The area is ", example.Shape_area(c)
      

    • Type checking knows about the inheritance structure of C++. For example:
      example.Shape_area(c)       # Works (c is a Shape)
      example.Circle_area(c)      # Works (c is a Circle)
      example.Square_area(c)      # Fails (c is definitely not a Square)
      

    • To invoke a destructor, simply do this
      example.delete_Shape(c)     # Deletes a shape
      
      (Note: destructors are currently not inherited. This might change later).

    • Static member variables are wrapped as C global variables. For example:
      n = example.cvar.Shape_nshapes     # Get a static data member
      example.cvar.Shapes_nshapes = 13   # Set a static data member
      

    General Comments