diff --git a/Doc/Manual/Go.html b/Doc/Manual/Go.html
new file mode 100644
index 000000000..7d2ce9db8
--- /dev/null
+++ b/Doc/Manual/Go.html
@@ -0,0 +1,463 @@
+
+
+
+SWIG and Go
+
+
+
+ 20 SWIG and Go
+
+
+
+
+
+
+
+This chapter describes SWIG's support of Go. For more information on
+the Go programming language
+see golang.org .
+
+
+ 20.1 Overview
+
+
+
+Go is a compiled language, not a scripting language. However, it does
+not support direct calling of functions written in C/C++. The cgo
+program may be used to generate wrappers to call C code from Go, but
+there is no convenient way to call C++ code. SWIG fills this gap.
+
+
+
+There are (at least) two different Go compilers. One is the gc
+compiler, normally invoked under the names 6g, 8g, or 5g. The other
+is the gccgo compiler, which is a frontend to the gcc compiler suite.
+The interface to C/C++ code is completely different for the two Go
+compilers. SWIG supports both, selected by a command line option.
+
+
+
+Because Go is a type-safe compiled language, SWIG's runtime type
+checking and runtime library are not used with Go. This should be
+borne in mind when reading the rest of the SWIG documentation.
+
+
+ 20.2 Running SWIG with Go
+
+
+
+To generate Go code, use the -go option with SWIG. By
+default SWIG will generate code for the gc compilers. To generate
+code for gccgo, you should use the -gccgo option.
+
+
+ 20.2.1 Additional Commandline Options
+
+
+
+These are the command line options for SWIG's GO module. They can
+also be seen by using:
+
+
+
+
+
+
+Go specific options
+
+
+
+-gccgo
+Generate code for gccgo. The default is to generate code for
+ 6g/8g/6g.
+
+
+
+-package <name>
+Set the name of the Go package to <name>. The default
+ package name is the SWIG module name.
+
+
+
+-go-prefix <prefix>
+When generating code for gccgo, set the prefix to use. This
+ corresponds to the -fgo-prefix option to gccgo.
+
+
+
+-long-type-size <s>
+Set the size for the C/C++ type long . This controls
+ whether long is converted to the Go type int32
+ or int64 . The <s> argument should be 32 or 64.
+
+
+
+-rename <old>=<new>
+Rename <old%gt; to <new> when processing the C/C++ code
+ and also the SWIG input file. This is a convenient way to rename
+ names in the C/C++ code which are the same expect for the first
+ letter, to avoid conflicts when applying the Go renaming rules
+ described below.
+
+
+
+
+ 20.2.2 Go Output Files
+
+
+ When generating Go code, SWIG will generate the following
+ files:
+
+
+
+MODULE.go will contain the Go functions that your Go code will call.
+These functions will be wrappers for the C++ functions defined by your
+module. This file should, of course, be compiled with the Go
+compiler.
+
+MODULE_wrap.c or MODULE_wrap.cxx will contain C/C++ functions will be
+invoked by the Go wrapper code. This file should be compiled with the
+usual C or C++ compiler and linked into a shared library.
+
+MODULE_wrap.h will be generated if you use the directors feature. It
+provides a definition of the generated C++ director classes. It is
+generally not necessary to use this file, but in some special cases it
+may be helpful to include it in your code, compiled with the usual C
+or C++ compiler.
+
+If using the gc compiler, MODULE_gc.c will contain C code which should
+be compiled with the C compiler which part of the gc compiler: 6c, 8c,
+or 5c. It should then be combined with the compiled MODULE.go using
+gopack. This file will not be generated when using gccgo.
+
+
+
+A typical command sequence would look like this:
+
+
+
+% swig -go example.i
+% gcc -c -fpic example.c
+% gcc -c -fpic example_wrap.c
+% gcc -shared example.o example_wrap.o -o example.so
+% 6g example.go
+% 6c example_gc.c
+% gopack grc example.a example.6 example_gc.6
+% 6g main.go # your code, not generated by SWIG
+% 6l main.6
+
+
+ 20.3 A tour of basic C/C++ wrapping
+
+
+
+By default, SWIG attempts to build a natural Go interface to your
+C/C++ code. However, the languages are somewhat different, so some
+modifications have to occur. This section briefly covers the
+essential aspects of this wrapping.
+
+
+ 20.3.1 Go Package Name
+
+
+
+All Go source code lives in a package. The name of this package will
+default to the name of the module from SWIG's %module
+directive. You may override this by using SWIG's -package
+command line option.
+
+
+ 20.3.2 Go Names
+
+
+
+In Go, a function is only visible outside the current package if the
+first letter of the name is uppercase. This is quite different from
+C/C++. Because of this, C/C++ names are modified when generating the
+Go interface: the first letter is forced to be uppercase if it is not
+already. This affects the names of functions, methods, variables,
+constants, enums, and classes.
+
+
+
+C/C++ variables are wrapped with setter and getter functions in Go.
+First the first letter of the variable name will be forced to
+uppercase, and then Get or Set will be prepended.
+For example, if the C/C++ variable is called var , then SWIG
+will define the functions GetVar and SetVar . If a
+variable is declared as const , or if
+SWIG's
+%immutable directive is used for the variable, then only
+the getter will be defined.
+
+
+
+C++ classes will be discussed further below. Here we'll note that the
+first letter of the class name will be forced to uppercase to give the
+name of a type in Go. A constructor will be named New
+followed by that name, and the destructor will be
+named Delete followed by that name.
+
+
+ 20.3.3 Go Constants
+
+
+
+C/C++ constants created via #define or the %constant
+directive become Go constants, declared with a const
+declaration.
+
+
20.3.4 Go Enumerations
+
+
+
+C/C++ enumeration types will cause SWIG to define an integer type with
+the name of the enumeration (with first letter forced to uppercase as
+usual). The values of the enumeration will become variables in Go;
+code should avoid modifying those variables.
+
+
+ 20.3.5 Go Classes
+
+
+
+Go has interfaces, methods and inheritance, but it does not have
+classes in the same sense as C++. This sections describes how SWIG
+represents C++ classes represented in Go.
+
+
+
+For a C++ class ClassName , SWIG will define two types in Go:
+an underlying type, which will just hold a pointer to the C++ type,
+and an interface type. The interface type will be
+named ClassName . SWIG will define a
+function NewClassName which will take any constructor
+arguments and return a value of the interface
+type ClassName . SWIG will also define a
+destructor DeleteClassName .
+
+
+
+SWIG will represent any methods of the C++ class as methods on the
+underlying type, and also as methods of the interface type. Thus C++
+methods may be invoked directly using the
+usual val.MethodName syntax. Public members of the C++ class
+will be given getter and setter functions defined as methods of the
+class.
+
+
+
+SWIG will represent static methods of C++ classes as ordinary Go
+functions. SWIG will use names like ClassName_MethodName .
+SWIG will give static members getter and setter functions with names
+like GetClassName_VarName .
+
+
+
+Given a value of the interface type, Go code can retrieve the pointer
+to the C++ type by calling the Swigcptr method. This will
+return a value of type SwigcptrClassName , which is just a
+name for uintptr . A Go type conversion can be used to
+convert this value to a different C++ type, but note that this
+conversion will not be type checked and is essentially equivalent
+to reinterpret_cast . This should only be used for very
+special cases, such as where C++ would use a dynamic_cast .
+
+
+ 20.3.5.1 Go Class Inheritance
+
+
+
+C++ class inheritance is automatically represented in Go due to its
+use of interfaces. The interface for a child class will be a superset
+of the interface of its parent class. Thus a value of the child class
+type in Go may be passed to a function which expects the parent class.
+Doing the reverse will require an explicit type assertion, which will
+be checked dynamically.
+
+
+ 20.3.6 Go Templates
+
+
+
+In order to use C++ templates in Go, you must tell SWIG to create
+wrappers for a particular template instantation. To do this, use
+the %template directive.
+
+
20.3.7 Go Director Classes
+
+
+
+SWIG's director feature permits a Go type to act as the subclass of a
+C++ class with virtual methods. This is complicated by the fact that
+C++ and Go define inheritance differently. In Go, structs can inherit
+methods via anonymous field embedding. However, when a method is
+called for an embedded struct, if that method calls any other methods,
+they are called for the embedded struct, not for the original type.
+Therefore, SWIG must use Go interfaces to represent C++ inheritance.
+
+
+
+In order to use the director feature in Go, you must define a type in
+your Go code. You must then add methods for the type. Define a
+method in Go for each C++ virtual function that you want to override.
+You must then create a value of your new type, and pass a pointer to
+it to the function NewDirectorClassName ,
+where ClassName is the name of the C++ class. That will
+return a value of type ClassName .
+
+
+
+For example:
+
+
+
+
+type GoClass struct { }
+func (p *GoClass) VirtualFunction() { }
+func MakeClass() ClassName {
+ return NewDirectorClassName(&GoClass{})
+}
+
+
+
+
+Any call in C++ code to the virtual function will wind up calling the
+method defined in Go. The Go code may of course call other methods on
+itself, and those methods may be defined either in Go or in C++.
+
+
+ 20.3.8 Default Go primitive type mappings
+
+
+
+The following table lists the default type mapping from C/C++ to Go.
+This table will tell you which Go type to expect for a function which
+uses a given C/C++ type.
+
+
+
+
+C/C++ type
+Go type
+
+
+
+bool
+bool
+
+
+
+char
+byte
+
+
+
+signed char
+int8
+
+
+
+unsigned char
+byte
+
+
+
+short
+int16
+
+
+
+unsigned short
+uint16
+
+
+
+int
+int
+
+
+
+unsigned int
+uint
+
+
+
+long
+int32 or int64, depending on -long-type-size
+
+
+
+unsigned long
+uint32 or uint64, depending on -long-type-size
+
+
+
+long long
+int64
+
+
+
+unsigned long long
+uint64
+
+
+
+float
+float32
+
+
+
+double
+float64
+
+
+
+char * char []
+string
+
+
+
+
+
+Note that SWIG wraps the C char type as a character. Pointers
+and arrays of this type are wrapped as strings. The signed
+char type can be used if you want to treat char as a
+signed number rather than a character. Also note that all const
+references to primitive types are treated as if they are passed by
+value.
+
+
+
+These type mappings are defined by the "go" typemap. You may change
+that typemap, or add new values, to control how C/C++ types are mapped
+into Go types.
+
+
+
+
diff --git a/Doc/Manual/SWIG.html b/Doc/Manual/SWIG.html
index b4f332b14..d523bee77 100644
--- a/Doc/Manual/SWIG.html
+++ b/Doc/Manual/SWIG.html
@@ -113,6 +113,7 @@ can be obtained by typing swig -help or swig
-clisp Generate CLISP wrappers
-cffi Generate CFFI wrappers
-csharp Generate C# wrappers
+-go Generate Go wrappers
-guile Generate Guile wrappers
-java Generate Java wrappers
-lua Generate Lua wrappers
diff --git a/Doc/Manual/Sections.html b/Doc/Manual/Sections.html
index e514f726d..8693adc07 100644
--- a/Doc/Manual/Sections.html
+++ b/Doc/Manual/Sections.html
@@ -36,6 +36,7 @@ Last update : SWIG-2.0.1 (in progress)
Allegro CL support
C# support
Chicken support
+Go support
Guile support
Java support
Lua support
diff --git a/Doc/Manual/chapters b/Doc/Manual/chapters
index bf180f1b4..cd399996b 100644
--- a/Doc/Manual/chapters
+++ b/Doc/Manual/chapters
@@ -17,6 +17,7 @@ CCache.html
Allegrocl.html
CSharp.html
Chicken.html
+Go.html
Guile.html
Java.html
Lisp.html
diff --git a/Examples/Makefile.in b/Examples/Makefile.in
index 9dee0347f..5960d79fb 100644
--- a/Examples/Makefile.in
+++ b/Examples/Makefile.in
@@ -1141,3 +1141,74 @@ r_clean:
rm -f *.@OBJEXT@ *@SO@ NAMESPACE
rm -f $(RRSRC) runme.Rout .RData
+##################################################################
+##### Go ######
+##################################################################
+
+GO = @GO@
+GOGCC = @GOGCC@
+
+GOSWIGARG = `if $(GOGCC) ; then echo -gccgo; fi`
+GOCOMPILEARG = `if $(GOGCC) ; then echo -c -g; fi`
+
+GOSRCS = $(INTERFACE:.i=.go)
+GOCSRCS = $(INTERFACE:.i=_gc.c)
+
+GOC = $(GO:g=c)
+GOLD = $(GO:g=l)
+
+GOPACKAGE = $(INTERFACE:.i=.a)
+
+GOOBJEXT = $(GO:g=)
+GOGCOBJS = $(GOSRCS:.go=.$(GOOBJEXT))
+GOGCCOBJS = $(GOSRCS:.go=.@OBJEXT@)
+
+# ----------------------------------------------------------------
+# Build a Go dynamically loadable module (C)
+# ----------------------------------------------------------------
+
+go: $(SRCS)
+ $(SWIG) -go $(GOSWIGARG) $(SWIGOPT) $(INTERFACEPATH)
+ $(CC) -g -c $(CCSHARED) $(CFLAGS) $(SRCS) $(ISRCS) $(INCLUDES)
+ $(LDSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
+ $(GO) -I . $(GOCOMPILEARG) $(GOSRCS)
+ if ! $(GOGCC) ; then \
+ $(GOC) -I $${GOROOT}/pkg/$${GOOS}_$${GOARCH} $(GOCSRCS) && \
+ gopack grc $(GOPACKAGE) $(GOGCOBJS) $(GOCSRCS:.c=.$(GOOBJEXT)); \
+ fi
+
+# ----------------------------------------------------------------
+# Build a Go dynamically loadable module (C++)
+# ----------------------------------------------------------------
+
+go_cpp: $(SRCS)
+ $(SWIG) -go -c++ $(GOSWIGARG) $(SWIGOPT) $(INTERFACEPATH)
+ $(CXX) -g -c $(CCSHARED) $(CFLAGS) $(SRCS) $(CXXSRCS) $(ICXXSRCS) $(INCLUDES)
+ $(CXXSHARED) $(CFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
+ $(GO) -I . $(GOCOMPILEARG) $(GOSRCS)
+ if ! $(GOGCC) ; then \
+ $(GOC) -I $${GOROOT}/pkg/$${GOOS}_$${GOARCH} $(GOCSRCS) && \
+ gopack grc $(GOPACKAGE) $(GOGCOBJS) $(GOCSRCS:.c=.$(GOOBJEXT)); \
+ else true; fi
+
+# -----------------------------------------------------------------
+# Running a Go example
+# -----------------------------------------------------------------
+
+go_run: runme.go
+ $(GO) $(GOCOMPILEARG) runme.go
+ if $(GOGCC) ; then \
+ $(GO) -o runme runme.@OBJEXT@ $(GOGCCOBJS) $(LIBPREFIX)$(TARGET)$(SO); \
+ else \
+ $(GOLD) -r $${GOROOT}/pkg/$${GOOS}_$${GOARCH}:. -o runme runme.$(GOOBJEXT); \
+ fi
+ env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH ./runme
+
+# -----------------------------------------------------------------
+# Cleaning the Go examples
+# -----------------------------------------------------------------
+
+go_clean:
+ rm -f *_wrap* *_gc* .~* runme
+ rm -f core @EXTRA_CLEAN@
+ rm -f *.@OBJEXT@ *.[568] *.a *@SO@
diff --git a/Examples/go/callback/Makefile b/Examples/go/callback/Makefile
new file mode 100644
index 000000000..9dc8b8851
--- /dev/null
+++ b/Examples/go/callback/Makefile
@@ -0,0 +1,18 @@
+TOP = ../..
+SWIG = $(TOP)/../preinst-swig
+CXXSRCS = example.cxx
+TARGET = example
+INTERFACE = example.i
+SWIGOPT =
+
+all:: go
+
+go::
+ $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
+ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_cpp
+
+clean::
+ $(MAKE) -f $(TOP)/Makefile go_clean
+
+check: all
+ $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
diff --git a/Examples/go/callback/example.cxx b/Examples/go/callback/example.cxx
new file mode 100644
index 000000000..450d75608
--- /dev/null
+++ b/Examples/go/callback/example.cxx
@@ -0,0 +1,4 @@
+/* File : example.cxx */
+
+#include "example.h"
+
diff --git a/Examples/go/callback/example.go b/Examples/go/callback/example.go
new file mode 100644
index 000000000..5c0cfb051
--- /dev/null
+++ b/Examples/go/callback/example.go
@@ -0,0 +1,188 @@
+/* ----------------------------------------------------------------------------
+ * This file was automatically generated by SWIG (http://www.swig.org).
+ * Version 2.0.1
+ *
+ * This file is not intended to be easily readable and contains a number of
+ * coding conventions designed to improve portability and efficiency. Do not make
+ * changes to this file unless you know what you are doing--modify the SWIG
+ * interface file instead.
+ * ----------------------------------------------------------------------------- */
+
+package example
+
+
+type _swig_fnptr *byte
+type _swig_memberptr *byte
+
+
+func _swig_allocatememory(int) *byte
+func _swig_internal_allocate(len int) *byte {
+ return _swig_allocatememory(len)
+}
+
+func _swig_allocatestring(*byte, int) string
+func _swig_internal_makegostring(p *byte, l int) string {
+ return _swig_allocatestring(p, l)
+}
+
+func _swig_internal_gopanic(p *byte, l int) {
+ panic(_swig_allocatestring(p, l))
+}
+
+type _swig_DirectorCallback struct {
+ SwigcptrCallback
+ v interface{}
+}
+
+func (p *_swig_DirectorCallback) Swigcptr() uintptr {
+ return p.SwigcptrCallback.Swigcptr()
+}
+
+func (p *_swig_DirectorCallback) SwigIsCallback() {
+}
+
+func (p *_swig_DirectorCallback) DirectorInterface() interface{} {
+ return p.v
+}
+
+func _swig_NewDirectorCallbackCallback(*_swig_DirectorCallback) SwigcptrCallback
+
+func NewDirectorCallback(v interface{}) Callback {
+ p := &_swig_DirectorCallback{0, v}
+ p.SwigcptrCallback = _swig_NewDirectorCallbackCallback(p)
+ return p
+}
+
+func _swig_wrap_DeleteDirectorCallback(uintptr)
+
+func DeleteDirectorCallback(arg1 Callback) {
+ _swig_wrap_DeleteDirectorCallback(arg1.Swigcptr())
+}
+
+func Swiggo_DeleteDirector_Callback(p *_swig_DirectorCallback) {
+ p.SwigcptrCallback = 0
+}
+
+type _swig_DirectorInterfaceCallbackRun interface {
+ Run()
+}
+
+func _swig_wrap__swig_DirectorCallback_upcall_Run(SwigcptrCallback)
+func (swig_p *_swig_DirectorCallback) Run() {
+ if swig_g, swig_ok := swig_p.v.(_swig_DirectorInterfaceCallbackRun); swig_ok {
+ swig_g.Run()
+ return
+ }
+ _swig_wrap__swig_DirectorCallback_upcall_Run(swig_p.SwigcptrCallback)
+}
+
+func DirectorCallbackRun(p Callback) {
+ _swig_wrap__swig_DirectorCallback_upcall_Run(p.(*_swig_DirectorCallback).SwigcptrCallback)
+}
+
+func Swig_DirectorCallback_callback_run(p *_swig_DirectorCallback) {
+ p.Run()
+}
+
+type SwigcptrCallback uintptr
+
+func (p SwigcptrCallback) Swigcptr() uintptr {
+ return (uintptr)(p)
+}
+
+func (p SwigcptrCallback) SwigIsCallback() {
+}
+
+func (p SwigcptrCallback) DirectorInterface() interface{} {
+ return nil
+}
+
+func _swig_wrap_delete_Callback(uintptr)
+
+func DeleteCallback(arg1 Callback) {
+ _swig_wrap_delete_Callback(arg1.Swigcptr())
+}
+
+func _swig_wrap_Callback_run(SwigcptrCallback)
+
+func (arg1 SwigcptrCallback) Run() {
+ _swig_wrap_Callback_run(arg1)
+}
+
+func _swig_wrap_new_Callback() SwigcptrCallback
+
+func NewCallback() Callback {
+ return _swig_wrap_new_Callback()
+}
+
+type Callback interface {
+ Swigcptr() uintptr
+ SwigIsCallback()
+ DirectorInterface() interface{}
+ Run()
+}
+
+type SwigcptrCaller uintptr
+
+func (p SwigcptrCaller) Swigcptr() uintptr {
+ return (uintptr)(p)
+}
+
+func (p SwigcptrCaller) SwigIsCaller() {
+}
+
+func _swig_wrap_new_Caller() SwigcptrCaller
+
+func NewCaller() Caller {
+ return _swig_wrap_new_Caller()
+}
+
+func _swig_wrap_delete_Caller(uintptr)
+
+func DeleteCaller(arg1 Caller) {
+ _swig_wrap_delete_Caller(arg1.Swigcptr())
+}
+
+func _swig_wrap_Caller_delCallback(SwigcptrCaller)
+
+func (arg1 SwigcptrCaller) DelCallback() {
+ _swig_wrap_Caller_delCallback(arg1)
+}
+
+func _swig_wrap_Caller_setCallback(SwigcptrCaller, uintptr)
+
+func (arg1 SwigcptrCaller) SetCallback(arg2 Callback) {
+ _swig_wrap_Caller_setCallback(arg1, arg2.Swigcptr())
+}
+
+func _swig_wrap_Caller_call(SwigcptrCaller)
+
+func (arg1 SwigcptrCaller) Call() {
+ _swig_wrap_Caller_call(arg1)
+}
+
+type Caller interface {
+ Swigcptr() uintptr
+ SwigIsCaller()
+ DelCallback()
+ SetCallback(arg2 Callback)
+ Call()
+}
+
+
+type SwigcptrSwigDirector_Callback uintptr
+type SwigDirector_Callback interface {
+ Swigcptr() uintptr;
+}
+func (p SwigcptrSwigDirector_Callback) Swigcptr() uintptr {
+ return uintptr(p)
+}
+
+type SwigcptrVoid uintptr
+type Void interface {
+ Swigcptr() uintptr;
+}
+func (p SwigcptrVoid) Swigcptr() uintptr {
+ return uintptr(p)
+}
+
diff --git a/Examples/go/callback/example.h b/Examples/go/callback/example.h
new file mode 100644
index 000000000..1a0e8c432
--- /dev/null
+++ b/Examples/go/callback/example.h
@@ -0,0 +1,23 @@
+/* File : example.h */
+
+#include
+#include
+
+class Callback {
+public:
+ virtual ~Callback() { std::cout << "Callback::~Callback()" << std:: endl; }
+ virtual void run() { std::cout << "Callback::run()" << std::endl; }
+};
+
+
+class Caller {
+private:
+ Callback *_callback;
+public:
+ Caller(): _callback(0) {}
+ ~Caller() { delCallback(); }
+ void delCallback() { delete _callback; _callback = 0; }
+ void setCallback(Callback *cb) { delCallback(); _callback = cb; }
+ void call() { if (_callback) _callback->run(); }
+};
+
diff --git a/Examples/go/callback/example.i b/Examples/go/callback/example.i
new file mode 100644
index 000000000..90beda01a
--- /dev/null
+++ b/Examples/go/callback/example.i
@@ -0,0 +1,13 @@
+/* File : example.i */
+%module(directors="1") example
+%{
+#include "example.h"
+%}
+
+%include "std_string.i"
+
+/* turn on director wrapping Callback */
+%feature("director") Callback;
+
+%include "example.h"
+
diff --git a/Examples/go/callback/index.html b/Examples/go/callback/index.html
new file mode 100644
index 000000000..b053cf547
--- /dev/null
+++ b/Examples/go/callback/index.html
@@ -0,0 +1,81 @@
+
+
+SWIG:Examples:go:callback
+
+
+
+
+
+SWIG/Examples/go/callback/
+
+
+Implementing C++ callbacks in Go
+
+
+This example illustrates how to use directors to implement C++
+callbacks in Go.
+
+
+
+Because Go and C++ use inheritance differently, you must call a
+different function to create a class which uses callbacks. Instead of
+calling the usual constructor function whose name is New
+followed by the capitalized name of the class, you call a function
+named NewDirector followed by the capitalized name of the
+class.
+
+
+
+The first argument to the NewDirector function is an instance
+of a type. The NewDirector function will return an interface
+value as usual. However, when calling any method on the returned
+value, the program will first check whether the value passed
+to NewDirector implements that method. If it does, the
+method will be called in Go. This is true whether the method is
+called from Go code or C++ code.
+
+
+
+Note that the Go code will be called with just the Go value, not the
+C++ value. If the Go code needs to call a C++ method on itself, you
+need to get a copy of the C++ object. This is typically done as
+follows:
+
+
+
+type Child struct { abi Parent }
+func (p *Child) ChildMethod() {
+ p.abi.ParentMethod()
+}
+func f() {
+ p := &Child{nil}
+ d := NewDirectorParent(p)
+ p.abi = d
+ ...
+}
+
+
+
+In other words, we first create the Go value. We pass that to
+the NewDirector function to create the C++ value; this C++
+value will be created with an association to the Go value. We then
+store the C++ value in the Go value, giving us the reverse
+association. That permits us to call parent methods from the child.
+
+
+
+
+To delete a director object, use the function DeleteDirector
+followed by the capitalized name of the class.
+
+
+
+
+
+
+
+
diff --git a/Examples/go/callback/runme.go b/Examples/go/callback/runme.go
new file mode 100644
index 000000000..ffa4b3874
--- /dev/null
+++ b/Examples/go/callback/runme.go
@@ -0,0 +1,41 @@
+package main
+
+import (
+ "fmt"
+ . "./example"
+)
+
+func main() {
+ fmt.Println("Adding and calling a normal C++ callback")
+ fmt.Println("----------------------------------------")
+
+ caller := NewCaller()
+ callback := NewCallback()
+
+ caller.SetCallback(callback)
+ caller.Call()
+ caller.DelCallback()
+
+ callback = NewDirectorCallback(new(GoCallback))
+
+ fmt.Println()
+ fmt.Println("Adding and calling a Go callback")
+ fmt.Println("------------------------------------")
+
+ caller.SetCallback(callback)
+ caller.Call()
+ caller.DelCallback()
+
+ // Test that a double delete does not occur as the object has
+ // already been deleted from the C++ layer.
+ DeleteDirectorCallback(callback)
+
+ fmt.Println()
+ fmt.Println("Go exit")
+}
+
+type GoCallback struct{}
+
+func (p *GoCallback) Run() {
+ fmt.Println("GoCallback.Run")
+}
diff --git a/Examples/go/check.list b/Examples/go/check.list
new file mode 100644
index 000000000..5399b8979
--- /dev/null
+++ b/Examples/go/check.list
@@ -0,0 +1,13 @@
+# see top-level Makefile.in
+callback
+class
+constants
+enum
+extend
+funcptr
+multimap
+pointer
+reference
+simple
+template
+variables
diff --git a/Examples/go/class/Makefile b/Examples/go/class/Makefile
new file mode 100644
index 000000000..53d31d1a4
--- /dev/null
+++ b/Examples/go/class/Makefile
@@ -0,0 +1,16 @@
+TOP = ../..
+SWIG = $(TOP)/../preinst-swig
+CXXSRCS = example.cxx
+TARGET = example
+INTERFACE = example.i
+LIBS = -lm
+
+all::
+ $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
+ TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_cpp
+
+clean::
+ $(MAKE) -f $(TOP)/Makefile go_clean
+
+check: all
+ $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
diff --git a/Examples/go/class/example.cxx b/Examples/go/class/example.cxx
new file mode 100644
index 000000000..1e8e203dd
--- /dev/null
+++ b/Examples/go/class/example.cxx
@@ -0,0 +1,28 @@
+/* File : example.c */
+
+#include "example.h"
+#define M_PI 3.14159265358979323846
+
+/* Move the shape to a new location */
+void Shape::move(double dx, double dy) {
+ x += dx;
+ y += dy;
+}
+
+int Shape::nshapes = 0;
+
+double Circle::area(void) {
+ return M_PI*radius*radius;
+}
+
+double Circle::perimeter(void) {
+ return 2*M_PI*radius;
+}
+
+double Square::area(void) {
+ return width*width;
+}
+
+double Square::perimeter(void) {
+ return 4*width;
+}
diff --git a/Examples/go/class/example.go b/Examples/go/class/example.go
new file mode 100644
index 000000000..ec8113ad4
--- /dev/null
+++ b/Examples/go/class/example.go
@@ -0,0 +1,284 @@
+/* ----------------------------------------------------------------------------
+ * This file was automatically generated by SWIG (http://www.swig.org).
+ * Version 2.0.1
+ *
+ * This file is not intended to be easily readable and contains a number of
+ * coding conventions designed to improve portability and efficiency. Do not make
+ * changes to this file unless you know what you are doing--modify the SWIG
+ * interface file instead.
+ * ----------------------------------------------------------------------------- */
+
+package example
+
+
+type _swig_fnptr *byte
+type _swig_memberptr *byte
+
+
+func _swig_allocatememory(int) *byte
+func _swig_internal_allocate(len int) *byte {
+ return _swig_allocatememory(len)
+}
+
+func _swig_allocatestring(*byte, int) string
+func _swig_internal_makegostring(p *byte, l int) string {
+ return _swig_allocatestring(p, l)
+}
+
+func _swig_internal_gopanic(p *byte, l int) {
+ panic(_swig_allocatestring(p, l))
+}
+
+type SwigcptrShape uintptr
+
+func (p SwigcptrShape) Swigcptr() uintptr {
+ return (uintptr)(p)
+}
+
+func (p SwigcptrShape) SwigIsShape() {
+}
+
+func _swig_wrap_delete_Shape(uintptr)
+
+func DeleteShape(arg1 Shape) {
+ _swig_wrap_delete_Shape(arg1.Swigcptr())
+}
+
+func _swig_wrap_Shape_x_set(SwigcptrShape, float64)
+
+func (arg1 SwigcptrShape) SetX(arg2 float64) {
+ _swig_wrap_Shape_x_set(arg1, arg2)
+}
+
+func _swig_wrap_Shape_x_get(SwigcptrShape) float64
+
+func (arg1 SwigcptrShape) GetX() float64 {
+ return _swig_wrap_Shape_x_get(arg1)
+}
+
+func _swig_wrap_Shape_y_set(SwigcptrShape, float64)
+
+func (arg1 SwigcptrShape) SetY(arg2 float64) {
+ _swig_wrap_Shape_y_set(arg1, arg2)
+}
+
+func _swig_wrap_Shape_y_get(SwigcptrShape) float64
+
+func (arg1 SwigcptrShape) GetY() float64 {
+ return _swig_wrap_Shape_y_get(arg1)
+}
+
+func _swig_wrap_Shape_move(SwigcptrShape, float64, float64)
+
+func (arg1 SwigcptrShape) Move(arg2 float64, arg3 float64) {
+ _swig_wrap_Shape_move(arg1, arg2, arg3)
+}
+
+func _swig_wrap_Shape_area(SwigcptrShape) float64
+
+func (arg1 SwigcptrShape) Area() float64 {
+ return _swig_wrap_Shape_area(arg1)
+}
+
+func _swig_wrap_Shape_perimeter(SwigcptrShape) float64
+
+func (arg1 SwigcptrShape) Perimeter() float64 {
+ return _swig_wrap_Shape_perimeter(arg1)
+}
+
+func _swig_wrap_Shape_nshapes_set(int)
+
+func SetShapeNshapes(arg1 int) {
+ _swig_wrap_Shape_nshapes_set(arg1)
+}
+
+func GetShapeNshapes() int
+type Shape interface {
+ Swigcptr() uintptr
+ SwigIsShape()
+ SetX(arg2 float64)
+ GetX() float64
+ SetY(arg2 float64)
+ GetY() float64
+ Move(arg2 float64, arg3 float64)
+ Area() float64
+ Perimeter() float64
+}
+
+type SwigcptrCircle uintptr
+
+func (p SwigcptrCircle) Swigcptr() uintptr {
+ return (uintptr)(p)
+}
+
+func (p SwigcptrCircle) SwigIsCircle() {
+}
+
+func _swig_wrap_new_Circle(float64) SwigcptrCircle
+
+func NewCircle(arg1 float64) Circle {
+ return _swig_wrap_new_Circle(arg1)
+}
+
+func _swig_wrap_Circle_area(SwigcptrCircle) float64
+
+func (arg1 SwigcptrCircle) Area() float64 {
+ return _swig_wrap_Circle_area(arg1)
+}
+
+func _swig_wrap_Circle_perimeter(SwigcptrCircle) float64
+
+func (arg1 SwigcptrCircle) Perimeter() float64 {
+ return _swig_wrap_Circle_perimeter(arg1)
+}
+
+func _swig_wrap_delete_Circle(uintptr)
+
+func DeleteCircle(arg1 Circle) {
+ _swig_wrap_delete_Circle(arg1.Swigcptr())
+}
+
+func _swig_wrap_SetCircle_X(SwigcptrCircle, float64)
+
+func (_swig_base SwigcptrCircle) SetX(arg1 float64) {
+ _swig_wrap_SetCircle_X(_swig_base, arg1)
+}
+
+func _swig_wrap_GetCircle_X(SwigcptrCircle) float64
+
+func (_swig_base SwigcptrCircle) GetX() float64 {
+ return _swig_wrap_GetCircle_X(_swig_base)
+}
+
+func _swig_wrap_SetCircle_Y(SwigcptrCircle, float64)
+
+func (_swig_base SwigcptrCircle) SetY(arg1 float64) {
+ _swig_wrap_SetCircle_Y(_swig_base, arg1)
+}
+
+func _swig_wrap_GetCircle_Y(SwigcptrCircle) float64
+
+func (_swig_base SwigcptrCircle) GetY() float64 {
+ return _swig_wrap_GetCircle_Y(_swig_base)
+}
+
+func _swig_wrap_Circle_move(SwigcptrCircle, float64, float64)
+
+func (_swig_base SwigcptrCircle) Move(arg1 float64, arg2 float64) {
+ _swig_wrap_Circle_move(_swig_base, arg1, arg2)
+}
+
+func (p SwigcptrCircle) SwigIsShape() {
+}
+
+func (p SwigcptrCircle) SwigGetShape() Shape {
+ return SwigcptrShape(p.Swigcptr())
+}
+
+type Circle interface {
+ Swigcptr() uintptr
+ SwigIsCircle()
+ Area() float64
+ Perimeter() float64
+ SetX(arg1 float64)
+ GetX() float64
+ SetY(arg1 float64)
+ GetY() float64
+ Move(arg1 float64, arg2 float64)
+ SwigIsShape()
+ SwigGetShape() Shape
+}
+
+type SwigcptrSquare uintptr
+
+func (p SwigcptrSquare) Swigcptr() uintptr {
+ return (uintptr)(p)
+}
+
+func (p SwigcptrSquare) SwigIsSquare() {
+}
+
+func _swig_wrap_new_Square(float64) SwigcptrSquare
+
+func NewSquare(arg1 float64) Square {
+ return _swig_wrap_new_Square(arg1)
+}
+
+func _swig_wrap_Square_area(SwigcptrSquare) float64
+
+func (arg1 SwigcptrSquare) Area() float64 {
+ return _swig_wrap_Square_area(arg1)
+}
+
+func _swig_wrap_Square_perimeter(SwigcptrSquare) float64
+
+func (arg1 SwigcptrSquare) Perimeter() float64 {
+ return _swig_wrap_Square_perimeter(arg1)
+}
+
+func _swig_wrap_delete_Square(uintptr)
+
+func DeleteSquare(arg1 Square) {
+ _swig_wrap_delete_Square(arg1.Swigcptr())
+}
+
+func _swig_wrap_SetSquare_X(SwigcptrSquare, float64)
+
+func (_swig_base SwigcptrSquare) SetX(arg1 float64) {
+ _swig_wrap_SetSquare_X(_swig_base, arg1)
+}
+
+func _swig_wrap_GetSquare_X(SwigcptrSquare) float64
+
+func (_swig_base SwigcptrSquare) GetX() float64 {
+ return _swig_wrap_GetSquare_X(_swig_base)
+}
+
+func _swig_wrap_SetSquare_Y(SwigcptrSquare, float64)
+
+func (_swig_base SwigcptrSquare) SetY(arg1 float64) {
+ _swig_wrap_SetSquare_Y(_swig_base, arg1)
+}
+
+func _swig_wrap_GetSquare_Y(SwigcptrSquare) float64
+
+func (_swig_base SwigcptrSquare) GetY() float64 {
+ return _swig_wrap_GetSquare_Y(_swig_base)
+}
+
+func _swig_wrap_Square_move(SwigcptrSquare, float64, float64)
+
+func (_swig_base SwigcptrSquare) Move(arg1 float64, arg2 float64) {
+ _swig_wrap_Square_move(_swig_base, arg1, arg2)
+}
+
+func (p SwigcptrSquare) SwigIsShape() {
+}
+
+func (p SwigcptrSquare) SwigGetShape() Shape {
+ return SwigcptrShape(p.Swigcptr())
+}
+
+type Square interface {
+ Swigcptr() uintptr
+ SwigIsSquare()
+ Area() float64
+ Perimeter() float64
+ SetX(arg1 float64)
+ GetX() float64
+ SetY(arg1 float64)
+ GetY() float64
+ Move(arg1 float64, arg2 float64)
+ SwigIsShape()
+ SwigGetShape() Shape
+}
+
+
+type SwigcptrVoid uintptr
+type Void interface {
+ Swigcptr() uintptr;
+}
+func (p SwigcptrVoid) Swigcptr() uintptr {
+ return uintptr(p)
+}
+
diff --git a/Examples/go/class/example.h b/Examples/go/class/example.h
new file mode 100644
index 000000000..46d901361
--- /dev/null
+++ b/Examples/go/class/example.h
@@ -0,0 +1,39 @@
+/* File : example.h */
+
+class Shape {
+public:
+ Shape() {
+ nshapes++;
+ }
+ virtual ~Shape() {
+ nshapes--;
+ };
+ double x, y;
+ void move(double dx, double dy);
+ virtual double area(void) = 0;
+ virtual double perimeter(void) = 0;
+ static int nshapes;
+};
+
+class Circle : public Shape {
+private:
+ double radius;
+public:
+ Circle(double r) : radius(r) { };
+ virtual double area(void);
+ virtual double perimeter(void);
+};
+
+class Square : public Shape {
+private:
+ double width;
+public:
+ Square(double w) : width(w) { };
+ virtual double area(void);
+ virtual double perimeter(void);
+};
+
+
+
+
+
diff --git a/Examples/go/class/example.i b/Examples/go/class/example.i
new file mode 100644
index 000000000..75700b305
--- /dev/null
+++ b/Examples/go/class/example.i
@@ -0,0 +1,10 @@
+/* File : example.i */
+%module example
+
+%{
+#include "example.h"
+%}
+
+/* Let's just grab the original header file here */
+%include "example.h"
+
diff --git a/Examples/go/class/index.html b/Examples/go/class/index.html
new file mode 100644
index 000000000..b39119d12
--- /dev/null
+++ b/Examples/go/class/index.html
@@ -0,0 +1,203 @@
+
+
+SWIG:Examples:go:class
+
+
+
+
+
+SWIG/Examples/go/class/
+
+
+Wrapping a simple C++ class
+
+
+This example illustrates the most primitive form of C++ class wrapping
+performed by SWIG. In this case, C++ classes are simply transformed
+into a collection of C-style functions that provide access to class
+members.
+
+
The C++ Code
+
+Suppose you have some C++ classes described by the following (and
+admittedly lame) header file:
+
+
+
+/* File : example.h */
+
+class Shape {
+public:
+ Shape() {
+ nshapes++;
+ }
+ virtual ~Shape() {
+ nshapes--;
+ };
+ double x, y;
+ void move(double dx, double dy);
+ virtual double area() = 0;
+ virtual double perimeter() = 0;
+ static int nshapes;
+};
+
+class Circle : public Shape {
+private:
+ double radius;
+public:
+ Circle(double r) : radius(r) { };
+ virtual double area();
+ virtual double perimeter();
+};
+
+class Square : public Shape {
+private:
+ double width;
+public:
+ Square(double w) : width(w) { };
+ virtual double area();
+ virtual double perimeter();
+};
+
+
+
+The SWIG interface
+
+A simple SWIG interface for this can be built by simply grabbing the
+header file like this:
+
+
+
+/* File : example.i */
+%module example
+
+%{
+#include "example.h"
+%}
+
+/* Let's just grab the original header file here */
+%include "example.h"
+
+
+
+Note: when creating a C++ extension, you must run SWIG with
+the -c++ option like this:
+
+
+% swig -c++ -go example.i
+
+
+
+A sample Go script
+
+See example.go for a program that calls the
+C++ functions from Go.
+
+Key points
+
+
+To create a new object, you call a constructor like this:
+
+
+
+c := example.NewCircle(10.0)
+
+
+
+The name of the constructor is New followed by the name of
+the class, capitalized.
+
+
+
+The constructor returns a value of interface type. The methods of the
+interface will be the methods of the C++ class, plus member accessor
+functions.
+
+
+
To access member data, a pair of accessor methods are used. For
+example:
+
+
+
+c.SetX(15) # Set member data
+x := c.GetX() # Get member data.
+
+
+
+These are methods on the type returned by the constructor. The getter
+is named Get followed by the name of the member,
+capitalized. The setter is similar but uses Set .
+
+
+
To invoke a member function, you simply do this
+
+
+
+fmt.Println("The area is", example.c.Area())
+
+
+
+ To invoke a destructor, simply do this
+
+
+
+example.DeleteShape(c) # Deletes a shape
+
+
+
+The name of the destructor is Delete followed by the name of
+the class, capitalized. (Note: destructors are currently not
+inherited. This might change later).
+
+
+
Static member variables are wrapped much like C global variables.
+For example:
+
+
+
+n := GetShapeNshapes() # Get a static data member
+SetShapeNshapes(13) # Set a static data member
+
+
+
+The name is Get or Set , followed by the name of the
+class, capitalized, followed by the name of the member, capitalized.
+
+
+
+General Comments
+
+
+This low-level interface is not the only way to handle C++ code.
+Director classes provide a much higher-level interface.
+
+
+
Because C++ and Go implement inheritance quite differently, you
+can not simply upcast an object in Go code when using multiple
+inheritance. When using only single inheritance, you can simply pass
+a class to a function expecting a parent class. When using multiple
+inheritance, you have to call an automatically generated getter
+function named Get followed by the capitalized name of the
+immediate parent. This will return the same object converted to the
+ parent class.
+
+
+
+Overloaded methods should normally work. However, when calling an
+overloaded method you must explicitly convert constants to the
+expected type when it is not int or float . In
+particular, a floating point constant will default to
+type float , but C++ functions typically expect the C++
+type double which is equivalent to the Go
+type float64 So calling an overloaded method with a floating
+point constant typically requires an explicit conversion
+to float64 .
+
+
+
Namespaces are not supported in any very coherent way.
+
+
+
+
+
+
diff --git a/Examples/go/class/runme.go b/Examples/go/class/runme.go
new file mode 100644
index 000000000..ff64bb4be
--- /dev/null
+++ b/Examples/go/class/runme.go
@@ -0,0 +1,63 @@
+// This example illustrates how C++ classes can be used from Go using SWIG.
+
+package main
+
+import (
+ "fmt"
+ . "./example"
+)
+
+func main() {
+ // ----- Object creation -----
+
+ fmt.Println("Creating some objects:")
+ c := NewCircle(10)
+ fmt.Println(" Created circle", c)
+ s := NewSquare(10)
+ fmt.Println(" Created square", s)
+
+ // ----- Access a static member -----
+
+ fmt.Println("\nA total of", GetShapeNshapes(), "shapes were created")
+
+ // ----- Member data access -----
+
+ // Notice how we can do this using functions specific to
+ // the 'Circle' class.
+ c.SetX(20)
+ c.SetY(30)
+
+ // Now use the same functions in the base class
+ var shape Shape = s
+ shape.SetX(-10)
+ shape.SetY(5)
+
+ fmt.Println("\nHere is their current position:")
+ fmt.Println(" Circle = (", c.GetX(), " ", c.GetY(), ")")
+ fmt.Println(" Square = (", s.GetX(), " ", s.GetY(), ")")
+
+ // ----- Call some methods -----
+
+ fmt.Println("\nHere are some properties of the shapes:")
+ shapes := []Shape{c, s}
+ for i := 0; i < len(shapes); i++ {
+ fmt.Println(" ", shapes[i])
+ fmt.Println(" area = ", shapes[i].Area())
+ fmt.Println(" perimeter = ", shapes[i].Perimeter())
+ }
+
+ // Notice how the area() and perimeter() functions really
+ // invoke the appropriate virtual method on each object.
+
+ // ----- Delete everything -----
+
+ fmt.Println("\nGuess I'll clean up now")
+
+ // Note: this invokes the virtual destructor
+ // You could leave this to the garbage collector
+ DeleteCircle(c)
+ DeleteSquare(s)
+
+ fmt.Println(GetShapeNshapes(), " shapes remain")
+ fmt.Println("Goodbye")
+}
diff --git a/Examples/go/constants/Makefile b/Examples/go/constants/Makefile
new file mode 100644
index 000000000..71d4d73a4
--- /dev/null
+++ b/Examples/go/constants/Makefile
@@ -0,0 +1,16 @@
+TOP = ../..
+SWIG = $(TOP)/../preinst-swig
+CXXSRCS =
+TARGET = example
+INTERFACE = example.i
+SWIGOPT =
+
+all::
+ $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
+ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go
+
+clean::
+ $(MAKE) -f $(TOP)/Makefile go_clean
+
+check: all
+ $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
diff --git a/Examples/go/constants/example.go b/Examples/go/constants/example.go
new file mode 100644
index 000000000..0e5e66418
--- /dev/null
+++ b/Examples/go/constants/example.go
@@ -0,0 +1,44 @@
+/* ----------------------------------------------------------------------------
+ * This file was automatically generated by SWIG (http://www.swig.org).
+ * Version 2.0.1
+ *
+ * This file is not intended to be easily readable and contains a number of
+ * coding conventions designed to improve portability and efficiency. Do not make
+ * changes to this file unless you know what you are doing--modify the SWIG
+ * interface file instead.
+ * ----------------------------------------------------------------------------- */
+
+package example
+
+
+type _swig_fnptr *byte
+type _swig_memberptr *byte
+
+
+func _swig_allocatememory(int) *byte
+func _swig_internal_allocate(len int) *byte {
+ return _swig_allocatememory(len)
+}
+
+func _swig_allocatestring(*byte, int) string
+func _swig_internal_makegostring(p *byte, l int) string {
+ return _swig_allocatestring(p, l)
+}
+
+func _swig_internal_gopanic(p *byte, l int) {
+ panic(_swig_allocatestring(p, l))
+}
+
+const ICONST int = 42
+const FCONST float64 = 2.1828
+const CCONST byte = 'x'
+func _swig_getCCONST2() byte
+var CCONST2 byte = _swig_getCCONST2()
+const SCONST string = "Hello World"
+func _swig_getSCONST2() string
+var SCONST2 string = _swig_getSCONST2()
+func _swig_getEXPR() float64
+var EXPR float64 = _swig_getEXPR()
+const Iconst int = 37
+const Fconst float64 = 3.14
+
diff --git a/Examples/go/constants/example.i b/Examples/go/constants/example.i
new file mode 100644
index 000000000..daca042df
--- /dev/null
+++ b/Examples/go/constants/example.i
@@ -0,0 +1,25 @@
+/* File : example.i */
+%module example
+
+/* A few preprocessor macros */
+
+#define ICONST 42
+#define FCONST 2.1828
+#define CCONST 'x'
+#define CCONST2 '\n'
+#define SCONST "Hello World"
+#define SCONST2 "\"Hello World\""
+
+/* This should work just fine */
+#define EXPR ICONST + 3*(FCONST)
+
+/* This shouldn't do anything */
+#define EXTERN extern
+
+/* Neither should this (BAR isn't defined) */
+#define FOO (ICONST + BAR)
+
+/* The following directives also produce constants */
+
+%constant int iconst = 37;
+%constant double fconst = 3.14;
diff --git a/Examples/go/constants/index.html b/Examples/go/constants/index.html
new file mode 100644
index 000000000..b1397ab2d
--- /dev/null
+++ b/Examples/go/constants/index.html
@@ -0,0 +1,55 @@
+
+
+SWIG:Examples:go:constants
+
+
+
+
+SWIG/Examples/go/constants/
+
+
+Wrapping C Constants
+
+
+When SWIG encounters C preprocessor macros and C declarations that
+look like constants, it creates a Go constant with an identical value.
+Click here to see a SWIG interface with some
+constant declarations in it.
+
+
+
Accessing Constants from Go
+Click here for
+the section on constants in the SWIG and Go documentation.
+
+
+Click here to see a Go program that prints out
+the values of the constants contained in the above file.
+Key points
+
+All names are capitalized to make them visible.
+ The values of preprocessor macros are converted into Go constants.
+ C string literals such as "Hello World" are converted into Go strings.
+ Macros that are not fully defined are simply ignored. For example:
+
+
+#define EXTERN extern
+
+
+is ignored because SWIG has no idea what type of variable this would be.
+
+
+
Expressions are allowed provided that all of their components are
+defined. Otherwise, the constant is ignored.
+
+ Certain C declarations involving 'const' are also turned into Go
+constants.
+ The constants that appear in a SWIG interface file do not have to
+appear in any sort of matching C source file since the creation of a
+constant does not require linkage to a stored value (i.e., a value
+held in a C global variable or memory location).
+
+
+
+
+
+
diff --git a/Examples/go/constants/runme.go b/Examples/go/constants/runme.go
new file mode 100644
index 000000000..78a047e20
--- /dev/null
+++ b/Examples/go/constants/runme.go
@@ -0,0 +1,18 @@
+package main
+
+import (
+ "fmt"
+ "./example"
+)
+
+func main() {
+ fmt.Println("ICONST = ", example.ICONST, " (should be 42)")
+ fmt.Println("FCONST = ", example.FCONST, " (should be 2.1828)")
+ fmt.Printf("CCONST = %c (should be 'x')\n", example.CCONST)
+ fmt.Printf("CCONST2 = %c(this should be on a new line)\n", example.CCONST2)
+ fmt.Println("SCONST = ", example.SCONST, " (should be 'Hello World')")
+ fmt.Println("SCONST2 = ", example.SCONST2, " (should be '\"Hello World\"')")
+ fmt.Println("EXPR = ", example.EXPR, " (should be 48.5484)")
+ fmt.Println("iconst = ", example.Iconst, " (should be 37)")
+ fmt.Println("fconst = ", example.Fconst, " (should be 3.14)")
+}
diff --git a/Examples/go/enum/Makefile b/Examples/go/enum/Makefile
new file mode 100644
index 000000000..9dc8b8851
--- /dev/null
+++ b/Examples/go/enum/Makefile
@@ -0,0 +1,18 @@
+TOP = ../..
+SWIG = $(TOP)/../preinst-swig
+CXXSRCS = example.cxx
+TARGET = example
+INTERFACE = example.i
+SWIGOPT =
+
+all:: go
+
+go::
+ $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
+ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_cpp
+
+clean::
+ $(MAKE) -f $(TOP)/Makefile go_clean
+
+check: all
+ $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
diff --git a/Examples/go/enum/example.cxx b/Examples/go/enum/example.cxx
new file mode 100644
index 000000000..df7bb6328
--- /dev/null
+++ b/Examples/go/enum/example.cxx
@@ -0,0 +1,37 @@
+/* File : example.cxx */
+
+#include "example.h"
+#include
+
+void Foo::enum_test(speed s) {
+ if (s == IMPULSE) {
+ printf("IMPULSE speed\n");
+ } else if (s == WARP) {
+ printf("WARP speed\n");
+ } else if (s == LUDICROUS) {
+ printf("LUDICROUS speed\n");
+ } else {
+ printf("Unknown speed\n");
+ }
+}
+
+void enum_test(color c, Foo::speed s) {
+ if (c == RED) {
+ printf("color = RED, ");
+ } else if (c == BLUE) {
+ printf("color = BLUE, ");
+ } else if (c == GREEN) {
+ printf("color = GREEN, ");
+ } else {
+ printf("color = Unknown color!, ");
+ }
+ if (s == Foo::IMPULSE) {
+ printf("speed = IMPULSE speed\n");
+ } else if (s == Foo::WARP) {
+ printf("speed = WARP speed\n");
+ } else if (s == Foo::LUDICROUS) {
+ printf("speed = LUDICROUS speed\n");
+ } else {
+ printf("speed = Unknown speed!\n");
+ }
+}
diff --git a/Examples/go/enum/example.go b/Examples/go/enum/example.go
new file mode 100644
index 000000000..4653ab57a
--- /dev/null
+++ b/Examples/go/enum/example.go
@@ -0,0 +1,93 @@
+/* ----------------------------------------------------------------------------
+ * This file was automatically generated by SWIG (http://www.swig.org).
+ * Version 2.0.1
+ *
+ * This file is not intended to be easily readable and contains a number of
+ * coding conventions designed to improve portability and efficiency. Do not make
+ * changes to this file unless you know what you are doing--modify the SWIG
+ * interface file instead.
+ * ----------------------------------------------------------------------------- */
+
+package example
+
+
+type _swig_fnptr *byte
+type _swig_memberptr *byte
+
+
+func _swig_allocatememory(int) *byte
+func _swig_internal_allocate(len int) *byte {
+ return _swig_allocatememory(len)
+}
+
+func _swig_allocatestring(*byte, int) string
+func _swig_internal_makegostring(p *byte, l int) string {
+ return _swig_allocatestring(p, l)
+}
+
+func _swig_internal_gopanic(p *byte, l int) {
+ panic(_swig_allocatestring(p, l))
+}
+
+type Color int
+func _swig_getRED() Color
+var RED Color = _swig_getRED()
+func _swig_getBLUE() Color
+var BLUE Color = _swig_getBLUE()
+func _swig_getGREEN() Color
+var GREEN Color = _swig_getGREEN()
+type SwigcptrFoo uintptr
+
+func (p SwigcptrFoo) Swigcptr() uintptr {
+ return (uintptr)(p)
+}
+
+func (p SwigcptrFoo) SwigIsFoo() {
+}
+
+func _swig_wrap_new_Foo() SwigcptrFoo
+
+func NewFoo() Foo {
+ return _swig_wrap_new_Foo()
+}
+
+type FooSpeed int
+func _swig_getFoo_IMPULSE_Foo() FooSpeed
+var FooIMPULSE FooSpeed = _swig_getFoo_IMPULSE_Foo()
+func _swig_getFoo_WARP_Foo() FooSpeed
+var FooWARP FooSpeed = _swig_getFoo_WARP_Foo()
+func _swig_getFoo_LUDICROUS_Foo() FooSpeed
+var FooLUDICROUS FooSpeed = _swig_getFoo_LUDICROUS_Foo()
+func _swig_wrap_Foo_enum_test(SwigcptrFoo, FooSpeed)
+
+func (arg1 SwigcptrFoo) Enum_test(arg2 FooSpeed) {
+ _swig_wrap_Foo_enum_test(arg1, arg2)
+}
+
+func _swig_wrap_delete_Foo(uintptr)
+
+func DeleteFoo(arg1 Foo) {
+ _swig_wrap_delete_Foo(arg1.Swigcptr())
+}
+
+type Foo interface {
+ Swigcptr() uintptr
+ SwigIsFoo()
+ Enum_test(arg2 FooSpeed)
+}
+
+func _swig_wrap_enum_test(Color, FooSpeed)
+
+func Enum_test(arg1 Color, arg2 FooSpeed) {
+ _swig_wrap_enum_test(arg1, arg2)
+}
+
+
+type SwigcptrVoid uintptr
+type Void interface {
+ Swigcptr() uintptr;
+}
+func (p SwigcptrVoid) Swigcptr() uintptr {
+ return uintptr(p)
+}
+
diff --git a/Examples/go/enum/example.h b/Examples/go/enum/example.h
new file mode 100644
index 000000000..9119cd9fc
--- /dev/null
+++ b/Examples/go/enum/example.h
@@ -0,0 +1,13 @@
+/* File : example.h */
+
+enum color { RED, BLUE, GREEN };
+
+class Foo {
+ public:
+ Foo() { }
+ enum speed { IMPULSE=10, WARP=20, LUDICROUS=30 };
+ void enum_test(speed s);
+};
+
+void enum_test(color c, Foo::speed s);
+
diff --git a/Examples/go/enum/example.i b/Examples/go/enum/example.i
new file mode 100644
index 000000000..23ee8a822
--- /dev/null
+++ b/Examples/go/enum/example.i
@@ -0,0 +1,11 @@
+/* File : example.i */
+%module example
+
+%{
+#include "example.h"
+%}
+
+/* Let's just grab the original header file here */
+
+%include "example.h"
+
diff --git a/Examples/go/enum/index.html b/Examples/go/enum/index.html
new file mode 100644
index 000000000..868efe6ad
--- /dev/null
+++ b/Examples/go/enum/index.html
@@ -0,0 +1,42 @@
+
+
+SWIG:Examples:go:enum
+
+
+
+
+
+SWIG/Examples/go/enum/
+
+
+Wrapping enumerations
+
+
+This example tests SWIG's ability to wrap enumerations.
+
+
+Enum values are expressed as constants or variables in GO.
+
+If the enum is named, then that name, capitalized, as defined as a new
+type name for int . All the enum values will be defined to
+have that type.
+
+If the enum is declared at global level, then the name in Go is simply
+the enum value, capitalized.
+
+If the enum is declared within a C++ class or struct, then the name in
+Go is the capitalized name of the class or struct followed by the
+capitalized name of the enum value.
+
+
+
+
+
+
+
+
+
diff --git a/Examples/go/enum/runme.go b/Examples/go/enum/runme.go
new file mode 100644
index 000000000..419df5f93
--- /dev/null
+++ b/Examples/go/enum/runme.go
@@ -0,0 +1,32 @@
+package main
+
+import (
+ "fmt"
+ . "./example"
+)
+
+func main() {
+ // Print out the value of some enums
+ fmt.Println("*** color ***")
+ fmt.Println(" RED = ", RED)
+ fmt.Println(" BLUE = ", BLUE)
+ fmt.Println(" GREEN = ", GREEN)
+
+ fmt.Println("\n*** Foo::speed ***")
+ fmt.Println(" Foo::IMPULSE = ", FooIMPULSE)
+ fmt.Println(" Foo::WARP = ", FooWARP)
+ fmt.Println(" Foo::LUDICROUS = ", FooLUDICROUS)
+
+ fmt.Println("\nTesting use of enums with functions\n")
+
+ Enum_test(RED, FooIMPULSE)
+ Enum_test(BLUE, FooWARP)
+ Enum_test(GREEN, FooLUDICROUS)
+
+ fmt.Println("\nTesting use of enum with class method")
+ f := NewFoo()
+
+ f.Enum_test(FooIMPULSE)
+ f.Enum_test(FooWARP)
+ f.Enum_test(FooLUDICROUS)
+}
diff --git a/Examples/go/extend/Makefile b/Examples/go/extend/Makefile
new file mode 100644
index 000000000..9dc8b8851
--- /dev/null
+++ b/Examples/go/extend/Makefile
@@ -0,0 +1,18 @@
+TOP = ../..
+SWIG = $(TOP)/../preinst-swig
+CXXSRCS = example.cxx
+TARGET = example
+INTERFACE = example.i
+SWIGOPT =
+
+all:: go
+
+go::
+ $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
+ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_cpp
+
+clean::
+ $(MAKE) -f $(TOP)/Makefile go_clean
+
+check: all
+ $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
diff --git a/Examples/go/extend/example.cxx b/Examples/go/extend/example.cxx
new file mode 100644
index 000000000..450d75608
--- /dev/null
+++ b/Examples/go/extend/example.cxx
@@ -0,0 +1,4 @@
+/* File : example.cxx */
+
+#include "example.h"
+
diff --git a/Examples/go/extend/example.go b/Examples/go/extend/example.go
new file mode 100644
index 000000000..08f21e6ab
--- /dev/null
+++ b/Examples/go/extend/example.go
@@ -0,0 +1,397 @@
+/* ----------------------------------------------------------------------------
+ * This file was automatically generated by SWIG (http://www.swig.org).
+ * Version 2.0.1
+ *
+ * This file is not intended to be easily readable and contains a number of
+ * coding conventions designed to improve portability and efficiency. Do not make
+ * changes to this file unless you know what you are doing--modify the SWIG
+ * interface file instead.
+ * ----------------------------------------------------------------------------- */
+
+package example
+
+
+type _swig_fnptr *byte
+type _swig_memberptr *byte
+
+
+func _swig_allocatememory(int) *byte
+func _swig_internal_allocate(len int) *byte {
+ return _swig_allocatememory(len)
+}
+
+func _swig_allocatestring(*byte, int) string
+func _swig_internal_makegostring(p *byte, l int) string {
+ return _swig_allocatestring(p, l)
+}
+
+func _swig_internal_gopanic(p *byte, l int) {
+ panic(_swig_allocatestring(p, l))
+}
+
+type _swig_DirectorEmployee struct {
+ SwigcptrEmployee
+ v interface{}
+}
+
+func (p *_swig_DirectorEmployee) Swigcptr() uintptr {
+ return p.SwigcptrEmployee.Swigcptr()
+}
+
+func (p *_swig_DirectorEmployee) SwigIsEmployee() {
+}
+
+func (p *_swig_DirectorEmployee) DirectorInterface() interface{} {
+ return p.v
+}
+
+func _swig_NewDirectorEmployeeEmployee(*_swig_DirectorEmployee, string) SwigcptrEmployee
+
+func NewDirectorEmployee(v interface{}, arg1 string) Employee {
+ p := &_swig_DirectorEmployee{0, v}
+ p.SwigcptrEmployee = _swig_NewDirectorEmployeeEmployee(p, arg1)
+ return p
+}
+
+type _swig_DirectorInterfaceEmployeeGetTitle interface {
+ GetTitle() string
+}
+
+func _swig_wrap__swig_DirectorEmployee_upcall_GetTitle(SwigcptrEmployee) string
+func (swig_p *_swig_DirectorEmployee) GetTitle() string {
+ if swig_g, swig_ok := swig_p.v.(_swig_DirectorInterfaceEmployeeGetTitle); swig_ok {
+ return swig_g.GetTitle()
+ }
+ return _swig_wrap__swig_DirectorEmployee_upcall_GetTitle(swig_p.SwigcptrEmployee)
+}
+
+func DirectorEmployeeGetTitle(p Employee) string {
+ return _swig_wrap__swig_DirectorEmployee_upcall_GetTitle(p.(*_swig_DirectorEmployee).SwigcptrEmployee)
+}
+
+func Swig_DirectorEmployee_callback_getTitle(p *_swig_DirectorEmployee) (swig_result string) {
+ return p.GetTitle()
+}
+
+type _swig_DirectorInterfaceEmployeeGetName interface {
+ GetName() string
+}
+
+func _swig_wrap__swig_DirectorEmployee_upcall_GetName(SwigcptrEmployee) string
+func (swig_p *_swig_DirectorEmployee) GetName() string {
+ if swig_g, swig_ok := swig_p.v.(_swig_DirectorInterfaceEmployeeGetName); swig_ok {
+ return swig_g.GetName()
+ }
+ return _swig_wrap__swig_DirectorEmployee_upcall_GetName(swig_p.SwigcptrEmployee)
+}
+
+func DirectorEmployeeGetName(p Employee) string {
+ return _swig_wrap__swig_DirectorEmployee_upcall_GetName(p.(*_swig_DirectorEmployee).SwigcptrEmployee)
+}
+
+func Swig_DirectorEmployee_callback_getName(p *_swig_DirectorEmployee) (swig_result string) {
+ return p.GetName()
+}
+
+type _swig_DirectorInterfaceEmployeeGetPosition interface {
+ GetPosition() string
+}
+
+func _swig_wrap__swig_DirectorEmployee_upcall_GetPosition(SwigcptrEmployee) string
+func (swig_p *_swig_DirectorEmployee) GetPosition() string {
+ if swig_g, swig_ok := swig_p.v.(_swig_DirectorInterfaceEmployeeGetPosition); swig_ok {
+ return swig_g.GetPosition()
+ }
+ return _swig_wrap__swig_DirectorEmployee_upcall_GetPosition(swig_p.SwigcptrEmployee)
+}
+
+func DirectorEmployeeGetPosition(p Employee) string {
+ return _swig_wrap__swig_DirectorEmployee_upcall_GetPosition(p.(*_swig_DirectorEmployee).SwigcptrEmployee)
+}
+
+func Swig_DirectorEmployee_callback_getPosition(p *_swig_DirectorEmployee) (swig_result string) {
+ return p.GetPosition()
+}
+
+func _swig_wrap_DeleteDirectorEmployee(uintptr)
+
+func DeleteDirectorEmployee(arg1 Employee) {
+ _swig_wrap_DeleteDirectorEmployee(arg1.Swigcptr())
+}
+
+func Swiggo_DeleteDirector_Employee(p *_swig_DirectorEmployee) {
+ p.SwigcptrEmployee = 0
+}
+
+type SwigcptrEmployee uintptr
+
+func (p SwigcptrEmployee) Swigcptr() uintptr {
+ return (uintptr)(p)
+}
+
+func (p SwigcptrEmployee) SwigIsEmployee() {
+}
+
+func (p SwigcptrEmployee) DirectorInterface() interface{} {
+ return nil
+}
+
+func _swig_wrap_new_Employee(string) SwigcptrEmployee
+
+func NewEmployee(arg1 string) Employee {
+ return _swig_wrap_new_Employee(arg1)
+}
+
+func _swig_wrap_Employee_getTitle(SwigcptrEmployee) string
+
+func (arg1 SwigcptrEmployee) GetTitle() string {
+ return _swig_wrap_Employee_getTitle(arg1)
+}
+
+func _swig_wrap_Employee_getName(SwigcptrEmployee) string
+
+func (arg1 SwigcptrEmployee) GetName() string {
+ return _swig_wrap_Employee_getName(arg1)
+}
+
+func _swig_wrap_Employee_getPosition(SwigcptrEmployee) string
+
+func (arg1 SwigcptrEmployee) GetPosition() string {
+ return _swig_wrap_Employee_getPosition(arg1)
+}
+
+func _swig_wrap_delete_Employee(uintptr)
+
+func DeleteEmployee(arg1 Employee) {
+ _swig_wrap_delete_Employee(arg1.Swigcptr())
+}
+
+type Employee interface {
+ Swigcptr() uintptr
+ SwigIsEmployee()
+ DirectorInterface() interface{}
+ GetTitle() string
+ GetName() string
+ GetPosition() string
+}
+
+type _swig_DirectorManager struct {
+ SwigcptrManager
+ v interface{}
+}
+
+func (p *_swig_DirectorManager) Swigcptr() uintptr {
+ return p.SwigcptrManager.Swigcptr()
+}
+
+func (p *_swig_DirectorManager) SwigIsManager() {
+}
+
+func (p *_swig_DirectorManager) DirectorInterface() interface{} {
+ return p.v
+}
+
+func _swig_NewDirectorManagerManager(*_swig_DirectorManager, string) SwigcptrManager
+
+func NewDirectorManager(v interface{}, arg1 string) Manager {
+ p := &_swig_DirectorManager{0, v}
+ p.SwigcptrManager = _swig_NewDirectorManagerManager(p, arg1)
+ return p
+}
+
+type _swig_DirectorInterfaceManagerGetTitle interface {
+ GetTitle() string
+}
+
+func _swig_wrap__swig_DirectorManager_upcall_GetTitle(SwigcptrManager) string
+func (swig_p *_swig_DirectorManager) GetTitle() string {
+ if swig_g, swig_ok := swig_p.v.(_swig_DirectorInterfaceManagerGetTitle); swig_ok {
+ return swig_g.GetTitle()
+ }
+ return _swig_wrap__swig_DirectorManager_upcall_GetTitle(swig_p.SwigcptrManager)
+}
+
+func DirectorManagerGetTitle(p Manager) string {
+ return _swig_wrap__swig_DirectorManager_upcall_GetTitle(p.(*_swig_DirectorManager).SwigcptrManager)
+}
+
+func Swig_DirectorManager_callback_getTitle(p *_swig_DirectorManager) (swig_result string) {
+ return p.GetTitle()
+}
+
+type _swig_DirectorInterfaceManagerGetName interface {
+ GetName() string
+}
+
+func _swig_wrap__swig_DirectorManager_upcall_GetName(SwigcptrManager) string
+func (swig_p *_swig_DirectorManager) GetName() string {
+ if swig_g, swig_ok := swig_p.v.(_swig_DirectorInterfaceManagerGetName); swig_ok {
+ return swig_g.GetName()
+ }
+ return _swig_wrap__swig_DirectorManager_upcall_GetName(swig_p.SwigcptrManager)
+}
+
+func DirectorManagerGetName(p Manager) string {
+ return _swig_wrap__swig_DirectorManager_upcall_GetName(p.(*_swig_DirectorManager).SwigcptrManager)
+}
+
+func Swig_DirectorManager_callback_getName(p *_swig_DirectorManager) (swig_result string) {
+ return p.GetName()
+}
+
+type _swig_DirectorInterfaceManagerGetPosition interface {
+ GetPosition() string
+}
+
+func _swig_wrap__swig_DirectorManager_upcall_GetPosition(SwigcptrManager) string
+func (swig_p *_swig_DirectorManager) GetPosition() string {
+ if swig_g, swig_ok := swig_p.v.(_swig_DirectorInterfaceManagerGetPosition); swig_ok {
+ return swig_g.GetPosition()
+ }
+ return _swig_wrap__swig_DirectorManager_upcall_GetPosition(swig_p.SwigcptrManager)
+}
+
+func DirectorManagerGetPosition(p Manager) string {
+ return _swig_wrap__swig_DirectorManager_upcall_GetPosition(p.(*_swig_DirectorManager).SwigcptrManager)
+}
+
+func Swig_DirectorManager_callback_getPosition(p *_swig_DirectorManager) (swig_result string) {
+ return p.GetPosition()
+}
+
+func _swig_wrap_DeleteDirectorManager(uintptr)
+
+func DeleteDirectorManager(arg1 Manager) {
+ _swig_wrap_DeleteDirectorManager(arg1.Swigcptr())
+}
+
+func Swiggo_DeleteDirector_Manager(p *_swig_DirectorManager) {
+ p.SwigcptrManager = 0
+}
+
+type SwigcptrManager uintptr
+
+func (p SwigcptrManager) Swigcptr() uintptr {
+ return (uintptr)(p)
+}
+
+func (p SwigcptrManager) SwigIsManager() {
+}
+
+func (p SwigcptrManager) DirectorInterface() interface{} {
+ return nil
+}
+
+func _swig_wrap_new_Manager(string) SwigcptrManager
+
+func NewManager(arg1 string) Manager {
+ return _swig_wrap_new_Manager(arg1)
+}
+
+func _swig_wrap_Manager_getPosition(SwigcptrManager) string
+
+func (arg1 SwigcptrManager) GetPosition() string {
+ return _swig_wrap_Manager_getPosition(arg1)
+}
+
+func _swig_wrap_delete_Manager(uintptr)
+
+func DeleteManager(arg1 Manager) {
+ _swig_wrap_delete_Manager(arg1.Swigcptr())
+}
+
+func _swig_wrap_Manager_getTitle(SwigcptrManager) string
+
+func (_swig_base SwigcptrManager) GetTitle() string {
+ return _swig_wrap_Manager_getTitle(_swig_base)
+}
+
+func _swig_wrap_Manager_getName(SwigcptrManager) string
+
+func (_swig_base SwigcptrManager) GetName() string {
+ return _swig_wrap_Manager_getName(_swig_base)
+}
+
+func (p SwigcptrManager) SwigIsEmployee() {
+}
+
+func (p SwigcptrManager) SwigGetEmployee() Employee {
+ return SwigcptrEmployee(p.Swigcptr())
+}
+
+type Manager interface {
+ Swigcptr() uintptr
+ SwigIsManager()
+ DirectorInterface() interface{}
+ GetPosition() string
+ GetTitle() string
+ GetName() string
+ SwigIsEmployee()
+ SwigGetEmployee() Employee
+}
+
+type SwigcptrEmployeeList uintptr
+
+func (p SwigcptrEmployeeList) Swigcptr() uintptr {
+ return (uintptr)(p)
+}
+
+func (p SwigcptrEmployeeList) SwigIsEmployeeList() {
+}
+
+func _swig_wrap_new_EmployeeList() SwigcptrEmployeeList
+
+func NewEmployeeList() EmployeeList {
+ return _swig_wrap_new_EmployeeList()
+}
+
+func _swig_wrap_EmployeeList_addEmployee(SwigcptrEmployeeList, uintptr)
+
+func (arg1 SwigcptrEmployeeList) AddEmployee(arg2 Employee) {
+ _swig_wrap_EmployeeList_addEmployee(arg1, arg2.Swigcptr())
+}
+
+func _swig_wrap_EmployeeList_get_item(SwigcptrEmployeeList, int) SwigcptrEmployee
+
+func (arg1 SwigcptrEmployeeList) Get_item(arg2 int) Employee {
+ return _swig_wrap_EmployeeList_get_item(arg1, arg2)
+}
+
+func _swig_wrap_delete_EmployeeList(uintptr)
+
+func DeleteEmployeeList(arg1 EmployeeList) {
+ _swig_wrap_delete_EmployeeList(arg1.Swigcptr())
+}
+
+type EmployeeList interface {
+ Swigcptr() uintptr
+ SwigIsEmployeeList()
+ AddEmployee(arg2 Employee)
+ Get_item(arg2 int) Employee
+}
+
+
+type SwigcptrSwigDirector_Manager uintptr
+type SwigDirector_Manager interface {
+ Swigcptr() uintptr;
+}
+func (p SwigcptrSwigDirector_Manager) Swigcptr() uintptr {
+ return uintptr(p)
+}
+
+type SwigcptrSwigDirector_Employee uintptr
+type SwigDirector_Employee interface {
+ Swigcptr() uintptr;
+}
+func (p SwigcptrSwigDirector_Employee) Swigcptr() uintptr {
+ return uintptr(p)
+}
+
+type SwigcptrVoid uintptr
+type Void interface {
+ Swigcptr() uintptr;
+}
+func (p SwigcptrVoid) Swigcptr() uintptr {
+ return uintptr(p)
+}
+
diff --git a/Examples/go/extend/example.h b/Examples/go/extend/example.h
new file mode 100644
index 000000000..b27ab9711
--- /dev/null
+++ b/Examples/go/extend/example.h
@@ -0,0 +1,56 @@
+/* File : example.h */
+
+#include
+#include
+#include
+#include
+#include
+
+class Employee {
+private:
+ std::string name;
+public:
+ Employee(const char* n): name(n) {}
+ virtual std::string getTitle() { return getPosition() + " " + getName(); }
+ virtual std::string getName() { return name; }
+ virtual std::string getPosition() const { return "Employee"; }
+ virtual ~Employee() { printf("~Employee() @ %p\n", this); }
+};
+
+
+class Manager: public Employee {
+public:
+ Manager(const char* n): Employee(n) {}
+ virtual std::string getPosition() const { return "Manager"; }
+};
+
+
+class EmployeeList {
+ std::vector list;
+public:
+ EmployeeList() {
+ list.push_back(new Employee("Bob"));
+ list.push_back(new Employee("Jane"));
+ list.push_back(new Manager("Ted"));
+ }
+ void addEmployee(Employee *p) {
+ list.push_back(p);
+ std::cout << "New employee added. Current employees are:" << std::endl;
+ std::vector::iterator i;
+ for (i=list.begin(); i!=list.end(); i++) {
+ std::cout << " " << (*i)->getTitle() << std::endl;
+ }
+ }
+ const Employee *get_item(int i) {
+ return list[i];
+ }
+ ~EmployeeList() {
+ std::vector::iterator i;
+ std::cout << "~EmployeeList, deleting " << list.size() << " employees." << std::endl;
+ for (i=list.begin(); i!=list.end(); i++) {
+ delete *i;
+ }
+ std::cout << "~EmployeeList empty." << std::endl;
+ }
+};
+
diff --git a/Examples/go/extend/example.i b/Examples/go/extend/example.i
new file mode 100644
index 000000000..c8ec32e09
--- /dev/null
+++ b/Examples/go/extend/example.i
@@ -0,0 +1,15 @@
+/* File : example.i */
+%module(directors="1") example
+%{
+#include "example.h"
+%}
+
+%include "std_vector.i"
+%include "std_string.i"
+
+/* turn on director wrapping for Manager */
+%feature("director") Employee;
+%feature("director") Manager;
+
+%include "example.h"
+
diff --git a/Examples/go/extend/index.html b/Examples/go/extend/index.html
new file mode 100644
index 000000000..471fa9cdc
--- /dev/null
+++ b/Examples/go/extend/index.html
@@ -0,0 +1,27 @@
+
+
+SWIG:Examples:go:extend
+
+
+
+
+
+SWIG/Examples/go/extend/
+
+
+Extending a simple C++ class in Go
+
+
+This example illustrates the extending of a C++ class with cross
+language polymorphism.
+
+
+
+
+
+
+
diff --git a/Examples/go/extend/runme.go b/Examples/go/extend/runme.go
new file mode 100644
index 000000000..796c5ce68
--- /dev/null
+++ b/Examples/go/extend/runme.go
@@ -0,0 +1,77 @@
+// This file illustrates the cross language polymorphism using directors.
+
+package main
+
+import (
+ "fmt"
+ . "./example"
+)
+
+type CEO struct{}
+
+func (p *CEO) GetPosition() string {
+ return "CEO"
+}
+
+func main() {
+ // Create an instance of CEO, a class derived from the Go
+ // proxy of the underlying C++ class. The calls to getName()
+ // and getPosition() are standard, the call to getTitle() uses
+ // the director wrappers to call CEO.getPosition().
+
+ e := NewDirectorManager(new(CEO), "Alice")
+ fmt.Println(e.GetName(), " is a ", e.GetPosition())
+ fmt.Println("Just call her \"", e.GetTitle(), "\"")
+ fmt.Println("----------------------")
+
+
+ // Create a new EmployeeList instance. This class does not
+ // have a C++ director wrapper, but can be used freely with
+ // other classes that do.
+
+ list := NewEmployeeList()
+
+ // EmployeeList owns its items, so we must surrender ownership
+ // of objects we add.
+ // e.DisownMemory()
+ list.AddEmployee(e)
+ fmt.Println("----------------------")
+
+ // Now we access the first four items in list (three are C++
+ // objects that EmployeeList's constructor adds, the last is
+ // our CEO). The virtual methods of all these instances are
+ // treated the same. For items 0, 1, and 2, all methods
+ // resolve in C++. For item 3, our CEO, GetTitle calls
+ // GetPosition which resolves in Go. The call to GetPosition
+ // is slightly different, however, because of the overidden
+ // GetPosition() call, since now the object reference has been
+ // "laundered" by passing through EmployeeList as an
+ // Employee*. Previously, Go resolved the call immediately in
+ // CEO, but now Go thinks the object is an instance of class
+ // Employee. So the call passes through the Employee proxy
+ // class and on to the C wrappers and C++ director, eventually
+ // ending up back at the Java CEO implementation of
+ // getPosition(). The call to GetTitle() for item 3 runs the
+ // C++ Employee::getTitle() method, which in turn calls
+ // GetPosition(). This virtual method call passes down
+ // through the C++ director class to the Java implementation
+ // in CEO. All this routing takes place transparently.
+
+ fmt.Println("(position, title) for items 0-3:")
+
+ fmt.Println(" ", list.Get_item(0).GetPosition(), ", \"", list.Get_item(0).GetTitle(), "\"")
+ fmt.Println(" ", list.Get_item(1).GetPosition(), ", \"", list.Get_item(1).GetTitle(), "\"")
+ fmt.Println(" ", list.Get_item(2).GetPosition(), ", \"", list.Get_item(2).GetTitle(), "\"")
+ fmt.Println(" ", list.Get_item(3).GetPosition(), ", \"", list.Get_item(3).GetTitle(), "\"")
+ fmt.Println("----------------------")
+
+ // Time to delete the EmployeeList, which will delete all the
+ // Employee* items it contains. The last item is our CEO,
+ // which gets destroyed as well.
+ DeleteEmployeeList(list)
+ fmt.Println("----------------------")
+
+ // All done.
+
+ fmt.Println("Go exit")
+}
diff --git a/Examples/go/funcptr/Makefile b/Examples/go/funcptr/Makefile
new file mode 100644
index 000000000..b0aa9c970
--- /dev/null
+++ b/Examples/go/funcptr/Makefile
@@ -0,0 +1,18 @@
+TOP = ../..
+SWIG = $(TOP)/../preinst-swig
+SRCS = example.c
+TARGET = example
+INTERFACE = example.i
+SWIGOPT =
+
+all:: go
+
+go::
+ $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
+ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go
+
+clean::
+ $(MAKE) -f $(TOP)/Makefile go_clean
+
+check: all
+ $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
diff --git a/Examples/go/funcptr/example.c b/Examples/go/funcptr/example.c
new file mode 100644
index 000000000..5c4a3dabf
--- /dev/null
+++ b/Examples/go/funcptr/example.c
@@ -0,0 +1,19 @@
+/* File : example.c */
+
+int do_op(int a, int b, int (*op)(int,int)) {
+ return (*op)(a,b);
+}
+
+int add(int a, int b) {
+ return a+b;
+}
+
+int sub(int a, int b) {
+ return a-b;
+}
+
+int mul(int a, int b) {
+ return a*b;
+}
+
+int (*funcvar)(int,int) = add;
diff --git a/Examples/go/funcptr/example.go b/Examples/go/funcptr/example.go
new file mode 100644
index 000000000..b059bae8d
--- /dev/null
+++ b/Examples/go/funcptr/example.go
@@ -0,0 +1,54 @@
+/* ----------------------------------------------------------------------------
+ * This file was automatically generated by SWIG (http://www.swig.org).
+ * Version 2.0.1
+ *
+ * This file is not intended to be easily readable and contains a number of
+ * coding conventions designed to improve portability and efficiency. Do not make
+ * changes to this file unless you know what you are doing--modify the SWIG
+ * interface file instead.
+ * ----------------------------------------------------------------------------- */
+
+package example
+
+
+type _swig_fnptr *byte
+type _swig_memberptr *byte
+
+
+func _swig_allocatememory(int) *byte
+func _swig_internal_allocate(len int) *byte {
+ return _swig_allocatememory(len)
+}
+
+func _swig_allocatestring(*byte, int) string
+func _swig_internal_makegostring(p *byte, l int) string {
+ return _swig_allocatestring(p, l)
+}
+
+func _swig_internal_gopanic(p *byte, l int) {
+ panic(_swig_allocatestring(p, l))
+}
+
+func Do_op(int, int, _swig_fnptr) int
+func _swig_getADD() _swig_fnptr
+var ADD _swig_fnptr = _swig_getADD()
+func _swig_getSUB() _swig_fnptr
+var SUB _swig_fnptr = _swig_getSUB()
+func _swig_getMUL() _swig_fnptr
+var MUL _swig_fnptr = _swig_getMUL()
+func _swig_wrap_funcvar_set(_swig_fnptr)
+
+func SetFuncvar(arg1 _swig_fnptr) {
+ _swig_wrap_funcvar_set(arg1)
+}
+
+func GetFuncvar() _swig_fnptr
+
+type SwigcptrVoid uintptr
+type Void interface {
+ Swigcptr() uintptr;
+}
+func (p SwigcptrVoid) Swigcptr() uintptr {
+ return uintptr(p)
+}
+
diff --git a/Examples/go/funcptr/example.h b/Examples/go/funcptr/example.h
new file mode 100644
index 000000000..9936e24fc
--- /dev/null
+++ b/Examples/go/funcptr/example.h
@@ -0,0 +1,9 @@
+/* file: example.h */
+
+extern int do_op(int,int, int (*op)(int,int));
+extern int add(int,int);
+extern int sub(int,int);
+extern int mul(int,int);
+
+extern int (*funcvar)(int,int);
+
diff --git a/Examples/go/funcptr/example.i b/Examples/go/funcptr/example.i
new file mode 100644
index 000000000..8b3bef678
--- /dev/null
+++ b/Examples/go/funcptr/example.i
@@ -0,0 +1,16 @@
+/* File : example.i */
+%module example
+%{
+#include "example.h"
+%}
+
+/* Wrap a function taking a pointer to a function */
+extern int do_op(int a, int b, int (*op)(int, int));
+
+/* Now install a bunch of "ops" as constants */
+%constant int (*ADD)(int,int) = add;
+%constant int (*SUB)(int,int) = sub;
+%constant int (*MUL)(int,int) = mul;
+
+extern int (*funcvar)(int,int);
+
diff --git a/Examples/go/funcptr/index.html b/Examples/go/funcptr/index.html
new file mode 100644
index 000000000..4212260a9
--- /dev/null
+++ b/Examples/go/funcptr/index.html
@@ -0,0 +1,89 @@
+
+
+SWIG:Examples:go:funcptr
+
+
+
+
+
+SWIG/Examples/go/funcptr/
+
+
+Pointers to Functions
+
+
+Okay, just what in the heck does SWIG do with a declaration like this?
+
+
+
+int do_op(int a, int b, int (*op)(int, int));
+
+
+
+Well, it creates a wrapper as usual. Of course, that does raise some
+questions about the third argument (the pointer to a function).
+
+
+In this case, SWIG will wrap the function pointer as it does for all
+other pointers. However, in order to actually call this function from
+a Go program, you will need to pass some kind of C function pointer
+object. In C, this is easy, you just supply a function name as an
+argument like this:
+
+
+
+/* Some callback function */
+int add(int a, int b) {
+ return a+b;
+}
+...
+int r = do_op(x,y,add);
+
+
+
+To make this work with SWIG, you will need to do a little extra work.
+Specifically, you need to create some function pointer objects using
+the %constant directive like this:
+
+
+
+%constant(int (*)(int,int)) ADD = add;
+
+
+
+Now, in a Go program, you would do this:
+
+
+
+int r = do_op(x,y, example.ADD)
+
+
+where example is the module name.
+
+An Example
+
+Here are some files that illustrate this with a simple example:
+
+
+
+Notes
+
+
+The value of a function pointer must correspond to a function
+written in C or C++. It is not possible to pass an arbitrary Go
+function in as a substitute for a C function pointer.
+
+
+
+
+
+
+
+
+
+
diff --git a/Examples/go/funcptr/runme.go b/Examples/go/funcptr/runme.go
new file mode 100644
index 000000000..73ecbb805
--- /dev/null
+++ b/Examples/go/funcptr/runme.go
@@ -0,0 +1,25 @@
+package main
+
+import (
+ "fmt"
+ . "./example"
+)
+
+func main() {
+ a := 37
+ b := 42
+
+ // Now call our C function with a bunch of callbacks
+
+ fmt.Println("Trying some C callback functions")
+ fmt.Println(" a = ", a)
+ fmt.Println(" b = ", b)
+ fmt.Println(" ADD(a,b) = ", Do_op(a, b, ADD))
+ fmt.Println(" SUB(a,b) = ", Do_op(a, b, SUB))
+ fmt.Println(" MUL(a,b) = ", Do_op(a, b, MUL))
+
+ fmt.Println("Here is what the C callback function classes are called in Go")
+ fmt.Println(" ADD = ", ADD)
+ fmt.Println(" SUB = ", SUB)
+ fmt.Println(" MUL = ", MUL)
+}
diff --git a/Examples/go/index.html b/Examples/go/index.html
new file mode 100644
index 000000000..21dda21b5
--- /dev/null
+++ b/Examples/go/index.html
@@ -0,0 +1,89 @@
+
+
+SWIG:Examples:Go
+
+
+
+SWIG Go Examples
+
+
+The following examples illustrate the use of SWIG with Go.
+
+
+simple . A minimal example showing how SWIG can
+be used to wrap a C function, a global variable, and a constant.
+constants . This shows how preprocessor macros and
+certain C declarations are turned into constants.
+variables . An example showing how to access C global variables from Go.
+enum . Wrapping enumerations.
+class . Wrapping a simple C++ class.
+reference . C++ references.
+pointer . Simple pointer handling.
+funcptr . Pointers to functions.
+template . C++ templates.
+callback . C++ callbacks using directors.
+extend . Polymorphism using directors.
+
+
+Compilation Issues
+
+
+To create a Go extension, SWIG is run with the following options:
+
+
+
+% swig -go interface.i
+
+
+
+ On Unix the compilation of examples is done using the
+file Example/Makefile . This makefile performs a manual
+module compilation which is platform specific. When using
+the 6g or 8g compiler, the steps look like this
+(GNU/Linux):
+
+
+
+% swig -go interface.i
+% gcc -fpic -c interface_wrap.c
+% gcc -shared interface_wrap.o $(OBJS) -o interfacemodule.so
+% 6g interface.go
+% 6c interface_gc.c
+% gopack grc interface.a interface.6 interface_gc.6
+% 6l program.6
+
+
+
+ When using the gccgo compiler, the steps look like this:
+
+
+
+% swig -go interface.i
+% gcc -c interface_wrap.c
+% gccgo -c interface.go
+% gccgo program.o interface.o interface_wrap.o
+
+
+
+Compatibility
+
+The examples have been extensively tested on the following platforms:
+
+
+
+All of the examples were last tested with the following configuration
+(10 May 2010):
+
+
+Ubuntu Hardy
+ gcc-4.2.4
+
+
+Your mileage may vary. If you experience a problem, please let us know by
+contacting us on the mailing lists .
+
+
diff --git a/Examples/go/multimap/Makefile b/Examples/go/multimap/Makefile
new file mode 100644
index 000000000..b0aa9c970
--- /dev/null
+++ b/Examples/go/multimap/Makefile
@@ -0,0 +1,18 @@
+TOP = ../..
+SWIG = $(TOP)/../preinst-swig
+SRCS = example.c
+TARGET = example
+INTERFACE = example.i
+SWIGOPT =
+
+all:: go
+
+go::
+ $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
+ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go
+
+clean::
+ $(MAKE) -f $(TOP)/Makefile go_clean
+
+check: all
+ $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
diff --git a/Examples/go/multimap/example.c b/Examples/go/multimap/example.c
new file mode 100644
index 000000000..b8360fa8a
--- /dev/null
+++ b/Examples/go/multimap/example.c
@@ -0,0 +1,53 @@
+/* File : example.c */
+#include
+#include
+#include
+
+/* Compute the greatest common divisor of positive integers */
+int gcd(int x, int y) {
+ int g;
+ g = y;
+ while (x > 0) {
+ g = x;
+ x = y % x;
+ y = g;
+ }
+ return g;
+}
+
+int gcdmain(int argc, char *argv[]) {
+ int x,y;
+ if (argc != 3) {
+ printf("usage: gcd x y\n");
+ return -1;
+ }
+ x = atoi(argv[1]);
+ y = atoi(argv[2]);
+ printf("gcd(%d,%d) = %d\n", x,y,gcd(x,y));
+ return 0;
+}
+
+int count(char *bytes, int len, char c) {
+ int i;
+ int count = 0;
+ for (i = 0; i < len; i++) {
+ if (bytes[i] == c) count++;
+ }
+ return count;
+}
+
+void capitalize(char *str, int len) {
+ int i;
+ for (i = 0; i < len; i++) {
+ str[i] = (char)toupper(str[i]);
+ }
+}
+
+void circle(double x, double y) {
+ double a = x*x + y*y;
+ if (a > 1.0) {
+ printf("Bad points %g, %g\n", x,y);
+ } else {
+ printf("Good points %g, %g\n", x,y);
+ }
+}
diff --git a/Examples/go/multimap/example.go b/Examples/go/multimap/example.go
new file mode 100644
index 000000000..59ed9eaad
--- /dev/null
+++ b/Examples/go/multimap/example.go
@@ -0,0 +1,55 @@
+/* ----------------------------------------------------------------------------
+ * This file was automatically generated by SWIG (http://www.swig.org).
+ * Version 2.0.1
+ *
+ * This file is not intended to be easily readable and contains a number of
+ * coding conventions designed to improve portability and efficiency. Do not make
+ * changes to this file unless you know what you are doing--modify the SWIG
+ * interface file instead.
+ * ----------------------------------------------------------------------------- */
+
+package example
+
+
+type _swig_fnptr *byte
+type _swig_memberptr *byte
+
+
+func _swig_allocatememory(int) *byte
+func _swig_internal_allocate(len int) *byte {
+ return _swig_allocatememory(len)
+}
+
+func _swig_allocatestring(*byte, int) string
+func _swig_internal_makegostring(p *byte, l int) string {
+ return _swig_allocatestring(p, l)
+}
+
+func _swig_internal_gopanic(p *byte, l int) {
+ panic(_swig_allocatestring(p, l))
+}
+
+func Gcd(int, int) int
+func Gcdmain([]string) int
+func Count(string, byte) int
+func _swig_wrap_capitalize([]string)
+
+func Capitalize(arg1 []string) {
+ _swig_wrap_capitalize(arg1)
+}
+
+func _swig_wrap_circle(float64, float64)
+
+func Circle(arg1 float64, arg2 float64) {
+ _swig_wrap_circle(arg1, arg2)
+}
+
+
+type SwigcptrVoid uintptr
+type Void interface {
+ Swigcptr() uintptr;
+}
+func (p SwigcptrVoid) Swigcptr() uintptr {
+ return uintptr(p)
+}
+
diff --git a/Examples/go/multimap/example.i b/Examples/go/multimap/example.i
new file mode 100644
index 000000000..04d6eea20
--- /dev/null
+++ b/Examples/go/multimap/example.i
@@ -0,0 +1,110 @@
+/* File : example.i */
+%module example
+
+%{
+extern int gcd(int x, int y);
+extern int gcdmain(int argc, char *argv[]);
+extern int count(char *bytes, int len, char c);
+extern void capitalize (char *str, int len);
+extern void circle (double cx, double cy);
+extern int squareCubed (int n, int *OUTPUT);
+%}
+
+extern int gcd(int x, int y);
+
+%typemap(go) (int argc, char *argv[]) "[]string"
+
+%typemap(in) (int argc, char *argv[])
+%{
+ {
+ int i;
+ _gostring_* a;
+
+ $1 = $input.len;
+ a = (_gostring_*) $input.array;
+ $2 = (char **) malloc (($1 + 1) * sizeof (char *));
+ for (i = 0; i < $1; i++) {
+ _gostring_ *ps = &a[i];
+ $2[i] = (char *) ps->p;
+ }
+ $2[i] = NULL;
+ }
+%}
+
+%typemap(argout) (int argc, char *argv[]) "" /* override char *[] default */
+
+%typemap(freearg) (int argc, char *argv[])
+%{
+ free($2);
+%}
+
+extern int gcdmain(int argc, char *argv[]);
+
+%typemap(go) (char *bytes, int len) "string"
+
+%typemap(in) (char *bytes, int len)
+%{
+ $1 = $input.p;
+ $2 = $input.n;
+%}
+
+extern int count(char *bytes, int len, char c);
+
+/* This example shows how to wrap a function that mutates a c string. A one
+ * element Go string slice is used so that the string can be returned
+ * modified.
+ */
+
+%typemap(go) (char *str, int len) "[]string"
+
+%typemap(in) (char *str, int len)
+%{
+ {
+ _gostring_ *a;
+ char *p;
+ int n;
+
+ a = (_gostring_*) $input.array;
+ p = a[0].p;
+ n = a[0].n;
+ $1 = malloc(n + 1);
+ $2 = n;
+ memcpy($1, p, n);
+ }
+%}
+
+/* Return the mutated string as a modified element in the array. */
+%typemap(argout) (char *str, int len)
+%{
+ {
+ _gostring_ *a;
+
+ a = (_gostring_*) $input.array;
+ a[0] = _swig_makegostring($1, $2);
+ }
+%}
+
+%typemap(freearg) (char *str, int len)
+%{
+ free($1);
+%}
+
+extern void capitalize(char *str, int len);
+
+/* A multi-valued constraint. Force two arguments to lie
+ inside the unit circle */
+
+%typemap(check) (double cx, double cy)
+%{
+ {
+ double a = $1*$1 + $2*$2;
+ if (a > 1.0) {
+ _swig_gopanic("$1_name and $2_name must be in unit circle");
+ return;
+ }
+ }
+%}
+
+extern void circle(double cx, double cy);
+
+
diff --git a/Examples/go/multimap/runme.go b/Examples/go/multimap/runme.go
new file mode 100644
index 000000000..94c29127c
--- /dev/null
+++ b/Examples/go/multimap/runme.go
@@ -0,0 +1,26 @@
+package main
+
+import (
+ "fmt"
+ . "./example"
+)
+
+func main() {
+ // Call our gcd() function
+ x := 42
+ y := 105
+ g := Gcd(x, y)
+ fmt.Println("The gcd of ", x, " and ", y, " is ", g)
+
+ // Call the gcdmain() function
+ args := []string{"gcdmain", "42", "105"}
+ Gcdmain(args)
+
+ // Call the count function
+ fmt.Println(Count("Hello World", 'l'))
+
+ // Call the capitalize function
+ capitalizeMe := []string{"hello world"}
+ Capitalize(capitalizeMe)
+ fmt.Println(capitalizeMe[0])
+}
diff --git a/Examples/go/pointer/Makefile b/Examples/go/pointer/Makefile
new file mode 100644
index 000000000..b0aa9c970
--- /dev/null
+++ b/Examples/go/pointer/Makefile
@@ -0,0 +1,18 @@
+TOP = ../..
+SWIG = $(TOP)/../preinst-swig
+SRCS = example.c
+TARGET = example
+INTERFACE = example.i
+SWIGOPT =
+
+all:: go
+
+go::
+ $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
+ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go
+
+clean::
+ $(MAKE) -f $(TOP)/Makefile go_clean
+
+check: all
+ $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
diff --git a/Examples/go/pointer/example.c b/Examples/go/pointer/example.c
new file mode 100644
index 000000000..b877d9a5b
--- /dev/null
+++ b/Examples/go/pointer/example.c
@@ -0,0 +1,16 @@
+/* File : example.c */
+
+void add(int *x, int *y, int *result) {
+ *result = *x + *y;
+}
+
+void sub(int *x, int *y, int *result) {
+ *result = *x - *y;
+}
+
+int divide(int n, int d, int *r) {
+ int q;
+ q = n/d;
+ *r = n - q*d;
+ return q;
+}
diff --git a/Examples/go/pointer/example.go b/Examples/go/pointer/example.go
new file mode 100644
index 000000000..567c41c32
--- /dev/null
+++ b/Examples/go/pointer/example.go
@@ -0,0 +1,68 @@
+/* ----------------------------------------------------------------------------
+ * This file was automatically generated by SWIG (http://www.swig.org).
+ * Version 2.0.1
+ *
+ * This file is not intended to be easily readable and contains a number of
+ * coding conventions designed to improve portability and efficiency. Do not make
+ * changes to this file unless you know what you are doing--modify the SWIG
+ * interface file instead.
+ * ----------------------------------------------------------------------------- */
+
+package example
+
+
+type _swig_fnptr *byte
+type _swig_memberptr *byte
+
+
+func _swig_allocatememory(int) *byte
+func _swig_internal_allocate(len int) *byte {
+ return _swig_allocatememory(len)
+}
+
+func _swig_allocatestring(*byte, int) string
+func _swig_internal_makegostring(p *byte, l int) string {
+ return _swig_allocatestring(p, l)
+}
+
+func _swig_internal_gopanic(p *byte, l int) {
+ panic(_swig_allocatestring(p, l))
+}
+
+func _swig_wrap_add(*int, *int, *int)
+
+func Add(arg1 *int, arg2 *int, arg3 *int) {
+ _swig_wrap_add(arg1, arg2, arg3)
+}
+
+func New_intp() *int
+func Copy_intp(int) *int
+func _swig_wrap_delete_intp(*int)
+
+func Delete_intp(arg1 *int) {
+ _swig_wrap_delete_intp(arg1)
+}
+
+func _swig_wrap_intp_assign(*int, int)
+
+func Intp_assign(arg1 *int, arg2 int) {
+ _swig_wrap_intp_assign(arg1, arg2)
+}
+
+func Intp_value(*int) int
+func _swig_wrap_sub(int, int, []int)
+
+func Sub(arg1 int, arg2 int, arg3 []int) {
+ _swig_wrap_sub(arg1, arg2, arg3)
+}
+
+func Divide(int, int, []int) int
+
+type SwigcptrVoid uintptr
+type Void interface {
+ Swigcptr() uintptr;
+}
+func (p SwigcptrVoid) Swigcptr() uintptr {
+ return uintptr(p)
+}
+
diff --git a/Examples/go/pointer/example.i b/Examples/go/pointer/example.i
new file mode 100644
index 000000000..a8ac79499
--- /dev/null
+++ b/Examples/go/pointer/example.i
@@ -0,0 +1,30 @@
+/* File : example.i */
+%module example
+
+%{
+extern void add(int *, int *, int *);
+extern void sub(int *, int *, int *);
+extern int divide(int, int, int *);
+%}
+
+/* This example illustrates a couple of different techniques
+ for manipulating C pointers */
+
+/* First we'll use the pointer library */
+extern void add(int *x, int *y, int *result);
+%include cpointer.i
+%pointer_functions(int, intp);
+
+/* Next we'll use some typemaps */
+
+%include typemaps.i
+extern void sub(int *INPUT, int *INPUT, int *OUTPUT);
+
+/* Next we'll use typemaps and the %apply directive */
+
+%apply int *OUTPUT { int *r };
+extern int divide(int n, int d, int *r);
+
+
+
+
diff --git a/Examples/go/pointer/index.html b/Examples/go/pointer/index.html
new file mode 100644
index 000000000..cfa8a3acc
--- /dev/null
+++ b/Examples/go/pointer/index.html
@@ -0,0 +1,143 @@
+
+
+SWIG:Examples:go:pointer
+
+
+
+
+SWIG/Examples/go/pointer/
+
+
+Simple Pointer Handling
+
+
+This example illustrates a couple of techniques for handling simple
+pointers in SWIG. The prototypical example is a C function that
+operates on pointers such as this:
+
+
+
+void add(int *x, int *y, int *r) {
+ *r = *x + *y;
+}
+
+
+
+By default, SWIG wraps this function exactly as specified and creates
+an interface that expects pointer objects for arguments. This only
+works when there is a precise correspondence between the C type and
+some Go type.
+
+
+
Other approaches
+
+
+
The SWIG pointer library provides a different, safer, way to
+ handle pointers. For example, in the interface file you would do
+ this:
+
+
+
+%include cpointer.i
+%pointer_functions(int, intp);
+
+
+
+and from Go you would use pointers like this:
+
+
+
+a := example.New_intp()
+b := example.New_intp()
+c := example.New_intp()
+Intp_Assign(a, 37)
+Intp_Assign(b, 42)
+
+fmt.Println(" a =", a)
+fmt.Println(" b =", b)
+fmt.Println(" c =", c)
+
+// Call the add() function with some pointers
+example.Add(a,b,c)
+
+// Now get the result
+res := example.Intp_value(c)
+fmt.Println(" 37 + 42 =", res)
+
+// Clean up the pointers
+example.Delete_intp(a)
+example.Delete_intp(b)
+example.Delete_intp(c)
+
+
+
+
+
Use the SWIG typemap library. This library allows you to
+completely change the way arguments are processed by SWIG. For
+example:
+
+
+
+%include "typemaps.i"
+void add(int *INPUT, int *INPUT, int *OUTPUT);
+
+
+
+And in a Go program:
+
+
+
+r := []int{0}
+example.Sub(37,42,r)
+fmt.Println("Result =", r[0])
+
+
+Needless to say, this is substantially easier although a bit unusual.
+
+
+
A final alternative is to use the typemaps library in combination
+with the %apply directive. This allows you to change the names of parameters
+that behave as input or output parameters. For example:
+
+
+
+%include "typemaps.i"
+%apply int *INPUT {int *x, int *y};
+%apply int *OUTPUT {int *r};
+
+void add(int *x, int *y, int *r);
+void sub(int *x, int *y, int *r);
+void mul(int *x, int *y, int *r);
+... etc ...
+
+
+
+
+
+Example
+
+The following example illustrates the use of these features for pointer
+extraction.
+
+
+
+Notes
+
+
+Since pointers are used for so many different things (arrays, output values,
+etc...) the complexity of pointer handling can be as complicated as you want to
+make it.
+
+
+
More documentation on the typemaps.i and cpointer.i library files can be
+found in the SWIG user manual. The files also contain documentation.
+
+
+
+
+
+
diff --git a/Examples/go/pointer/runme.go b/Examples/go/pointer/runme.go
new file mode 100644
index 000000000..9cbcda489
--- /dev/null
+++ b/Examples/go/pointer/runme.go
@@ -0,0 +1,47 @@
+package main
+
+import (
+ "fmt"
+ . "./example"
+)
+
+func main() {
+ // First create some objects using the pointer library.
+ fmt.Println("Testing the pointer library")
+ a := New_intp()
+ b := New_intp()
+ c := New_intp()
+ Intp_assign(a, 37)
+ Intp_assign(b, 42)
+
+ fmt.Println(" a =", a)
+ fmt.Println(" b =", b)
+ fmt.Println(" c =", c)
+
+ // Call the add() function with some pointers
+ Add(a, b, c)
+
+ // Now get the result
+ res := Intp_value(c)
+ fmt.Println(" 37 + 42 =", res)
+
+ // Clean up the pointers
+ Delete_intp(a)
+ Delete_intp(b)
+ Delete_intp(c)
+
+ // Now try the typemap library
+ // Now it is no longer necessary to manufacture pointers.
+ // Instead we use a single element array which in Java is modifiable.
+
+ fmt.Println("Trying the typemap library")
+ r := []int{0}
+ Sub(37, 42, r)
+ fmt.Println(" 37 - 42 = ", r[0])
+
+ // Now try the version with return value
+
+ fmt.Println("Testing return value")
+ q := Divide(42, 37, r)
+ fmt.Println(" 42/37 = ", q, " remainder ", r[0])
+}
diff --git a/Examples/go/reference/Makefile b/Examples/go/reference/Makefile
new file mode 100644
index 000000000..9dc8b8851
--- /dev/null
+++ b/Examples/go/reference/Makefile
@@ -0,0 +1,18 @@
+TOP = ../..
+SWIG = $(TOP)/../preinst-swig
+CXXSRCS = example.cxx
+TARGET = example
+INTERFACE = example.i
+SWIGOPT =
+
+all:: go
+
+go::
+ $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
+ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_cpp
+
+clean::
+ $(MAKE) -f $(TOP)/Makefile go_clean
+
+check: all
+ $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
diff --git a/Examples/go/reference/example.cxx b/Examples/go/reference/example.cxx
new file mode 100644
index 000000000..8a513bf49
--- /dev/null
+++ b/Examples/go/reference/example.cxx
@@ -0,0 +1,46 @@
+/* File : example.cxx */
+
+/* Deal with Microsoft's attempt at deprecating C standard runtime functions */
+#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER)
+# define _CRT_SECURE_NO_DEPRECATE
+#endif
+
+#include "example.h"
+#include
+#include
+
+Vector operator+(const Vector &a, const Vector &b) {
+ Vector r;
+ r.x = a.x + b.x;
+ r.y = a.y + b.y;
+ r.z = a.z + b.z;
+ return r;
+}
+
+char *Vector::print() {
+ static char temp[512];
+ sprintf(temp,"Vector %p (%g,%g,%g)", this, x,y,z);
+ return temp;
+}
+
+VectorArray::VectorArray(int size) {
+ items = new Vector[size];
+ maxsize = size;
+}
+
+VectorArray::~VectorArray() {
+ delete [] items;
+}
+
+Vector &VectorArray::operator[](int index) {
+ if ((index < 0) || (index >= maxsize)) {
+ printf("Panic! Array index out of bounds.\n");
+ exit(1);
+ }
+ return items[index];
+}
+
+int VectorArray::size() {
+ return maxsize;
+}
+
diff --git a/Examples/go/reference/example.go b/Examples/go/reference/example.go
new file mode 100644
index 000000000..fb98f8a18
--- /dev/null
+++ b/Examples/go/reference/example.go
@@ -0,0 +1,126 @@
+/* ----------------------------------------------------------------------------
+ * This file was automatically generated by SWIG (http://www.swig.org).
+ * Version 2.0.1
+ *
+ * This file is not intended to be easily readable and contains a number of
+ * coding conventions designed to improve portability and efficiency. Do not make
+ * changes to this file unless you know what you are doing--modify the SWIG
+ * interface file instead.
+ * ----------------------------------------------------------------------------- */
+
+package example
+
+
+type _swig_fnptr *byte
+type _swig_memberptr *byte
+
+
+func _swig_allocatememory(int) *byte
+func _swig_internal_allocate(len int) *byte {
+ return _swig_allocatememory(len)
+}
+
+func _swig_allocatestring(*byte, int) string
+func _swig_internal_makegostring(p *byte, l int) string {
+ return _swig_allocatestring(p, l)
+}
+
+func _swig_internal_gopanic(p *byte, l int) {
+ panic(_swig_allocatestring(p, l))
+}
+
+type SwigcptrVector uintptr
+
+func (p SwigcptrVector) Swigcptr() uintptr {
+ return (uintptr)(p)
+}
+
+func (p SwigcptrVector) SwigIsVector() {
+}
+
+func _swig_wrap_new_Vector(float64, float64, float64) SwigcptrVector
+
+func NewVector(arg1 float64, arg2 float64, arg3 float64) Vector {
+ return _swig_wrap_new_Vector(arg1, arg2, arg3)
+}
+
+func _swig_wrap_delete_Vector(uintptr)
+
+func DeleteVector(arg1 Vector) {
+ _swig_wrap_delete_Vector(arg1.Swigcptr())
+}
+
+func _swig_wrap_Vector_print(SwigcptrVector) string
+
+func (arg1 SwigcptrVector) Print() string {
+ return _swig_wrap_Vector_print(arg1)
+}
+
+type Vector interface {
+ Swigcptr() uintptr
+ SwigIsVector()
+ Print() string
+}
+
+func _swig_wrap_addv(uintptr, uintptr) SwigcptrVector
+
+func Addv(arg1 Vector, arg2 Vector) Vector {
+ return _swig_wrap_addv(arg1.Swigcptr(), arg2.Swigcptr())
+}
+
+type SwigcptrVectorArray uintptr
+
+func (p SwigcptrVectorArray) Swigcptr() uintptr {
+ return (uintptr)(p)
+}
+
+func (p SwigcptrVectorArray) SwigIsVectorArray() {
+}
+
+func _swig_wrap_new_VectorArray(int) SwigcptrVectorArray
+
+func NewVectorArray(arg1 int) VectorArray {
+ return _swig_wrap_new_VectorArray(arg1)
+}
+
+func _swig_wrap_delete_VectorArray(uintptr)
+
+func DeleteVectorArray(arg1 VectorArray) {
+ _swig_wrap_delete_VectorArray(arg1.Swigcptr())
+}
+
+func _swig_wrap_VectorArray_size(SwigcptrVectorArray) int
+
+func (arg1 SwigcptrVectorArray) Size() int {
+ return _swig_wrap_VectorArray_size(arg1)
+}
+
+func _swig_wrap_VectorArray_get(SwigcptrVectorArray, int) SwigcptrVector
+
+func (arg1 SwigcptrVectorArray) Get(arg2 int) Vector {
+ return _swig_wrap_VectorArray_get(arg1, arg2)
+}
+
+func _swig_wrap_VectorArray_set(SwigcptrVectorArray, int, uintptr)
+
+func (arg1 SwigcptrVectorArray) Set(arg2 int, arg3 Vector) {
+ _swig_wrap_VectorArray_set(arg1, arg2, arg3.Swigcptr())
+}
+
+type VectorArray interface {
+ Swigcptr() uintptr
+ SwigIsVectorArray()
+ Size() int
+ Get(arg2 int) Vector
+ Set(arg2 int, arg3 Vector)
+}
+
+
+type SwigcptrVoid uintptr
+type Void interface {
+ Swigcptr() uintptr;
+}
+func (p SwigcptrVoid) Swigcptr() uintptr {
+ return uintptr(p)
+}
+
diff --git a/Examples/go/reference/example.h b/Examples/go/reference/example.h
new file mode 100644
index 000000000..4915adb1b
--- /dev/null
+++ b/Examples/go/reference/example.h
@@ -0,0 +1,26 @@
+/* File : example.h */
+
+class Vector {
+private:
+ double x,y,z;
+public:
+ Vector() : x(0), y(0), z(0) { };
+ Vector(double x, double y, double z) : x(x), y(y), z(z) { };
+ friend Vector operator+(const Vector &a, const Vector &b);
+ char *print();
+};
+
+class VectorArray {
+private:
+ Vector *items;
+ int maxsize;
+public:
+ VectorArray(int maxsize);
+ ~VectorArray();
+ Vector &operator[](int);
+ int size();
+};
+
+
+
+
diff --git a/Examples/go/reference/example.i b/Examples/go/reference/example.i
new file mode 100644
index 000000000..1cf19c82c
--- /dev/null
+++ b/Examples/go/reference/example.i
@@ -0,0 +1,42 @@
+/* File : example.i */
+
+/* This file has a few "typical" uses of C++ references. */
+
+%module example
+
+%{
+#include "example.h"
+%}
+
+class Vector {
+public:
+ Vector(double x, double y, double z);
+ ~Vector();
+ char *print();
+};
+
+/* This helper function calls an overloaded operator */
+%inline %{
+Vector addv(Vector &a, Vector &b) {
+ return a+b;
+}
+%}
+
+/* Wrapper around an array of vectors class */
+
+class VectorArray {
+public:
+ VectorArray(int maxsize);
+ ~VectorArray();
+ int size();
+
+ /* This wrapper provides an alternative to the [] operator */
+ %extend {
+ Vector &get(int index) {
+ return (*$self)[index];
+ }
+ void set(int index, Vector &a) {
+ (*$self)[index] = a;
+ }
+ }
+};
diff --git a/Examples/go/reference/index.html b/Examples/go/reference/index.html
new file mode 100644
index 000000000..5e8589349
--- /dev/null
+++ b/Examples/go/reference/index.html
@@ -0,0 +1,143 @@
+
+
+SWIG:Examples:go:reference
+
+
+
+
+
+SWIG/Examples/go/reference/
+
+
+C++ Reference Handling
+
+
+This example tests SWIG's handling of C++ references. A reference in
+C++ is much like a pointer. Go represents C++ classes as pointers
+which are stored in interface values. Therefore, a reference to a
+class in C++ simply becomes an object of the class type in Go. For
+types which are not classes, a reference in C++ is represented as a
+pointer in Go.
+
+
Some examples
+
+References are most commonly used as function parameters. For
+example, you might have a function like this:
+
+
+
+Vector addv(const Vector &a, const Vector &b) {
+ Vector result;
+ result.x = a.x + b.x;
+ result.y = a.y + b.y;
+ result.z = a.z + b.z;
+ return result;
+}
+
+
+
+In these cases, SWIG transforms everything into a pointer and creates
+a wrapper that looks like this in C++.
+
+
+
+Vector wrap_addv(Vector *a, Vector *b);
+
+
+
+or like this in Go:
+
+
+
+func Addv(arg1 Vector, arg2 Vector) Vector
+
+
+
+Occasionally, a reference is used as a return value of a function
+when the return result is to be used as an lvalue in an expression.
+The prototypical example is an operator like this:
+
+
+
+Vector &operator[](int index);
+
+
+
+or a method:
+
+
+
+Vector &get(int index);
+
+
+
+For functions returning references, a wrapper like this is created:
+
+
+
+Vector *wrap_Object_get(Object *self, int index) {
+ Vector &result = self->get(index);
+ return &result;
+}
+
+
+
+The following header file contains some class
+definitions with some operators and use of references.
+
+SWIG Interface
+
+SWIG does NOT support overloaded operators so it can not directly
+build an interface to the classes in the above file. However, a
+number of workarounds can be made. For example, an overloaded
+operator can be stuck behind a function call such as the addv
+function above. Array access can be handled with a pair of set/get
+functions like this:
+
+
+
+class VectorArray {
+public:
+ ...
+ %addmethods {
+ Vector &get(int index) {
+ return (*self)[index];
+ }
+ void set(int index, Vector &a) {
+ (*self)[index] = a;
+ }
+ }
+ ...
+}
+
+
+
+Click here to see a SWIG interface file with
+these additions.
+
+Sample Go program
+
+Click here to see a Go program that manipulates
+some C++ references.
+
+Notes:
+
+
+C++ references primarily provide notational convenience for C++
+source code. However, Go only supports the 'x.a' notation so it
+doesn't much matter.
+
+
+
When a program returns a reference, a pointer is returned. Unlike
+return by value, memory is not allocated to hold the return result.
+
+
+
SWIG has particular trouble handling various combinations of
+references and pointers. This is side effect of an old parsing scheme
+and type representation that will be replaced in future versions.
+
+
+
+
+
+
diff --git a/Examples/go/reference/runme.go b/Examples/go/reference/runme.go
new file mode 100644
index 000000000..3683d6144
--- /dev/null
+++ b/Examples/go/reference/runme.go
@@ -0,0 +1,71 @@
+// This example illustrates the manipulation of C++ references in Java.
+
+package main
+
+import (
+ "fmt"
+ . "./example"
+)
+
+func main() {
+ fmt.Println("Creating some objects:")
+ a := NewVector(3, 4, 5)
+ b := NewVector(10, 11, 12)
+
+ fmt.Println(" Created ", a.Print())
+ fmt.Println(" Created ", b.Print())
+
+ // ----- Call an overloaded operator -----
+
+ // This calls the wrapper we placed around
+ //
+ // operator+(const Vector &a, const Vector &)
+ //
+ // It returns a new allocated object.
+
+ fmt.Println("Adding a+b")
+ c := Addv(a, b)
+ fmt.Println(" a+b = " + c.Print())
+
+ // Because addv returns a reference, Addv will return a
+ // pointer allocated using Go's memory allocator. That means
+ // that it will be freed by Go's garbage collector, and we can
+ // not use DeleteVector to release it.
+
+ c = nil
+
+ // ----- Create a vector array -----
+
+ fmt.Println("Creating an array of vectors")
+ va := NewVectorArray(10)
+ fmt.Println(" va = ", va)
+
+ // ----- Set some values in the array -----
+
+ // These operators copy the value of Vector a and Vector b to
+ // the vector array
+ va.Set(0, a)
+ va.Set(1, b)
+
+ va.Set(2, Addv(a, b))
+
+ // Get some values from the array
+
+ fmt.Println("Getting some array values")
+ for i := 0; i < 5; i++ {
+ fmt.Println(" va(", i, ") = ", va.Get(i).Print())
+ }
+
+ // Watch under resource meter to check on this
+ fmt.Println("Making sure we don't leak memory.")
+ for i := 0; i < 1000000; i++ {
+ c = va.Get(i % 10)
+ }
+
+ // ----- Clean up ----- This could be omitted. The garbage
+ // collector would then clean up for us.
+ fmt.Println("Cleaning up")
+ DeleteVectorArray(va)
+ DeleteVector(a)
+ DeleteVector(b)
+}
diff --git a/Examples/go/simple/Makefile b/Examples/go/simple/Makefile
new file mode 100644
index 000000000..e67fa8bb6
--- /dev/null
+++ b/Examples/go/simple/Makefile
@@ -0,0 +1,15 @@
+TOP = ../..
+SWIG = $(TOP)/../preinst-swig
+SRCS = example.c
+TARGET = example
+INTERFACE = example.i
+
+all::
+ $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
+ TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go
+
+clean::
+ $(MAKE) -f $(TOP)/Makefile go_clean
+
+check: all
+ $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
diff --git a/Examples/go/simple/example.c b/Examples/go/simple/example.c
new file mode 100644
index 000000000..1c2af789c
--- /dev/null
+++ b/Examples/go/simple/example.c
@@ -0,0 +1,18 @@
+/* File : example.c */
+
+/* A global variable */
+double Foo = 3.0;
+
+/* Compute the greatest common divisor of positive integers */
+int gcd(int x, int y) {
+ int g;
+ g = y;
+ while (x > 0) {
+ g = x;
+ x = y % x;
+ y = g;
+ }
+ return g;
+}
+
+
diff --git a/Examples/go/simple/example.go b/Examples/go/simple/example.go
new file mode 100644
index 000000000..df0e70564
--- /dev/null
+++ b/Examples/go/simple/example.go
@@ -0,0 +1,48 @@
+/* ----------------------------------------------------------------------------
+ * This file was automatically generated by SWIG (http://www.swig.org).
+ * Version 2.0.1
+ *
+ * This file is not intended to be easily readable and contains a number of
+ * coding conventions designed to improve portability and efficiency. Do not make
+ * changes to this file unless you know what you are doing--modify the SWIG
+ * interface file instead.
+ * ----------------------------------------------------------------------------- */
+
+package example
+
+
+type _swig_fnptr *byte
+type _swig_memberptr *byte
+
+
+func _swig_allocatememory(int) *byte
+func _swig_internal_allocate(len int) *byte {
+ return _swig_allocatememory(len)
+}
+
+func _swig_allocatestring(*byte, int) string
+func _swig_internal_makegostring(p *byte, l int) string {
+ return _swig_allocatestring(p, l)
+}
+
+func _swig_internal_gopanic(p *byte, l int) {
+ panic(_swig_allocatestring(p, l))
+}
+
+func Gcd(int, int) int
+func _swig_wrap_Foo_set(float64)
+
+func SetFoo(arg1 float64) {
+ _swig_wrap_Foo_set(arg1)
+}
+
+func GetFoo() float64
+
+type SwigcptrVoid uintptr
+type Void interface {
+ Swigcptr() uintptr;
+}
+func (p SwigcptrVoid) Swigcptr() uintptr {
+ return uintptr(p)
+}
+
diff --git a/Examples/go/simple/example.i b/Examples/go/simple/example.i
new file mode 100644
index 000000000..24093b9bf
--- /dev/null
+++ b/Examples/go/simple/example.i
@@ -0,0 +1,7 @@
+/* File : example.i */
+%module example
+
+%inline %{
+extern int gcd(int x, int y);
+extern double Foo;
+%}
diff --git a/Examples/go/simple/index.html b/Examples/go/simple/index.html
new file mode 100644
index 000000000..82372ef37
--- /dev/null
+++ b/Examples/go/simple/index.html
@@ -0,0 +1,126 @@
+
+
+SWIG:Examples:go:simple
+
+
+
+
+
+SWIG/Examples/go/simple/
+
+
+Simple Go Example
+
+
+This example illustrates how you can hook Go to a very simple C program containing
+a function and a global variable.
+
+
The C Code
+
+Suppose you have the following C code:
+
+
+
+/* File : example.c */
+
+/* A global variable */
+double Foo = 3.0;
+
+/* Compute the greatest common divisor of positive integers */
+int gcd(int x, int y) {
+ int g;
+ g = y;
+ while (x > 0) {
+ g = x;
+ x = y % x;
+ y = g;
+ }
+ return g;
+}
+
+
+
+The SWIG interface
+
+Here is a simple SWIG interface file:
+
+
+
+/* File: example.i */
+%module example
+
+extern int gcd(int x, int y);
+extern double Foo;
+
+
+
+Compilation
+
+These are the instructions if you are using 6g /8g
+rather than gccgo .
+
+
+Run swig -go example.i . This
+ will create the three
+ files example.go , example_gc.c ,
+ and example_wrap.c .
+ Compile example.go
+ using 6g or 8g ; e.g., 6g example.go .
+ Compile example_gc.c
+ using 6c or 8c ; e.g., 6c example_gc.c .
+ Put the two object files together into an archive
+ named example.a ; e.g., gopack grc example.a example.6
+ example_gc.6 .
+ Compile the example_wrap.c
+ file using your standard C compiler with the -fpic option;
+ e.g., gcc -c -O -fpic example_wrap.c .
+ Put the gcc compiled object file into a shared library;
+ e.g., gcc -shared -o example.so example_wrap.o .
+ Compile the program which demonstrates how to use the library;
+ e.g., 6g runme.go .
+ Link the program; e.g., 6l -o runme runme.6 .
+ Now you should have a program runme .
+
+
+Using the extension
+
+The Go program which demonstrates calling the C functions from Go
+is runme.go .
+
+Key points
+
+
+Use the import statement to load your extension module from Go. For example:
+
+
+import "example"
+
+
+
+ C functions work just like Go functions. However, the function
+ names are automatically capitalized in order to make the names
+ visible from other Go packages. For example:
+
+
+g := example.Gcd(42,105)
+
+
+
+(If there are name conflicts, you can use the %rename
+directive in the .i file or the -rename option to Go to
+rename one or the other symbol).
+
+ C global variables are accessed using getter and setter
+ functions. The getter function is named Get followed by
+ the capitalized name of the C variable. The Setter function
+ uses Set instead of Get .
+
+
+a = example.GetFoo()
+
+
+
+
+
+
+
diff --git a/Examples/go/simple/runme.go b/Examples/go/simple/runme.go
new file mode 100644
index 000000000..c829ad21a
--- /dev/null
+++ b/Examples/go/simple/runme.go
@@ -0,0 +1,25 @@
+package main
+
+import (
+ "fmt"
+ "./example"
+)
+
+func main() {
+ // Call our gcd() function
+ x := 42
+ y := 105
+ g := example.Gcd(x, y)
+ fmt.Println("The gcd of", x, "and", y, "is", g)
+
+ // Manipulate the Foo global variable
+
+ // Output its current value
+ fmt.Println("Foo =", example.GetFoo())
+
+ // Change its value
+ example.SetFoo(3.1415926)
+
+ // See if the change took effect
+ fmt.Println("Foo =", example.GetFoo())
+}
diff --git a/Examples/go/template/Makefile b/Examples/go/template/Makefile
new file mode 100644
index 000000000..b9278b53e
--- /dev/null
+++ b/Examples/go/template/Makefile
@@ -0,0 +1,18 @@
+TOP = ../..
+SWIG = $(TOP)/../preinst-swig
+CXXSRCS =
+TARGET = example
+INTERFACE = example.i
+SWIGOPT =
+
+all:: go
+
+go::
+ $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
+ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_cpp
+
+clean::
+ $(MAKE) -f $(TOP)/Makefile go_clean
+
+check: all
+ $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
diff --git a/Examples/go/template/example.go b/Examples/go/template/example.go
new file mode 100644
index 000000000..671b5c2ba
--- /dev/null
+++ b/Examples/go/template/example.go
@@ -0,0 +1,150 @@
+/* ----------------------------------------------------------------------------
+ * This file was automatically generated by SWIG (http://www.swig.org).
+ * Version 2.0.1
+ *
+ * This file is not intended to be easily readable and contains a number of
+ * coding conventions designed to improve portability and efficiency. Do not make
+ * changes to this file unless you know what you are doing--modify the SWIG
+ * interface file instead.
+ * ----------------------------------------------------------------------------- */
+
+package example
+
+
+type _swig_fnptr *byte
+type _swig_memberptr *byte
+
+
+func _swig_allocatememory(int) *byte
+func _swig_internal_allocate(len int) *byte {
+ return _swig_allocatememory(len)
+}
+
+func _swig_allocatestring(*byte, int) string
+func _swig_internal_makegostring(p *byte, l int) string {
+ return _swig_allocatestring(p, l)
+}
+
+func _swig_internal_gopanic(p *byte, l int) {
+ panic(_swig_allocatestring(p, l))
+}
+
+func Maxint(int, int) int
+func Maxdouble(float64, float64) float64
+type SwigcptrVecint uintptr
+
+func (p SwigcptrVecint) Swigcptr() uintptr {
+ return (uintptr)(p)
+}
+
+func (p SwigcptrVecint) SwigIsVecint() {
+}
+
+func _swig_wrap_new_vecint(int) SwigcptrVecint
+
+func NewVecint(arg1 int) Vecint {
+ return _swig_wrap_new_vecint(arg1)
+}
+
+func _swig_wrap_vecint_get(SwigcptrVecint, int) *int
+
+func (arg1 SwigcptrVecint) Get(arg2 int) *int {
+ return _swig_wrap_vecint_get(arg1, arg2)
+}
+
+func _swig_wrap_vecint_set(SwigcptrVecint, int, *int)
+
+func (arg1 SwigcptrVecint) Set(arg2 int, arg3 *int) {
+ _swig_wrap_vecint_set(arg1, arg2, arg3)
+}
+
+func _swig_wrap_vecint_getitem(SwigcptrVecint, int) int
+
+func (arg1 SwigcptrVecint) Getitem(arg2 int) int {
+ return _swig_wrap_vecint_getitem(arg1, arg2)
+}
+
+func _swig_wrap_vecint_setitem(SwigcptrVecint, int, int)
+
+func (arg1 SwigcptrVecint) Setitem(arg2 int, arg3 int) {
+ _swig_wrap_vecint_setitem(arg1, arg2, arg3)
+}
+
+func _swig_wrap_delete_vecint(uintptr)
+
+func DeleteVecint(arg1 Vecint) {
+ _swig_wrap_delete_vecint(arg1.Swigcptr())
+}
+
+type Vecint interface {
+ Swigcptr() uintptr
+ SwigIsVecint()
+ Get(arg2 int) *int
+ Set(arg2 int, arg3 *int)
+ Getitem(arg2 int) int
+ Setitem(arg2 int, arg3 int)
+}
+
+type SwigcptrVecdouble uintptr
+
+func (p SwigcptrVecdouble) Swigcptr() uintptr {
+ return (uintptr)(p)
+}
+
+func (p SwigcptrVecdouble) SwigIsVecdouble() {
+}
+
+func _swig_wrap_new_vecdouble(int) SwigcptrVecdouble
+
+func NewVecdouble(arg1 int) Vecdouble {
+ return _swig_wrap_new_vecdouble(arg1)
+}
+
+func _swig_wrap_vecdouble_get(SwigcptrVecdouble, int) *float64
+
+func (arg1 SwigcptrVecdouble) Get(arg2 int) *float64 {
+ return _swig_wrap_vecdouble_get(arg1, arg2)
+}
+
+func _swig_wrap_vecdouble_set(SwigcptrVecdouble, int, *float64)
+
+func (arg1 SwigcptrVecdouble) Set(arg2 int, arg3 *float64) {
+ _swig_wrap_vecdouble_set(arg1, arg2, arg3)
+}
+
+func _swig_wrap_vecdouble_getitem(SwigcptrVecdouble, int) float64
+
+func (arg1 SwigcptrVecdouble) Getitem(arg2 int) float64 {
+ return _swig_wrap_vecdouble_getitem(arg1, arg2)
+}
+
+func _swig_wrap_vecdouble_setitem(SwigcptrVecdouble, int, float64)
+
+func (arg1 SwigcptrVecdouble) Setitem(arg2 int, arg3 float64) {
+ _swig_wrap_vecdouble_setitem(arg1, arg2, arg3)
+}
+
+func _swig_wrap_delete_vecdouble(uintptr)
+
+func DeleteVecdouble(arg1 Vecdouble) {
+ _swig_wrap_delete_vecdouble(arg1.Swigcptr())
+}
+
+type Vecdouble interface {
+ Swigcptr() uintptr
+ SwigIsVecdouble()
+ Get(arg2 int) *float64
+ Set(arg2 int, arg3 *float64)
+ Getitem(arg2 int) float64
+ Setitem(arg2 int, arg3 float64)
+}
+
+
+type SwigcptrVoid uintptr
+type Void interface {
+ Swigcptr() uintptr;
+}
+func (p SwigcptrVoid) Swigcptr() uintptr {
+ return uintptr(p)
+}
+
diff --git a/Examples/go/template/example.h b/Examples/go/template/example.h
new file mode 100644
index 000000000..7401df650
--- /dev/null
+++ b/Examples/go/template/example.h
@@ -0,0 +1,32 @@
+/* File : example.h */
+
+// Some template definitions
+
+template T max(T a, T b) { return a>b ? a : b; }
+
+template class vector {
+ T *v;
+ int sz;
+ public:
+ vector(int _sz) {
+ v = new T[_sz];
+ sz = _sz;
+ }
+ T &get(int index) {
+ return v[index];
+ }
+ void set(int index, T &val) {
+ v[index] = val;
+ }
+#ifdef SWIG
+ %extend {
+ T getitem(int index) {
+ return $self->get(index);
+ }
+ void setitem(int index, T val) {
+ $self->set(index,val);
+ }
+ }
+#endif
+};
+
diff --git a/Examples/go/template/example.i b/Examples/go/template/example.i
new file mode 100644
index 000000000..8f94c4da1
--- /dev/null
+++ b/Examples/go/template/example.i
@@ -0,0 +1,17 @@
+/* File : example.i */
+%module example
+
+%{
+#include "example.h"
+%}
+
+/* Let's just grab the original header file here */
+%include "example.h"
+
+/* Now instantiate some specific template declarations */
+
+%template(maxint) max;
+%template(maxdouble) max;
+%template(vecint) vector;
+%template(vecdouble) vector;
+
diff --git a/Examples/go/template/index.html b/Examples/go/template/index.html
new file mode 100644
index 000000000..a14e3b29a
--- /dev/null
+++ b/Examples/go/template/index.html
@@ -0,0 +1,113 @@
+
+
+SWIG:Examples:go:template
+
+
+
+
+
+SWIG/Examples/go/template/
+
+
+C++ template support
+
+
+This example illustrates how C++ templates can be used from Go using
+SWIG.
+
+
The C++ Code
+
+Lets take a templated function and a templated class as follows:
+
+
+
+/* File : example.h */
+
+// Some template definitions
+
+template T max(T a, T b) { return a>b ? a : b; }
+
+template class vector {
+ T *v;
+ int sz;
+ public:
+ vector(int _sz) {
+ v = new T[_sz];
+ sz = _sz;
+ }
+ T &get(int index) {
+ return v[index];
+ }
+ void set(int index, T &val) {
+ v[index] = val;
+ }
+#ifdef SWIG
+ %addmethods {
+ T getitem(int index) {
+ return self->get(index);
+ }
+ void setitem(int index, T val) {
+ self->set(index,val);
+ }
+ }
+#endif
+};
+
+
+The %addmethods is used for a neater interface from Go as the
+functions get and set use C++ references to
+primitive types. These are tricky to use from Go as they end up as
+pointers, which only work when the C++ and Go types correspond
+precisely.
+
+The SWIG interface
+
+A simple SWIG interface for this can be built by simply grabbing the
+header file like this:
+
+
+
+/* File : example.i */
+%module example
+
+%{
+#include "example.h"
+%}
+
+/* Let's just grab the original header file here */
+%include "example.h"
+
+/* Now instantiate some specific template declarations */
+
+%template(maxint) max;
+%template(maxdouble) max;
+%template(vecint) vector;
+%template(vecdouble) vector;
+
+
+
+Note that SWIG parses the templated function max and
+templated class vector and so knows about them. However to
+generate code for use from Go, SWIG has to be told which class/type to
+use as the template parameter. The SWIG directive %template is used
+for this.
+
+A sample Go program
+
+Click here to see a Go program that calls the
+C++ functions from Go.
+
+Notes Use templated classes just like you would any other
+SWIG generated Go class. Use the classnames specified by the %template
+directive.
+
+
+
+vecdouble dv = new vecdouble(1000);
+dv.setitem(i, 12.34));
+
+
+
+
+
+
diff --git a/Examples/go/template/runme.go b/Examples/go/template/runme.go
new file mode 100644
index 000000000..8b3d4000e
--- /dev/null
+++ b/Examples/go/template/runme.go
@@ -0,0 +1,43 @@
+// This example illustrates how C++ templates can be used from Go.
+
+package main
+
+import (
+ "fmt"
+ . "./example"
+)
+
+func main() {
+
+ // Call some templated functions
+ fmt.Println(Maxint(3, 7))
+ fmt.Println(Maxdouble(3.14, 2.18))
+
+ // Create some class
+ iv := NewVecint(100)
+ dv := NewVecdouble(1000)
+
+ for i := 0; i < 100; i++ {
+ iv.Setitem(i, 2*i)
+ }
+
+ for i := 0; i < 1000; i++ {
+ dv.Setitem(i, 1.0/float64(i+1))
+ }
+
+ {
+ sum := 0
+ for i := 0; i < 100; i++ {
+ sum = sum + iv.Getitem(i)
+ }
+ fmt.Println(sum)
+ }
+
+ {
+ sum := float64(0.0)
+ for i := 0; i < 1000; i++ {
+ sum = sum + dv.Getitem(i)
+ }
+ fmt.Println(sum)
+ }
+}
diff --git a/Examples/go/variables/Makefile b/Examples/go/variables/Makefile
new file mode 100644
index 000000000..b0aa9c970
--- /dev/null
+++ b/Examples/go/variables/Makefile
@@ -0,0 +1,18 @@
+TOP = ../..
+SWIG = $(TOP)/../preinst-swig
+SRCS = example.c
+TARGET = example
+INTERFACE = example.i
+SWIGOPT =
+
+all:: go
+
+go::
+ $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
+ SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go
+
+clean::
+ $(MAKE) -f $(TOP)/Makefile go_clean
+
+check: all
+ $(MAKE) -f $(TOP)/Makefile TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
diff --git a/Examples/go/variables/example.c b/Examples/go/variables/example.c
new file mode 100644
index 000000000..aa4ffe9b3
--- /dev/null
+++ b/Examples/go/variables/example.c
@@ -0,0 +1,91 @@
+/* File : example.c */
+
+/* I'm a file containing some C global variables */
+
+/* Deal with Microsoft's attempt at deprecating C standard runtime functions */
+#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER)
+# define _CRT_SECURE_NO_DEPRECATE
+#endif
+
+#include
+#include
+#include "example.h"
+
+int ivar = 0;
+short svar = 0;
+long lvar = 0;
+unsigned int uivar = 0;
+unsigned short usvar = 0;
+unsigned long ulvar = 0;
+signed char scvar = 0;
+unsigned char ucvar = 0;
+char cvar = 0;
+float fvar = 0;
+double dvar = 0;
+char *strvar = 0;
+const char cstrvar[] = "Goodbye";
+int *iptrvar = 0;
+char name[256] = "Dave";
+char path[256] = "/home/beazley";
+
+
+/* Global variables involving a structure */
+Point *ptptr = 0;
+Point pt = { 10, 20 };
+
+/* A variable that we will make read-only in the interface */
+int status = 1;
+
+/* A debugging function to print out their values */
+
+void print_vars() {
+ printf("ivar = %d\n", ivar);
+ printf("svar = %d\n", svar);
+ printf("lvar = %ld\n", lvar);
+ printf("uivar = %u\n", uivar);
+ printf("usvar = %u\n", usvar);
+ printf("ulvar = %lu\n", ulvar);
+ printf("scvar = %d\n", scvar);
+ printf("ucvar = %u\n", ucvar);
+ printf("fvar = %g\n", fvar);
+ printf("dvar = %g\n", dvar);
+ printf("cvar = %c\n", cvar);
+ printf("strvar = %s\n", strvar ? strvar : "(null)");
+ printf("cstrvar = %s\n", cstrvar ? cstrvar : "(null)");
+ printf("iptrvar = %p\n", iptrvar);
+ printf("name = %s\n", name);
+ printf("ptptr = %p (%d, %d)\n", ptptr, ptptr ? ptptr->x : 0, ptptr ? ptptr->y : 0);
+ printf("pt = (%d, %d)\n", pt.x, pt.y);
+ printf("status = %d\n", status);
+}
+
+/* A function to create an integer (to test iptrvar) */
+
+int *new_int(int value) {
+ int *ip = (int *) malloc(sizeof(int));
+ *ip = value;
+ return ip;
+}
+
+/* A function to create a point */
+
+Point *new_Point(int x, int y) {
+ Point *p = (Point *) malloc(sizeof(Point));
+ p->x = x;
+ p->y = y;
+ return p;
+}
+
+char * Point_print(Point *p) {
+ static char buffer[256];
+ if (p) {
+ sprintf(buffer,"(%d,%d)", p->x,p->y);
+ } else {
+ sprintf(buffer,"null");
+ }
+ return buffer;
+}
+
+void pt_print() {
+ printf("(%d, %d)\n", pt.x, pt.y);
+}
diff --git a/Examples/go/variables/example.go b/Examples/go/variables/example.go
new file mode 100644
index 000000000..f4f299b73
--- /dev/null
+++ b/Examples/go/variables/example.go
@@ -0,0 +1,198 @@
+/* ----------------------------------------------------------------------------
+ * This file was automatically generated by SWIG (http://www.swig.org).
+ * Version 2.0.1
+ *
+ * This file is not intended to be easily readable and contains a number of
+ * coding conventions designed to improve portability and efficiency. Do not make
+ * changes to this file unless you know what you are doing--modify the SWIG
+ * interface file instead.
+ * ----------------------------------------------------------------------------- */
+
+package example
+
+
+type _swig_fnptr *byte
+type _swig_memberptr *byte
+
+
+func _swig_allocatememory(int) *byte
+func _swig_internal_allocate(len int) *byte {
+ return _swig_allocatememory(len)
+}
+
+func _swig_allocatestring(*byte, int) string
+func _swig_internal_makegostring(p *byte, l int) string {
+ return _swig_allocatestring(p, l)
+}
+
+func _swig_internal_gopanic(p *byte, l int) {
+ panic(_swig_allocatestring(p, l))
+}
+
+func _swig_wrap_ivar_set(int)
+
+func SetIvar(arg1 int) {
+ _swig_wrap_ivar_set(arg1)
+}
+
+func GetIvar() int
+func _swig_wrap_svar_set(int16)
+
+func SetSvar(arg1 int16) {
+ _swig_wrap_svar_set(arg1)
+}
+
+func GetSvar() int16
+func _swig_wrap_lvar_set(int32)
+
+func SetLvar(arg1 int32) {
+ _swig_wrap_lvar_set(arg1)
+}
+
+func GetLvar() int32
+func _swig_wrap_uivar_set(uint)
+
+func SetUivar(arg1 uint) {
+ _swig_wrap_uivar_set(arg1)
+}
+
+func GetUivar() uint
+func _swig_wrap_usvar_set(uint16)
+
+func SetUsvar(arg1 uint16) {
+ _swig_wrap_usvar_set(arg1)
+}
+
+func GetUsvar() uint16
+func _swig_wrap_ulvar_set(uint32)
+
+func SetUlvar(arg1 uint32) {
+ _swig_wrap_ulvar_set(arg1)
+}
+
+func GetUlvar() uint32
+func _swig_wrap_scvar_set(int8)
+
+func SetScvar(arg1 int8) {
+ _swig_wrap_scvar_set(arg1)
+}
+
+func GetScvar() int8
+func _swig_wrap_ucvar_set(byte)
+
+func SetUcvar(arg1 byte) {
+ _swig_wrap_ucvar_set(arg1)
+}
+
+func GetUcvar() byte
+func _swig_wrap_cvar_set(byte)
+
+func SetCvar(arg1 byte) {
+ _swig_wrap_cvar_set(arg1)
+}
+
+func GetCvar() byte
+func _swig_wrap_fvar_set(float32)
+
+func SetFvar(arg1 float32) {
+ _swig_wrap_fvar_set(arg1)
+}
+
+func GetFvar() float32
+func _swig_wrap_dvar_set(float64)
+
+func SetDvar(arg1 float64) {
+ _swig_wrap_dvar_set(arg1)
+}
+
+func GetDvar() float64
+func _swig_wrap_strvar_set(string)
+
+func SetStrvar(arg1 string) {
+ _swig_wrap_strvar_set(arg1)
+}
+
+func GetStrvar() string
+func GetCstrvar() string
+func _swig_wrap_iptrvar_set(*int)
+
+func SetIptrvar(arg1 *int) {
+ _swig_wrap_iptrvar_set(arg1)
+}
+
+func GetIptrvar() *int
+func _swig_wrap_name_set(string)
+
+func SetName(arg1 string) {
+ _swig_wrap_name_set(arg1)
+}
+
+func GetName() string
+func _swig_wrap_ptptr_set(uintptr)
+
+func SetPtptr(arg1 Point) {
+ _swig_wrap_ptptr_set(arg1.Swigcptr())
+}
+
+func _swig_wrap_ptptr_get() SwigcptrPoint
+
+func GetPtptr() Point {
+ return _swig_wrap_ptptr_get()
+}
+
+func _swig_wrap_pt_set(uintptr)
+
+func SetPt(arg1 Point) {
+ _swig_wrap_pt_set(arg1.Swigcptr())
+}
+
+func _swig_wrap_pt_get() SwigcptrPoint
+
+func GetPt() Point {
+ return _swig_wrap_pt_get()
+}
+
+func GetStatus() int
+func GetPath() string
+func _swig_wrap_print_vars()
+
+func Print_vars() {
+ _swig_wrap_print_vars()
+}
+
+func New_int(int) *int
+func _swig_wrap_new_Point(int, int) SwigcptrPoint
+
+func New_Point(arg1 int, arg2 int) Point {
+ return _swig_wrap_new_Point(arg1, arg2)
+}
+
+func _swig_wrap_Point_print(uintptr) string
+
+func Point_print(arg1 Point) string {
+ return _swig_wrap_Point_print(arg1.Swigcptr())
+}
+
+func _swig_wrap_pt_print()
+
+func Pt_print() {
+ _swig_wrap_pt_print()
+}
+
+
+type SwigcptrPoint uintptr
+type Point interface {
+ Swigcptr() uintptr;
+}
+func (p SwigcptrPoint) Swigcptr() uintptr {
+ return uintptr(p)
+}
+
+type SwigcptrVoid uintptr
+type Void interface {
+ Swigcptr() uintptr;
+}
+func (p SwigcptrVoid) Swigcptr() uintptr {
+ return uintptr(p)
+}
+
diff --git a/Examples/go/variables/example.h b/Examples/go/variables/example.h
new file mode 100644
index 000000000..0f7e89594
--- /dev/null
+++ b/Examples/go/variables/example.h
@@ -0,0 +1,6 @@
+/* File: example.h */
+
+typedef struct {
+ int x,y;
+} Point;
+
diff --git a/Examples/go/variables/example.i b/Examples/go/variables/example.i
new file mode 100644
index 000000000..591b871ed
--- /dev/null
+++ b/Examples/go/variables/example.i
@@ -0,0 +1,49 @@
+/* File : example.i */
+%module example
+%{
+#include "example.h"
+%}
+
+/* Some global variable declarations */
+%inline %{
+extern int ivar;
+extern short svar;
+extern long lvar;
+extern unsigned int uivar;
+extern unsigned short usvar;
+extern unsigned long ulvar;
+extern signed char scvar;
+extern unsigned char ucvar;
+extern char cvar;
+extern float fvar;
+extern double dvar;
+extern char *strvar;
+extern const char cstrvar[];
+extern int *iptrvar;
+extern char name[256];
+
+extern Point *ptptr;
+extern Point pt;
+%}
+
+
+/* Some read-only variables */
+
+%immutable;
+
+%inline %{
+extern int status;
+extern char path[256];
+%}
+
+%mutable;
+
+/* Some helper functions to make it easier to test */
+%inline %{
+extern void print_vars();
+extern int *new_int(int value);
+extern Point *new_Point(int x, int y);
+extern char *Point_print(Point *p);
+extern void pt_print();
+%}
+
diff --git a/Examples/go/variables/index.html b/Examples/go/variables/index.html
new file mode 100644
index 000000000..5a11194df
--- /dev/null
+++ b/Examples/go/variables/index.html
@@ -0,0 +1,87 @@
+
+
+SWIG:Examples:go:variables
+
+
+
+
+SWIG/Examples/go/variables/
+
+
+Wrapping C Global Variables
+
+
+When a C global variable appears in an interface file, SWIG provides
+getter and setter functions for the variable. The getter function is
+named Get followed by the capitalized name of the variable.
+The setter variable starts with Set instead. The getter
+function takes no parameters and returns the value of the variable.
+The setter function takes a single parameter with the same type as the
+variable, and returns nothing.
+
+
Click here to see a SWIG interface with
+some variable declarations in it.
+
+
Manipulating Variables from Go
+
+For example, if the package is called example , the global
+variable
+
+
+
+double foo;
+
+
+
+will be accessed from Go as
+
+
+example.GetFoo();
+example.SetFoo(12.3);
+
+
+
+Click here to see the example program that
+updates and prints out the values of the variables using this
+technique.
+
+Key points
+
+
+The name of the variable is capitalized.
+ When a global variable has the type "char * ", SWIG
+manages it as a character string.
+ signed char and unsigned char are handled as
+small 8-bit integers.
+String array variables such as 'char name[256] ' are
+managed as Go strings, but when setting the value, the result is
+truncated to the maximum length of the array. Furthermore, the string
+is assumed to be null-terminated.
+ When structures and classes are used as global variables, they are
+mapped into pointers. Getting the "value" returns a pointer to the
+global variable. Setting the value of a structure results in a memory
+copy from a pointer to the global.
+
+
+Creating read-only variables
+
+The %immutable and %mutable directives can be used
+to specify a collection of read-only variables. A read only variable
+will have a getter function but no setter function. For example:
+
+
+
+%immutable;
+int status;
+double blah;
+...
+%mutable;
+
+
+
+The %immutable directive remains in effect until it is
+explicitly disabled using the %mutable directive.
+
+
+
+
diff --git a/Examples/go/variables/runme.go b/Examples/go/variables/runme.go
new file mode 100644
index 000000000..26cad4b3c
--- /dev/null
+++ b/Examples/go/variables/runme.go
@@ -0,0 +1,67 @@
+// This example illustrates global variable access from Go.
+
+package main
+
+import (
+ "fmt"
+ "./example"
+)
+
+func main() {
+ // Try to set the values of some global variables
+
+ example.SetIvar(42)
+ example.SetSvar(-31000)
+ example.SetLvar(65537)
+ example.SetUivar(123456)
+ example.SetUsvar(61000)
+ example.SetUlvar(654321)
+ example.SetScvar(-13)
+ example.SetUcvar(251)
+ example.SetCvar('S')
+ example.SetFvar(3.14159)
+ example.SetDvar(2.1828)
+ example.SetStrvar("Hello World")
+ example.SetIptrvar(example.New_int(37))
+ example.SetPtptr(example.New_Point(37, 42))
+ example.SetName("Bill")
+
+ // Now print out the values of the variables
+
+ fmt.Println("Variables (values printed from Go)")
+
+ fmt.Println("ivar =", example.GetIvar())
+ fmt.Println("svar =", example.GetSvar())
+ fmt.Println("lvar =", example.GetLvar())
+ fmt.Println("uivar =", example.GetUivar())
+ fmt.Println("usvar =", example.GetUsvar())
+ fmt.Println("ulvar =", example.GetUlvar())
+ fmt.Println("scvar =", example.GetScvar())
+ fmt.Println("ucvar =", example.GetUcvar())
+ fmt.Println("fvar =", example.GetFvar())
+ fmt.Println("dvar =", example.GetDvar())
+ fmt.Printf("cvar = %c\n", example.GetCvar())
+ fmt.Println("strvar =", example.GetStrvar())
+ fmt.Println("cstrvar =", example.GetCstrvar())
+ fmt.Println("iptrvar =", example.GetIptrvar())
+ fmt.Println("name =", example.GetName())
+ fmt.Println("ptptr =", example.GetPtptr(), example.Point_print(example.GetPtptr()))
+ fmt.Println("pt =", example.GetPt(), example.Point_print(example.GetPt()))
+
+ fmt.Println("\nVariables (values printed from C)")
+
+ example.Print_vars()
+
+ // This line would not compile: since status is marked with
+ // %immutable, there is no SetStatus function.
+ // fmt.Println("\nNow I'm going to try and modify some read only variables")
+ // example.SetStatus(0)
+
+ fmt.Println("\nI'm going to try and update a structure variable.\n")
+
+ example.SetPt(example.GetPtptr())
+
+ fmt.Println("The new value is")
+ example.Pt_print()
+ fmt.Println("You should see the value", example.Point_print(example.GetPtptr()))
+}
diff --git a/Examples/test-suite/dynamic_cast.i b/Examples/test-suite/dynamic_cast.i
index 5d4fbb0b6..ccbaa5b47 100644
--- a/Examples/test-suite/dynamic_cast.i
+++ b/Examples/test-suite/dynamic_cast.i
@@ -1,7 +1,7 @@
/* File : example.i */
%module dynamic_cast
-#if !defined(SWIGJAVA) && !defined(SWIGCSHARP)
+#if !defined(SWIGJAVA) && !defined(SWIGCSHARP) && !defined(SWIGGO)
%apply SWIGTYPE *DYNAMIC { Foo * };
#endif
@@ -17,7 +17,7 @@ public:
};
%}
-#if defined(SWIGJAVA) || defined(SWIGCSHARP)
+#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGGO)
%typemap(out) Foo *blah {
Bar *downcast = dynamic_cast($1);
*(Bar **)&$result = downcast;
@@ -37,6 +37,14 @@ public:
}
#endif
+#if defined(SWIGGO)
+%insert(go_runtime) %{
+func FooToBar(f Foo) Bar {
+ return SwigcptrBar(f.Swigcptr())
+}
+%}
+#endif
+
%inline %{
class Bar : public Foo {
@@ -54,7 +62,7 @@ char *do_test(Bar *b) {
}
%}
-#if !defined(SWIGJAVA) && !defined(SWIGCSHARP)
+#if !defined(SWIGJAVA) && !defined(SWIGCSHARP) && !defined(SWIGGO)
// A general purpose function for dynamic casting of a Foo *
%{
static swig_type_info *
diff --git a/Examples/test-suite/go/Makefile.in b/Examples/test-suite/go/Makefile.in
new file mode 100644
index 000000000..d666c81bf
--- /dev/null
+++ b/Examples/test-suite/go/Makefile.in
@@ -0,0 +1,110 @@
+#######################################################################
+# Makefile for Go test-suite
+#######################################################################
+
+LANGUAGE = go
+GO = 6g
+GOGCC = false
+SCRIPTSUFFIX = _runme.go
+
+GOCOMPILEARG = `if $(GOGCC) ; then echo -c -g; fi`
+GOC = $(GO:g=c)
+GOLD = $(GO:g=l)
+
+GOOBJEXT = $(GO:g=)
+
+SO = @SO@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+top_builddir = @top_builddir@
+
+include $(srcdir)/../common.mk
+
+# Custom tests - tests with additional commandline options
+constant_pointers.cpptest: SWIGOPT += -rename foo=foofn
+director_enum.cpptest: SWIGOPT += -rename Hello=Helloe
+director_finalizer.cpptest: SWIGOPT += -rename deleteFoo=deleteFooFn
+enum_thorough.cpptest: SWIGOPT += -rename One=Onee -rename Two=Twoe
+mixed_types.cpptest: SWIGOPT += -rename Hello=Helloe
+overload_simple.cpptest: SWIGOPT += -rename foo=foofn
+smart_pointer_extend.cpptest: SWIGOPT += -rename CPtrFoo=CPtrFoos
+smart_pointer_member.cpptest: SWIGOPT += -rename Foo=Foos
+special_variable_macros.cpptest: SWIGOPT += -rename Name=Names
+template_partial_specialization.cpptest: SWIGOPT += -rename b=bfn
+template_partial_specialization_typedef.cpptest: SWIGOPT += -rename b=bfn
+template_specialization_enum.cpptest: SWIGOPT += -rename Hello=Helloe
+preproc.ctest: SWIGOPT += -rename a5=a5c -rename a6=a6c
+mod.multicpptest: SWIGOPT += -rename GetC=GetCFn
+
+.SUFFIXES: .cpptest .ctest .multicpptest
+
+# Rules for the different types of tests
+%.cpptest:
+ $(setup)
+ +$(swig_and_compile_cpp)
+ $(run_testcase)
+
+%.ctest:
+ $(setup)
+ +$(swig_and_compile_c)
+ $(run_testcase)
+
+%.multicpptest:
+ $(setup)
+ +$(swig_and_compile_multi_cpp)
+ $(run_multi_testcase)
+
+multi_import.multicpptest:
+ $(setup)
+ for f in multi_import_b multi_import_a; do \
+ $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile CXXSRCS="$(CXXSRCS)" \
+ SWIG_LIB="$(SWIG_LIB)" SWIG="$(SWIG)" LIBS='$(LIBS)' \
+ INCLUDES="$(INCLUDES)" SWIGOPT="$(SWIGOPT)" NOLINK=true \
+ TARGET="$(TARGETPREFIX)$${f}$(TARGETSUFFIX)" INTERFACEDIR="$(INTERFACEDIR)" INTERFACE="$$f.i" \
+ $(LANGUAGE)$(VARIANT)_cpp; \
+ done
+ $(run_multi_testcase)
+
+# Runs the testcase.
+run_testcase = \
+ if test -f $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); then \
+ $(GO) -I . $(GOCOMPILEARG) $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) && \
+ if $(GOGCC) ; then \
+ $(GO) -o $*_runme $(SCRIPTPREFIX)$*_runme.@OBJEXT@ $*.@OBJEXT@ $*$(SO); \
+ else \
+ $(GOLD) -L . -r $${GOROOT}/pkg/$${GOOS}_$${GOARCH}:. -o $*_runme $(SCRIPTPREFIX)$*_runme.$(GOOBJEXT); \
+ fi && \
+ env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH ./$*_runme; \
+ fi
+
+run_multi_testcase = \
+ if test -f $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); then \
+ $(GO) -I . $(GOCOMPILEARG) $(srcdir)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) && \
+ if $(GOGCC) ; then \
+ files=`cat $(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)/$*.list`; \
+ $(GO) -o $*_runme $(SCRIPTPREFIX)$*_runme.@OBJEXT@ `for f in $$files; do echo $$f.@OBJEXT@ $$f$(SO); done`; \
+ else \
+ $(GOLD) -L . -r $${GOROOT}/pkg/$${GOOS}_$${GOARCH}:. -o $*_runme $(SCRIPTPREFIX)$*_runme.$(GOOBJEXT); \
+ fi && \
+ env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH ./$*_runme; \
+ fi
+
+%.clean:
+ @rm -f $*.go $*_gc.c $*_wrap.* $*_runme
+
+clean:
+ $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile go_clean
+ rm -f mod_a.go mod_b.go imports_a.go imports_b.go
+ rm -f clientdata_prop_a.go clientdata_prop_b.go
+ rm -f multi_import_a.go multi_import_b.go
+ rm -f packageoption_a.go packageoption_b.go packageoption_c.go
+
+cvsignore:
+ @echo '*_gc.c *_wrap.* *.so *.dll *.exp *.lib'
+ @echo Makefile
+ @echo mod_a.go mod_b.go imports_a.go imports_b.go
+ @echo clientdata_prop_a.go clientdata_prop_b.go
+ @echo multi_import_a.go multi_import_b.go
+ @echo packageoption_a.go packageoption_b.go packageoption_c.go
+ @for i in ${CPP_TEST_CASES} ${C_TEST_CASES}; do echo $$i.go; done
diff --git a/Examples/test-suite/go/abstract_access_runme.go b/Examples/test-suite/go/abstract_access_runme.go
new file mode 100644
index 000000000..a2cfeda92
--- /dev/null
+++ b/Examples/test-suite/go/abstract_access_runme.go
@@ -0,0 +1,10 @@
+package main
+
+import "./abstract_access"
+
+func main() {
+ d := abstract_access.NewD()
+ if d.Do_x() != 1 {
+ panic(d.Do_x())
+ }
+}
diff --git a/Examples/test-suite/go/abstract_typedef2_runme.go b/Examples/test-suite/go/abstract_typedef2_runme.go
new file mode 100644
index 000000000..ef760e45d
--- /dev/null
+++ b/Examples/test-suite/go/abstract_typedef2_runme.go
@@ -0,0 +1,7 @@
+package main
+
+import "./abstract_typedef2"
+
+func main() {
+ abstract_typedef2.NewA_UF()
+}
diff --git a/Examples/test-suite/go/abstract_typedef_runme.go b/Examples/test-suite/go/abstract_typedef_runme.go
new file mode 100644
index 000000000..99ff94ded
--- /dev/null
+++ b/Examples/test-suite/go/abstract_typedef_runme.go
@@ -0,0 +1,11 @@
+package main
+
+import "./abstract_typedef"
+
+func main() {
+ e := abstract_typedef.NewEngine()
+ a := abstract_typedef.NewA()
+ if !a.Write(e) {
+ panic("failed")
+ }
+}
diff --git a/Examples/test-suite/go/abstract_virtual_runme.go b/Examples/test-suite/go/abstract_virtual_runme.go
new file mode 100644
index 000000000..b87cf9b5c
--- /dev/null
+++ b/Examples/test-suite/go/abstract_virtual_runme.go
@@ -0,0 +1,8 @@
+package main
+
+import "./abstract_virtual"
+
+func main() {
+ abstract_virtual.NewD()
+ abstract_virtual.NewE()
+}
diff --git a/Examples/test-suite/go/array_member_runme.go b/Examples/test-suite/go/array_member_runme.go
new file mode 100644
index 000000000..d8a8fac2b
--- /dev/null
+++ b/Examples/test-suite/go/array_member_runme.go
@@ -0,0 +1,26 @@
+package main
+
+import . "./array_member"
+
+func main() {
+ f := NewFoo()
+ f.SetData(GetGlobal_data())
+
+ for i := 0; i < 8; i++ {
+ if Get_value(f.GetData(), i) != Get_value(GetGlobal_data(), i) {
+ panic("Bad array assignment")
+ }
+ }
+
+ for i := 0; i < 8; i++ {
+ Set_value(f.GetData(), i, -i)
+ }
+
+ SetGlobal_data(f.GetData())
+
+ for i := 0; i < 8; i++ {
+ if Get_value(f.GetData(), i) != Get_value(GetGlobal_data(), i) {
+ panic("Bad array assignment")
+ }
+ }
+}
diff --git a/Examples/test-suite/go/arrays_global_runme.go b/Examples/test-suite/go/arrays_global_runme.go
new file mode 100644
index 000000000..0ff40090c
--- /dev/null
+++ b/Examples/test-suite/go/arrays_global_runme.go
@@ -0,0 +1,22 @@
+package main
+
+import . "./arrays_global"
+
+func main() {
+ SetArray_i(GetArray_const_i())
+
+ GetBeginString_FIX44a()
+ GetBeginString_FIX44b()
+ GetBeginString_FIX44c()
+ GetBeginString_FIX44d()
+ GetBeginString_FIX44d()
+ SetBeginString_FIX44b("12\00045")
+ GetBeginString_FIX44b()
+ GetBeginString_FIX44d()
+ GetBeginString_FIX44e()
+ GetBeginString_FIX44f()
+
+ Test_a("hello", "hi", "chello", "chi")
+
+ Test_b("1234567", "hi")
+}
diff --git a/Examples/test-suite/go/class_ignore_runme.go b/Examples/test-suite/go/class_ignore_runme.go
new file mode 100644
index 000000000..82e52eff5
--- /dev/null
+++ b/Examples/test-suite/go/class_ignore_runme.go
@@ -0,0 +1,10 @@
+package main
+
+import "./class_ignore"
+
+func main() {
+ a := class_ignore.NewBar()
+ if class_ignore.Do_blah(a) != "Bar::blah" {
+ panic(class_ignore.Do_blah(a))
+ }
+}
diff --git a/Examples/test-suite/go/class_scope_weird_runme.go b/Examples/test-suite/go/class_scope_weird_runme.go
new file mode 100644
index 000000000..332586f31
--- /dev/null
+++ b/Examples/test-suite/go/class_scope_weird_runme.go
@@ -0,0 +1,11 @@
+package main
+
+import "./class_scope_weird"
+
+func main() {
+ f := class_scope_weird.NewFoo()
+ class_scope_weird.NewFoo(3)
+ if f.Bar(3) != 3 {
+ panic(f.Bar(3))
+ }
+}
diff --git a/Examples/test-suite/go/compactdefaultargs_runme.go b/Examples/test-suite/go/compactdefaultargs_runme.go
new file mode 100644
index 000000000..8818dce07
--- /dev/null
+++ b/Examples/test-suite/go/compactdefaultargs_runme.go
@@ -0,0 +1,29 @@
+package main
+
+import . "./compactdefaultargs"
+
+func main() {
+ defaults1 := NewDefaults1(1000)
+ defaults1 = NewDefaults1()
+
+ if defaults1.Ret(float64(10.0)) != 10.0 {
+ println(1, defaults1.Ret(float64(10.0)))
+ panic(defaults1.Ret(float64(10.0)))
+ }
+
+ if defaults1.Ret() != -1.0 {
+ println(2, defaults1.Ret())
+ panic(defaults1.Ret())
+ }
+
+ defaults2 := NewDefaults2(1000)
+ defaults2 = NewDefaults2()
+
+ if defaults2.Ret(float64(10.0)) != 10.0 {
+ panic(defaults2.Ret(float64(10.0)))
+ }
+
+ if defaults2.Ret() != -1.0 {
+ panic(defaults2.Ret())
+ }
+}
diff --git a/Examples/test-suite/go/constover_runme.go b/Examples/test-suite/go/constover_runme.go
new file mode 100644
index 000000000..e649140a6
--- /dev/null
+++ b/Examples/test-suite/go/constover_runme.go
@@ -0,0 +1,50 @@
+package main
+
+import (
+ "fmt"
+ "os"
+ "./constover"
+)
+
+func main() {
+ error := 0
+
+ p := constover.Test("test")
+ if p != "test" {
+ fmt.Println("test failed!")
+ error = 1
+ }
+
+ p = constover.Test_pconst("test")
+ if p != "test_pconst" {
+ fmt.Println("test_pconst failed!")
+ error = 1
+ }
+
+ f := constover.NewFoo()
+ p = f.Test("test")
+ if p != "test" {
+ fmt.Println("member-test failed!")
+ error = 1
+ }
+
+ p = f.Test_pconst("test")
+ if p != "test_pconst" {
+ fmt.Println("member-test_pconst failed!")
+ error = 1
+ }
+
+ p = f.Test_constm("test")
+ if p != "test_constmethod" {
+ fmt.Println("member-test_constm failed!")
+ error = 1
+ }
+
+ p = f.Test_pconstm("test")
+ if p != "test_pconstmethod" {
+ fmt.Println("member-test_pconstm failed!")
+ error = 1
+ }
+
+ os.Exit(error)
+}
diff --git a/Examples/test-suite/go/constructor_copy_runme.go b/Examples/test-suite/go/constructor_copy_runme.go
new file mode 100644
index 000000000..d9b77a9db
--- /dev/null
+++ b/Examples/test-suite/go/constructor_copy_runme.go
@@ -0,0 +1,34 @@
+package main
+
+import . "./constructor_copy"
+
+func main() {
+ f1 := NewFoo1(3)
+ f11 := NewFoo1(f1)
+
+ if f1.GetX() != f11.GetX() {
+ panic("f1/f11 x mismatch")
+ }
+
+ bi := NewBari(5)
+ bc := NewBari(bi)
+
+ if bi.GetX() != bc.GetX() {
+ panic("bi/bc x mismatch")
+ }
+
+ bd := NewBard(5)
+ good := false
+ func() {
+ defer func() {
+ if recover() != nil {
+ good = true
+ }
+ }()
+ NewBard(bd)
+ }()
+
+ if !good {
+ panic("bd !good")
+ }
+}
diff --git a/Examples/test-suite/go/contract_runme.go b/Examples/test-suite/go/contract_runme.go
new file mode 100644
index 000000000..d86110be2
--- /dev/null
+++ b/Examples/test-suite/go/contract_runme.go
@@ -0,0 +1,208 @@
+package main
+
+import "./contract"
+
+func main() {
+ contract.Test_preassert(1, 2)
+ contract.Test_postassert(3)
+ func() {
+ defer func() {
+ if recover() == nil {
+ panic("Failed! Postassertions are broken")
+ }
+ }()
+ contract.Test_postassert(-3)
+ }()
+
+ contract.Test_prepost(2, 3)
+ contract.Test_prepost(5, -4)
+ func() {
+ defer func() {
+ if recover() == nil {
+ panic("Failed! Preassertions are broken")
+ }
+ }()
+ contract.Test_prepost(-3, 4)
+ }()
+
+ func() {
+ defer func() {
+ if recover() == nil {
+ panic("Failed! Postassertions are broken")
+ }
+ }()
+ contract.Test_prepost(4, -10)
+ }()
+
+ f := contract.NewFoo()
+ f.Test_preassert(4, 5)
+ func() {
+ defer func() {
+ if recover() == nil {
+ panic("Failed! Method preassertion.")
+ }
+ }()
+ f.Test_preassert(-2, 3)
+ }()
+
+ f.Test_postassert(4)
+ func() {
+ defer func() {
+ if recover() == nil {
+ panic("Failed! Method postassertion")
+ }
+ }()
+ f.Test_postassert(-4)
+ }()
+
+ f.Test_prepost(3, 4)
+ f.Test_prepost(4, -3)
+ func() {
+ defer func() {
+ if recover() == nil {
+ panic("Failed! Method preassertion.")
+ }
+ }()
+ f.Test_prepost(-4, 2)
+ }()
+
+ func() {
+ defer func() {
+ if recover() == nil {
+ panic("Failed! Method postassertion.")
+ }
+ }()
+ f.Test_prepost(4, -10)
+ }()
+
+ contract.FooStest_prepost(4, 0)
+ func() {
+ defer func() {
+ if recover() == nil {
+ panic("Failed! Static method preassertion")
+ }
+ }()
+ contract.FooStest_prepost(-4, 2)
+ }()
+
+ func() {
+ defer func() {
+ if recover() == nil {
+ panic("Failed! Static method posteassertion")
+ }
+ }()
+ contract.FooStest_prepost(4, -10)
+ }()
+
+ b := contract.NewBar()
+ func() {
+ defer func() {
+ if recover() == nil {
+ panic("Failed! Inherited preassertion.")
+ }
+ }()
+ b.Test_prepost(2, -4)
+ }()
+
+ d := contract.NewD()
+ func() {
+ defer func() {
+ if recover() == nil {
+ panic("Failed! Inherited preassertion (D).")
+ }
+ }()
+ d.Foo(-1, 1, 1, 1, 1)
+ }()
+
+ func() {
+ defer func() {
+ if recover() == nil {
+ panic("Failed! Inherited preassertion (D).")
+ }
+ }()
+ d.Foo(1, -1, 1, 1, 1)
+ }()
+
+ func() {
+ defer func() {
+ if recover() == nil {
+ panic("Failed! Inherited preassertion (D).")
+ }
+ }()
+ d.Foo(1, 1, -1, 1, 1)
+ }()
+
+ func() {
+ defer func() {
+ if recover() == nil {
+ panic("Failed! Inherited preassertion (D).")
+ }
+ }()
+ d.Foo(1, 1, 1, -1, 1)
+ }()
+
+ func() {
+ defer func() {
+ if recover() == nil {
+ panic("Failed! Inherited preassertion (D).")
+ }
+ }()
+ d.Foo(1, 1, 1, 1, -1)
+ }()
+
+ func() {
+ defer func() {
+ if recover() == nil {
+ panic("Failed! Inherited preassertion (D).")
+ }
+ }()
+ d.Bar(-1, 1, 1, 1, 1)
+ }()
+
+ func() {
+ defer func() {
+ if recover() == nil {
+ panic("Failed! Inherited preassertion (D).")
+ }
+ }()
+ d.Bar(1, -1, 1, 1, 1)
+ }()
+
+ func() {
+ defer func() {
+ if recover() == nil {
+ panic("Failed! Inherited preassertion (D).")
+ }
+ }()
+ d.Bar(1, 1, -1, 1, 1)
+ }()
+
+ func() {
+ defer func() {
+ if recover() == nil {
+ panic("Failed! Inherited preassertion (D).")
+ }
+ }()
+ d.Bar(1, 1, 1, -1, 1)
+ }()
+
+ func() {
+ defer func() {
+ if recover() == nil {
+ panic("Failed! Inherited preassertion (D).")
+ }
+ }()
+ d.Bar(1, 1, 1, 1, -1)
+ }()
+
+ //Namespace
+ my := contract.NewMyClass(1)
+ func() {
+ defer func() {
+ if recover() == nil {
+ panic("Failed! constructor preassertion")
+ }
+ }()
+ my = contract.NewMyClass(0)
+ }()
+}
diff --git a/Examples/test-suite/go/cpp_enum_runme.go b/Examples/test-suite/go/cpp_enum_runme.go
new file mode 100644
index 000000000..7d7db953d
--- /dev/null
+++ b/Examples/test-suite/go/cpp_enum_runme.go
@@ -0,0 +1,27 @@
+package main
+
+import "./cpp_enum"
+
+func main() {
+ f := cpp_enum.NewFoo()
+
+ if f.GetHola() != cpp_enum.FooHello {
+ panic(f.GetHola())
+ }
+
+ f.SetHola(cpp_enum.FooHi)
+ if f.GetHola() != cpp_enum.FooHi {
+ panic(f.GetHola())
+ }
+
+ f.SetHola(cpp_enum.FooHello)
+
+ if f.GetHola() != cpp_enum.FooHello {
+ panic(f.GetHola())
+ }
+
+ cpp_enum.SetHi(cpp_enum.Hello)
+ if cpp_enum.GetHi() != cpp_enum.Hello {
+ panic(cpp_enum.Hi)
+ }
+}
diff --git a/Examples/test-suite/go/cpp_namespace_runme.go b/Examples/test-suite/go/cpp_namespace_runme.go
new file mode 100644
index 000000000..8482b043f
--- /dev/null
+++ b/Examples/test-suite/go/cpp_namespace_runme.go
@@ -0,0 +1,57 @@
+// Note: This example assumes that namespaces are flattened
+package main
+
+import "./cpp_namespace"
+
+func main() {
+ n := cpp_namespace.Fact(4)
+ if n != 24 {
+ panic("Bad return value!")
+ }
+
+ if cpp_namespace.GetFoo() != 42 {
+ panic("Bad variable value!")
+ }
+
+ t := cpp_namespace.NewTest()
+ if t.Method() != "Test::method" {
+ panic("Bad method return value!")
+ }
+
+ if cpp_namespace.Do_method(t) != "Test::method" {
+ panic("Bad return value!")
+ }
+
+ if cpp_namespace.Do_method2(t) != "Test::method" {
+ panic("Bad return value!")
+ }
+
+ cpp_namespace.Weird("hello", 4)
+
+ cpp_namespace.DeleteTest(t)
+
+ t2 := cpp_namespace.NewTest2()
+ t3 := cpp_namespace.NewTest3()
+ t4 := cpp_namespace.NewTest4()
+ t5 := cpp_namespace.NewTest5()
+
+ if cpp_namespace.Foo3(42) != 42 {
+ panic("Bad return value!")
+ }
+
+ if cpp_namespace.Do_method3(t2, 40) != "Test2::method" {
+ panic("Bad return value!")
+ }
+
+ if cpp_namespace.Do_method3(t3, 40) != "Test3::method" {
+ panic("Bad return value!")
+ }
+
+ if cpp_namespace.Do_method3(t4, 40) != "Test4::method" {
+ panic("Bad return value!")
+ }
+
+ if cpp_namespace.Do_method3(t5, 40) != "Test5::method" {
+ panic("Bad return value!")
+ }
+}
diff --git a/Examples/test-suite/go/cpp_static_runme.go b/Examples/test-suite/go/cpp_static_runme.go
new file mode 100644
index 000000000..ead433466
--- /dev/null
+++ b/Examples/test-suite/go/cpp_static_runme.go
@@ -0,0 +1,13 @@
+package main
+
+import . "./cpp_static"
+
+func main() {
+ StaticFunctionTestStatic_func()
+ StaticFunctionTestStatic_func_2(1)
+ StaticFunctionTestStatic_func_3(1, 2)
+ SetStaticMemberTestStatic_int(10)
+ if GetStaticMemberTestStatic_int() != 10 {
+ panic(GetStaticMemberTestStatic_int())
+ }
+}
diff --git a/Examples/test-suite/go/default_args_runme.go b/Examples/test-suite/go/default_args_runme.go
new file mode 100644
index 000000000..38243ac44
--- /dev/null
+++ b/Examples/test-suite/go/default_args_runme.go
@@ -0,0 +1,26 @@
+package main
+
+import "./default_args"
+
+func main() {
+ if default_args.StaticsStaticmethod() != 60 {
+ panic(0)
+ }
+
+ if default_args.Cfunc1(1) != 2 {
+ panic(0)
+ }
+
+ if default_args.Cfunc2(1) != 3 {
+ panic(0)
+ }
+
+ if default_args.Cfunc3(1) != 4 {
+ panic(0)
+ }
+
+ f := default_args.NewFoo()
+
+ f.Newname()
+ f.Newname(1)
+}
diff --git a/Examples/test-suite/go/default_constructor_runme.go b/Examples/test-suite/go/default_constructor_runme.go
new file mode 100644
index 000000000..e5e325475
--- /dev/null
+++ b/Examples/test-suite/go/default_constructor_runme.go
@@ -0,0 +1,35 @@
+package main
+
+import dc "./default_constructor"
+
+func main() {
+ a := dc.NewA()
+ dc.DeleteA(a)
+
+ aa := dc.NewAA()
+ dc.DeleteAA(aa)
+
+ cc := dc.NewCC()
+ dc.DeleteCC(cc)
+
+ e := dc.NewE()
+ dc.DeleteE(e)
+
+ ee := dc.NewEE()
+ dc.DeleteEE(ee)
+
+ f := dc.NewF()
+ f.Destroy()
+
+ ff := dc.NewFFF()
+ ff.Destroy()
+
+ g := dc.NewG()
+
+ dc.GDestroy(g)
+
+ gg := dc.NewGG()
+ dc.DeleteGG(gg)
+
+ dc.NewHH(1, 1)
+}
diff --git a/Examples/test-suite/go/director_abstract_runme.go b/Examples/test-suite/go/director_abstract_runme.go
new file mode 100644
index 000000000..37279383a
--- /dev/null
+++ b/Examples/test-suite/go/director_abstract_runme.go
@@ -0,0 +1,62 @@
+package main
+
+import "./director_abstract"
+
+type MyFoo struct{}
+
+func (p *MyFoo) Ping() string {
+ return "MyFoo::ping()"
+}
+
+func f1() {
+ a := director_abstract.NewDirectorFoo(&MyFoo{})
+
+ if a.Ping() != "MyFoo::ping()" {
+ panic(a.Ping())
+ }
+
+ if a.Pong() != "Foo::pong();MyFoo::ping()" {
+ panic(a.Pong())
+ }
+}
+
+type MyExample1 struct{}
+
+func (p *MyExample1) Color(r, g, b byte) int {
+ return int(r)
+}
+
+type MyExample2 struct{}
+
+func (p *MyExample2) Color(r, g, b byte) int {
+ return int(g)
+}
+
+type MyExample3 struct{}
+
+func (p *MyExample3) Color(r, g, b byte) int {
+ return int(b)
+}
+
+func f2() {
+ me1 := director_abstract.NewDirectorExample1(&MyExample1{})
+ if director_abstract.Example1Get_color(me1, 1, 2, 3) != 1 {
+ println(director_abstract.Example1Get_color(me1, 1, 2, 3))
+ panic(0)
+ }
+
+ me2 := director_abstract.NewDirectorExample2(&MyExample2{}, 1, 2)
+ if director_abstract.Example2Get_color(me2, 1, 2, 3) != 2 {
+ panic(0)
+ }
+
+ me3 := director_abstract.NewDirectorExample3_i(&MyExample3{})
+ if director_abstract.Example3_iGet_color(me3, 1, 2, 3) != 3 {
+ panic(0)
+ }
+}
+
+func main() {
+ f1()
+ f2()
+}
diff --git a/Examples/test-suite/go/director_basic_runme.go b/Examples/test-suite/go/director_basic_runme.go
new file mode 100644
index 000000000..1995452ce
--- /dev/null
+++ b/Examples/test-suite/go/director_basic_runme.go
@@ -0,0 +1,115 @@
+package main
+
+import "./director_basic"
+
+type GoFoo struct{}
+
+func (p *GoFoo) Ping() string {
+ return "GoFoo::ping()"
+}
+
+func f1() {
+ a := director_basic.NewDirectorFoo(&GoFoo{})
+
+ if a.Ping() != "GoFoo::ping()" {
+ panic(a.Ping())
+ }
+
+ if a.Pong() != "Foo::pong();GoFoo::ping()" {
+ panic(a.Pong())
+ }
+
+ b := director_basic.NewFoo()
+
+ if b.Ping() != "Foo::ping()" {
+ panic(b.Ping())
+ }
+
+ if b.Pong() != "Foo::pong();Foo::ping()" {
+ panic(b.Pong())
+ }
+
+ a1 := director_basic.NewA1(1)
+
+ if a1.Rg(2) != 2 {
+ panic(0)
+ }
+}
+
+type GoClass struct {
+ cmethod int
+}
+
+func (p *GoClass) Method(uintptr) {
+ p.cmethod = 7
+}
+func (p *GoClass) Vmethod(b director_basic.Bar) director_basic.Bar {
+ b.SetX(b.GetX() + 31)
+ return b
+}
+
+var bc director_basic.Bar
+
+func f2() {
+ b := director_basic.NewBar(3)
+ d := director_basic.NewMyClass()
+ pc := &GoClass{0}
+ c := director_basic.NewDirectorMyClass(pc)
+
+ cc := director_basic.MyClassGet_self(c)
+ dd := director_basic.MyClassGet_self(d)
+
+ bc = cc.Cmethod(b)
+ bd := dd.Cmethod(b)
+
+ cc.Method(b.Swigcptr())
+ if pc.cmethod != 7 {
+ panic(pc.cmethod)
+ }
+
+ if bc.GetX() != 34 {
+ panic(bc.GetX())
+ }
+
+ if bd.GetX() != 16 {
+ panic(bd.GetX())
+ }
+}
+
+type GoMulti struct {
+ GoClass
+}
+
+func (p *GoMulti) Vmethod(b director_basic.Bar) director_basic.Bar {
+ b.SetX(b.GetX() + 31)
+ return b
+}
+func (p *GoMulti) Ping() string {
+ return "GoFoo::ping()"
+}
+
+func f3() {
+ for i := 0; i < 100; i++ {
+ p := &GoMulti{GoClass{0}}
+ gomult := director_basic.NewDirectorFoo(p)
+ gomult.Pong()
+ director_basic.DeleteDirectorFoo(gomult)
+ }
+
+ p := &GoMulti{GoClass{0}}
+ gomult := director_basic.NewDirectorMyClass(p)
+ fgomult := director_basic.NewDirectorFoo(gomult)
+
+ p1 := director_basic.FooGet_self(fgomult.(director_basic.Foo))
+ p2 := director_basic.MyClassGet_self(gomult.(director_basic.MyClass))
+
+ p1.Ping()
+ p2.Vmethod(bc)
+}
+
+
+func main() {
+ f1()
+ f2()
+ f3()
+}
diff --git a/Examples/test-suite/go/director_classic_runme.go b/Examples/test-suite/go/director_classic_runme.go
new file mode 100644
index 000000000..45e89eac5
--- /dev/null
+++ b/Examples/test-suite/go/director_classic_runme.go
@@ -0,0 +1,135 @@
+package main
+
+import "fmt"
+import . "./director_classic"
+
+type TargetLangPerson struct{} // From Person
+func (p *TargetLangPerson) Id() string {
+ return "TargetLangPerson"
+}
+
+type TargetLangChild struct{} // Form Child
+func (p *TargetLangChild) Id() string {
+ return "TargetLangChild"
+}
+
+type TargetLangGrandChild struct{} // From Grandchild
+func (p *TargetLangGrandChild) Id() string {
+ return "TargetLangGrandChild"
+}
+
+// Semis - don't override id() in target language
+
+type TargetLangSemiPerson struct{} // From Person
+
+type TargetLangSemiChild struct{} // From Child
+
+type TargetLangSemiGrandChild struct{} // From GrandChild
+
+// Orphans - don't override id() in C++
+
+type TargetLangOrphanPerson struct{} // From OrphanPerson
+func (p *TargetLangOrphanPerson) Id() string {
+ return "TargetLangOrphanPerson"
+}
+
+type TargetLangOrphanChild struct{} // From OrphanChild
+func (p *TargetLangOrphanChild) Id() string {
+ return "TargetLangOrphanChild"
+}
+
+func check(person Person, expected string) {
+ debug := false
+
+ // Normal target language polymorphic call
+ ret := person.Id()
+ if debug {
+ fmt.Println(ret)
+ }
+ if ret != expected {
+ panic("Failed. Received: " + ret + " Expected: " + expected)
+ }
+
+ // Polymorphic call from C++
+ caller := NewCaller()
+ caller.SetCallback(person)
+ ret = caller.Call()
+ if debug {
+ fmt.Println(ret)
+ }
+ if ret != expected {
+ panic("Failed. Received: " + ret + " Expected: " + expected)
+ }
+
+ // Polymorphic call of object created in target language and
+ // passed to C++ and back again
+ baseclass := caller.BaseClass()
+ ret = baseclass.Id()
+ if debug {
+ fmt.Println(ret)
+ }
+ if ret != expected {
+ panic("Failed. Received: " + ret + " Expected: " + expected)
+ }
+
+ caller.ResetCallback()
+ if debug {
+ fmt.Println("----------------------------------------")
+ }
+}
+
+func main() {
+ person := NewPerson()
+ check(person, "Person")
+ DeletePerson(person)
+
+ person = NewChild()
+ check(person, "Child")
+ DeletePerson(person)
+
+ person = NewGrandChild()
+ check(person, "GrandChild")
+ DeletePerson(person)
+
+ person = NewDirectorPerson(&TargetLangPerson{})
+ check(person, "TargetLangPerson")
+ DeleteDirectorPerson(person)
+
+ person = NewDirectorChild(&TargetLangChild{})
+ check(person, "TargetLangChild")
+ DeleteDirectorChild(person.(Child))
+
+ person = NewDirectorGrandChild(&TargetLangGrandChild{})
+ check(person, "TargetLangGrandChild")
+ DeleteDirectorGrandChild(person.(GrandChild))
+
+ // Semis - don't override id() in target language
+ person = NewDirectorPerson(&TargetLangSemiPerson{})
+ check(person, "Person")
+ DeleteDirectorPerson(person)
+
+ person = NewDirectorChild(&TargetLangSemiChild{})
+ check(person, "Child")
+ DeleteDirectorChild(person.(Child))
+
+ person = NewDirectorGrandChild(&TargetLangSemiGrandChild{})
+ check(person, "GrandChild")
+ DeleteDirectorGrandChild(person.(GrandChild))
+
+ // Orphans - don't override id() in C++
+ person = NewOrphanPerson()
+ check(person, "Person")
+ DeleteOrphanPerson(person.(OrphanPerson))
+
+ person = NewOrphanChild()
+ check(person, "Child")
+ DeleteOrphanChild(person.(OrphanChild))
+
+ person = NewDirectorOrphanPerson(&TargetLangOrphanPerson{})
+ check(person, "TargetLangOrphanPerson")
+ DeleteDirectorOrphanPerson(person.(OrphanPerson))
+
+ person = NewDirectorOrphanChild(&TargetLangOrphanChild{})
+ check(person, "TargetLangOrphanChild")
+ DeleteDirectorOrphanChild(person.(OrphanChild))
+}
diff --git a/Examples/test-suite/go/director_default_runme.go b/Examples/test-suite/go/director_default_runme.go
new file mode 100644
index 000000000..2f963b239
--- /dev/null
+++ b/Examples/test-suite/go/director_default_runme.go
@@ -0,0 +1,11 @@
+package main
+
+import . "./director_default"
+
+func main() {
+ NewFoo()
+ NewFoo(1)
+
+ NewBar()
+ NewBar(1)
+}
diff --git a/Examples/test-suite/go/director_detect_runme.go b/Examples/test-suite/go/director_detect_runme.go
new file mode 100644
index 000000000..9f1ad94a9
--- /dev/null
+++ b/Examples/test-suite/go/director_detect_runme.go
@@ -0,0 +1,46 @@
+package main
+
+import "./director_detect"
+
+type MyBar struct {
+ val int
+} // From director_detect.Bar
+
+func NewMyBar() director_detect.Bar {
+ return director_detect.NewDirectorBar(&MyBar{2})
+}
+
+func (p *MyBar) Get_value() int {
+ p.val++
+ return p.val
+}
+
+func (p *MyBar) Get_class() director_detect.A {
+ p.val++
+ return director_detect.NewA()
+}
+
+func (p *MyBar) Just_do_it() {
+ p.val++
+}
+
+func (p *MyBar) Clone() director_detect.Bar {
+ return director_detect.NewDirectorBar(&MyBar{p.val})
+}
+
+func main() {
+ b := NewMyBar()
+
+ f := b.Baseclass()
+
+ v := f.Get_value()
+ _ = f.Get_class()
+ f.Just_do_it()
+
+ c := b.DirectorInterface().(*MyBar).Clone()
+ vc := c.Get_value()
+
+ if (v != 3) || (b.DirectorInterface().(*MyBar).val != 5) || (vc != 6) {
+ panic("Bad virtual detection")
+ }
+}
diff --git a/Examples/test-suite/go/director_enum_runme.go b/Examples/test-suite/go/director_enum_runme.go
new file mode 100644
index 000000000..e0dad900b
--- /dev/null
+++ b/Examples/test-suite/go/director_enum_runme.go
@@ -0,0 +1,17 @@
+package main
+
+import "./director_enum"
+
+type MyFoo struct{} // From director_enum.Foo
+func (p *MyFoo) Say_hi(val director_enum.EnumDirectorHelloe) director_enum.EnumDirectorHelloe {
+ return val
+}
+
+func main() {
+ b := director_enum.NewFoo()
+ a := director_enum.NewDirectorFoo(&MyFoo{})
+
+ if a.Say_hi(director_enum.Hello) != b.Say_hello(director_enum.Hi) {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/director_exception_runme.go b/Examples/test-suite/go/director_exception_runme.go
new file mode 100644
index 000000000..29df3e40b
--- /dev/null
+++ b/Examples/test-suite/go/director_exception_runme.go
@@ -0,0 +1,95 @@
+package main
+
+import . "./director_exception"
+
+type Exception struct {
+ msg string
+}
+
+func NewException(a, b string) *Exception {
+ return &Exception{a + b}
+}
+
+type MyFoo struct{} // From Foo
+func (p *MyFoo) Ping() string {
+ panic("MyFoo::ping() EXCEPTION")
+}
+
+type MyFoo2 struct{} // From Foo
+func (p *MyFoo2) Ping() bool {
+ return true // should return a string
+}
+
+type MyFoo3 struct{} // From Foo
+func (p *MyFoo3) Ping() string {
+ panic(NewException("foo", "bar"))
+}
+
+func main() {
+ // Check that the NotImplementedError raised by MyFoo.ping()
+ // is returned by MyFoo.pong().
+ ok := false
+ a := NewDirectorFoo(&MyFoo{})
+ b := Launder(a)
+ func() {
+ defer func() {
+ e := recover()
+ if e.(string) == "MyFoo::ping() EXCEPTION" {
+ ok = true
+ } else {
+ panic("Unexpected error message: " + e.(string))
+ }
+ }()
+ b.Pong()
+ }()
+ if !ok {
+ panic(0)
+ }
+
+ // Check that if the method has the wrong return type it is
+ // not called.
+ ok = false
+ a = NewDirectorFoo(&MyFoo2{})
+ b = Launder(a)
+ e := b.Pong()
+ if e != "Foo::pong();"+"Foo::ping()" {
+ panic(e)
+ }
+
+ // Check that the director can return an exception which
+ // requires two arguments to the constructor, without mangling
+ // it.
+ ok = false
+ a = NewDirectorFoo(&MyFoo3{})
+ b = Launder(a)
+ func() {
+ defer func() {
+ e := recover()
+ if e.(*Exception).msg == "foobar" {
+ ok = true
+ } else {
+ panic("Unexpected error message: " + e.(string))
+ }
+ }()
+ b.Pong()
+ }()
+ if !ok {
+ panic(0)
+ }
+
+ func() {
+ defer func() {
+ e := recover()
+ _ = e.(Exception2)
+ }()
+ panic(NewException2())
+ }()
+
+ func() {
+ defer func() {
+ e := recover()
+ _ = e.(Exception1)
+ }()
+ panic(NewException1())
+ }()
+}
diff --git a/Examples/test-suite/go/director_extend_runme.go b/Examples/test-suite/go/director_extend_runme.go
new file mode 100644
index 000000000..70e2ab41b
--- /dev/null
+++ b/Examples/test-suite/go/director_extend_runme.go
@@ -0,0 +1,18 @@
+// Test case from bug #1506850 "When threading is enabled, the
+// interpreter will infinitely wait on a mutex the second time this
+// type of extended method is called. Attached is an example program
+// that waits on the mutex to be unlocked."
+
+package main
+
+import . "./director_extend"
+
+func main() {
+ m := NewSpObject()
+ if m.Dummy() != 666 {
+ panic("1st call")
+ }
+ if m.Dummy() != 666 {
+ panic("2nd call")
+ }
+}
diff --git a/Examples/test-suite/go/director_finalizer_runme.go b/Examples/test-suite/go/director_finalizer_runme.go
new file mode 100644
index 000000000..96fcf860e
--- /dev/null
+++ b/Examples/test-suite/go/director_finalizer_runme.go
@@ -0,0 +1,37 @@
+package main
+
+import . "./director_finalizer"
+
+type MyFoo struct{} // From Foo
+func DeleteMyFoo(p Foo) {
+ p.OrStatus(2)
+ DeleteFoo(p)
+}
+
+func main() {
+ ResetStatus()
+
+ a := NewDirectorFoo(&MyFoo{})
+ DeleteMyFoo(a)
+
+ if GetStatus() != 3 {
+ panic(0)
+ }
+
+ ResetStatus()
+
+ a = NewDirectorFoo(&MyFoo{})
+ Launder(a)
+
+ if GetStatus() != 0 {
+ panic(0)
+ }
+
+ DeleteMyFoo(a)
+
+ if GetStatus() != 3 {
+ panic(0)
+ }
+
+ ResetStatus()
+}
diff --git a/Examples/test-suite/go/director_frob_runme.go b/Examples/test-suite/go/director_frob_runme.go
new file mode 100644
index 000000000..a6afedf69
--- /dev/null
+++ b/Examples/test-suite/go/director_frob_runme.go
@@ -0,0 +1,12 @@
+package main
+
+import . "./director_frob"
+
+func main() {
+ foo := NewBravo()
+ s := foo.Abs_method()
+
+ if s != "Bravo::abs_method()" {
+ panic(s)
+ }
+}
diff --git a/Examples/test-suite/go/director_nested_runme.go b/Examples/test-suite/go/director_nested_runme.go
new file mode 100644
index 000000000..2d3bc77e1
--- /dev/null
+++ b/Examples/test-suite/go/director_nested_runme.go
@@ -0,0 +1,79 @@
+package main
+
+import . "./director_nested"
+
+type A struct{} // From FooBar_int
+func (p *A) Do_step() string {
+ return "A::do_step;"
+}
+func (p *A) Get_value() string {
+ return "A::get_value"
+}
+
+func f1() {
+ a := NewDirectorFooBar_int(&A{})
+ if a.Step() != "Bar::step;Foo::advance;Bar::do_advance;A::do_step;" {
+ panic("Bad A virtual resolution")
+ }
+}
+
+type B struct{} // From FooBar_int
+func (p *B) Do_advance() string {
+ return "B::do_advance;" + p.Do_step()
+}
+func (p *B) Do_step() string {
+ return "B::do_step;"
+}
+func (p *B) Get_value() int {
+ return 1
+}
+
+func f2() {
+ b := NewDirectorFooBar_int(&B{})
+
+ if b.Step() != "Bar::step;Foo::advance;B::do_advance;B::do_step;" {
+ panic("Bad B virtual resolution")
+ }
+}
+
+type C struct {
+ fbi FooBar_int
+} // From FooBar_int
+
+func (p *C) Do_advance() string {
+ return "C::do_advance;" + DirectorFooBar_intDo_advance(p.fbi)
+}
+
+func (p *C) Do_step() string {
+ return "C::do_step;"
+}
+
+func (p *C) Get_value() int {
+ return 2
+}
+
+func (p *C) Get_name() string {
+ return DirectorFooBar_intGet_name(p.fbi) + " hello"
+}
+
+func f3() {
+ m := &C{nil}
+ cc := NewDirectorFooBar_int(m)
+ m.fbi = cc
+ c := FooBar_intGet_self(cc)
+ c.Advance()
+
+ if c.Get_name() != "FooBar::get_name hello" {
+ panic(0)
+ }
+
+ if c.Name() != "FooBar::get_name hello" {
+ panic(0)
+ }
+}
+
+func main() {
+ f1()
+ f2()
+ f3()
+}
diff --git a/Examples/test-suite/go/director_profile_runme.go b/Examples/test-suite/go/director_profile_runme.go
new file mode 100644
index 000000000..87edcbe26
--- /dev/null
+++ b/Examples/test-suite/go/director_profile_runme.go
@@ -0,0 +1,49 @@
+package main
+
+import "fmt"
+import "./director_profile"
+
+type MyB struct{} // From director_profile.B
+func (p *MyB) Vfi(a int) int {
+ return a + 3
+}
+
+func main() {
+ _ = director_profile.NewA()
+ myb := director_profile.NewDirectorB(&MyB{})
+ b := director_profile.BGet_self(myb)
+
+ fi := func(a int) int {
+ return b.Fi(a)
+ }
+
+ i := 50000
+ a := 1
+ for i != 0 {
+ a = fi(a) // 1
+ a = fi(a) // 2
+ a = fi(a) // 3
+ a = fi(a) // 4
+ a = fi(a) // 5
+ a = fi(a) // 6
+ a = fi(a) // 7
+ a = fi(a) // 8
+ a = fi(a) // 9
+ a = fi(a) // 10
+ a = fi(a) // 1
+ a = fi(a) // 2
+ a = fi(a) // 3
+ a = fi(a) // 4
+ a = fi(a) // 5
+ a = fi(a) // 6
+ a = fi(a) // 7
+ a = fi(a) // 8
+ a = fi(a) // 9
+ a = fi(a) // 20
+ i -= 1
+ }
+
+ if false {
+ fmt.Println(a)
+ }
+}
diff --git a/Examples/test-suite/go/director_protected_runme.go b/Examples/test-suite/go/director_protected_runme.go
new file mode 100644
index 000000000..3ffc1fbfa
--- /dev/null
+++ b/Examples/test-suite/go/director_protected_runme.go
@@ -0,0 +1,48 @@
+package main
+
+import . "./director_protected"
+
+type FooBar struct{} // From Bar
+func (p *FooBar) Ping() string {
+ return "FooBar::ping();"
+}
+
+type FooBar2 struct{} // From Bar
+func (p *FooBar2) Ping() string {
+ return "FooBar2::ping();"
+}
+func (p *FooBar2) Pang() string {
+ return "FooBar2::pang();"
+}
+
+func main() {
+ b := NewBar()
+ f := b.Create()
+ fb := NewDirectorBar(&FooBar{})
+ fb2 := NewDirectorBar(&FooBar2{})
+
+ s := fb.Used()
+ if s != "Foo::pang();Bar::pong();Foo::pong();FooBar::ping();" {
+ panic(0)
+ }
+
+ s = fb2.Used()
+ if s != "FooBar2::pang();Bar::pong();Foo::pong();FooBar2::ping();" {
+ panic(0)
+ }
+
+ s = b.Pong()
+ if s != "Bar::pong();Foo::pong();Bar::ping();" {
+ panic(0)
+ }
+
+ s = f.Pong()
+ if s != "Bar::pong();Foo::pong();Bar::ping();" {
+ panic(0)
+ }
+
+ s = fb.Pong()
+ if s != "Bar::pong();Foo::pong();FooBar::ping();" {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/director_string_runme.go b/Examples/test-suite/go/director_string_runme.go
new file mode 100644
index 000000000..c5201ab96
--- /dev/null
+++ b/Examples/test-suite/go/director_string_runme.go
@@ -0,0 +1,39 @@
+package main
+
+import . "./director_string"
+
+type B struct { // From A
+ abi A
+ smem string
+}
+
+func NewB(s string) A {
+ p := &B{nil, ""}
+ ret := NewDirectorA(p, s)
+ p.abi = ret
+ return ret
+}
+
+func (p *B) Get_first() string {
+ return DirectorAGet_first(p.abi) + " world!"
+}
+
+func (p *B) Process_text(s string) {
+ DirectorAProcess_text(p.abi, s)
+ p.smem = "hello"
+}
+
+func main() {
+ b := NewB("hello")
+
+ b.Get(0)
+ if b.Get_first() != "hello world!" {
+ panic(b.Get_first())
+ }
+
+ b.Call_process_func()
+
+ if b.DirectorInterface().(*B).smem != "hello" {
+ panic(b.DirectorInterface().(*B).smem)
+ }
+}
diff --git a/Examples/test-suite/go/director_thread_runme.go b/Examples/test-suite/go/director_thread_runme.go
new file mode 100644
index 000000000..ddfacedbe
--- /dev/null
+++ b/Examples/test-suite/go/director_thread_runme.go
@@ -0,0 +1,28 @@
+package main
+
+import . "./director_thread"
+
+type Derived struct {
+ abi Foo
+} // From Foo
+func (p *Derived) Do_foo() {
+ p.abi.SetVal(p.abi.GetVal() - 1)
+}
+
+func main() {
+
+ // FIXME: This test fails until we fix callbacks from a
+ // different thread.
+ return
+
+ p := &Derived{nil}
+ d := NewDirectorFoo(p)
+ p.abi = d
+ d.Run()
+
+ if d.GetVal() >= 0 {
+ panic(d.GetVal())
+ }
+
+ d.Stop()
+}
diff --git a/Examples/test-suite/go/director_unroll_runme.go b/Examples/test-suite/go/director_unroll_runme.go
new file mode 100644
index 000000000..6d2894a72
--- /dev/null
+++ b/Examples/test-suite/go/director_unroll_runme.go
@@ -0,0 +1,21 @@
+package main
+
+import "./director_unroll"
+
+type MyFoo struct{} // From director_unroll.Foo
+func (p *MyFoo) Ping() string {
+ return "MyFoo::ping()"
+}
+
+func main() {
+ a := director_unroll.NewDirectorFoo(&MyFoo{})
+
+ b := director_unroll.NewBar()
+
+ b.Set(a)
+ c := b.Get()
+
+ if c.Ping() != "MyFoo::ping()" {
+ panic(c.Ping())
+ }
+}
diff --git a/Examples/test-suite/go/disown_runme.go b/Examples/test-suite/go/disown_runme.go
new file mode 100644
index 000000000..3e853de59
--- /dev/null
+++ b/Examples/test-suite/go/disown_runme.go
@@ -0,0 +1,10 @@
+package main
+
+import . "./disown"
+
+func main() {
+ a := NewA()
+
+ b := NewB()
+ b.Acquire(a)
+}
diff --git a/Examples/test-suite/go/dynamic_cast_runme.go b/Examples/test-suite/go/dynamic_cast_runme.go
new file mode 100644
index 000000000..476734805
--- /dev/null
+++ b/Examples/test-suite/go/dynamic_cast_runme.go
@@ -0,0 +1,16 @@
+package main
+
+import "./dynamic_cast"
+
+func main() {
+ f := dynamic_cast.NewFoo()
+ b := dynamic_cast.NewBar()
+
+ _ = f.Blah()
+ y := b.Blah()
+
+ a := dynamic_cast.Do_test(dynamic_cast.FooToBar(y))
+ if a != "Bar::test" {
+ panic("Failed!!")
+ }
+}
diff --git a/Examples/test-suite/go/empty_runme.go b/Examples/test-suite/go/empty_runme.go
new file mode 100644
index 000000000..f74285cb0
--- /dev/null
+++ b/Examples/test-suite/go/empty_runme.go
@@ -0,0 +1,6 @@
+package main
+
+import _ "./empty"
+
+func main() {
+}
diff --git a/Examples/test-suite/go/enum_template_runme.go b/Examples/test-suite/go/enum_template_runme.go
new file mode 100644
index 000000000..269fe7d5b
--- /dev/null
+++ b/Examples/test-suite/go/enum_template_runme.go
@@ -0,0 +1,11 @@
+package main
+
+import "./enum_template"
+
+func main() {
+ if enum_template.MakeETest() != 1 {
+ panic(0)
+ }
+
+ enum_template.TakeETest(0)
+}
diff --git a/Examples/test-suite/go/enums_runme.go b/Examples/test-suite/go/enums_runme.go
new file mode 100644
index 000000000..ab193f74b
--- /dev/null
+++ b/Examples/test-suite/go/enums_runme.go
@@ -0,0 +1,25 @@
+package main
+
+import "./enums"
+
+func main() {
+ enums.Bar2(1)
+ enums.Bar3(1)
+ enums.Bar1(1)
+
+ if enums.GetEnumInstance() != 2 {
+ panic(0)
+ }
+
+ if enums.GetSlap() != 10 {
+ panic(0)
+ }
+
+ if enums.GetMine() != 11 {
+ panic(0)
+ }
+
+ if enums.GetThigh() != 12 {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/exception_order_runme.go b/Examples/test-suite/go/exception_order_runme.go
new file mode 100644
index 000000000..626a826f8
--- /dev/null
+++ b/Examples/test-suite/go/exception_order_runme.go
@@ -0,0 +1,58 @@
+package main
+
+import "strings"
+import . "./exception_order"
+
+func main() {
+ a := NewA()
+
+ func() {
+ defer func() {
+ e := recover()
+ if strings.Index(e.(string), "E1") == -1 {
+ panic(e.(string))
+ }
+ }()
+ a.Foo()
+ }()
+
+ func() {
+ defer func() {
+ e := recover()
+ if strings.Index(e.(string), "E2") == -1 {
+ panic(e.(string))
+ }
+ }()
+ a.Bar()
+ }()
+
+ func() {
+ defer func() {
+ e := recover()
+ if e.(string) != "postcatch unknown" {
+ panic("bad exception order")
+ }
+ }()
+ a.Foobar()
+ }()
+
+ func() {
+ defer func() {
+ e := recover()
+ if strings.Index(e.(string), "E1") == -1 {
+ panic(e.(string))
+ }
+ }()
+ a.Barfoo(1)
+ }()
+
+ func() {
+ defer func() {
+ e := recover()
+ if strings.Index(e.(string), "E2") == -1 {
+ panic(e.(string))
+ }
+ }()
+ a.Barfoo(2)
+ }()
+}
diff --git a/Examples/test-suite/go/extend_placement_runme.go b/Examples/test-suite/go/extend_placement_runme.go
new file mode 100644
index 000000000..f74831c7d
--- /dev/null
+++ b/Examples/test-suite/go/extend_placement_runme.go
@@ -0,0 +1,47 @@
+package main
+
+import "./extend_placement"
+
+func main() {
+ foo := extend_placement.NewFoo()
+ foo = extend_placement.NewFoo(1)
+ foo = extend_placement.NewFoo(1, 1)
+ foo.Spam()
+ foo.Spam("hello")
+ foo.Spam(1)
+ foo.Spam(1, 1)
+ foo.Spam(1, 1, 1)
+ foo.Spam(extend_placement.NewFoo())
+ foo.Spam(extend_placement.NewFoo(), float64(1.0))
+
+ bar := extend_placement.NewBar()
+ bar = extend_placement.NewBar(1)
+ bar.Spam()
+ bar.Spam("hello")
+ bar.Spam(1)
+ bar.Spam(1, 1)
+ bar.Spam(1, 1, 1)
+ bar.Spam(extend_placement.NewBar())
+ bar.Spam(extend_placement.NewBar(), float64(1.0))
+
+ footi := extend_placement.NewFooTi()
+ footi = extend_placement.NewFooTi(1)
+ footi = extend_placement.NewFooTi(1, 1)
+ footi.Spam()
+ footi.Spam("hello")
+ footi.Spam(1)
+ footi.Spam(1, 1)
+ footi.Spam(1, 1, 1)
+ footi.Spam(extend_placement.NewFoo())
+ footi.Spam(extend_placement.NewFoo(), float64(1.0))
+
+ barti := extend_placement.NewBarTi()
+ barti = extend_placement.NewBarTi(1)
+ barti.Spam()
+ barti.Spam("hello")
+ barti.Spam(1)
+ barti.Spam(1, 1)
+ barti.Spam(1, 1, 1)
+ barti.Spam(extend_placement.NewBar())
+ barti.Spam(extend_placement.NewBar(), float64(1.0))
+}
diff --git a/Examples/test-suite/go/extend_template_ns_runme.go b/Examples/test-suite/go/extend_template_ns_runme.go
new file mode 100644
index 000000000..164a31b26
--- /dev/null
+++ b/Examples/test-suite/go/extend_template_ns_runme.go
@@ -0,0 +1,14 @@
+package main
+
+import . "./extend_template_ns"
+
+func main() {
+ f := NewFoo_One()
+ if f.Test1(37) != 37 {
+ panic(0)
+ }
+
+ if f.Test2(42) != 42 {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/extend_template_runme.go b/Examples/test-suite/go/extend_template_runme.go
new file mode 100644
index 000000000..5adb4b3c2
--- /dev/null
+++ b/Examples/test-suite/go/extend_template_runme.go
@@ -0,0 +1,14 @@
+package main
+
+import "./extend_template"
+
+func main() {
+ f := extend_template.NewFoo_0()
+ if f.Test1(37) != 37 {
+ panic(0)
+ }
+
+ if f.Test2(42) != 42 {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/extend_variable_runme.go b/Examples/test-suite/go/extend_variable_runme.go
new file mode 100644
index 000000000..c6428c467
--- /dev/null
+++ b/Examples/test-suite/go/extend_variable_runme.go
@@ -0,0 +1,9 @@
+package main
+
+import . "./extend_variable"
+
+func main() {
+ if FooBar != 42 {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/extern_c_runme.go b/Examples/test-suite/go/extern_c_runme.go
new file mode 100644
index 000000000..0fb5b21cc
--- /dev/null
+++ b/Examples/test-suite/go/extern_c_runme.go
@@ -0,0 +1,7 @@
+package main
+
+import "./extern_c"
+
+func main() {
+ extern_c.RealFunction(2)
+}
diff --git a/Examples/test-suite/go/friends_runme.go b/Examples/test-suite/go/friends_runme.go
new file mode 100644
index 000000000..80177bae8
--- /dev/null
+++ b/Examples/test-suite/go/friends_runme.go
@@ -0,0 +1,50 @@
+package main
+
+import "./friends"
+
+func main() {
+ a := friends.NewA(2)
+
+ if friends.Get_val1(a).(int) != 2 {
+ panic(0)
+ }
+ if friends.Get_val2(a) != 4 {
+ panic(0)
+ }
+ if friends.Get_val3(a) != 6 {
+ panic(0)
+ }
+
+ // nice overload working fine
+ if friends.Get_val1(1, 2, 3).(int) != 1 {
+ panic(0)
+ }
+
+ b := friends.NewB(3)
+
+ // David's case
+ if friends.Mix(a, b) != 5 {
+ panic(0)
+ }
+
+ di := friends.NewD_d(2)
+ dd := friends.NewD_d(3.3)
+
+ // incredible template overloading working just fine
+ if friends.Get_val1(di).(float64) != 2 {
+ panic(0)
+ }
+ if friends.Get_val1(dd).(float64) != 3.3 {
+ panic(0)
+ }
+
+ friends.Set(di, float64(4.0))
+ friends.Set(dd, float64(1.3))
+
+ if friends.Get_val1(di).(float64) != 4 {
+ panic(0)
+ }
+ if friends.Get_val1(dd).(float64) != 1.3 {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/fvirtual_runme.go b/Examples/test-suite/go/fvirtual_runme.go
new file mode 100644
index 000000000..8810d5cbb
--- /dev/null
+++ b/Examples/test-suite/go/fvirtual_runme.go
@@ -0,0 +1,13 @@
+package main
+
+import . "./fvirtual"
+
+func main() {
+ sw := NewNodeSwitch()
+ n := NewNode()
+ i := sw.AddChild(n)
+
+ if i != 2 {
+ panic("addChild")
+ }
+}
diff --git a/Examples/test-suite/go/global_ns_arg_runme.go b/Examples/test-suite/go/global_ns_arg_runme.go
new file mode 100644
index 000000000..f4c8a7ed5
--- /dev/null
+++ b/Examples/test-suite/go/global_ns_arg_runme.go
@@ -0,0 +1,8 @@
+package main
+
+import . "./global_ns_arg"
+
+func main() {
+ Foo(1)
+ Bar()
+}
diff --git a/Examples/test-suite/go/grouping_runme.go b/Examples/test-suite/go/grouping_runme.go
new file mode 100644
index 000000000..c63d6fb12
--- /dev/null
+++ b/Examples/test-suite/go/grouping_runme.go
@@ -0,0 +1,19 @@
+package main
+
+import "./grouping"
+
+func main() {
+ x := grouping.Test1(42)
+ if x != 42 {
+ panic(0)
+ }
+
+ grouping.Test2(42)
+
+ x = grouping.Do_unary(37, grouping.NEGATE)
+ if x != -37 {
+ panic(0)
+ }
+
+ grouping.SetTest3(42)
+}
diff --git a/Examples/test-suite/go/import_nomodule_runme.go b/Examples/test-suite/go/import_nomodule_runme.go
new file mode 100644
index 000000000..a6bbd7de5
--- /dev/null
+++ b/Examples/test-suite/go/import_nomodule_runme.go
@@ -0,0 +1,12 @@
+package main
+
+import . "./import_nomodule"
+
+func main() {
+ f := Create_Foo()
+ Test1(f, 42)
+ Delete_Foo(f)
+
+ b := NewBar()
+ Test1(b, 37)
+}
diff --git a/Examples/test-suite/go/imports_runme.go b/Examples/test-suite/go/imports_runme.go
new file mode 100644
index 000000000..896036cbf
--- /dev/null
+++ b/Examples/test-suite/go/imports_runme.go
@@ -0,0 +1,17 @@
+// This is the import runtime testcase.
+
+package main
+
+import "imports_b"
+import "imports_a"
+
+func main() {
+ x := imports_b.NewB()
+ x.Hello()
+
+ _ = imports_a.NewA()
+
+ c := imports_b.NewC()
+ _ = c.Get_a(c)
+ _ = c.Get_a_type(c)
+}
diff --git a/Examples/test-suite/go/inctest_runme.go b/Examples/test-suite/go/inctest_runme.go
new file mode 100644
index 000000000..f8a2c116c
--- /dev/null
+++ b/Examples/test-suite/go/inctest_runme.go
@@ -0,0 +1,18 @@
+package main
+
+import "./inctest"
+
+func main() {
+ inctest.NewA()
+ inctest.NewB()
+
+ // Check the import in subdirectory worked
+ if inctest.Importtest1(5) != 15 {
+ panic("import test 1 failed")
+ }
+
+ a := []byte("black")
+ if inctest.Importtest2(string(a)) != "white" {
+ panic("import test 2 failed")
+ }
+}
diff --git a/Examples/test-suite/go/inherit_missing_runme.go b/Examples/test-suite/go/inherit_missing_runme.go
new file mode 100644
index 000000000..ba9a2a516
--- /dev/null
+++ b/Examples/test-suite/go/inherit_missing_runme.go
@@ -0,0 +1,26 @@
+package main
+
+import "./inherit_missing"
+
+func main() {
+ a := inherit_missing.New_Foo()
+ b := inherit_missing.NewBar()
+ c := inherit_missing.NewSpam()
+
+ x := inherit_missing.Do_blah(a)
+ if x != "Foo::blah" {
+ panic(x)
+ }
+
+ x = inherit_missing.Do_blah(b)
+ if x != "Bar::blah" {
+ panic(x)
+ }
+
+ x = inherit_missing.Do_blah(c)
+ if x != "Spam::blah" {
+ panic(x)
+ }
+
+ inherit_missing.Delete_Foo(a)
+}
diff --git a/Examples/test-suite/go/input_runme.go b/Examples/test-suite/go/input_runme.go
new file mode 100644
index 000000000..207bdaa28
--- /dev/null
+++ b/Examples/test-suite/go/input_runme.go
@@ -0,0 +1,14 @@
+package main
+
+import . "./input"
+
+func main() {
+ f := NewFoo()
+ if f.Foo(2) != 4 {
+ panic(0)
+ }
+
+ if Sfoo("Hello") != "Hello world" {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/keyword_rename_runme.go b/Examples/test-suite/go/keyword_rename_runme.go
new file mode 100644
index 000000000..e36bc5968
--- /dev/null
+++ b/Examples/test-suite/go/keyword_rename_runme.go
@@ -0,0 +1,8 @@
+package main
+
+import "./keyword_rename"
+
+func main() {
+ keyword_rename.Xgo(1)
+ keyword_rename.Xchan(1)
+}
diff --git a/Examples/test-suite/go/li_attribute_runme.go b/Examples/test-suite/go/li_attribute_runme.go
new file mode 100644
index 000000000..5d2c3d0c3
--- /dev/null
+++ b/Examples/test-suite/go/li_attribute_runme.go
@@ -0,0 +1,90 @@
+package main
+
+import "./li_attribute"
+
+func main() {
+ aa := li_attribute.NewA(1, 2, 3)
+
+ if aa.GetA() != 1 {
+ panic(0)
+ }
+ aa.SetA(3)
+ if aa.GetA() != 3 {
+ panic(aa.GetA())
+ }
+
+ if aa.GetB() != 2 {
+ panic(aa.GetB())
+ }
+ aa.SetB(5)
+ if aa.GetB() != 5 {
+ panic(0)
+ }
+
+ if aa.GetD() != aa.GetB() {
+ panic(0)
+ }
+
+ if aa.GetC() != 3 {
+ panic(0)
+ }
+
+ pi := li_attribute.NewParam_i(7)
+ if pi.GetValue() != 7 {
+ panic(0)
+ }
+ pi.SetValue(3)
+ if pi.GetValue() != 3 {
+ panic(0)
+ }
+
+ b := li_attribute.NewB(aa)
+
+ if b.GetA().GetC() != 3 {
+ panic(0)
+ }
+
+ // class/struct attribute with get/set methods using
+ // return/pass by reference
+ myFoo := li_attribute.NewMyFoo()
+ myFoo.SetX(8)
+ myClass := li_attribute.NewMyClass()
+ myClass.SetFoo(myFoo)
+ if myClass.GetFoo().GetX() != 8 {
+ panic(0)
+ }
+
+ // class/struct attribute with get/set methods using
+ // return/pass by value
+ myClassVal := li_attribute.NewMyClassVal()
+ if myClassVal.GetReadWriteFoo().GetX() != -1 {
+ panic(0)
+ }
+ if myClassVal.GetReadOnlyFoo().GetX() != -1 {
+ panic(0)
+ }
+ myClassVal.SetReadWriteFoo(myFoo)
+ if myClassVal.GetReadWriteFoo().GetX() != 8 {
+ panic(0)
+ }
+ if myClassVal.GetReadOnlyFoo().GetX() != 8 {
+ panic(0)
+ }
+
+ // string attribute with get/set methods using return/pass by
+ // value
+ myStringyClass := li_attribute.NewMyStringyClass("initial string")
+ if myStringyClass.GetReadWriteString() != "initial string" {
+ panic(0)
+ }
+ if myStringyClass.GetReadOnlyString() != "initial string" {
+ panic(0)
+ }
+ myStringyClass.SetReadWriteString("changed string")
+ if myStringyClass.GetReadWriteString() != "changed string" {
+ panic(0)
+ }
+ if myStringyClass.GetReadOnlyString() != "changed string" {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/li_carrays_runme.go b/Examples/test-suite/go/li_carrays_runme.go
new file mode 100644
index 000000000..0cbe92cd8
--- /dev/null
+++ b/Examples/test-suite/go/li_carrays_runme.go
@@ -0,0 +1,14 @@
+package main
+
+import . "./li_carrays"
+
+func main() {
+ d := NewDoubleArray(10)
+
+ d.Setitem(0, 7)
+ d.Setitem(5, d.Getitem(0)+3)
+
+ if d.Getitem(5)+d.Getitem(0) != 17 {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/li_cdata_runme.go b/Examples/test-suite/go/li_cdata_runme.go
new file mode 100644
index 000000000..f71a3a2c3
--- /dev/null
+++ b/Examples/test-suite/go/li_cdata_runme.go
@@ -0,0 +1,13 @@
+package main
+
+import . "./li_cdata"
+
+func main() {
+ s := "ABC abc"
+ m := Malloc(256)
+ Memmove(m, s, len(s))
+ ss := Cdata(m, 7)
+ if string(ss) != "ABC abc" {
+ panic("failed")
+ }
+}
diff --git a/Examples/test-suite/go/li_cmalloc_runme.go b/Examples/test-suite/go/li_cmalloc_runme.go
new file mode 100644
index 000000000..45f47b45f
--- /dev/null
+++ b/Examples/test-suite/go/li_cmalloc_runme.go
@@ -0,0 +1,25 @@
+package main
+
+import . "./li_cmalloc"
+
+func main() {
+ p := Malloc_int()
+ Free_int(p)
+
+ ok := false
+ func() {
+ defer func() {
+ if recover() != nil {
+ ok = true
+ }
+ }()
+ p = Calloc_int(-1)
+ if p == nil {
+ ok = true
+ }
+ Free_int(p)
+ }()
+ if !ok {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/li_cpointer_runme.go b/Examples/test-suite/go/li_cpointer_runme.go
new file mode 100644
index 000000000..57493b122
--- /dev/null
+++ b/Examples/test-suite/go/li_cpointer_runme.go
@@ -0,0 +1,14 @@
+package main
+
+import . "./li_cpointer"
+
+func main() {
+ p := New_intp()
+ Intp_assign(p, 3)
+
+ if Intp_value(p) != 3 {
+ panic(0)
+ }
+
+ Delete_intp(p)
+}
diff --git a/Examples/test-suite/go/li_std_map_runme.go b/Examples/test-suite/go/li_std_map_runme.go
new file mode 100644
index 000000000..66e74dd60
--- /dev/null
+++ b/Examples/test-suite/go/li_std_map_runme.go
@@ -0,0 +1,30 @@
+package main
+
+import "./li_std_map"
+
+func main() {
+ a1 := li_std_map.NewA(3)
+ a2 := li_std_map.NewA(7)
+
+ _ = li_std_map.NewPairii(1, 2)
+ p1 := li_std_map.NewPairA(1, a1)
+ m := li_std_map.NewMapA()
+ m.Set(1, a1)
+ m.Set(2, a2)
+
+ _ = li_std_map.P_identa(p1)
+ _ = li_std_map.M_identa(m)
+
+ m = li_std_map.NewMapA()
+ m.Set(1, a1)
+ m.Set(2, a2)
+
+ mii := li_std_map.NewIntIntMap()
+
+ mii.Set(1, 1)
+ mii.Set(1, 2)
+
+ if mii.Get(1) != 2 {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/member_pointer_runme.go b/Examples/test-suite/go/member_pointer_runme.go
new file mode 100644
index 000000000..9a55bc4b9
--- /dev/null
+++ b/Examples/test-suite/go/member_pointer_runme.go
@@ -0,0 +1,49 @@
+// Example using pointers to member functions
+
+package main
+
+import "fmt"
+import . "./member_pointer"
+
+func check(what string, expected float64, actual float64) {
+ if expected != actual {
+ panic(fmt.Sprintf("Failed: %s Expected: %f Actual; %f", what, expected, actual))
+ }
+}
+
+func main() {
+ // Get the pointers
+
+ area_pt := Areapt()
+ perim_pt := Perimeterpt()
+
+ // Create some objects
+
+ s := NewSquare(10)
+
+ // Do some calculations
+
+ check("Square area ", 100.0, Do_op(s, area_pt))
+ check("Square perim", 40.0, Do_op(s, perim_pt))
+
+ _ = GetAreavar()
+ _ = GetPerimetervar()
+
+ // Try the variables
+ check("Square area ", 100.0, Do_op(s, GetAreavar()))
+ check("Square perim", 40.0, Do_op(s, GetPerimetervar()))
+
+ // Modify one of the variables
+ SetAreavar(perim_pt)
+
+ check("Square perimeter", 40.0, Do_op(s, GetAreavar()))
+
+ // Try the constants
+
+ _ = AREAPT
+ _ = PERIMPT
+ _ = NULLPT
+
+ check("Square area ", 100.0, Do_op(s, AREAPT))
+ check("Square perim", 40.0, Do_op(s, PERIMPT))
+}
diff --git a/Examples/test-suite/go/memberin_extend_c_runme.go b/Examples/test-suite/go/memberin_extend_c_runme.go
new file mode 100644
index 000000000..ec8b11e60
--- /dev/null
+++ b/Examples/test-suite/go/memberin_extend_c_runme.go
@@ -0,0 +1,11 @@
+package main
+
+import "./memberin_extend_c"
+
+func main() {
+ t := memberin_extend_c.NewPerson()
+ t.SetName("Fred Bloggs")
+ if t.GetName() != "FRED BLOGGS" {
+ panic("name wrong")
+ }
+}
diff --git a/Examples/test-suite/go/minherit_runme.go b/Examples/test-suite/go/minherit_runme.go
new file mode 100644
index 000000000..c69fe92c1
--- /dev/null
+++ b/Examples/test-suite/go/minherit_runme.go
@@ -0,0 +1,82 @@
+package main
+
+import "fmt"
+import "./minherit"
+
+func main() {
+ a := minherit.NewFoo()
+ b := minherit.NewBar()
+ c := minherit.NewFooBar()
+ d := minherit.NewSpam()
+
+ if a.Xget() != 1 {
+ panic("1 Bad attribute value")
+ }
+
+ if b.Yget() != 2 {
+ panic("2 Bad attribute value")
+ }
+
+ if c.Xget() != 1 || c.Yget() != 2 || c.Zget() != 3 {
+ panic("3 Bad attribute value")
+ }
+
+ if d.Xget() != 1 || d.Yget() != 2 || d.Zget() != 3 || d.Wget() != 4 {
+ panic("4 Bad attribute value")
+ }
+
+ if minherit.Xget(a) != 1 {
+ panic(fmt.Sprintf("5 Bad attribute value %d", minherit.Xget(a)))
+ }
+
+ if minherit.Yget(b) != 2 {
+ panic(fmt.Sprintf("6 Bad attribute value %d", minherit.Yget(b)))
+ }
+
+ if minherit.Xget(c) != 1 || minherit.Yget(c.SwigGetBar()) != 2 || minherit.Zget(c) != 3 {
+ panic(fmt.Sprintf("7 Bad attribute value %d %d %d", minherit.Xget(c), minherit.Yget(c.SwigGetBar()), minherit.Zget(c)))
+ }
+
+ if minherit.Xget(d) != 1 || minherit.Yget(d.SwigGetBar()) != 2 || minherit.Zget(d) != 3 || minherit.Wget(d) != 4 {
+ panic(fmt.Sprintf("8 Bad attribute value %d %d %d %d", minherit.Xget(d), minherit.Yget(d.SwigGetBar()), minherit.Zget(d), minherit.Wget(d)))
+ }
+
+ // Cleanse all of the pointers and see what happens
+
+ aa := minherit.ToFooPtr(a)
+ bb := minherit.ToBarPtr(b)
+ cc := minherit.ToFooBarPtr(c)
+ dd := minherit.ToSpamPtr(d)
+
+ if aa.Xget() != 1 {
+ panic("9 Bad attribute value")
+ }
+
+ if bb.Yget() != 2 {
+ panic("10 Bad attribute value")
+ }
+
+ if cc.Xget() != 1 || cc.Yget() != 2 || cc.Zget() != 3 {
+ panic("11 Bad attribute value")
+ }
+
+ if dd.Xget() != 1 || dd.Yget() != 2 || dd.Zget() != 3 || dd.Wget() != 4 {
+ panic("12 Bad attribute value")
+ }
+
+ if minherit.Xget(aa) != 1 {
+ panic(fmt.Sprintf("13 Bad attribute value %d", minherit.Xget(aa)))
+ }
+
+ if minherit.Yget(bb) != 2 {
+ panic(fmt.Sprintf("14 Bad attribute value %d", minherit.Yget(bb)))
+ }
+
+ if minherit.Xget(cc) != 1 || minherit.Yget(cc.SwigGetBar()) != 2 || minherit.Zget(cc) != 3 {
+ panic(fmt.Sprintf("15 Bad attribute value %d %d %d", minherit.Xget(cc), minherit.Yget(cc.SwigGetBar()), minherit.Zget(cc)))
+ }
+
+ if minherit.Xget(dd) != 1 || minherit.Yget(dd.SwigGetBar()) != 2 || minherit.Zget(dd) != 3 || minherit.Wget(dd) != 4 {
+ panic(fmt.Sprintf("16 Bad attribute value %d %d %d %d", minherit.Xget(dd), minherit.Yget(dd.SwigGetBar()), minherit.Zget(dd), minherit.Wget(dd)))
+ }
+}
diff --git a/Examples/test-suite/go/mod_runme.go b/Examples/test-suite/go/mod_runme.go
new file mode 100644
index 000000000..581c83918
--- /dev/null
+++ b/Examples/test-suite/go/mod_runme.go
@@ -0,0 +1,10 @@
+package main
+
+import "mod_a"
+import "mod_b"
+
+func main() {
+ c := mod_b.NewC()
+ d := mod_b.NewD()
+ d.DoSomething(mod_a.SwigcptrA(c.Swigcptr()))
+}
diff --git a/Examples/test-suite/go/multi_import_runme.go b/Examples/test-suite/go/multi_import_runme.go
new file mode 100644
index 000000000..973af1e7b
--- /dev/null
+++ b/Examples/test-suite/go/multi_import_runme.go
@@ -0,0 +1,29 @@
+package main
+
+import "multi_import_a"
+import "multi_import_b"
+
+func main() {
+ x := multi_import_b.NewXXX()
+ if x.Testx() != 0 {
+ panic(0)
+ }
+
+ y := multi_import_b.NewYYY()
+ if y.Testx() != 0 {
+ panic(0)
+ }
+ if y.Testy() != 1 {
+ panic(0)
+ }
+
+ z := multi_import_a.NewZZZ()
+ if z.Testx() != 0 {
+ println("z.Testx", z.Testx(), z.Testz())
+ panic(0)
+ }
+ if z.Testz() != 2 {
+ println("z.Testz", z.Testz())
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/namespace_class_runme.go b/Examples/test-suite/go/namespace_class_runme.go
new file mode 100644
index 000000000..2ed5567f7
--- /dev/null
+++ b/Examples/test-suite/go/namespace_class_runme.go
@@ -0,0 +1,19 @@
+package main
+
+import . "./namespace_class"
+
+func main() {
+ EulerT3DToFrame(1, 1, 1)
+
+ _ = NewBooT_i()
+ _ = NewBooT_H()
+
+ f1 := NewFooT_i()
+ f1.Quack(1)
+
+ f2 := NewFooT_d()
+ f2.Moo(1)
+
+ f3 := NewFooT_H()
+ f3.Foo(Hi)
+}
diff --git a/Examples/test-suite/go/namespace_typemap_runme.go b/Examples/test-suite/go/namespace_typemap_runme.go
new file mode 100644
index 000000000..95311a37a
--- /dev/null
+++ b/Examples/test-suite/go/namespace_typemap_runme.go
@@ -0,0 +1,116 @@
+package main
+
+import . "./namespace_typemap"
+
+func main() {
+ if Stest1("hello") != "hello" {
+ panic(0)
+ }
+
+ if Stest2("hello") != "hello" {
+ panic(0)
+ }
+
+ if Stest3("hello") != "hello" {
+ panic(0)
+ }
+
+ if Stest4("hello") != "hello" {
+ panic(0)
+ }
+
+ if Stest5("hello") != "hello" {
+ panic(0)
+ }
+
+ if Stest6("hello") != "hello" {
+ panic(0)
+ }
+
+ if Stest7("hello") != "hello" {
+ panic(0)
+ }
+
+ if Stest8("hello") != "hello" {
+ panic(0)
+ }
+
+ if Stest9("hello") != "hello" {
+ panic(0)
+ }
+
+ if Stest10("hello") != "hello" {
+ panic(0)
+ }
+
+ if Stest11("hello") != "hello" {
+ panic(0)
+ }
+
+ if Stest12("hello") != "hello" {
+ panic(0)
+ }
+
+ c := cmplx(float64(2), float64(3))
+ r := real(c)
+
+ if Ctest1(c) != r {
+ println(Ctest1(c))
+ panic(Ctest1(c))
+ }
+
+ if Ctest2(c) != r {
+ panic(0)
+ }
+
+ if Ctest3(c) != r {
+ panic(0)
+ }
+
+ if Ctest4(c) != r {
+ panic(0)
+ }
+
+ if Ctest5(c) != r {
+ panic(0)
+ }
+
+ if Ctest6(c) != r {
+ panic(0)
+ }
+
+ if Ctest7(c) != r {
+ panic(0)
+ }
+
+ if Ctest8(c) != r {
+ panic(0)
+ }
+
+ if Ctest9(c) != r {
+ panic(0)
+ }
+
+ if Ctest10(c) != r {
+ panic(0)
+ }
+
+ if Ctest11(c) != r {
+ panic(0)
+ }
+
+ if Ctest12(c) != r {
+ panic(0)
+ }
+
+ ok := false
+ func() {
+ defer func() {
+ ok = recover() != nil
+ }()
+ Ttest1(-14)
+ }()
+ if !ok {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/namespace_virtual_method_runme.go b/Examples/test-suite/go/namespace_virtual_method_runme.go
new file mode 100644
index 000000000..3f8e774c6
--- /dev/null
+++ b/Examples/test-suite/go/namespace_virtual_method_runme.go
@@ -0,0 +1,7 @@
+package main
+
+import "./namespace_virtual_method"
+
+func main() {
+ _ = namespace_virtual_method.NewSpam()
+}
diff --git a/Examples/test-suite/go/naturalvar_runme.go b/Examples/test-suite/go/naturalvar_runme.go
new file mode 100644
index 000000000..e3723e6ab
--- /dev/null
+++ b/Examples/test-suite/go/naturalvar_runme.go
@@ -0,0 +1,17 @@
+package main
+
+import . "./naturalvar"
+
+func main() {
+ f := NewFoo()
+ b := NewBar()
+
+ b.SetF(f)
+
+ SetS("hello")
+ b.SetS("hello")
+
+ if b.GetS() != GetS() {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/nested_workaround_runme.go b/Examples/test-suite/go/nested_workaround_runme.go
new file mode 100644
index 000000000..5737aaaf7
--- /dev/null
+++ b/Examples/test-suite/go/nested_workaround_runme.go
@@ -0,0 +1,19 @@
+package main
+
+import . "./nested_workaround"
+
+func main() {
+ inner := NewInner(5)
+ outer := NewOuter()
+ newInner := outer.DoubleInnerValue(inner)
+ if newInner.GetValue() != 10 {
+ panic(0)
+ }
+
+ outer = NewOuter()
+ inner = outer.CreateInner(3)
+ newInner = outer.DoubleInnerValue(inner)
+ if outer.GetInnerValue(newInner) != 6 {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/overload_complicated_runme.go b/Examples/test-suite/go/overload_complicated_runme.go
new file mode 100644
index 000000000..e3911c218
--- /dev/null
+++ b/Examples/test-suite/go/overload_complicated_runme.go
@@ -0,0 +1,62 @@
+package main
+
+import . "./overload_complicated"
+
+func main() {
+ var pInt *int
+
+ // Check the correct constructors are available
+ p := NewPop(pInt)
+
+ p = NewPop(pInt, false)
+
+ // Check overloaded in const only and pointers/references
+ // which target languages cannot disambiguate
+ if p.Hip(false) != 701 {
+ panic("Test 1 failed")
+ }
+
+ if p.Hip(pInt) != 702 {
+ panic("Test 2 failed")
+ }
+
+ // Reverse the order for the above
+ if p.Hop(pInt) != 805 {
+ panic("Test 3 failed")
+ }
+
+ if p.Hop(false) != 801 {
+ panic("Test 4 failed")
+ }
+
+ // Few more variations and order shuffled
+ if p.Pop(false) != 901 {
+ panic("Test 5 failed")
+ }
+
+ if p.Pop(pInt) != 902 {
+ panic("Test 6 failed")
+ }
+
+ if p.Pop() != 905 {
+ panic("Test 7 failed")
+ }
+
+ // Overload on const only
+ if p.Bop(pInt) != 1001 {
+ panic("Test 8 failed")
+ }
+
+ if p.Bip(pInt) != 2001 {
+ panic("Test 9 failed")
+ }
+
+ // Globals
+ if Muzak(false) != 3001 {
+ panic("Test 10 failed")
+ }
+
+ if Muzak(pInt) != 3002 {
+ panic("Test 11 failed")
+ }
+}
diff --git a/Examples/test-suite/go/overload_copy_runme.go b/Examples/test-suite/go/overload_copy_runme.go
new file mode 100644
index 000000000..d35ff70b1
--- /dev/null
+++ b/Examples/test-suite/go/overload_copy_runme.go
@@ -0,0 +1,8 @@
+package main
+
+import . "./overload_copy"
+
+func main() {
+ f := NewFoo()
+ _ = NewFoo(f)
+}
diff --git a/Examples/test-suite/go/overload_extend_runme.go b/Examples/test-suite/go/overload_extend_runme.go
new file mode 100644
index 000000000..228dfe89c
--- /dev/null
+++ b/Examples/test-suite/go/overload_extend_runme.go
@@ -0,0 +1,22 @@
+package main
+
+import "./overload_extend"
+
+func main() {
+ f := overload_extend.NewFoo()
+ if f.Test().(int) != 0 {
+ panic(0)
+ }
+ if f.Test(3).(int) != 1 {
+ panic(0)
+ }
+ if f.Test("hello").(int) != 2 {
+ panic(0)
+ }
+ if f.Test(float64(3), float64(2)).(float64) != 5 {
+ panic(0)
+ }
+ if f.Test(float64(3.0)).(float64) != 1003 {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/overload_extendc_runme.go b/Examples/test-suite/go/overload_extendc_runme.go
new file mode 100644
index 000000000..aec8935f5
--- /dev/null
+++ b/Examples/test-suite/go/overload_extendc_runme.go
@@ -0,0 +1,33 @@
+package main
+
+import "./overload_extendc"
+
+func main() {
+ f := overload_extendc.NewFoo()
+ if f.Test(3) != 1 {
+ panic(0)
+ }
+ if f.Test("hello") != 2 {
+ panic(0)
+ }
+ if f.Test(float64(3.5), float64(2.5)) != 3 {
+ panic(0)
+ }
+ if f.Test("hello", 20) != 1020 {
+ panic(0)
+ }
+ if f.Test("hello", 20, 100) != 120 {
+ panic(0)
+ }
+
+ // C default args
+ if f.Test(f) != 30 {
+ panic(0)
+ }
+ if f.Test(f, 100) != 120 {
+ panic(0)
+ }
+ if f.Test(f, 100, 200) != 300 {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/overload_rename_runme.go b/Examples/test-suite/go/overload_rename_runme.go
new file mode 100644
index 000000000..dca5843c3
--- /dev/null
+++ b/Examples/test-suite/go/overload_rename_runme.go
@@ -0,0 +1,10 @@
+package main
+
+import "./overload_rename"
+
+func main() {
+ _ = overload_rename.NewFoo(float32(1))
+ _ = overload_rename.NewFoo(float32(1), float32(1))
+ _ = overload_rename.NewFoo_int(float32(1), 1)
+ _ = overload_rename.NewFoo_int(float32(1), 1, float32(1))
+}
diff --git a/Examples/test-suite/go/overload_simple_runme.go b/Examples/test-suite/go/overload_simple_runme.go
new file mode 100644
index 000000000..58fe46dab
--- /dev/null
+++ b/Examples/test-suite/go/overload_simple_runme.go
@@ -0,0 +1,125 @@
+package main
+
+import . "./overload_simple"
+
+func main() {
+ if Foofn(3) != "foo:int" {
+ panic("foo(int)")
+ }
+
+ if Foofn(float64(3.0)) != "foo:double" {
+ panic("foo(double)")
+ }
+
+ if Foofn("hello") != "foo:char *" {
+ panic("foo(char *)")
+ }
+
+ f := NewFoo()
+ b := NewBar()
+
+ if Foofn(f) != "foo:Foo *" {
+ panic("foo(Foo *)")
+ }
+
+ if Foofn(b) != "foo:Bar *" {
+ panic("foo(Bar *)")
+ }
+
+ v := Malloc_void(32)
+
+ if Foofn(v) != "foo:void *" {
+ panic("foo(void *)")
+ }
+ s := NewSpam()
+
+ if s.Foofn(3) != "foo:int" {
+ panic("Spam::foo(int)")
+ }
+
+ if s.Foofn(float64(3.0)) != "foo:double" {
+ panic("Spam::foo(double)")
+ }
+
+ if s.Foofn("hello") != "foo:char *" {
+ panic("Spam::foo(char *)")
+ }
+
+ if s.Foofn(f) != "foo:Foo *" {
+ panic("Spam::foo(Foo *)")
+ }
+
+ if s.Foofn(b) != "foo:Bar *" {
+ panic("Spam::foo(Bar *)")
+ }
+
+ if s.Foofn(v) != "foo:void *" {
+ panic("Spam::foo(void *)")
+ }
+
+ if SpamBar(3) != "bar:int" {
+ panic("Spam::bar(int)")
+ }
+
+ if SpamBar(float64(3.0)) != "bar:double" {
+ panic("Spam::bar(double)")
+ }
+
+ if SpamBar("hello") != "bar:char *" {
+ panic("Spam::bar(char *)")
+ }
+
+ if SpamBar(f) != "bar:Foo *" {
+ panic("Spam::bar(Foo *)")
+ }
+
+ if SpamBar(b) != "bar:Bar *" {
+ panic("Spam::bar(Bar *)")
+ }
+
+ if SpamBar(v) != "bar:void *" {
+ panic("Spam::bar(void *)")
+ }
+
+ // Test constructors
+
+ s = NewSpam()
+ if s.GetXtype() != "none" {
+ panic("Spam()")
+ }
+
+ s = NewSpam(3)
+ if s.GetXtype() != "int" {
+ panic("Spam(int)")
+ }
+
+ s = NewSpam(float64(3.4))
+ if s.GetXtype() != "double" {
+ panic("Spam(double)")
+ }
+
+ s = NewSpam("hello")
+ if s.GetXtype() != "char *" {
+ panic("Spam(char *)")
+ }
+
+ s = NewSpam(f)
+ if s.GetXtype() != "Foo *" {
+ panic("Spam(Foo *)")
+ }
+
+ s = NewSpam(b)
+ if s.GetXtype() != "Bar *" {
+ panic("Spam(Bar *)")
+ }
+
+ s = NewSpam(v)
+ if s.GetXtype() != "void *" {
+ panic("Spam(void *)")
+ }
+
+ Free_void(v)
+
+ a := NewClassA()
+ _ = a.Method1(1)
+}
diff --git a/Examples/test-suite/go/overload_subtype_runme.go b/Examples/test-suite/go/overload_subtype_runme.go
new file mode 100644
index 000000000..dc56d1ca7
--- /dev/null
+++ b/Examples/test-suite/go/overload_subtype_runme.go
@@ -0,0 +1,16 @@
+package main
+
+import . "./overload_subtype"
+
+func main() {
+ f := NewFoo()
+ b := NewBar()
+
+ if Spam(f) != 1 {
+ panic("foo")
+ }
+
+ if Spam(b) != 2 {
+ panic("bar")
+ }
+}
diff --git a/Examples/test-suite/go/overload_template_fast_runme.go b/Examples/test-suite/go/overload_template_fast_runme.go
new file mode 100644
index 000000000..8fc7c364c
--- /dev/null
+++ b/Examples/test-suite/go/overload_template_fast_runme.go
@@ -0,0 +1,187 @@
+package main
+
+import . "./overload_template_fast"
+
+func main() {
+ _ = Foo()
+
+ _ = Maximum(3, 4)
+ _ = Maximum(float64(3.4), float64(5.2))
+
+ // mix 1
+ if Mix1("hi") != 101 {
+ panic("mix1(const char*)")
+ }
+
+ if Mix1(float64(1.0), float64(1.0)) != 102 {
+ panic("mix1(double, const double &)")
+ }
+
+ if Mix1(float64(1.0)) != 103 {
+ panic("mix1(double)")
+ }
+
+ // mix 2
+ if Mix2("hi") != 101 {
+ panic("mix2(const char*)")
+ }
+
+ if Mix2(float64(1.0), float64(1.0)) != 102 {
+ panic("mix2(double, const double &)")
+ }
+
+ if Mix2(float64(1.0)) != 103 {
+ panic("mix2(double)")
+ }
+
+ // mix 3
+ if Mix3("hi") != 101 {
+ panic("mix3(const char*)")
+ }
+
+ if Mix3(float64(1.0), float64(1.0)) != 102 {
+ panic("mix3(double, const double &)")
+ }
+
+ if Mix3(float64(1.0)) != 103 {
+ panic("mix3(double)")
+ }
+
+ // Combination 1
+ if Overtparams1(100) != 10 {
+ panic("overtparams1(int)")
+ }
+
+ if Overtparams1(float64(100.0), 100) != 20 {
+ panic("overtparams1(double, int)")
+ }
+
+ // Combination 2
+ if Overtparams2(float64(100.0), 100) != 40 {
+ panic("overtparams2(double, int)")
+ }
+
+ // Combination 3
+ if Overloaded() != 60 {
+ panic("overloaded()")
+ }
+
+ if Overloaded(float64(100.0), 100) != 70 {
+ panic("overloaded(double, int)")
+ }
+
+ // Combination 4
+ if Overloadedagain("hello") != 80 {
+ panic("overloadedagain(const char *)")
+ }
+
+ if Overloadedagain() != 90 {
+ panic("overloadedagain(double)")
+ }
+
+ // specializations
+ if Specialization(10) != 202 {
+ panic("specialization(int)")
+ }
+
+ if Specialization(float64(10.0)) != 203 {
+ panic("specialization(double)")
+ }
+
+ if Specialization(10, 10) != 204 {
+ panic("specialization(int, int)")
+ }
+
+ if Specialization(float64(10.0), float64(10.0)) != 205 {
+ panic("specialization(double, double)")
+ }
+
+ if Specialization("hi", "hi") != 201 {
+ panic("specialization(const char *, const char *)")
+ }
+
+ // simple specialization
+ Xyz()
+ Xyz_int()
+ Xyz_double()
+
+ // a bit of everything
+ if Overload("hi") != 0 {
+ panic("overload()")
+ }
+
+ if Overload(1) != 10 {
+ panic("overload(int t)")
+ }
+
+ if Overload(1, 1) != 20 {
+ panic("overload(int t, const int &)")
+ }
+
+ if Overload(1, "hello") != 30 {
+ panic("overload(int t, const char *)")
+ }
+
+ k := NewKlass()
+ if Overload(k) != 10 {
+ panic("overload(Klass t)")
+ }
+
+ if Overload(k, k) != 20 {
+ panic("overload(Klass t, const Klass &)")
+ }
+
+ if Overload(k, "hello") != 30 {
+ panic("overload(Klass t, const char *)")
+ }
+
+ if Overload(float64(10.0), "hi") != 40 {
+ panic("overload(double t, const char *)")
+ }
+
+ if Overload() != 50 {
+ panic("overload(const char *)")
+ }
+
+
+ // everything put in a namespace
+ if Nsoverload("hi") != 1000 {
+ panic("nsoverload()")
+ }
+
+ if Nsoverload(1) != 1010 {
+ panic("nsoverload(int t)")
+ }
+
+ if Nsoverload(1, 1) != 1020 {
+ panic("nsoverload(int t, const int &)")
+ }
+
+ if Nsoverload(1, "hello") != 1030 {
+ panic("nsoverload(int t, const char *)")
+ }
+
+ if Nsoverload(k) != 1010 {
+ panic("nsoverload(Klass t)")
+ }
+
+ if Nsoverload(k, k) != 1020 {
+ panic("nsoverload(Klass t, const Klass &)")
+ }
+
+ if Nsoverload(k, "hello") != 1030 {
+ panic("nsoverload(Klass t, const char *)")
+ }
+
+ if Nsoverload(float64(10.0), "hi") != 1040 {
+ panic("nsoverload(double t, const char *)")
+ }
+
+ if Nsoverload() != 1050 {
+ panic("nsoverload(const char *)")
+ }
+
+ AFoo(1)
+ b := NewB()
+ b.Foo(1)
+}
diff --git a/Examples/test-suite/go/overload_template_runme.go b/Examples/test-suite/go/overload_template_runme.go
new file mode 100644
index 000000000..124402f37
--- /dev/null
+++ b/Examples/test-suite/go/overload_template_runme.go
@@ -0,0 +1,188 @@
+package main
+
+import . "./overload_template"
+
+func main() {
+ _ = Foo()
+
+ _ = Maximum(3, 4)
+ _ = Maximum(float64(3.4), float64(5.2))
+
+ // mix 1
+ if Mix1("hi") != 101 {
+ panic("mix1(const char*)")
+ }
+
+ if Mix1(float64(1.0), float64(1.0)) != 102 {
+ panic("mix1(double, const double &)")
+ }
+
+ if Mix1(float64(1.0)) != 103 {
+ panic("mix1(double)")
+ }
+
+ // mix 2
+ if Mix2("hi") != 101 {
+ panic("mix2(const char*)")
+ }
+
+ if Mix2(float64(1.0), float64(1.0)) != 102 {
+ panic("mix2(double, const double &)")
+ }
+
+ if Mix2(float64(1.0)) != 103 {
+ panic("mix2(double)")
+ }
+
+ // mix 3
+ if Mix3("hi") != 101 {
+ panic("mix3(const char*)")
+ }
+
+ if Mix3(float64(1.0), float64(1.0)) != 102 {
+ panic("mix3(double, const double &)")
+ }
+
+ if Mix3(float64(1.0)) != 103 {
+ panic("mix3(double)")
+ }
+
+ // Combination 1
+ if Overtparams1(100) != 10 {
+ panic("overtparams1(int)")
+ }
+
+ if Overtparams1(float64(100.0), 100) != 20 {
+ panic("overtparams1(double, int)")
+ }
+
+ // Combination 2
+ if Overtparams2(float64(100.0), 100) != 40 {
+ panic("overtparams2(double, int)")
+ }
+
+ // Combination 3
+ if Overloaded() != 60 {
+ panic("overloaded()")
+ }
+
+ if Overloaded(float64(100.0), 100) != 70 {
+ panic("overloaded(double, int)")
+ }
+
+ // Combination 4
+ if Overloadedagain("hello") != 80 {
+ panic("overloadedagain(const char *)")
+ }
+
+ if Overloadedagain() != 90 {
+ panic("overloadedagain(double)")
+ }
+
+ // specializations
+ if Specialization(10) != 202 {
+ panic("specialization(int)")
+ }
+
+ if Specialization(float64(10.0)) != 203 {
+ panic("specialization(double)")
+ }
+
+ if Specialization(10, 10) != 204 {
+ panic("specialization(int, int)")
+ }
+
+ if Specialization(float64(10.0), float64(10.0)) != 205 {
+ panic("specialization(double, double)")
+ }
+
+ if Specialization("hi", "hi") != 201 {
+ panic("specialization(const char *, const char *)")
+ }
+
+
+ // simple specialization
+ Xyz()
+ Xyz_int()
+ Xyz_double()
+
+ // a bit of everything
+ if Overload("hi") != 0 {
+ panic("overload()")
+ }
+
+ if Overload(1) != 10 {
+ panic("overload(int t)")
+ }
+
+ if Overload(1, 1) != 20 {
+ panic("overload(int t, const int &)")
+ }
+
+ if Overload(1, "hello") != 30 {
+ panic("overload(int t, const char *)")
+ }
+
+ k := NewKlass()
+ if Overload(k) != 10 {
+ panic("overload(Klass t)")
+ }
+
+ if Overload(k, k) != 20 {
+ panic("overload(Klass t, const Klass &)")
+ }
+
+ if Overload(k, "hello") != 30 {
+ panic("overload(Klass t, const char *)")
+ }
+
+ if Overload(float64(10.0), "hi") != 40 {
+ panic("overload(double t, const char *)")
+ }
+
+ if Overload() != 50 {
+ panic("overload(const char *)")
+ }
+
+
+ // everything put in a namespace
+ if Nsoverload("hi") != 1000 {
+ panic("nsoverload()")
+ }
+
+ if Nsoverload(1) != 1010 {
+ panic("nsoverload(int t)")
+ }
+
+ if Nsoverload(1, 1) != 1020 {
+ panic("nsoverload(int t, const int &)")
+ }
+
+ if Nsoverload(1, "hello") != 1030 {
+ panic("nsoverload(int t, const char *)")
+ }
+
+ if Nsoverload(k) != 1010 {
+ panic("nsoverload(Klass t)")
+ }
+
+ if Nsoverload(k, k) != 1020 {
+ panic("nsoverload(Klass t, const Klass &)")
+ }
+
+ if Nsoverload(k, "hello") != 1030 {
+ panic("nsoverload(Klass t, const char *)")
+ }
+
+ if Nsoverload(float64(10.0), "hi") != 1040 {
+ panic("nsoverload(double t, const char *)")
+ }
+
+ if Nsoverload() != 1050 {
+ panic("nsoverload(const char *)")
+ }
+
+ AFoo(1)
+ b := NewB()
+ b.Foo(1)
+}
diff --git a/Examples/test-suite/go/preproc_runme.go b/Examples/test-suite/go/preproc_runme.go
new file mode 100644
index 000000000..a15062241
--- /dev/null
+++ b/Examples/test-suite/go/preproc_runme.go
@@ -0,0 +1,21 @@
+package main
+
+import "./preproc"
+
+func main() {
+ if preproc.GetEndif() != 1 {
+ panic(0)
+ }
+
+ if preproc.GetDefine() != 1 {
+ panic(0)
+ }
+
+ if preproc.GetDefined() != 1 {
+ panic(0)
+ }
+
+ if 2*preproc.One != preproc.Two {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/primitive_ref_runme.go b/Examples/test-suite/go/primitive_ref_runme.go
new file mode 100644
index 000000000..973806955
--- /dev/null
+++ b/Examples/test-suite/go/primitive_ref_runme.go
@@ -0,0 +1,57 @@
+package main
+
+import . "./primitive_ref"
+
+func main() {
+ if Ref_int(3) != 3 {
+ panic(0)
+ }
+
+ if Ref_uint(3) != 3 {
+ panic(0)
+ }
+
+ if Ref_short(3) != 3 {
+ panic(0)
+ }
+
+ if Ref_ushort(3) != 3 {
+ panic(0)
+ }
+
+ if Ref_long(3) != 3 {
+ panic(0)
+ }
+
+ if Ref_ulong(3) != 3 {
+ panic(0)
+ }
+
+ if Ref_schar(3) != 3 {
+ panic(0)
+ }
+
+ if Ref_uchar(3) != 3 {
+ panic(0)
+ }
+
+ if Ref_float(3.5) != 3.5 {
+ panic(0)
+ }
+
+ if Ref_double(3.5) != 3.5 {
+ panic(0)
+ }
+
+ if Ref_bool(true) != true {
+ panic(0)
+ }
+
+ if Ref_char('x') != 'x' {
+ panic(0)
+ }
+
+ if Ref_over(0) != 0 {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/profiletest_runme.go b/Examples/test-suite/go/profiletest_runme.go
new file mode 100644
index 000000000..30b6cee69
--- /dev/null
+++ b/Examples/test-suite/go/profiletest_runme.go
@@ -0,0 +1,38 @@
+package main
+
+import "fmt"
+import "./profiletest"
+
+func main() {
+ a := profiletest.NewA()
+ if false {
+ fmt.Println(a)
+ }
+
+ b := profiletest.NewB()
+ fn := func(a profiletest.A) profiletest.A { return b.Fn(a) }
+ i := 50000
+ for i != 0 {
+ a = fn(a) //1
+ a = fn(a) //2
+ a = fn(a) //3
+ a = fn(a) //4
+ a = fn(a) //5
+ a = fn(a) //6
+ a = fn(a) //7
+ a = fn(a) //8
+ a = fn(a) //9
+ a = fn(a) //10
+ a = fn(a) //1
+ a = fn(a) //2
+ a = fn(a) //3
+ a = fn(a) //4
+ a = fn(a) //5
+ a = fn(a) //6
+ a = fn(a) //7
+ a = fn(a) //8
+ a = fn(a) //9
+ a = fn(a) //20
+ i -= 1
+ }
+}
diff --git a/Examples/test-suite/go/refcount_runme.go b/Examples/test-suite/go/refcount_runme.go
new file mode 100644
index 000000000..fdb271cc6
--- /dev/null
+++ b/Examples/test-suite/go/refcount_runme.go
@@ -0,0 +1,32 @@
+package main
+
+import . "./refcount"
+
+// very innocent example
+
+func main() {
+ a := NewA3()
+ _ = NewB(a)
+ b2 := BCreate(a)
+
+ if a.Ref_count() != 3 {
+ panic("This program will crash... now")
+ }
+
+ rca := b2.Get_rca()
+ // _ = BCreate(rca)
+ _ = rca
+
+ if a.Ref_count() != 4 {
+ panic("This program will crash... now")
+ }
+
+ /* Requires smart pointer support.
+ v := NewVector_A(2)
+ v.Set(0, a)
+ v.Set(1, a)
+
+ _ = v.Get(0)
+ DeleteVector_A(v)
+ */
+}
diff --git a/Examples/test-suite/go/reference_global_vars_runme.go b/Examples/test-suite/go/reference_global_vars_runme.go
new file mode 100644
index 000000000..b8cbb304a
--- /dev/null
+++ b/Examples/test-suite/go/reference_global_vars_runme.go
@@ -0,0 +1,98 @@
+package main
+
+import . "./reference_global_vars"
+
+func main() {
+ // const class reference variable
+ if GetconstTC().GetNum() != 33 {
+ panic(0)
+ }
+
+ // primitive reference variables
+ SetVar_bool(Createref_bool(false))
+ if Value_bool(GetVar_bool()) != false {
+ println(1, GetVar_bool(), Value_bool(GetVar_bool()))
+ panic(0)
+ }
+
+ SetVar_bool(Createref_bool(true))
+ if Value_bool(GetVar_bool()) != true {
+ println(2, GetVar_bool(), Value_bool(GetVar_bool()))
+ panic(0)
+ }
+
+ SetVar_char(Createref_char('w'))
+ if Value_char(GetVar_char()) != 'w' {
+ println(3, GetVar_char(), Value_char(GetVar_char()))
+ panic(0)
+ }
+
+ SetVar_unsigned_char(Createref_unsigned_char(10))
+ if Value_unsigned_char(GetVar_unsigned_char()) != 10 {
+ println(4, GetVar_unsigned_char(), Value_unsigned_char(GetVar_unsigned_char()))
+ panic(0)
+ }
+
+ SetVar_signed_char(Createref_signed_char(10))
+ if Value_signed_char(GetVar_signed_char()) != 10 {
+ panic(0)
+ }
+
+ SetVar_short(Createref_short(10))
+ if Value_short(GetVar_short()) != 10 {
+ panic(0)
+ }
+
+ SetVar_unsigned_short(Createref_unsigned_short(10))
+ if Value_unsigned_short(GetVar_unsigned_short()) != 10 {
+ panic(0)
+ }
+
+ SetVar_int(Createref_int(10))
+ if Value_int(GetVar_int()) != 10 {
+ panic(0)
+ }
+
+ SetVar_unsigned_int(Createref_unsigned_int(10))
+ if Value_unsigned_int(GetVar_unsigned_int()) != 10 {
+ panic(0)
+ }
+
+ SetVar_long(Createref_long(10))
+ if Value_long(GetVar_long()) != 10 {
+ panic(0)
+ }
+
+ SetVar_unsigned_long(Createref_unsigned_long(10))
+ if Value_unsigned_long(GetVar_unsigned_long()) != 10 {
+ panic(0)
+ }
+
+ SetVar_long_long(Createref_long_long(0x6FFFFFFFFFFFFFF8))
+ if Value_long_long(GetVar_long_long()) != 0x6FFFFFFFFFFFFFF8 {
+ panic(0)
+ }
+
+ //ull = abs(0xFFFFFFF2FFFFFFF0)
+ ull := uint64(55834574864)
+ SetVar_unsigned_long_long(Createref_unsigned_long_long(ull))
+ if Value_unsigned_long_long(GetVar_unsigned_long_long()) != ull {
+ panic(0)
+ }
+
+ SetVar_float(Createref_float(10.5))
+ if Value_float(GetVar_float()) != 10.5 {
+ panic(0)
+ }
+
+ SetVar_double(Createref_double(10.5))
+ if Value_double(GetVar_double()) != 10.5 {
+ panic(0)
+ }
+
+ // class reference variable
+ SetVar_TestClass(Createref_TestClass(NewTestClass(20)))
+ if Value_TestClass(GetVar_TestClass()).GetNum() != 20 {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/rename_scope_runme.go b/Examples/test-suite/go/rename_scope_runme.go
new file mode 100644
index 000000000..995f8c64d
--- /dev/null
+++ b/Examples/test-suite/go/rename_scope_runme.go
@@ -0,0 +1,18 @@
+package main
+
+import . "./rename_scope"
+
+func main() {
+ a := NewNatural_UP()
+ b := NewNatural_BP()
+
+ if a.Rtest() != 1 {
+ panic(0)
+ }
+
+ if b.Rtest() != 1 {
+ panic(0)
+ }
+
+ _ = Equals
+}
diff --git a/Examples/test-suite/go/rename_strip_encoder_runme.go b/Examples/test-suite/go/rename_strip_encoder_runme.go
new file mode 100644
index 000000000..1d0bcb660
--- /dev/null
+++ b/Examples/test-suite/go/rename_strip_encoder_runme.go
@@ -0,0 +1,9 @@
+package main
+
+import . "./rename_strip_encoder"
+
+func main() {
+ _ = NewSomeWidget()
+ a := NewAnotherWidget()
+ a.DoSomething()
+}
diff --git a/Examples/test-suite/go/ret_by_value_runme.go b/Examples/test-suite/go/ret_by_value_runme.go
new file mode 100644
index 000000000..44743d2b7
--- /dev/null
+++ b/Examples/test-suite/go/ret_by_value_runme.go
@@ -0,0 +1,14 @@
+package main
+
+import "./ret_by_value"
+
+func main() {
+ a := ret_by_value.Get_test()
+ if a.GetMyInt() != 100 {
+ panic(0)
+ }
+
+ if a.GetMyShort() != 200 {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/return_const_value_runme.go b/Examples/test-suite/go/return_const_value_runme.go
new file mode 100644
index 000000000..790921b74
--- /dev/null
+++ b/Examples/test-suite/go/return_const_value_runme.go
@@ -0,0 +1,15 @@
+package main
+
+import "./return_const_value"
+
+func main() {
+ p := return_const_value.Foo_ptrGetPtr()
+ if p.GetVal() != 17 {
+ panic("Runtime test1 failed")
+ }
+
+ p = return_const_value.Foo_ptrGetConstPtr()
+ if p.GetVal() != 17 {
+ panic("Runtime test2 failed")
+ }
+}
diff --git a/Examples/test-suite/go/smart_pointer_extend_runme.go b/Examples/test-suite/go/smart_pointer_extend_runme.go
new file mode 100644
index 000000000..ee5ce0538
--- /dev/null
+++ b/Examples/test-suite/go/smart_pointer_extend_runme.go
@@ -0,0 +1,40 @@
+package main
+
+import . "./smart_pointer_extend"
+
+func main() {
+ f := NewFoo()
+ b := NewBar(f)
+
+ if b.Extension() != f.Extension() {
+ panic(0)
+ }
+
+ b2 := NewCBase()
+ d := NewCDerived()
+ p := NewCPtr()
+
+ if b2.Bar() != p.Bar() {
+ panic(0)
+ }
+
+ if d.Foo() != p.Foo() {
+ panic(0)
+ }
+
+ if CBaseHello() != p.Hello() {
+ panic(0)
+ }
+
+ d2 := NewDFoo()
+
+ dp := NewDPtrFoo(d2)
+
+ if DFooSExt(1) != dp.SExt(1) {
+ panic(0)
+ }
+
+ if d2.Ext(1) != dp.Ext(1) {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/smart_pointer_member_runme.go b/Examples/test-suite/go/smart_pointer_member_runme.go
new file mode 100644
index 000000000..d0da83cef
--- /dev/null
+++ b/Examples/test-suite/go/smart_pointer_member_runme.go
@@ -0,0 +1,30 @@
+package main
+
+import "fmt"
+import . "./smart_pointer_member"
+
+func main() {
+ f := NewFoos()
+ f.SetY(1)
+
+ if f.GetY() != 1 {
+ panic(0)
+ }
+
+ b := NewBar(f)
+ b.SetY(2)
+
+ if f.GetY() != 2 {
+ fmt.Println(f.GetY())
+ fmt.Println(b.GetY())
+ panic(0)
+ }
+
+ if b.GetX() != f.GetX() {
+ panic(0)
+ }
+
+ if b.GetZ() != GetFoosZ() {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/smart_pointer_multi_runme.go b/Examples/test-suite/go/smart_pointer_multi_runme.go
new file mode 100644
index 000000000..d1a5f92f4
--- /dev/null
+++ b/Examples/test-suite/go/smart_pointer_multi_runme.go
@@ -0,0 +1,20 @@
+package main
+
+import . "./smart_pointer_multi"
+
+func main() {
+ f := NewFoo()
+ b := NewBar(f)
+ s := NewSpam(b)
+ g := NewGrok(b)
+
+ s.SetX(3)
+ if s.Getx() != 3 {
+ panic(0)
+ }
+
+ g.SetX(4)
+ if g.Getx() != 4 {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/smart_pointer_multi_typedef_runme.go b/Examples/test-suite/go/smart_pointer_multi_typedef_runme.go
new file mode 100644
index 000000000..f71740bbb
--- /dev/null
+++ b/Examples/test-suite/go/smart_pointer_multi_typedef_runme.go
@@ -0,0 +1,20 @@
+package main
+
+import . "./smart_pointer_multi_typedef"
+
+func main() {
+ f := NewFoo()
+ b := NewBar(f)
+ s := NewSpam(b)
+ g := NewGrok(b)
+
+ s.SetX(3)
+ if s.Getx() != 3 {
+ panic(0)
+ }
+
+ g.SetX(4)
+ if g.Getx() != 4 {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/smart_pointer_overload_runme.go b/Examples/test-suite/go/smart_pointer_overload_runme.go
new file mode 100644
index 000000000..0a06aa080
--- /dev/null
+++ b/Examples/test-suite/go/smart_pointer_overload_runme.go
@@ -0,0 +1,28 @@
+package main
+
+import . "./smart_pointer_overload"
+
+func main() {
+ f := NewFoo()
+ b := NewBar(f)
+
+ if f.Test(3) != 1 {
+ panic(0)
+ }
+ if f.Test(float64(3.5)) != 2 {
+ panic(0)
+ }
+ if f.Test("hello") != 3 {
+ panic(0)
+ }
+
+ if b.Test(3) != 1 {
+ panic(0)
+ }
+ if b.Test(float64(3.5)) != 2 {
+ panic(0)
+ }
+ if b.Test("hello") != 3 {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/smart_pointer_rename_runme.go b/Examples/test-suite/go/smart_pointer_rename_runme.go
new file mode 100644
index 000000000..678c305c8
--- /dev/null
+++ b/Examples/test-suite/go/smart_pointer_rename_runme.go
@@ -0,0 +1,20 @@
+package main
+
+import . "./smart_pointer_rename"
+
+func main() {
+ f := NewFoo()
+ b := NewBar(f)
+
+ if b.Test() != 3 {
+ panic(0)
+ }
+
+ if b.Ftest1(1) != 1 {
+ panic(0)
+ }
+
+ if b.Ftest2(2, 3) != 2 {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/smart_pointer_simple_runme.go b/Examples/test-suite/go/smart_pointer_simple_runme.go
new file mode 100644
index 000000000..328654225
--- /dev/null
+++ b/Examples/test-suite/go/smart_pointer_simple_runme.go
@@ -0,0 +1,19 @@
+package main
+
+import . "./smart_pointer_simple"
+
+func main() {
+ f := NewFoo()
+ b := NewBar(f)
+
+ b.SetX(3)
+ if b.Getx() != 3 {
+ panic(0)
+ }
+
+ fp := b.X__deref__()
+ fp.SetX(4)
+ if fp.Getx() != 4 {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/smart_pointer_templatevariables_runme.go b/Examples/test-suite/go/smart_pointer_templatevariables_runme.go
new file mode 100644
index 000000000..bf58ba52c
--- /dev/null
+++ b/Examples/test-suite/go/smart_pointer_templatevariables_runme.go
@@ -0,0 +1,22 @@
+package main
+
+import . "./smart_pointer_templatevariables"
+
+func main() {
+ d := NewDiffImContainerPtr_D(Create(1234, 5678))
+
+ if d.GetId() != 1234 {
+ panic(0)
+ }
+ //if (d.xyz != 5678):
+ // panic(0)
+
+ d.SetId(4321)
+ //d.xyz = 8765
+
+ if d.GetId() != 4321 {
+ panic(0)
+ }
+ //if (d.xyz != 8765):
+ // panic(0)
+}
diff --git a/Examples/test-suite/go/smart_pointer_typedef_runme.go b/Examples/test-suite/go/smart_pointer_typedef_runme.go
new file mode 100644
index 000000000..a67a0ccda
--- /dev/null
+++ b/Examples/test-suite/go/smart_pointer_typedef_runme.go
@@ -0,0 +1,19 @@
+package main
+
+import . "./smart_pointer_typedef"
+
+func main() {
+ f := NewFoo()
+ b := NewBar(f)
+
+ b.SetX(3)
+ if b.Getx() != 3 {
+ panic(0)
+ }
+
+ fp := b.X__deref__()
+ fp.SetX(4)
+ if fp.Getx() != 4 {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/sneaky1_runme.go b/Examples/test-suite/go/sneaky1_runme.go
new file mode 100644
index 000000000..ee38ae21b
--- /dev/null
+++ b/Examples/test-suite/go/sneaky1_runme.go
@@ -0,0 +1,10 @@
+package main
+
+import "./sneaky1"
+
+func main() {
+ _ = sneaky1.Add(3, 4)
+ _ = sneaky1.Subtract(3, 4)
+ _ = sneaky1.Mul(3, 4)
+ _ = sneaky1.Divide(3, 4)
+}
diff --git a/Examples/test-suite/go/special_variable_macros_runme.go b/Examples/test-suite/go/special_variable_macros_runme.go
new file mode 100644
index 000000000..366575551
--- /dev/null
+++ b/Examples/test-suite/go/special_variable_macros_runme.go
@@ -0,0 +1,25 @@
+package main
+
+import "./special_variable_macros"
+
+func main() {
+ name := special_variable_macros.NewNames()
+ if special_variable_macros.TestFred(name) != "none" {
+ panic("test failed")
+ }
+ if special_variable_macros.TestJack(name) != "$specialname" {
+ panic("test failed")
+ }
+ if special_variable_macros.TestJill(name) != "jilly" {
+ panic("test failed")
+ }
+ if special_variable_macros.TestMary(name) != "SWIGTYPE_p_NameWrap" {
+ panic("test failed")
+ }
+ if special_variable_macros.TestJim(name) != "multiname num" {
+ panic("test failed")
+ }
+ if special_variable_macros.TestJohn(special_variable_macros.NewPairIntBool(10, false)) != 123 {
+ panic("test failed")
+ }
+}
diff --git a/Examples/test-suite/go/static_const_member_2_runme.go b/Examples/test-suite/go/static_const_member_2_runme.go
new file mode 100644
index 000000000..0d345c3d6
--- /dev/null
+++ b/Examples/test-suite/go/static_const_member_2_runme.go
@@ -0,0 +1,18 @@
+package main
+
+import . "./static_const_member_2"
+
+func main() {
+ _ = NewTest_int()
+
+ _ = CavityPackFlagsForward_field
+ _ = Test_intCurrent_profile
+ _ = Test_intRightIndex
+ _ = CavityPackFlagsBackward_field
+ _ = Test_intLeftIndex
+ // _ = GetTest_int_Cavity_flags()
+
+ if GetFooBAZ().GetVal() != 2*GetFooBAR().GetVal() {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/struct_initialization_runme.go b/Examples/test-suite/go/struct_initialization_runme.go
new file mode 100644
index 000000000..58ac25010
--- /dev/null
+++ b/Examples/test-suite/go/struct_initialization_runme.go
@@ -0,0 +1,29 @@
+package main
+
+import . "./struct_initialization"
+
+func main() {
+ if GetInstanceC1().GetX() != 10 {
+ panic(0)
+ }
+
+ if GetInstanceD1().GetX() != 10 {
+ panic(0)
+ }
+
+ if GetInstanceD2().GetX() != 20 {
+ panic(0)
+ }
+
+ if GetInstanceD3().GetX() != 30 {
+ panic(0)
+ }
+
+ if GetInstanceE1().GetX() != 1 {
+ panic(0)
+ }
+
+ if GetInstanceF1().GetX() != 1 {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/struct_rename_runme.go b/Examples/test-suite/go/struct_rename_runme.go
new file mode 100644
index 000000000..845dac5be
--- /dev/null
+++ b/Examples/test-suite/go/struct_rename_runme.go
@@ -0,0 +1,7 @@
+package main
+
+import "./struct_rename"
+
+func main() {
+ _ = struct_rename.NewBar()
+}
diff --git a/Examples/test-suite/go/struct_value_runme.go b/Examples/test-suite/go/struct_value_runme.go
new file mode 100644
index 000000000..d0b60bd23
--- /dev/null
+++ b/Examples/test-suite/go/struct_value_runme.go
@@ -0,0 +1,17 @@
+package main
+
+import "./struct_value"
+
+func main() {
+ b := struct_value.NewBar()
+
+ b.GetA().SetX(3)
+ if b.GetA().GetX() != 3 {
+ panic(0)
+ }
+
+ b.GetB().SetX(3)
+ if b.GetB().GetX() != 3 {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/template_default_arg_runme.go b/Examples/test-suite/go/template_default_arg_runme.go
new file mode 100644
index 000000000..5be7f6d56
--- /dev/null
+++ b/Examples/test-suite/go/template_default_arg_runme.go
@@ -0,0 +1,107 @@
+package main
+
+import "./template_default_arg"
+
+func main() {
+ helloInt := template_default_arg.NewHello_int()
+ helloInt.Foo(template_default_arg.Hello_intHi)
+
+ x := template_default_arg.NewX_int()
+ if x.Meth(float64(20.0), 200).(int) != 200 {
+ panic("X_int test 1 failed")
+ }
+ if x.Meth(20).(int) != 20 {
+ panic("X_int test 2 failed")
+ }
+ if x.Meth().(int) != 0 {
+ panic("X_int test 3 failed")
+ }
+
+ y := template_default_arg.NewY_unsigned()
+ if y.Meth(float64(20.0), uint(200)).(uint) != 200 {
+ panic("Y_unsigned test 1 failed")
+ }
+ if y.Meth(uint(20)).(uint) != 20 {
+ panic("Y_unsigned test 2 failed")
+ }
+ if y.Meth().(uint) != 0 {
+ panic("Y_unsigned test 3 failed")
+ }
+
+ _ = template_default_arg.NewX_longlong()
+ _ = template_default_arg.NewX_longlong(float64(20.0))
+ _ = template_default_arg.NewX_longlong(float64(20.0), int64(200))
+
+ _ = template_default_arg.NewX_int()
+ _ = template_default_arg.NewX_int(float64(20.0))
+ _ = template_default_arg.NewX_int(float64(20.0), 200)
+
+ _ = template_default_arg.NewX_hello_unsigned()
+ _ = template_default_arg.NewX_hello_unsigned(float64(20.0))
+ _ = template_default_arg.NewX_hello_unsigned(float64(20.0), template_default_arg.NewHello_int())
+
+ yy := template_default_arg.NewY_hello_unsigned()
+ yy.Meth(float64(20.0), template_default_arg.NewHello_int())
+ yy.Meth(template_default_arg.NewHello_int())
+ yy.Meth()
+
+ fz := template_default_arg.NewFoo_Z_8()
+ xz := template_default_arg.NewX_Foo_Z_8()
+ _ = xz.Meth(fz)
+
+
+ // Templated functions
+
+ // plain function: int ott(Foo)
+ if template_default_arg.Ott(template_default_arg.NewFoo_int()) != 30 {
+ panic("ott test 1 failed")
+ }
+
+ // %template(ott) ott
+ if template_default_arg.Ott() != 10 {
+ panic("ott test 2 failed")
+ }
+ if template_default_arg.Ott(1) != 10 {
+ panic("ott test 3 failed")
+ }
+ if template_default_arg.Ott(1, 1) != 10 {
+ panic("ott test 4 failed")
+ }
+
+ if template_default_arg.Ott("hi") != 20 {
+ panic("ott test 5 failed")
+ }
+ if template_default_arg.Ott("hi", 1) != 20 {
+ panic("ott test 6 failed")
+ }
+ if template_default_arg.Ott("hi", 1, 1) != 20 {
+ panic("ott test 7 failed")
+ }
+
+ // %template(ott) ott
+ if template_default_arg.Ottstring(template_default_arg.NewHello_int(), "hi") != 40 {
+ panic("ott test 8 failed")
+ }
+
+ if template_default_arg.Ottstring(template_default_arg.NewHello_int()) != 40 {
+ panic("ott test 9 failed")
+ }
+
+ // %template(ott) ott
+ if template_default_arg.Ottint(template_default_arg.NewHello_int(), 1) != 50 {
+ panic("ott test 10 failed")
+ }
+
+ if template_default_arg.Ottint(template_default_arg.NewHello_int()) != 50 {
+ panic("ott test 11 failed")
+ }
+
+ // %template(ott) ott
+ if template_default_arg.Ott(template_default_arg.NewHello_int(), float64(1.0)) != 60 {
+ panic("ott test 12 failed")
+ }
+
+ if template_default_arg.Ott(template_default_arg.NewHello_int()) != 60 {
+ panic("ott test 13 failed")
+ }
+}
diff --git a/Examples/test-suite/go/template_extend1_runme.go b/Examples/test-suite/go/template_extend1_runme.go
new file mode 100644
index 000000000..5d6d376f5
--- /dev/null
+++ b/Examples/test-suite/go/template_extend1_runme.go
@@ -0,0 +1,16 @@
+package main
+
+import "./template_extend1"
+
+func main() {
+ a := template_extend1.NewLBaz()
+ b := template_extend1.NewDBaz()
+
+ if a.Foo() != "lBaz::foo" {
+ panic(0)
+ }
+
+ if b.Foo() != "dBaz::foo" {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/template_extend2_runme.go b/Examples/test-suite/go/template_extend2_runme.go
new file mode 100644
index 000000000..312410e27
--- /dev/null
+++ b/Examples/test-suite/go/template_extend2_runme.go
@@ -0,0 +1,16 @@
+package main
+
+import "./template_extend2"
+
+func main() {
+ a := template_extend2.NewLBaz()
+ b := template_extend2.NewDBaz()
+
+ if a.Foo() != "lBaz::foo" {
+ panic(0)
+ }
+
+ if b.Foo() != "dBaz::foo" {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/template_inherit_runme.go b/Examples/test-suite/go/template_inherit_runme.go
new file mode 100644
index 000000000..c0aca77c4
--- /dev/null
+++ b/Examples/test-suite/go/template_inherit_runme.go
@@ -0,0 +1,72 @@
+package main
+
+import . "./template_inherit"
+
+func main() {
+ a := NewFooInt()
+ b := NewFooDouble()
+ c := NewBarInt()
+ d := NewBarDouble()
+ e := NewFooUInt()
+ f := NewBarUInt()
+
+ if a.Blah() != "Foo" {
+ panic(0)
+ }
+
+ if b.Blah() != "Foo" {
+ panic(0)
+ }
+
+ if e.Blah() != "Foo" {
+ panic(0)
+ }
+
+ if c.Blah() != "Bar" {
+ panic(0)
+ }
+
+ if d.Blah() != "Bar" {
+ panic(0)
+ }
+
+ if f.Blah() != "Bar" {
+ panic(0)
+ }
+
+ if c.Foomethod() != "foomethod" {
+ panic(0)
+ }
+
+ if d.Foomethod() != "foomethod" {
+ panic(0)
+ }
+
+ if f.Foomethod() != "foomethod" {
+ panic(0)
+ }
+
+ if Invoke_blah_int(a) != "Foo" {
+ panic(0)
+ }
+
+ if Invoke_blah_int(c) != "Bar" {
+ panic(0)
+ }
+
+ if Invoke_blah_double(b) != "Foo" {
+ panic(0)
+ }
+
+ if Invoke_blah_double(d) != "Bar" {
+ panic(0)
+ }
+
+ if Invoke_blah_uint(e) != "Foo" {
+ panic(0)
+ }
+
+ if Invoke_blah_uint(f) != "Bar" {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/template_ns4_runme.go b/Examples/test-suite/go/template_ns4_runme.go
new file mode 100644
index 000000000..4caf8f587
--- /dev/null
+++ b/Examples/test-suite/go/template_ns4_runme.go
@@ -0,0 +1,10 @@
+package main
+
+import . "./template_ns4"
+
+func main() {
+ d := Make_Class_DD()
+ if d.Test() != "test" {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/template_ns_runme.go b/Examples/test-suite/go/template_ns_runme.go
new file mode 100644
index 000000000..5d463f814
--- /dev/null
+++ b/Examples/test-suite/go/template_ns_runme.go
@@ -0,0 +1,26 @@
+package main
+
+import . "./template_ns"
+
+func main() {
+ p1 := NewPairii(2, 3)
+ p2 := NewPairii(p1)
+
+ if p2.GetFirst() != 2 {
+ panic(0)
+ }
+ if p2.GetSecond() != 3 {
+ panic(0)
+ }
+
+ p3 := NewPairdd(float64(3.5), float64(2.5))
+ p4 := NewPairdd(p3)
+
+ if p4.GetFirst() != 3.5 {
+ panic(0)
+ }
+
+ if p4.GetSecond() != 2.5 {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/template_opaque_runme.go b/Examples/test-suite/go/template_opaque_runme.go
new file mode 100644
index 000000000..c22b71946
--- /dev/null
+++ b/Examples/test-suite/go/template_opaque_runme.go
@@ -0,0 +1,9 @@
+package main
+
+import "./template_opaque"
+
+func main() {
+ v := template_opaque.NewOpaqueVectorType(10)
+
+ template_opaque.FillVector(v)
+}
diff --git a/Examples/test-suite/go/template_ref_type_runme.go b/Examples/test-suite/go/template_ref_type_runme.go
new file mode 100644
index 000000000..e4bf626fb
--- /dev/null
+++ b/Examples/test-suite/go/template_ref_type_runme.go
@@ -0,0 +1,9 @@
+package main
+
+import "./template_ref_type"
+
+func main() {
+ xr := template_ref_type.NewXC()
+ y := template_ref_type.NewY()
+ y.Find(xr)
+}
diff --git a/Examples/test-suite/go/template_rename_runme.go b/Examples/test-suite/go/template_rename_runme.go
new file mode 100644
index 000000000..757ac7355
--- /dev/null
+++ b/Examples/test-suite/go/template_rename_runme.go
@@ -0,0 +1,16 @@
+package main
+
+import "./template_rename"
+
+func main() {
+ i := template_rename.NewIFoo()
+ d := template_rename.NewDFoo()
+
+ _ = i.Blah_test(4)
+ _ = i.Spam_test(5)
+ _ = i.Groki_test(6)
+
+ _ = d.Blah_test(7)
+ _ = d.Spam(8)
+ _ = d.Grok_test(9)
+}
diff --git a/Examples/test-suite/go/template_static_runme.go b/Examples/test-suite/go/template_static_runme.go
new file mode 100644
index 000000000..7fa50760a
--- /dev/null
+++ b/Examples/test-suite/go/template_static_runme.go
@@ -0,0 +1,7 @@
+package main
+
+import . "./template_static"
+
+func main() {
+ FooBar_double(1)
+}
diff --git a/Examples/test-suite/go/template_tbase_template_runme.go b/Examples/test-suite/go/template_tbase_template_runme.go
new file mode 100644
index 000000000..9a52e2fac
--- /dev/null
+++ b/Examples/test-suite/go/template_tbase_template_runme.go
@@ -0,0 +1,10 @@
+package main
+
+import . "./template_tbase_template"
+
+func main() {
+ a := Make_Class_dd()
+ if a.Test() != "test" {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/template_type_namespace_runme.go b/Examples/test-suite/go/template_type_namespace_runme.go
new file mode 100644
index 000000000..a3712ff59
--- /dev/null
+++ b/Examples/test-suite/go/template_type_namespace_runme.go
@@ -0,0 +1,8 @@
+package main
+
+import . "./template_type_namespace"
+
+func main() {
+ if Foo().Get(0) == "" {
+ }
+}
diff --git a/Examples/test-suite/go/template_typedef_cplx3_runme.go b/Examples/test-suite/go/template_typedef_cplx3_runme.go
new file mode 100644
index 000000000..f827d7a1e
--- /dev/null
+++ b/Examples/test-suite/go/template_typedef_cplx3_runme.go
@@ -0,0 +1,29 @@
+package main
+
+import . "./template_typedef_cplx3"
+
+func main() {
+ // this is OK
+
+
+ s := NewSin()
+ s.Get_base_value()
+ s.Get_value()
+ s.Get_arith_value()
+ My_func_r(s)
+ Make_Multiplies_double_double_double_double(s, s)
+
+ z := NewCSin()
+ z.Get_base_value()
+ z.Get_value()
+ z.Get_arith_value()
+ My_func_c(z)
+ Make_Multiplies_complex_complex_complex_complex(z, z)
+
+ // Here we fail
+ d := Make_Identity_double()
+ My_func_r(d)
+
+ c := Make_Identity_complex()
+ My_func_c(c)
+}
diff --git a/Examples/test-suite/go/template_typedef_cplx4_runme.go b/Examples/test-suite/go/template_typedef_cplx4_runme.go
new file mode 100644
index 000000000..9021cf135
--- /dev/null
+++ b/Examples/test-suite/go/template_typedef_cplx4_runme.go
@@ -0,0 +1,29 @@
+package main
+
+import . "./template_typedef_cplx4"
+
+func main() {
+ // this is OK
+
+
+ s := NewSin()
+ s.Get_base_value()
+ s.Get_value()
+ s.Get_arith_value()
+ My_func_r(s)
+ Make_Multiplies_double_double_double_double(s, s)
+
+ z := NewCSin()
+ z.Get_base_value()
+ z.Get_value()
+ z.Get_arith_value()
+ My_func_c(z)
+ Make_Multiplies_complex_complex_complex_complex(z, z)
+
+ // Here we fail
+ d := Make_Identity_double()
+ My_func_r(d)
+
+ c := Make_Identity_complex()
+ My_func_c(c)
+}
diff --git a/Examples/test-suite/go/template_typedef_import_runme.go b/Examples/test-suite/go/template_typedef_import_runme.go
new file mode 100644
index 000000000..8528b9a93
--- /dev/null
+++ b/Examples/test-suite/go/template_typedef_import_runme.go
@@ -0,0 +1,30 @@
+package main
+
+import "template_typedef_cplx2"
+import "template_typedef_import"
+
+func main() {
+ // this is OK
+
+
+ s := template_typedef_import.NewSin()
+ s.Get_base_value()
+ s.Get_value()
+ s.Get_arith_value()
+ template_typedef_import.My_func_r(s)
+ template_typedef_cplx2.Make_Multiplies_double_double_double_double(s, s)
+
+ z := template_typedef_import.NewCSin()
+ z.Get_base_value()
+ z.Get_value()
+ z.Get_arith_value()
+ template_typedef_import.My_func_c(z)
+ template_typedef_cplx2.Make_Multiplies_complex_complex_complex_complex(z, z)
+
+ // Here we fail
+ d := template_typedef_cplx2.Make_Identity_double()
+ template_typedef_import.My_func_r(d)
+
+ c := template_typedef_cplx2.Make_Identity_complex()
+ template_typedef_import.My_func_c(c)
+}
diff --git a/Examples/test-suite/go/threads_exception_runme.go b/Examples/test-suite/go/threads_exception_runme.go
new file mode 100644
index 000000000..742a827bd
--- /dev/null
+++ b/Examples/test-suite/go/threads_exception_runme.go
@@ -0,0 +1,66 @@
+package main
+
+import "strings"
+import "./threads_exception"
+
+func main() {
+ t := threads_exception.NewTest()
+
+ error := true
+ func() {
+ defer func() {
+ error = recover() == nil
+ }()
+ t.Unknown()
+ }()
+ if error {
+ panic(0)
+ }
+
+ error = true
+ func() {
+ defer func() {
+ error = strings.Index(recover().(string), "int exception") == -1
+ }()
+ t.Simple()
+ }()
+ if error {
+ panic(0)
+ }
+
+ error = true
+ func() {
+ defer func() {
+ error = recover().(string) != "I died."
+ }()
+ t.Message()
+ }()
+ if error {
+ panic(0)
+ }
+
+ error = true
+ func() {
+ defer func() {
+ e := recover().(string)
+ error = strings.Index(e, "Exc exception") == -1
+ }()
+ t.Hosed()
+ }()
+ if error {
+ panic(0)
+ }
+
+ for i := 1; i < 4; i++ {
+ error = true
+ func() {
+ defer func() {
+ error = recover() == nil
+ }()
+ t.Multi(i)
+ }()
+ if error {
+ panic(0)
+ }
+ }
+}
diff --git a/Examples/test-suite/go/typedef_class_runme.go b/Examples/test-suite/go/typedef_class_runme.go
new file mode 100644
index 000000000..ec25162de
--- /dev/null
+++ b/Examples/test-suite/go/typedef_class_runme.go
@@ -0,0 +1,11 @@
+package main
+
+import "./typedef_class"
+
+func main() {
+ a := typedef_class.NewRealA()
+ a.SetA(3)
+
+ b := typedef_class.NewB()
+ b.TestA(a)
+}
diff --git a/Examples/test-suite/go/typedef_inherit_runme.go b/Examples/test-suite/go/typedef_inherit_runme.go
new file mode 100644
index 000000000..49097999c
--- /dev/null
+++ b/Examples/test-suite/go/typedef_inherit_runme.go
@@ -0,0 +1,31 @@
+package main
+
+import "./typedef_inherit"
+
+func main() {
+ a := typedef_inherit.NewFoo()
+ b := typedef_inherit.NewBar()
+
+ x := typedef_inherit.Do_blah(a)
+ if x != "Foo::blah" {
+ panic(x)
+ }
+
+ x = typedef_inherit.Do_blah(b)
+ if x != "Bar::blah" {
+ panic(x)
+ }
+
+ c := typedef_inherit.NewSpam()
+ d := typedef_inherit.NewGrok()
+
+ x = typedef_inherit.Do_blah2(c)
+ if x != "Spam::blah" {
+ panic(x)
+ }
+
+ x = typedef_inherit.Do_blah2(d)
+ if x != "Grok::blah" {
+ panic(x)
+ }
+}
diff --git a/Examples/test-suite/go/typedef_scope_runme.go b/Examples/test-suite/go/typedef_scope_runme.go
new file mode 100644
index 000000000..1c4314427
--- /dev/null
+++ b/Examples/test-suite/go/typedef_scope_runme.go
@@ -0,0 +1,16 @@
+package main
+
+import "./typedef_scope"
+
+func main() {
+ b := typedef_scope.NewBar()
+ x := b.Test1(42, "hello")
+ if x != 42 {
+ panic("Failed!!")
+ }
+
+ xb := b.Test2(42, "hello")
+ if xb != "hello" {
+ panic("Failed!!")
+ }
+}
diff --git a/Examples/test-suite/go/typemap_namespace_runme.go b/Examples/test-suite/go/typemap_namespace_runme.go
new file mode 100644
index 000000000..45184fd1e
--- /dev/null
+++ b/Examples/test-suite/go/typemap_namespace_runme.go
@@ -0,0 +1,13 @@
+package main
+
+import . "./typemap_namespace"
+
+func main() {
+ if Test1("hello") != "hello" {
+ panic(0)
+ }
+
+ if Test2("hello") != "hello" {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/typemap_ns_using_runme.go b/Examples/test-suite/go/typemap_ns_using_runme.go
new file mode 100644
index 000000000..877e44b3a
--- /dev/null
+++ b/Examples/test-suite/go/typemap_ns_using_runme.go
@@ -0,0 +1,9 @@
+package main
+
+import "./typemap_ns_using"
+
+func main() {
+ if typemap_ns_using.Spam(37) != 37 {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/typemap_out_optimal_runme.go b/Examples/test-suite/go/typemap_out_optimal_runme.go
new file mode 100644
index 000000000..7cbd0ad9b
--- /dev/null
+++ b/Examples/test-suite/go/typemap_out_optimal_runme.go
@@ -0,0 +1,8 @@
+package main
+
+import . "./typemap_out_optimal"
+
+func main() {
+ SetXXDebug(false)
+ _ = XXCreate()
+}
diff --git a/Examples/test-suite/go/typename_runme.go b/Examples/test-suite/go/typename_runme.go
new file mode 100644
index 000000000..0bc15f11a
--- /dev/null
+++ b/Examples/test-suite/go/typename_runme.go
@@ -0,0 +1,13 @@
+package main
+
+import "./typename"
+
+func main() {
+ f := typename.NewFoo()
+ b := typename.NewBar()
+
+ var x float64 = typename.TwoFoo(f)
+ var y int = typename.TwoBar(b)
+ _ = x
+ _ = y
+}
diff --git a/Examples/test-suite/go/unions_runme.go b/Examples/test-suite/go/unions_runme.go
new file mode 100644
index 000000000..ba9c27b17
--- /dev/null
+++ b/Examples/test-suite/go/unions_runme.go
@@ -0,0 +1,51 @@
+// This is the union runtime testcase. It ensures that values within a
+// union embedded within a struct can be set and read correctly.
+
+package main
+
+import "./unions"
+
+func main() {
+ // Create new instances of SmallStruct and BigStruct for later use
+ small := unions.NewSmallStruct()
+ small.SetJill(200)
+
+ big := unions.NewBigStruct()
+ big.SetSmallstruct(small)
+ big.SetJack(300)
+
+ // Use SmallStruct then BigStruct to setup EmbeddedUnionTest.
+ // Ensure values in EmbeddedUnionTest are set correctly for each.
+ eut := unions.NewEmbeddedUnionTest()
+
+ // First check the SmallStruct in EmbeddedUnionTest
+ eut.SetNumber(1)
+ eut.GetUni().SetSmall(small)
+ Jill1 := eut.GetUni().GetSmall().GetJill()
+ if Jill1 != 200 {
+ panic("Runtime test1 failed")
+ }
+
+ Num1 := eut.GetNumber()
+ if Num1 != 1 {
+ panic("Runtime test2 failed")
+ }
+
+ // Secondly check the BigStruct in EmbeddedUnionTest
+ eut.SetNumber(2)
+ eut.GetUni().SetBig(big)
+ Jack1 := eut.GetUni().GetBig().GetJack()
+ if Jack1 != 300 {
+ panic("Runtime test3 failed")
+ }
+
+ Jill2 := eut.GetUni().GetBig().GetSmallstruct().GetJill()
+ if Jill2 != 200 {
+ panic("Runtime test4 failed")
+ }
+
+ Num2 := eut.GetNumber()
+ if Num2 != 2 {
+ panic("Runtime test5 failed")
+ }
+}
diff --git a/Examples/test-suite/go/using1_runme.go b/Examples/test-suite/go/using1_runme.go
new file mode 100644
index 000000000..8cc571288
--- /dev/null
+++ b/Examples/test-suite/go/using1_runme.go
@@ -0,0 +1,9 @@
+package main
+
+import "./using1"
+
+func main() {
+ if using1.Spam(37) != 37 {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/using2_runme.go b/Examples/test-suite/go/using2_runme.go
new file mode 100644
index 000000000..f679b0c40
--- /dev/null
+++ b/Examples/test-suite/go/using2_runme.go
@@ -0,0 +1,9 @@
+package main
+
+import "./using2"
+
+func main() {
+ if using2.Spam(37) != 37 {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/using_composition_runme.go b/Examples/test-suite/go/using_composition_runme.go
new file mode 100644
index 000000000..1602e9627
--- /dev/null
+++ b/Examples/test-suite/go/using_composition_runme.go
@@ -0,0 +1,44 @@
+package main
+
+import . "./using_composition"
+
+func main() {
+ f := NewFooBar()
+ if f.Blah(3).(int) != 3 {
+ panic("FooBar::blah(int)")
+ }
+
+ if f.Blah(float64(3.5)).(float64) != 3.5 {
+ panic("FooBar::blah(double)")
+ }
+
+ if f.Blah("hello").(string) != "hello" {
+ panic("FooBar::blah(char *)")
+ }
+
+ f2 := NewFooBar2()
+ if f2.Blah(3).(int) != 3 {
+ panic("FooBar2::blah(int)")
+ }
+
+ if f2.Blah(float64(3.5)).(float64) != 3.5 {
+ panic("FooBar2::blah(double)")
+ }
+
+ if f2.Blah("hello").(string) != "hello" {
+ panic("FooBar2::blah(char *)")
+ }
+
+ f3 := NewFooBar3()
+ if f3.Blah(3).(int) != 3 {
+ panic("FooBar3::blah(int)")
+ }
+
+ if f3.Blah(float64(3.5)).(float64) != 3.5 {
+ panic("FooBar3::blah(double)")
+ }
+
+ if f3.Blah("hello").(string) != "hello" {
+ panic("FooBar3::blah(char *)")
+ }
+}
diff --git a/Examples/test-suite/go/using_extend_runme.go b/Examples/test-suite/go/using_extend_runme.go
new file mode 100644
index 000000000..144fac47d
--- /dev/null
+++ b/Examples/test-suite/go/using_extend_runme.go
@@ -0,0 +1,30 @@
+package main
+
+import . "./using_extend"
+
+func main() {
+ f := NewFooBar()
+ if f.Blah(3).(int) != 3 {
+ panic("blah(int)")
+ }
+
+ if f.Blah(float64(3.5)).(float64) != 3.5 {
+ panic("blah(double)")
+ }
+
+ if f.Blah("hello").(string) != "hello" {
+ panic("blah(char *)")
+ }
+
+ if f.Blah(3, 4).(int) != 7 {
+ panic("blah(int,int)")
+ }
+
+ if f.Blah(float64(3.5), float64(7.5)).(float64) != (3.5 + 7.5) {
+ panic("blah(double,double)")
+ }
+
+ if f.Duh(3) != 3 {
+ panic("duh(int)")
+ }
+}
diff --git a/Examples/test-suite/go/using_inherit_runme.go b/Examples/test-suite/go/using_inherit_runme.go
new file mode 100644
index 000000000..669ed4d5f
--- /dev/null
+++ b/Examples/test-suite/go/using_inherit_runme.go
@@ -0,0 +1,59 @@
+package main
+
+import . "./using_inherit"
+
+func main() {
+ b := NewBar()
+ if b.Test(3).(int) != 3 {
+ panic("Bar::test(int)")
+ }
+
+ if b.Test(float64(3.5)).(float64) != 3.5 {
+ panic("Bar::test(double)")
+ }
+
+ b2 := NewBar2()
+ if b2.Test(3).(int) != 6 {
+ panic("Bar2::test(int)")
+ }
+
+ if b2.Test(float64(3.5)).(float64) != 7.0 {
+ panic("Bar2::test(double)")
+ }
+
+ b3 := NewBar3()
+ if b3.Test(3).(int) != 6 {
+ panic("Bar3::test(int)")
+ }
+
+ if b3.Test(float64(3.5)).(float64) != 7.0 {
+ panic("Bar3::test(double)")
+ }
+
+ b4 := NewBar4()
+ if b4.Test(3).(int) != 6 {
+ panic("Bar4::test(int)")
+ }
+
+ if b4.Test(float64(3.5)).(float64) != 7.0 {
+ panic("Bar4::test(double)")
+ }
+
+ bf1 := NewFred1()
+ if bf1.Test(3).(int) != 3 {
+ panic("Fred1::test(int)")
+ }
+
+ if bf1.Test(float64(3.5)).(float64) != 7.0 {
+ panic("Fred1::test(double)")
+ }
+
+ bf2 := NewFred2()
+ if bf2.Test(3).(int) != 3 {
+ panic("Fred2::test(int)")
+ }
+
+ if bf2.Test(float64(3.5)).(float64) != 7.0 {
+ panic("Fred2::test(double)")
+ }
+}
diff --git a/Examples/test-suite/go/using_private_runme.go b/Examples/test-suite/go/using_private_runme.go
new file mode 100644
index 000000000..d683ef856
--- /dev/null
+++ b/Examples/test-suite/go/using_private_runme.go
@@ -0,0 +1,20 @@
+package main
+
+import . "./using_private"
+
+func main() {
+ f := NewFooBar()
+ f.SetX(3)
+
+ if f.Blah(4) != 4 {
+ panic("blah(int)")
+ }
+
+ if f.Defaulted() != -1 {
+ panic("defaulted()")
+ }
+
+ if f.Defaulted(222) != 222 {
+ panic("defaulted(222)")
+ }
+}
diff --git a/Examples/test-suite/go/using_protected_runme.go b/Examples/test-suite/go/using_protected_runme.go
new file mode 100644
index 000000000..65edb5001
--- /dev/null
+++ b/Examples/test-suite/go/using_protected_runme.go
@@ -0,0 +1,12 @@
+package main
+
+import . "./using_protected"
+
+func main() {
+ f := NewFooBar()
+ f.SetX(3)
+
+ if f.Blah(4) != 4 {
+ panic("blah(int)")
+ }
+}
diff --git a/Examples/test-suite/go/varargs_runme.go b/Examples/test-suite/go/varargs_runme.go
new file mode 100644
index 000000000..4009c3ed3
--- /dev/null
+++ b/Examples/test-suite/go/varargs_runme.go
@@ -0,0 +1,26 @@
+package main
+
+import "./varargs"
+
+func main() {
+ if varargs.Test("Hello") != "Hello" {
+ panic("Failed")
+ }
+
+ f := varargs.NewFoo("Greetings")
+ if f.GetStr() != "Greetings" {
+ panic("Failed")
+ }
+
+ if f.Test("Hello") != "Hello" {
+ panic("Failed")
+ }
+
+ if varargs.Test_def("Hello", 1) != "Hello" {
+ panic("Failed")
+ }
+
+ if varargs.Test_def("Hello") != "Hello" {
+ panic("Failed")
+ }
+}
diff --git a/Examples/test-suite/go/virtual_derivation_runme.go b/Examples/test-suite/go/virtual_derivation_runme.go
new file mode 100644
index 000000000..48a7033a2
--- /dev/null
+++ b/Examples/test-suite/go/virtual_derivation_runme.go
@@ -0,0 +1,12 @@
+package main
+
+import . "./virtual_derivation"
+
+// very innocent example
+
+func main() {
+ b := NewB(3)
+ if b.Get_a() != b.Get_b() {
+ panic("something is really wrong")
+ }
+}
diff --git a/Examples/test-suite/go/virtual_poly_runme.go b/Examples/test-suite/go/virtual_poly_runme.go
new file mode 100644
index 000000000..7048ba8cf
--- /dev/null
+++ b/Examples/test-suite/go/virtual_poly_runme.go
@@ -0,0 +1,43 @@
+package main
+
+import "./virtual_poly"
+
+func main() {
+ d := virtual_poly.NewNDouble(3.5)
+ i := virtual_poly.NewNInt(2)
+
+ // the copy methods return the right polymorphic types
+ dc := d.Copy()
+ ic := i.Copy()
+
+ if d.Get() != dc.Get() {
+ panic(0)
+ }
+
+ if i.Get() != ic.Get() {
+ panic(0)
+ }
+
+ virtual_poly.Incr(ic)
+
+ if (i.Get() + 1) != ic.Get() {
+ panic(0)
+ }
+
+ dr := d.Ref_this()
+ if d.Get() != dr.Get() {
+ panic(0)
+ }
+
+
+ // 'narrowing' also works
+ ddc := virtual_poly.NDoubleNarrow(d.Nnumber())
+ if d.Get() != ddc.Get() {
+ panic(0)
+ }
+
+ dic := virtual_poly.NIntNarrow(i.Nnumber())
+ if i.Get() != dic.Get() {
+ panic(0)
+ }
+}
diff --git a/Examples/test-suite/go/voidtest_runme.go b/Examples/test-suite/go/voidtest_runme.go
new file mode 100644
index 000000000..0a685f081
--- /dev/null
+++ b/Examples/test-suite/go/voidtest_runme.go
@@ -0,0 +1,26 @@
+package main
+
+import "./voidtest"
+
+func main() {
+ voidtest.Globalfunc()
+ f := voidtest.NewFoo()
+ f.Memberfunc()
+
+ voidtest.FooStaticmemberfunc()
+
+ v1 := voidtest.Vfunc1(f.Swigcptr())
+ v2 := voidtest.Vfunc2(f)
+ if v1 != v2 {
+ panic(0)
+ }
+
+ v3 := voidtest.Vfunc3(v1)
+
+ v4 := voidtest.Vfunc1(f.Swigcptr())
+ if v4 != v1 {
+ panic(0)
+ }
+
+ v3.Memberfunc()
+}
diff --git a/Examples/test-suite/go/wrapmacro_runme.go b/Examples/test-suite/go/wrapmacro_runme.go
new file mode 100644
index 000000000..4d3791be8
--- /dev/null
+++ b/Examples/test-suite/go/wrapmacro_runme.go
@@ -0,0 +1,11 @@
+package main
+
+import "./wrapmacro"
+
+func main() {
+ a := 2
+ b := -1
+ wrapmacro.Maximum(a, b)
+ wrapmacro.Maximum(a/7.0, -b*256)
+ wrapmacro.GUINT16_SWAP_LE_BE_CONSTANT(1)
+}
diff --git a/Examples/test-suite/keyword_rename.i b/Examples/test-suite/keyword_rename.i
index da9328868..6a6082ff9 100644
--- a/Examples/test-suite/keyword_rename.i
+++ b/Examples/test-suite/keyword_rename.i
@@ -27,6 +27,10 @@ KW(synchronized, final)
KW(string, out)
struct sealed {int i;};
+/* Go Keywords */
+KW(go, defer)
+KW(chan, fallthrough)
+
%}
diff --git a/Examples/test-suite/minherit.i b/Examples/test-suite/minherit.i
index fed8b029c..82d1f3cce 100644
--- a/Examples/test-suite/minherit.i
+++ b/Examples/test-suite/minherit.i
@@ -6,7 +6,7 @@
%module(ruby_minherit="1") minherit
-#if defined(SWIGPYTHON) || defined(SWIGRUBY) || defined(SWIGOCAML) || defined(SWIGOCTAVE) || defined(SWIGPERL)
+#if defined(SWIGPYTHON) || defined(SWIGRUBY) || defined(SWIGOCAML) || defined(SWIGOCTAVE) || defined(SWIGPERL) || defined(SWIGGO)
%inline %{
diff --git a/Examples/test-suite/name_warnings.i b/Examples/test-suite/name_warnings.i
index 4032f20e1..3455c03bf 100644
--- a/Examples/test-suite/name_warnings.i
+++ b/Examples/test-suite/name_warnings.i
@@ -40,7 +40,9 @@ namespace std
#endif
virtual ~A() {}
+#ifndef SWIGGO // func is a keyword in Go.
virtual int func() = 0;
+#endif
private:
typedef complex False;
};
diff --git a/Examples/test-suite/namespace_typemap.i b/Examples/test-suite/namespace_typemap.i
index 984b93a6f..4952aa7ad 100644
--- a/Examples/test-suite/namespace_typemap.i
+++ b/Examples/test-suite/namespace_typemap.i
@@ -70,6 +70,15 @@ namespace test {
delete $1;
}
#endif
+#ifdef SWIGGO
+%typemap(go) test::test_complex * "complex128"
+%typemap(in) test::test_complex * {
+ $1 = new test_complex(__real__ $input, __imag__ $input);
+}
+%typemap(freearg) test::test_complex * {
+ delete $1;
+}
+#endif
namespace test {
class string_class;
@@ -97,6 +106,15 @@ namespace test {
delete $1;
}
#endif
+#ifdef SWIGGO
+ %typemap(go) string_class * "string"
+ %typemap(in) string_class * {
+ $1 = new string_class($input.p);
+ }
+ %typemap(freearg) string_class * {
+ delete $1;
+ }
+#endif
}
%inline %{
@@ -240,6 +258,14 @@ namespace Split {
}
}
#endif
+#ifdef SWIGGO
+ %typemap(in) PosInteger {
+ $1 = $input;
+ if ($1 < 0) {
+ _swig_gopanic("domain error");
+ }
+ }
+#endif
}
%inline %{
diff --git a/Examples/test-suite/null_pointer.i b/Examples/test-suite/null_pointer.i
index 59d554c2b..0bd7a9b92 100644
--- a/Examples/test-suite/null_pointer.i
+++ b/Examples/test-suite/null_pointer.i
@@ -1,5 +1,7 @@
%module null_pointer
+%warnfilter(SWIGWARN_PARSE_KEYWORD) func; // 'func' is a Go keyword, renamed as 'Xfunc'
+
%inline {
struct A {};
diff --git a/Examples/test-suite/overload_simple.i b/Examples/test-suite/overload_simple.i
index be7602083..b08777854 100644
--- a/Examples/test-suite/overload_simple.i
+++ b/Examples/test-suite/overload_simple.i
@@ -14,6 +14,8 @@
%warnfilter(SWIGWARN_LANG_OVERLOAD_SHADOW) fid;
#endif
+%warnfilter(SWIGWARN_PARSE_KEYWORD) type; // 'type' is a Go keyword, renamed as 'Xtype'
+
#ifndef SWIG_NO_OVERLOAD
%immutable Spam::type;
diff --git a/Examples/test-suite/return_const_value.i b/Examples/test-suite/return_const_value.i
index 1d688d175..473878521 100644
--- a/Examples/test-suite/return_const_value.i
+++ b/Examples/test-suite/return_const_value.i
@@ -4,6 +4,8 @@ It was reported in bug 899332 by Jermey Brown (jhbrown94) */
%module return_const_value
+%ignore Foo_ptr::operator=(const Foo_ptr&);
+
%inline %{
class Foo {
@@ -35,7 +37,12 @@ public:
{
f._own = 0;
}
-
+
+ Foo_ptr& operator=(const Foo_ptr& f) {
+ _ptr = f._ptr;
+ _own = f._own;
+ f._own = 0;
+ }
~Foo_ptr() {
if(_own) delete _ptr;
diff --git a/Examples/test-suite/rname.i b/Examples/test-suite/rname.i
index dde71f203..31b99833d 100644
--- a/Examples/test-suite/rname.i
+++ b/Examples/test-suite/rname.i
@@ -22,7 +22,12 @@
%rename (newname) Base::oldname(double d) const;
/* Rename derived class method only */
+#ifndef SWIGGO
%rename (func) Derived::fn(Base baseValue, Base* basePtr, Base& baseRef);
+#else
+/* func is a keyword in Go. */
+%rename (Xfunc) Derived::fn(Base baseValue, Base* basePtr, Base& baseRef);
+#endif
%inline %{
class Bar {
diff --git a/Examples/test-suite/typemap_namespace.i b/Examples/test-suite/typemap_namespace.i
index b3fa1a733..6bf53e989 100644
--- a/Examples/test-suite/typemap_namespace.i
+++ b/Examples/test-suite/typemap_namespace.i
@@ -25,9 +25,12 @@ namespace Foo {
%typemap(jstype) Str1 * = char *;
%typemap(javain) Str1 * = char *;
%typemap(javaout) Str1 * = char *;
+#endif
+#ifdef SWIGGO
+ %typemap(go) Str1 * = char *;
#endif
%typemap(in) Str1 * = char *;
-#if !(defined(SWIGCSHARP) || defined(SWIGLUA) || defined(SWIGPHP) || defined(SWIGMZSCHEME) || defined(SWIGOCAML))
+#if !(defined(SWIGCSHARP) || defined(SWIGLUA) || defined(SWIGPHP) || defined(SWIGMZSCHEME) || defined(SWIGOCAML) || defined(SWIGGO))
%typemap(freearg) Str1 * = char *;
#endif
%typemap(typecheck) Str1 * = char *;
diff --git a/Examples/test-suite/typemap_subst.i b/Examples/test-suite/typemap_subst.i
index d5a8416db..1b1f8a3f4 100644
--- a/Examples/test-suite/typemap_subst.i
+++ b/Examples/test-suite/typemap_subst.i
@@ -61,8 +61,8 @@
$1 = ($ltype) temp;
}
-/* Java and C# modules don't use SWIG's runtime type system */
-#if !defined(SWIGJAVA) && !defined(SWIGCSHARP)
+/* Java, C# and Go modules don't use SWIG's runtime type system */
+#if !defined(SWIGJAVA) && !defined(SWIGCSHARP) && !defined(SWIGGO)
%inline %{
void foo(const struct xyzzy **TEST) {}
%}
diff --git a/Examples/test-suite/union_parameter.i b/Examples/test-suite/union_parameter.i
index bb010d3fa..ed7bcacf8 100644
--- a/Examples/test-suite/union_parameter.i
+++ b/Examples/test-suite/union_parameter.i
@@ -1,5 +1,7 @@
%module union_parameter
+%warnfilter(SWIGWARN_PARSE_KEYWORD) type; // 'type' is a Go keyword, renamed as 'Xtype'
+
%inline %{
typedef unsigned char Uint8;
diff --git a/Lib/go/cdata.i b/Lib/go/cdata.i
new file mode 100644
index 000000000..c3307945a
--- /dev/null
+++ b/Lib/go/cdata.i
@@ -0,0 +1,135 @@
+/* -----------------------------------------------------------------------------
+ * cdata.i
+ *
+ * SWIG library file containing macros for manipulating raw C data as strings.
+ * ----------------------------------------------------------------------------- */
+
+%{
+typedef struct SWIGCDATA {
+ char *data;
+ int len;
+} SWIGCDATA;
+%}
+
+%typemap(go) SWIGCDATA %{ []byte %}
+%typemap(out) SWIGCDATA (swigcdata argp) {
+ argp = _swig_makegobyteslice($1.data, $1.len);
+ $result.data = (char*)argp.data;
+ $result.len = (int)argp.len;
+}
+
+/* The makegobyteslice function. */
+
+%insert(runtime) %{
+typedef struct {
+ char *data;
+ int len;
+} swigcdata;
+
+%}
+
+#ifndef SWIGGO_GCCGO
+%insert(runtime) %{
+extern
+#ifdef __cplusplus
+"C"
+#endif
+void _swig_gc_makegobyteslice(void *, int);
+static swigcdata _swig_makegobyteslice(const char *data, int len) {
+ struct {
+ const char *data;
+ int len;
+ swigcdata ret;
+ } a;
+ a.data = data;
+ a.len = len;
+ crosscall2(_swig_gc_makegobyteslice, &a, (int) sizeof a);
+ return a.ret;
+}
+%}
+
+%insert(gc_header) %{
+typedef struct {
+ byte *data;
+ int32 len;
+} swigcdata;
+extern void ·_swig_internal_makegobyteslice(void);
+#pragma dynexport _swig_gc_makegobyteslice _swig_gc_makegobyteslice
+void _swig_gc_makegobyteslice(void *a, int32 n) {
+ cgocallback(·_swig_internal_makegobyteslice, a, n);
+}
+void ·_swig_allocategobyteslice(byte *data, int32 len, swigcdata ret) {
+ ret.data = mal(len);
+ mcpy(ret.data, data, len);
+ ret.len = len;
+ FLUSH(&ret);
+}
+%}
+
+%insert(go_header) %{
+type swigcdata struct { data *byte; len int }
+func _swig_allocategobyteslice(*byte, int) swigcdata
+func _swig_internal_makegobyteslice(data *byte, len int) swigcdata {
+ return _swig_allocategobyteslice(data, len)
+}
+%}
+
+#else
+
+%insert(runtime) %{
+static swigcdata _swig_makegobyteslice(const char *data, int len) {
+ swigcdata ret;
+ ret.data = (char*)__go_alloc(len);
+ memcpy(ret.data, data, len);
+ ret.len = (int)len;
+ return ret;
+}
+
+%}
+
+#endif
+
+/* -----------------------------------------------------------------------------
+ * %cdata(TYPE [, NAME])
+ *
+ * Convert raw C data to a binary string.
+ * ----------------------------------------------------------------------------- */
+
+%define %cdata(TYPE,NAME...)
+
+%insert("header") {
+#if #NAME == ""
+static SWIGCDATA cdata_##TYPE(TYPE *ptr, int nelements) {
+#else
+static SWIGCDATA cdata_##NAME(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;
+}
+}
+
+%typemap(default) int nelements "$1 = 1;"
+
+#if #NAME == ""
+SWIGCDATA cdata_##TYPE(TYPE *ptr, int nelements);
+#else
+SWIGCDATA cdata_##NAME(TYPE *ptr, int nelements);
+#endif
+%enddef
+
+%typemap(default) int nelements;
+
+%rename(cdata) ::cdata_void(void *ptr, int nelements);
+
+%cdata(void);
+
+/* Memory move function. Due to multi-argument typemaps this appears
+ to be wrapped as
+ void memmove(void *data, const char *s); */
+void memmove(void *data, char *indata, int inlen);
diff --git a/Lib/go/exception.i b/Lib/go/exception.i
new file mode 100644
index 000000000..5abd306a4
--- /dev/null
+++ b/Lib/go/exception.i
@@ -0,0 +1,7 @@
+%typemap(throws,noblock=1) (...) {
+ SWIG_exception(SWIG_RuntimeError,"unknown exception");
+}
+
+%insert("runtime") %{
+#define SWIG_exception(code, msg) _swig_gopanic(msg)
+%}
diff --git a/Lib/go/go.swg b/Lib/go/go.swg
new file mode 100644
index 000000000..b1b8860df
--- /dev/null
+++ b/Lib/go/go.swg
@@ -0,0 +1,514 @@
+/* ------------------------------------------------------------
+ * go.swg
+ *
+ * Go configuration module.
+ * ------------------------------------------------------------ */
+
+/* Basic types */
+
+%typemap(go) bool, const bool & "bool"
+%typemap(go) char, const char & "byte"
+%typemap(go) signed char, const signed char & "int8"
+%typemap(go) unsigned char, const unsigned char & "byte"
+%typemap(go) short, const short & "int16"
+%typemap(go) unsigned short, const unsigned short & "uint16"
+%typemap(go) int, const int & "int"
+%typemap(go) unsigned int, const unsigned int & "uint"
+#if SWIGGO_LONG_TYPE_SIZE == 32
+%typemap(go) long, const long & "int32"
+%typemap(go) unsigned long, const unsigned long & "uint32"
+#elif SWIGGO_LONG_TYPE_SIZE == 64
+%typemap(go) long, const long & "int64"
+%typemap(go) unsigned long, const unsigned long & "uint64"
+#else
+#error "SWIGGO_LONG_TYPE_SIZE not 32 or 64"
+#endif
+%typemap(go) long long, const long long & "int64"
+%typemap(go) unsigned long long, const unsigned long long & "uint64"
+%typemap(go) float, const float & "float32"
+%typemap(go) double, const double & "float64"
+
+%typemap(in) bool,
+ char,
+ signed char,
+ unsigned char,
+ short,
+ unsigned short,
+ int,
+ unsigned int,
+ long,
+ unsigned long,
+ long long,
+ unsigned long long,
+ float,
+ double
+%{ $1 = ($1_ltype)$input; %}
+
+%typemap(in) const bool &,
+ const char &,
+ const signed char &,
+ const unsigned char &,
+ const short &,
+ const unsigned short &,
+ const int &,
+ const unsigned int &,
+ const long &,
+ const unsigned long &,
+ const long long &,
+ const unsigned long long &,
+ const float &,
+ const double &
+%{ $1 = ($1_ltype)&$input; %}
+
+%typemap(out) bool,
+ char,
+ signed char,
+ unsigned char,
+ short,
+ unsigned short,
+ int,
+ unsigned int,
+ long,
+ unsigned long,
+ long long,
+ unsigned long long,
+ float,
+ double
+%{ $result = $1; %}
+
+%typemap(out) const bool &,
+ const char &,
+ const signed char &,
+ const unsigned char &,
+ const short &,
+ const unsigned short &,
+ const int &,
+ const unsigned int &,
+ const long &,
+ const unsigned long &,
+ const long long &,
+ const unsigned long long &,
+ const float &,
+ const double &
+%{ $result = ($*1_ltype)*$1; %}
+
+%typemap(out) void ""
+
+%typemap(directorin) bool,
+ char,
+ signed char,
+ unsigned char,
+ short,
+ unsigned short,
+ int,
+ unsigned int,
+ long,
+ unsigned long,
+ long long,
+ unsigned long long,
+ float,
+ double
+%{ $input = ($1_ltype)$1_name; %}
+
+%typemap(directorin) const bool &,
+ const char &,
+ const signed char &,
+ const unsigned char &,
+ const short &,
+ const unsigned short &,
+ const int &,
+ const unsigned int &,
+ const long &,
+ const unsigned long &,
+ const long long &,
+ const unsigned long long &,
+ const float &,
+ const double &
+%{ $input = ($*1_ltype)$1_name; %}
+
+%typemap(directorout) bool,
+ char,
+ signed char,
+ unsigned char,
+ short,
+ unsigned short,
+ int,
+ unsigned int,
+ long,
+ unsigned long,
+ long long,
+ unsigned long long,
+ float,
+ double
+%{ $result = ($1_ltype)$input; %}
+
+%typemap(directorout) const bool &,
+ const char &,
+ const signed char &,
+ const unsigned char &,
+ const short &,
+ const unsigned short &,
+ const int &,
+ const unsigned int &,
+ const long &,
+ const unsigned long &,
+ const long long &,
+ const unsigned long long &,
+ const float &,
+ const double &
+%{
+ $result = ($1_ltype)_swig_allocate(sizeof($*1_ltype));
+ *$result = *($1_ltype)$input;
+%}
+
+/* The size_t type. */
+
+#if SWIGGO_LONG_TYPE_SIZE == 32
+%typemap(go) size_t, const size_t & %{int%}
+#else
+%typemap(go) size_t, const size_t & %{int64%}
+#endif
+
+%typemap(in) size_t
+%{ $1 = (size_t)$input; %}
+
+%typemap(in) const size_t &
+%{ $1 = ($1_ltype)&$input; %}
+
+%typemap(out) size_t
+%{ $result = $1; %}
+
+%typemap(out) const size_t &
+%{ $result = ($*1_ltype)*$1; %}
+
+%typemap(directorin) size_t
+%{ $input = (size_t)$1_name; %}
+
+%typemap(directorin) const size_t &
+%{ $input = ($*1_ltype)$1_name; %}
+
+%typemap(directorout) size_t
+%{ $result = ($1_ltype)$input; %}
+
+%typemap(directorout) const size_t &
+%{
+ $result = ($1_ltype)_swig_allocate(sizeof($*1_ltype));
+ *$result = *($1_ltype)$input;
+%}
+
+/* Member pointers. */
+
+%typemap(go) SWIGTYPE (CLASS::*)
+%{$gotypename%}
+
+%typemap(in) SWIGTYPE (CLASS::*)
+%{ $1 = *($&1_ltype)$input; %}
+
+%typemap(out) SWIGTYPE (CLASS::*)
+%{
+ $result = _swig_allocate(sizeof($1_ltype));
+ *($&1_ltype)$result = $1;
+%}
+
+%typemap(directorin) SWIGTYPE (CLASS::*)
+%{ $input = *($&1_ltype)$1_name; %}
+
+%typemap(directorout) SWIGTYPE (CLASS::*)
+%{
+ $result = _swig_allocate(sizeof($1_ltype));
+ *($&1_ltype)$result = $input;
+%}
+
+/* Pointers. */
+
+/* We can't translate pointers using a typemap, so that is handled in
+ the C++ code. */
+%typemap(go) SWIGTYPE *
+%{$gotypename%}
+
+%typemap(in) SWIGTYPE *
+%{ $1 = *($&1_ltype)&$input; %}
+
+%typemap(out) SWIGTYPE *
+%{ *($&1_ltype)&$result = $1; %}
+
+%typemap(directorin) SWIGTYPE *
+%{ $input = ($1_ltype)$1_name; %}
+
+%typemap(directorout) SWIGTYPE *
+%{ $result = ($1_ltype)$input; %}
+
+%apply SWIGTYPE * { SWIGTYPE *const }
+
+/* Pointer references. */
+
+%typemap(go) SWIGTYPE *const&
+%{$gotypename%}
+
+%typemap(in) SWIGTYPE *const& ($*1_ltype temp = 0)
+%{
+ temp = *($1_ltype)&$input;
+ $1 = ($1_ltype)&temp;
+%}
+
+%typemap(out) SWIGTYPE *const&
+%{ *($1_ltype)&$result = *$1; %}
+
+/* Function pointers are translated by the code in go.cxx into
+ _swig_fnptr. Member pointers are translated to _swig_memberptr. */
+
+%insert(go_header) %{
+type _swig_fnptr *byte
+type _swig_memberptr *byte
+%}
+
+/* References. */
+
+/* Converting a C++ reference to Go has to be handled in the C++
+ code. */
+%typemap(go) SWIGTYPE &
+%{$gotypename%}
+
+%typemap(in) SWIGTYPE &
+%{ $1 = *($&1_ltype)&$input; %}
+
+%typemap(out) SWIGTYPE &
+%{ *($&1_ltype)&$result = $1; %}
+
+%typemap(directorin) SWIGTYPE &
+%{ $input = ($1_ltype)&$1_name; %}
+
+%typemap(directorout) SWIGTYPE &
+%{ *($&1_ltype)&$result = $input; %}
+
+/* C arrays turn into Go pointers. If we know the length we can use a
+ slice. */
+
+%typemap(go) SWIGTYPE []
+%{$gotypename%}
+
+%typemap(in) SWIGTYPE []
+%{ $1 = *($&1_ltype)&$input; %}
+
+%typemap(out) SWIGTYPE []
+%{ *($&1_ltype)&$result = $1; %}
+
+%typemap(directorin) SWIGTYPE []
+%{ $input = *($1_ltype)&$1_name; %}
+
+%typemap(directorout) SWIGTYPE []
+%{ *($&1_ltype)&$result = $input; %}
+
+/* Strings. */
+
+%typemap(go)
+ char *, char *&, char[ANY], char[],
+ signed char *, signed char *&, signed char[ANY], signed char[],
+ unsigned char *, unsigned char *&, unsigned char[ANY], unsigned char[]
+"string"
+
+/* Needed to avoid confusion with the way the go module handles
+ references. */
+%typemap(go) char&, unsigned char& "*byte"
+%typemap(go) signed char& "*int8"
+
+%typemap(in)
+ char *, char[ANY], char[],
+ signed char *, signed char[ANY], signed char[],
+ unsigned char *, unsigned char[ANY], unsigned char[]
+%{ $1 = ($1_ltype)$input.p; %}
+
+%typemap(in) char *&, signed char *&, unsigned char *&
+%{ $1 = ($1_ltype)$input.p; %}
+
+%typemap(out)
+ char *, char *&, char[ANY], char[],
+ signed char *, signed char *&, signed char[ANY], signed char[],
+ unsigned char *, unsigned char *&, unsigned char[ANY], unsigned char[]
+%{ $result = _swig_makegostring((char*)$1, $1 ? strlen((char*)$1) : 0); %}
+
+%typemap(directorin)
+ char *, char *&, char[ANY], char[],
+ signed char *, signed char *&, signed char[ANY], signed char[],
+ unsigned char *, unsigned char *&, unsigned char[ANY], unsigned char[]
+%{
+ $input = _swig_makegostring((char*)$1_name, $1_name ? strlen((char*)$1_name) : 0);
+%}
+
+%typemap(directorout)
+ char *, char *&, char[ANY], char[],
+ signed char *, signed char *&, signed char[ANY], signed char[],
+ unsigned char *, unsigned char *&, unsigned char[ANY], unsigned char[]
+%{ $result = ($1_ltype)$input.p; %}
+
+/* Enums. We can't do the right thing for enums in typemap(go) so we
+ deliberately don't define them. The right thing would be to
+ capitalize the name. This is instead done in go.cxx. */
+
+%typemap(go) enum SWIGTYPE
+%{$gotypename%}
+
+%typemap(in) enum SWIGTYPE
+%{ $1 = ($1_ltype)$input; %}
+
+%typemap(out) enum SWIGTYPE
+%{ $result = $1; %}
+
+%typemap(directorin) enum SWIGTYPE
+%{ $input = ($1_ltype)$1_name; %}
+
+%typemap(directorout) enum SWIGTYPE
+%{ $result = ($1_ltype)$input; %}
+
+/* Arbitrary type. This is a type passed by value in the C/C++ code.
+ We convert it to a pointer for the Go code. Note that all basic
+ types are explicitly handled above. */
+
+%typemap(go) SWIGTYPE
+%{$gotypename%}
+
+%typemap(in) SWIGTYPE ($&1_type argp)
+%{
+ argp = ($&1_ltype)$input;
+ if (argp == NULL) {
+ _swig_gopanic("Attempt to dereference null $1_type");
+ }
+ $1 = ($1_ltype)*argp;
+%}
+
+%typemap(out) SWIGTYPE
+#ifdef __cplusplus
+%{ *($&1_ltype*)&$result = new $1_ltype($1); %}
+#else
+{
+ $&1_ltype $1ptr = ($&1_ltype)malloc(sizeof($1_ltype));
+ memmove($1ptr, &$1, sizeof($1_type));
+ *($&1_ltype*)&$result = $1ptr;
+}
+#endif
+
+%typemap(directorin) SWIGTYPE
+%{ $input = ($&1_ltype)&$1_name; %}
+
+%typemap(directorout) SWIGTYPE
+%{ $result = *($&1_ltype)$input; %}
+
+/* Exception handling */
+
+%typemap(throws) char *
+%{ _swig_gopanic($1); %}
+
+%typemap(throws) SWIGTYPE, SWIGTYPE &, SWIGTYPE *, SWIGTYPE [], SWIGTYPE [ANY]
+%{
+ (void)$1;
+ _swig_gopanic("C++ $1_type exception thrown");
+%}
+
+/* Typecheck typemaps. The purpose of these is merely to issue a
+ warning for overloaded C++ functions * that cannot be overloaded in
+ Go as more than one C++ type maps to a single Go type. */
+
+%typecheck(SWIG_TYPECHECK_BOOL) /* Go bool */
+ bool,
+ const bool &
+ ""
+
+%typecheck(SWIG_TYPECHECK_CHAR) /* Go byte */
+ char,
+ const char &,
+ unsigned char,
+ const unsigned char &
+ ""
+
+%typecheck(SWIG_TYPECHECK_INT8) /* Go int8 */
+ signed char,
+ const signed char &
+ ""
+
+%typecheck(SWIG_TYPECHECK_INT16) /* Go int16 */
+ short,
+ const short &
+ ""
+
+%typecheck(SWIG_TYPECHECK_INT16) /* Go uint16 */
+ unsigned short,
+ const unsigned short &
+ ""
+
+%typecheck(SWIG_TYPECHECK_INT32) /* Go int */
+ int,
+ const int &
+ ""
+
+%typecheck(SWIG_TYPECHECK_INT32) /* Go uint */
+ unsigned int,
+ const unsigned int &
+ ""
+
+#if SWIGGO_LONG_TYPE_SIZE == 32
+%typecheck(SWIG_TYPECHECK_INT32) /* Go int32 */
+ long,
+ const long &
+ ""
+
+%typecheck(SWIG_TYPECHECK_INT32) /* Go uint32 */
+ unsigned long,
+ const unsigned long &
+ ""
+#endif
+
+%typecheck(SWIG_TYPECHECK_INT64) /* Go int64 */
+#if SWIGGO_LONG_TYPE_SIZE == 64
+ long,
+ const long &,
+#endif
+ long long,
+ const long long &
+ ""
+
+%typecheck(SWIG_TYPECHECK_INT64) /* Go uint64 */
+#if SWIGGO_LONG_TYPE_SIZE == 64
+ unsigned long,
+ const unsigned long &,
+#endif
+ unsigned long long,
+ const unsigned long long &
+ ""
+
+%typecheck(SWIG_TYPECHECK_FLOAT) /* Go float32 */
+ float,
+ const float &
+ ""
+
+%typecheck(SWIG_TYPECHECK_DOUBLE) /* Go float64 */
+ double,
+ const double &
+ ""
+
+%typecheck(SWIG_TYPECHECK_STRING) /* Go string */
+ char *,
+ char *&,
+ char[ANY],
+ char [],
+ signed char *,
+ signed char *&,
+ signed char[ANY],
+ signed char [],
+ unsigned char *,
+ unsigned char *&,
+ unsigned char[ANY],
+ unsigned char []
+ ""
+
+%typecheck(SWIG_TYPECHECK_POINTER)
+ SWIGTYPE,
+ SWIGTYPE *,
+ SWIGTYPE &,
+ SWIGTYPE *const&,
+ SWIGTYPE [],
+ SWIGTYPE (CLASS::*)
+ ""
+/* Go keywords. */
+%include
+
+%include
diff --git a/Lib/go/gokw.swg b/Lib/go/gokw.swg
new file mode 100644
index 000000000..e7506d053
--- /dev/null
+++ b/Lib/go/gokw.swg
@@ -0,0 +1,31 @@
+/* Rename keywords. */
+
+#define GOKW(x) %keywordwarn("'" `x` "' is a Go keyword, renaming to 'X"`x`"'",rename="X%s") `x`
+
+GOKW(break);
+GOKW(case);
+GOKW(chan);
+GOKW(const);
+GOKW(continue);
+GOKW(default);
+GOKW(defer);
+GOKW(else);
+GOKW(fallthrough);
+GOKW(for);
+GOKW(func);
+GOKW(go);
+GOKW(goto);
+GOKW(if);
+GOKW(import);
+GOKW(interface);
+GOKW(map);
+GOKW(package);
+GOKW(range);
+GOKW(return);
+GOKW(select);
+GOKW(struct);
+GOKW(switch);
+GOKW(type);
+GOKW(var);
+
+#undef GOKW
diff --git a/Lib/go/goruntime.swg b/Lib/go/goruntime.swg
new file mode 100644
index 000000000..5a51fd4b6
--- /dev/null
+++ b/Lib/go/goruntime.swg
@@ -0,0 +1,208 @@
+/* ------------------------------------------------------------
+ * goruntime.swg
+ *
+ * Go runtime code for the various generated files.
+ * ------------------------------------------------------------ */
+
+%insert(runtime) %{
+#include
+#include
+#include
+
+typedef struct { char *p; int n; } _gostring_;
+typedef struct { void* array; unsigned int len; unsigned int cap; } _goslice_;
+
+%}
+
+#ifndef SWIGGO_GCCGO
+/* Boilerplate for C/C++ code when using 6g/8g. This code is compiled
+ with gcc. */
+%insert(runtime) %{
+
+#define __goswig_size_assert_eq(x, y, name) typedef char name[(x-y)*(x-y)*-2+1];
+#define __goswig_size_assert(t, n) __goswig_size_assert_eq(sizeof(t), n, _goswig_sizeof_##t##_is_not_##n)
+
+__goswig_size_assert(char, 1)
+__goswig_size_assert(short, 2)
+__goswig_size_assert(int, 4)
+typedef long long __goswig_long_long;
+__goswig_size_assert(__goswig_long_long, 8)
+__goswig_size_assert(float, 4)
+__goswig_size_assert(double, 8)
+
+extern
+#ifdef __cplusplus
+"C"
+#endif
+void crosscall2(void (*fn)(void *, int), void *, int);
+
+extern
+#ifdef __cplusplus
+"C"
+#endif
+void _swig_gc_allocate(void *, int);
+static void *_swig_allocate(int len) {
+ struct {
+ int len;
+ void *ret;
+ } a;
+ a.len = len;
+ crosscall2(_swig_gc_allocate, &a, (int) sizeof a);
+ return a.ret;
+}
+
+extern
+#ifdef __cplusplus
+"C"
+#endif
+void _swig_gc_makegostring(void *, int);
+static _gostring_ _swig_makegostring(const char *p, size_t l) {
+ struct {
+ const char *p;
+ int l;
+ _gostring_ ret;
+ } a;
+ a.p = p;
+ a.l = l;
+ crosscall2(_swig_gc_makegostring, &a, (int) sizeof a);
+ return a.ret;
+}
+
+extern
+#ifdef __cplusplus
+"C"
+#endif
+void _swig_gc_gopanic(void *, int);
+static void _swig_gopanic(const char *p) {
+ struct {
+ const char *p;
+ int l;
+ } a;
+ a.p = p;
+ a.l = strlen(p);
+ crosscall2(_swig_gc_gopanic, &a, (int) sizeof a);
+}
+
+%}
+
+/* Boilerplate for C code when using 6g/8g. This code is compiled
+ with 6c/8c. */
+%insert(gc_header) %{
+#include "runtime.h"
+#include "cgocall.h"
+
+#pragma dynimport initcgo initcgo "libcgo.so"
+#pragma dynimport libcgo_thread_start libcgo_thread_start "libcgo.so"
+#pragma dynimport libcgo_set_scheduler libcgo_set_scheduler "libcgo.so"
+
+#ifdef _64BIT
+#define SWIG_PARM_SIZE 8
+#else
+#define SWIG_PARM_SIZE 4
+#endif
+%}
+
+/* 6g/8g C boilerplate that is only needed once in a program. This
+ only gets added to the file if nothing is imported. */
+%insert(gc_once) %{
+
+extern void ·_swig_internal_allocate(void);
+#pragma dynexport _swig_gc_allocate _swig_gc_allocate
+void _swig_gc_allocate(void *a, int32 n) {
+ cgocallback(·_swig_internal_allocate, a, n);
+}
+
+void ·_swig_allocatememory(int32 len, byte *ret) {
+ ret = mal(len);
+ FLUSH(&ret);
+}
+
+extern void ·_swig_internal_makegostring(void);
+#pragma dynexport _swig_gc_makegostring _swig_gc_makegostring
+void _swig_gc_makegostring(void *a, int32 n) {
+ cgocallback(·_swig_internal_makegostring, a, n);
+}
+
+void ·_swig_allocatestring(byte *p, int32 l, String ret) {
+ ret.str = mal(l+1);
+ mcpy(ret.str, p, l);
+ ret.len = l;
+ FLUSH(&ret);
+}
+
+extern void ·_swig_internal_gopanic(void);
+#pragma dynexport _swig_gc_gopanic _swig_gc_gopanic
+void _swig_gc_gopanic(void *a, int32 n) {
+ cgocallback(·_swig_internal_gopanic, a, n);
+}
+
+%}
+
+/* Go code that is only needed once in a program. This is only added
+ to the file if nothing is imported. */
+%insert(go_once) %{
+func _swig_allocatememory(int) *byte
+func _swig_internal_allocate(len int) *byte {
+ return _swig_allocatememory(len)
+}
+
+func _swig_allocatestring(*byte, int) string
+func _swig_internal_makegostring(p *byte, l int) string {
+ return _swig_allocatestring(p, l)
+}
+
+func _swig_internal_gopanic(p *byte, l int) {
+ panic(_swig_allocatestring(p, l))
+}
+%}
+
+#else
+
+/* Boilerplate for C/C++ code when using gccgo. */
+%insert(runtime) %{
+#define SWIGGO_GCCGO
+
+extern
+#ifdef __cplusplus
+"C"
+#endif
+void *__go_alloc (size_t);
+
+static void *_swig_allocate(int len) {
+ return __go_alloc(len);
+}
+
+static _gostring_ _swig_makegostring(const char *p, size_t l) {
+ _gostring_ ret;
+ ret.p = (char*)__go_alloc(l);
+ memcpy(ret.p, p, l);
+ ret.n = l;
+ return ret;
+}
+
+extern
+#ifdef __cplusplus
+"C"
+#endif
+void __go_panic_msg(const char *);
+#define _swig_gopanic __go_panic_msg
+
+%}
+
+#endif
+
+%insert(runtime) %{
+#define SWIG_contract_assert(expr, msg) \
+ if (!(expr)) { _swig_gopanic(msg); } else
+%}
+
+#ifdef __cplusplus
+/* We don't need a Swig::Director class, but the Swig testsuite
+ expects one. */
+%insert(runtime) %{
+namespace Swig {
+ typedef int Director;
+}
+%}
+
+#endif
diff --git a/Lib/go/std_common.i b/Lib/go/std_common.i
new file mode 100644
index 000000000..c010facac
--- /dev/null
+++ b/Lib/go/std_common.i
@@ -0,0 +1,4 @@
+%include
+
+%apply size_t { std::size_t };
+%apply const size_t& { const std::size_t& };
diff --git a/Lib/go/std_deque.i b/Lib/go/std_deque.i
new file mode 100644
index 000000000..cb98f6c2f
--- /dev/null
+++ b/Lib/go/std_deque.i
@@ -0,0 +1 @@
+%include
diff --git a/Lib/go/std_except.i b/Lib/go/std_except.i
new file mode 100644
index 000000000..789a335f7
--- /dev/null
+++ b/Lib/go/std_except.i
@@ -0,0 +1,29 @@
+/* -----------------------------------------------------------------------------
+ * std_except.i
+ *
+ * Typemaps used by the STL wrappers that throw exceptions.
+ * These typemaps are used when methods are declared with an STL exception specification, such as
+ * size_t at() const throw (std::out_of_range);
+ * ----------------------------------------------------------------------------- */
+
+%{
+#include
+%}
+
+namespace std
+{
+ %ignore exception;
+ struct exception {};
+}
+
+%typemap(throws) std::bad_exception %{_swig_gopanic($1.what());%}
+%typemap(throws) std::domain_error %{_swig_gopanic($1.what());%}
+%typemap(throws) std::exception %{_swig_gopanic($1.what());%}
+%typemap(throws) std::invalid_argument %{_swig_gopanic($1.what());%}
+%typemap(throws) std::length_error %{_swig_gopanic($1.what());%}
+%typemap(throws) std::logic_error %{_swig_gopanic($1.what());%}
+%typemap(throws) std::out_of_range %{_swig_gopanic($1.what());%}
+%typemap(throws) std::overflow_error %{_swig_gopanic($1.what());%}
+%typemap(throws) std::range_error %{_swig_gopanic($1.what());%}
+%typemap(throws) std::runtime_error %{_swig_gopanic($1.what());%}
+%typemap(throws) std::underflow_error %{_swig_gopanic($1.what());%}
diff --git a/Lib/go/std_map.i b/Lib/go/std_map.i
new file mode 100644
index 000000000..e37a9e676
--- /dev/null
+++ b/Lib/go/std_map.i
@@ -0,0 +1,64 @@
+/* -----------------------------------------------------------------------------
+ * std_map.i
+ *
+ * SWIG typemaps for std::map
+ * ----------------------------------------------------------------------------- */
+
+%include
+
+// ------------------------------------------------------------------------
+// std::map
+// ------------------------------------------------------------------------
+
+// "map" is a keyword in Go.
+#define map cmap
+
+%{
+#define map cmap
+#include
+#include
+#include
+%}
+
+// exported class
+
+namespace std {
+
+ template class map {
+ // add typemaps here
+ public:
+ typedef size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef K key_type;
+ typedef T mapped_type;
+ map();
+ map(const map &);
+
+ unsigned int size() const;
+ bool empty() const;
+ void clear();
+ %extend {
+ const T& get(const K& key) throw (std::out_of_range) {
+ 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) throw (std::out_of_range) {
+ 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();
+ }
+ }
+ };
+}
diff --git a/Lib/go/std_pair.i b/Lib/go/std_pair.i
new file mode 100644
index 000000000..fe45ee676
--- /dev/null
+++ b/Lib/go/std_pair.i
@@ -0,0 +1,34 @@
+/* -----------------------------------------------------------------------------
+ * std_pair.i
+ *
+ * SWIG typemaps for std::pair
+ * ----------------------------------------------------------------------------- */
+
+%include
+%include
+
+// ------------------------------------------------------------------------
+// std::pair
+// ------------------------------------------------------------------------
+
+%{
+#include
+%}
+
+namespace std {
+
+ template struct pair {
+
+ pair();
+ pair(T first, U second);
+ pair(const pair& p);
+
+ template pair(const pair &p);
+
+ T first;
+ U second;
+ };
+
+ // add specializations here
+
+}
diff --git a/Lib/go/std_string.i b/Lib/go/std_string.i
new file mode 100644
index 000000000..3c94cbe10
--- /dev/null
+++ b/Lib/go/std_string.i
@@ -0,0 +1,55 @@
+/* -----------------------------------------------------------------------------
+ * std_string.i
+ *
+ * Typemaps for std::string and const std::string&
+ * These are mapped to a Go 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 {
+
+%naturalvar string;
+
+class string;
+
+%typemap(go) string, const string & "string"
+
+%typemap(in) string
+%{ $1.assign($input.p, $input.n); %}
+
+%typemap(directorout) string
+%{ $result.assign($input.p, $input.n); %}
+
+%typemap(out) string
+%{ $result = _swig_makegostring($1.data(), $1.length()); %}
+
+%typemap(directorin) string
+%{ $input = _swig_makegostring($1_name.data(), $1_name.length()); %}
+
+%typemap(in) const string &
+%{
+ std::string $1_str($input.p, $input.n);
+ $1 = &$1_str;
+%}
+
+%typemap(directorout,warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) const string &
+%{
+ static std::string $1_str;
+ $1_str.assign($input.p, $input.n);
+ $result = &$1_str;
+%}
+
+%typemap(out) const string &
+%{ $result = _swig_makegostring((*$1).data(), (*$1).length()); %}
+
+%typemap(directorin) const string &
+%{ $input = _swig_makegostring($1_name.data(), $1_name.length()); %}
+
+}
diff --git a/Lib/go/std_vector.i b/Lib/go/std_vector.i
new file mode 100644
index 000000000..f4ce8431c
--- /dev/null
+++ b/Lib/go/std_vector.i
@@ -0,0 +1,78 @@
+/* -----------------------------------------------------------------------------
+ * std_vector.i
+ * ----------------------------------------------------------------------------- */
+
+%{
+#include
+#include
+%}
+
+namespace std {
+
+ template class vector {
+ public:
+ typedef size_t size_type;
+ typedef T value_type;
+ typedef const value_type& const_reference;
+ vector();
+ vector(size_type n);
+ size_type size() const;
+ size_type capacity() const;
+ void reserve(size_type n);
+ %rename(isEmpty) empty;
+ bool empty() const;
+ void clear();
+ %rename(add) push_back;
+ void push_back(const value_type& x);
+ %extend {
+ const_reference get(int i) throw (std::out_of_range) {
+ int size = int(self->size());
+ if (i>=0 && isize());
+ if (i>=0 && i class vector {
+ public:
+ typedef size_t size_type;
+ typedef bool value_type;
+ typedef bool const_reference;
+ vector();
+ vector(size_type n);
+ size_type size() const;
+ size_type capacity() const;
+ void reserve(size_type n);
+ %rename(isEmpty) empty;
+ bool empty() const;
+ void clear();
+ %rename(add) push_back;
+ void push_back(const value_type& x);
+ %extend {
+ const_reference get(int i) throw (std::out_of_range) {
+ int size = int(self->size());
+ if (i>=0 && isize());
+ if (i>=0 && i
+%include
+%include
+%include
+%include
diff --git a/Lib/go/typemaps.i b/Lib/go/typemaps.i
new file mode 100644
index 000000000..17da80c23
--- /dev/null
+++ b/Lib/go/typemaps.i
@@ -0,0 +1,335 @@
+/* -----------------------------------------------------------------------------
+ * typemaps.i
+ *
+ * Pointer and reference handling typemap library
+ *
+ * These mappings provide support for input/output arguments and common
+ * uses for C/C++ pointers and C++ references.
+ * ----------------------------------------------------------------------------- */
+
+/*
+INPUT typemaps
+--------------
+
+These typemaps remap a C pointer or C++ reference to be an "INPUT" value which is
+passed by value instead of reference.
+
+The following typemaps can be applied to turn a pointer or reference into a simple
+input value. That is, instead of passing a pointer or reference to an object,
+you would use a real value instead.
+
+ bool *INPUT, bool &INPUT
+ signed char *INPUT, signed char &INPUT
+ unsigned char *INPUT, unsigned char &INPUT
+ short *INPUT, short &INPUT
+ unsigned short *INPUT, unsigned short &INPUT
+ int *INPUT, int &INPUT
+ unsigned int *INPUT, unsigned int &INPUT
+ long *INPUT, long &INPUT
+ unsigned long *INPUT, unsigned long &INPUT
+ long long *INPUT, long long &INPUT
+ unsigned long long *INPUT, unsigned long long &INPUT
+ float *INPUT, float &INPUT
+ double *INPUT, double &INPUT
+
+To use these, suppose you had a C function like this :
+
+ double fadd(double *a, double *b) {
+ return *a+*b;
+ }
+
+You could wrap it with SWIG as follows :
+
+ %include
+ double fadd(double *INPUT, double *INPUT);
+
+or you can use the %apply directive :
+
+ %include
+ %apply double *INPUT { double *a, double *b };
+ double fadd(double *a, double *b);
+
+In Go you could then use it like this:
+ answer := modulename.Fadd(10.0, 20.0)
+
+There are no char *INPUT typemaps, however you can apply the signed
+char * typemaps instead:
+ %include
+ %apply signed char *INPUT {char *input};
+ void f(char *input);
+*/
+
+%define INPUT_TYPEMAP(TYPE, GOTYPE)
+%typemap(go) TYPE *INPUT, TYPE &INPUT "GOTYPE"
+
+%typemap(in) TYPE *INPUT
+%{ $1 = ($1_ltype)&$input; %}
+
+%typemap(in) TYPE &INPUT
+%{ $1 = ($1_ltype)$input; %}
+
+%typemap(freearg) TYPE *INPUT, TYPE &INPUT ""
+
+%typemap(directorout) TYPE *INPUT
+%{ $result = ($1_ltype)&$input; %}
+
+%typemap(directorout) TYPE &INPUT
+%{ $result = ($1_ltype)$input; %}
+
+%typemap(directorin) TYPE &INPUT
+%{ $1 = ($input_ltype)&$input; %}
+
+// %typemap(typecheck) TYPE *INPUT = TYPE;
+// %typemap(typecheck) TYPE &INPUT = TYPE;
+%enddef
+
+INPUT_TYPEMAP(bool, bool);
+INPUT_TYPEMAP(signed char, int8);
+INPUT_TYPEMAP(char, byte);
+INPUT_TYPEMAP(unsigned char, byte);
+INPUT_TYPEMAP(short, int16);
+INPUT_TYPEMAP(unsigned short, uint16);
+INPUT_TYPEMAP(int, int);
+INPUT_TYPEMAP(unsigned int, uint);
+INPUT_TYPEMAP(long, int64);
+INPUT_TYPEMAP(unsigned long, uint64);
+INPUT_TYPEMAP(long long, int64);
+INPUT_TYPEMAP(unsigned long long, uint64);
+INPUT_TYPEMAP(float, float);
+INPUT_TYPEMAP(double, float64);
+
+#undef INPUT_TYPEMAP
+
+// OUTPUT typemaps. These typemaps are used for parameters that
+// are output only. An array replaces the c pointer or reference parameter.
+// The output value is returned in this array passed in.
+
+/*
+OUTPUT typemaps
+---------------
+
+The following typemaps can be applied to turn a pointer or reference
+into an "output" value. When calling a function, no input value would
+be given for a parameter, but an output value would be returned. This
+works by a Go slice being passed as a parameter where a c pointer or
+reference is required. As with any Go function, the array is passed
+by reference so that any modifications to the array will be picked up
+in the calling function. Note that the array passed in MUST have at
+least one element, but as the c function does not require any input,
+the value can be set to anything.
+
+ bool *OUTPUT, bool &OUTPUT
+ signed char *OUTPUT, signed char &OUTPUT
+ unsigned char *OUTPUT, unsigned char &OUTPUT
+ short *OUTPUT, short &OUTPUT
+ unsigned short *OUTPUT, unsigned short &OUTPUT
+ int *OUTPUT, int &OUTPUT
+ unsigned int *OUTPUT, unsigned int &OUTPUT
+ long *OUTPUT, long &OUTPUT
+ unsigned long *OUTPUT, unsigned long &OUTPUT
+ long long *OUTPUT, long long &OUTPUT
+ unsigned long long *OUTPUT, unsigned long long &OUTPUT
+ float *OUTPUT, float &OUTPUT
+ double *OUTPUT, double &OUTPUT
+
+For example, suppose you were trying to wrap the modf() function in the
+C math library which splits x into integral and fractional parts (and
+returns the integer part in one of its parameters):
+
+ double modf(double x, double *ip);
+
+You could wrap it with SWIG as follows :
+
+ %include
+ double modf(double x, double *OUTPUT);
+
+or you can use the %apply directive :
+
+ %include
+ %apply double *OUTPUT { double *ip };
+ double modf(double x, double *ip);
+
+The Go output of the function would be the function return value and the
+value in the single element array. In Go you would use it like this:
+
+ ptr := []float64{0.0}
+ fraction := modulename.Modf(5.0,ptr)
+
+There are no char *OUTPUT typemaps, however you can apply the signed
+char * typemaps instead:
+ %include
+ %apply signed char *OUTPUT {char *output};
+ void f(char *output);
+*/
+
+%define OUTPUT_TYPEMAP(TYPE, GOTYPE)
+%typemap(go) TYPE *OUTPUT, TYPE &OUTPUT %{[]GOTYPE%}
+
+%typemap(in) TYPE *OUTPUT($*1_ltype temp)
+{
+ if ($input.len == 0) {
+ _swig_gopanic("array must contain at least 1 element");
+ }
+ $1 = &temp;
+}
+
+%typemap(in) TYPE &OUTPUT($*1_ltype temp)
+{
+ if ($input->len == 0) {
+ _swig_gopanic("array must contain at least 1 element");
+ }
+ $1 = &temp;
+}
+
+%typemap(freearg) TYPE *OUTPUT, TYPE &OUTPUT ""
+
+%typemap(argout) TYPE *OUTPUT
+{
+ TYPE* a = (TYPE *) $input.array;
+ a[0] = temp$argnum;
+}
+
+%typemap(argout) TYPE &OUTPUT
+{
+ TYPE* a = (TYPE *) $input->array;
+ a[0] = temp$argnum;
+}
+
+%typemap(directorout,warning="Need to provide TYPE *OUTPUT directorout typemap") TYPE *OUTPUT, TYPE &OUTPUT {
+}
+
+%typemap(directorin) TYPE &OUTPUT
+%{ *(($&1_ltype) $input = &$1; %}
+
+%typemap(directorin,warning="Need to provide TYPE *OUTPUT directorin typemap, TYPE array length is unknown") TYPE *OUTPUT
+{
+}
+
+%enddef
+
+OUTPUT_TYPEMAP(bool, bool);
+OUTPUT_TYPEMAP(signed char, int8);
+OUTPUT_TYPEMAP(char, byte);
+OUTPUT_TYPEMAP(unsigned char, byte);
+OUTPUT_TYPEMAP(short, int16);
+OUTPUT_TYPEMAP(unsigned short, uint16);
+OUTPUT_TYPEMAP(int, int);
+OUTPUT_TYPEMAP(unsigned int, uint);
+OUTPUT_TYPEMAP(long, int64);
+OUTPUT_TYPEMAP(unsigned long, uint64);
+OUTPUT_TYPEMAP(long long, int64);
+OUTPUT_TYPEMAP(unsigned long long, uint64);
+OUTPUT_TYPEMAP(float, float);
+OUTPUT_TYPEMAP(double, float64);
+
+#undef OUTPUT_TYPEMAP
+
+/*
+INOUT typemaps
+--------------
+
+Mappings for a parameter that is both an input and an output parameter
+
+The following typemaps can be applied to make a function parameter both
+an input and output value. This combines the behavior of both the
+"INPUT" and "OUTPUT" typemaps described earlier. Output values are
+returned as an element in a Go slice.
+
+ bool *INOUT, bool &INOUT
+ signed char *INOUT, signed char &INOUT
+ unsigned char *INOUT, unsigned char &INOUT
+ short *INOUT, short &INOUT
+ unsigned short *INOUT, unsigned short &INOUT
+ int *INOUT, int &INOUT
+ unsigned int *INOUT, unsigned int &INOUT
+ long *INOUT, long &INOUT
+ unsigned long *INOUT, unsigned long &INOUT
+ long long *INOUT, long long &INOUT
+ unsigned long long *INOUT, unsigned long long &INOUT
+ float *INOUT, float &INOUT
+ double *INOUT, double &INOUT
+
+For example, suppose you were trying to wrap the following function :
+
+ void neg(double *x) {
+ *x = -(*x);
+ }
+
+You could wrap it with SWIG as follows :
+
+ %include
+ void neg(double *INOUT);
+
+or you can use the %apply directive :
+
+ %include
+ %apply double *INOUT { double *x };
+ void neg(double *x);
+
+This works similarly to C in that the mapping directly modifies the
+input value - the input must be an array with a minimum of one element.
+The element in the array is the input and the output is the element in
+the array.
+
+ x := []float64{5.0}
+ Neg(x);
+
+The implementation of the OUTPUT and INOUT typemaps is different to
+other languages in that other languages will return the output value
+as part of the function return value. This difference is due to Go
+being a typed language.
+
+There are no char *INOUT typemaps, however you can apply the signed
+char * typemaps instead:
+ %include
+ %apply signed char *INOUT {char *inout};
+ void f(char *inout);
+*/
+
+%define INOUT_TYPEMAP(TYPE, GOTYPE)
+%typemap(go) TYPE *INOUT, TYPE &INOUT %{[]GOTYPE%}
+
+%typemap(in) TYPE *INOUT {
+ if ($input.len == 0) {
+ _swig_gopanic("array must contain at least 1 element");
+ }
+ $1 = ($1_ltype) $input.array;
+}
+
+%typemap(in) TYPE &INOUT {
+ if ($input->len == 0) {
+ _swig_gopanic("array must contain at least 1 element");
+ }
+ $1 = ($1_ltype) $input->array;
+}
+
+%typemap(freearg) TYPE *INOUT, TYPE &INOUT ""
+
+%typemap(directorout,warning="Need to provide TYPE *INOUT directorout typemap") TYPE *INOUT, TYPE &INOUT {
+}
+
+%typemap(directorin) TYPE &INOUT
+%{ *(($&1_ltype)&$input) = &$1; %}
+
+%typemap(directorin,warning="Need to provide TYPE *INOUT directorin typemap, TYPE array length is unknown") TYPE *INOUT, TYPE &INOUT
+{
+}
+
+%enddef
+
+INOUT_TYPEMAP(bool, bool);
+INOUT_TYPEMAP(signed char, int8);
+INOUT_TYPEMAP(char, byte);
+INOUT_TYPEMAP(unsigned char, byte);
+INOUT_TYPEMAP(short, int16);
+INOUT_TYPEMAP(unsigned short, uint16);
+INOUT_TYPEMAP(int, int);
+INOUT_TYPEMAP(unsigned int, uint);
+INOUT_TYPEMAP(long, int64);
+INOUT_TYPEMAP(unsigned long, uint64);
+INOUT_TYPEMAP(long long, int64);
+INOUT_TYPEMAP(unsigned long long, uint64);
+INOUT_TYPEMAP(float, float);
+INOUT_TYPEMAP(double, float64);
+
+#undef INOUT_TYPEMAP
diff --git a/Makefile.in b/Makefile.in
index 0beb7cbdd..180ad3451 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -75,6 +75,7 @@ skip-clisp = test -n "@SKIP_CLISP@"
skip-cffi = test -n "@SKIP_CFFI@"
skip-uffi = test -n "@SKIP_UFFI@"
skip-r = test -n "@SKIP_R@"
+skip-go = test -n "@SKIP_GO@"
# Additional dependencies for some tests
skip-gcj = test -n "@SKIP_GCJ@"
@@ -110,6 +111,7 @@ check-aliveness:
@$(skip-modula3) || ./$(TARGET) -modula3 -help
@$(skip-lua) || ./$(TARGET) -lua -help
@$(skip-r) || ./$(TARGET) -r -help
+ @$(skip-go) || ./$(TARGET) -go -help
check-ccache:
test -z "$(ENABLE_CCACHE)" || (cd $(CCACHE) && $(MAKE) check)
@@ -135,7 +137,8 @@ check-examples: \
check-clisp-examples \
check-uffi-examples \
check-cffi-examples \
- check-r-examples
+ check-r-examples \
+ check-go-examples
tcl_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/tcl/check.list)
perl5_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/perl5/check.list)
@@ -157,6 +160,7 @@ clisp_examples :=
uffi_examples :=
cffi_examples :=
r_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/r/check.list)
+go_examples :=$(shell sed '/^\#/d' $(srcdir)/Examples/go/check.list)
# all examples
check-%-examples :
@@ -206,7 +210,8 @@ check-test-suite: \
check-uffi-test-suite \
check-cffi-test-suite \
check-chicken-test-suite \
- check-r-test-suite
+ check-r-test-suite \
+ check-go-test-suite
check-%-test-suite:
@if test -z "$(skip-$*)"; then \
@@ -257,7 +262,8 @@ all-test-suite: \
all-uffi-test-suite \
all-cffi-test-suite \
all-chicken-test-suite \
- all-r-test-suite
+ all-r-test-suite \
+ all-go-test-suite
all-%-test-suite:
@$(MAKE) -k -s check-$*-test-suite ACTION=all
@@ -284,7 +290,8 @@ broken-test-suite: \
broken-uffi-test-suite \
broken-cffi-test-suite \
broken-chicken-test-suite \
- broken-r-test-suite
+ broken-r-test-suite \
+ broken-go-test-suite
broken-%-test-suite:
@$(MAKE) -k -s check-$*-test-suite ACTION=broken
@@ -401,7 +408,7 @@ install-main:
@$(INSTALL_PROGRAM) $(TARGET) $(DESTDIR)$(BIN_DIR)/`echo $(TARGET_NOEXE) | sed '$(transform)'`@EXEEXT@
lib-languages = gcj typemaps tcl perl5 python guile java mzscheme ruby php ocaml octave \
- pike chicken csharp modula3 allegrocl clisp lua cffi uffi r
+ pike chicken csharp modula3 allegrocl clisp lua cffi uffi r go
lib-modules = std
diff --git a/Source/Makefile.am b/Source/Makefile.am
index 26f37b2fe..4677002e6 100644
--- a/Source/Makefile.am
+++ b/Source/Makefile.am
@@ -44,6 +44,7 @@ eswig_SOURCES = CParse/cscanner.c \
Modules/csharp.cxx \
Modules/directors.cxx \
Modules/emit.cxx \
+ Modules/go.cxx \
Modules/guile.cxx \
Modules/java.cxx \
Modules/lang.cxx \
diff --git a/Source/Modules/allegrocl.cxx b/Source/Modules/allegrocl.cxx
index de4a7bfa9..93ca6d8f3 100644
--- a/Source/Modules/allegrocl.cxx
+++ b/Source/Modules/allegrocl.cxx
@@ -1709,6 +1709,8 @@ int ALLEGROCL::top(Node *n) {
We don't need a dispatch function in the C++ wrapper
code; we want it over on the lisp side. */
+#define Swig_overload_rank Allegrocl_swig_overload_rank
+
#define MAX_OVERLOAD 256
/* Overload "argc" and "argv" */
diff --git a/Source/Modules/go.cxx b/Source/Modules/go.cxx
new file mode 100644
index 000000000..91a0f457b
--- /dev/null
+++ b/Source/Modules/go.cxx
@@ -0,0 +1,4824 @@
+/* -----------------------------------------------------------------------------
+ * See the LICENSE file for information on copyright, usage and redistribution
+ * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ *
+ * go.cxx
+ *
+ * Go language module for SWIG.
+ * ----------------------------------------------------------------------------- */
+
+char cvsroot_go_cxx[] = "$Id";
+
+#include "swigmod.h"
+#include "cparse.h"
+#include
+#include
+
+class GO:public Language {
+ static const char * const usage;
+
+ // Go package name.
+ String *package;
+ // Flag for generating gccgo output.
+ bool gccgo_flag;
+ // Prefix to use with gccgo.
+ String *go_prefix;
+ // Name of shared library to import.
+ String *soname;
+ // Size in bits of the C type "long".
+ int long_type_size;
+ // Rename directives.
+ String *renames;
+
+ /* Output files */
+ File *f_c_begin;
+ File *f_go_begin;
+ File *f_gc_begin;
+
+ /* Output fragments */
+ File *f_c_runtime;
+ File *f_c_header;
+ File *f_c_wrappers;
+ File *f_c_init;
+ File *f_c_directors;
+ File *f_c_directors_h;
+ File *f_go_runtime;
+ File *f_go_header;
+ File *f_go_wrappers;
+ File *f_go_once;
+ File *f_gc_runtime;
+ File *f_gc_header;
+ File *f_gc_wrappers;
+ File *f_gc_once;
+
+ // True if we imported a module.
+ bool saw_import;
+ // If not NULL, name of import package being processed.
+ String *imported_package;
+ // Build interface methods while handling a class. This is only
+ // non-NULL when we are handling methods.
+ String *interfaces;
+ // The class node while handling a class. This is only non-NULL
+ // when we are handling methods.
+ Node *class_node;
+ // The class name while handling a class. This is only non-NULL
+ // when we are handling methods. This is the name of the class as
+ // SWIG sees it.
+ String *class_name;
+ // The receiver name while handling a class. This is only non-NULL
+ // when we are handling methods. This is the name of the class
+ // as run through goCPointerType.
+ String *class_receiver;
+ // A hash table of method names that we have seen when processing a
+ // class. This lets us detect base class methods that we don't want
+ // to use.
+ Hash *class_methods;
+ // True when we are generating the wrapper functions for a variable.
+ bool making_variable_wrappers;
+ // True when working with a static member function.
+ bool is_static_member_function;
+ // A hash table of types that we have seen but which may not have
+ // been defined. The index is a SwigType.
+ Hash *undefined_types;
+ // A hash table of classes which were defined. The index is a Go
+ // type name.
+ Hash *defined_types;
+
+public:
+ GO():package(NULL),
+ gccgo_flag(false),
+ go_prefix(NULL),
+ soname(NULL),
+ long_type_size(32),
+ renames(NULL),
+ f_c_begin(NULL),
+ f_go_begin(NULL),
+ f_gc_begin(NULL),
+ f_c_runtime(NULL),
+ f_c_header(NULL),
+ f_c_wrappers(NULL),
+ f_c_init(NULL),
+ f_c_directors(NULL),
+ f_c_directors_h(NULL),
+ f_go_runtime(NULL),
+ f_go_header(NULL),
+ f_go_wrappers(NULL),
+ f_go_once(NULL),
+ f_gc_runtime(NULL),
+ f_gc_header(NULL),
+ f_gc_wrappers(NULL),
+ f_gc_once(NULL),
+ saw_import(false),
+ imported_package(NULL),
+ interfaces(NULL),
+ class_receiver(NULL),
+ class_methods(NULL),
+ making_variable_wrappers(false),
+ is_static_member_function(false),
+ undefined_types(NULL),
+ defined_types(NULL)
+ {
+ director_multiple_inheritance = 1;
+ director_language = 1;
+ director_prot_ctor_code = NewString("_swig_gopanic(\"accessing abstract class or protected constructor\");");
+ }
+
+private:
+ /* ------------------------------------------------------------
+ * main()
+ * ------------------------------------------------------------ */
+ virtual void main(int argc, char *argv[]) {
+
+ SWIG_library_directory("go");
+
+ // Process command line options.
+ for (int i = 1; i < argc; i++) {
+ if (argv[i]) {
+ if (strcmp(argv[i], "-package") == 0) {
+ if (argv[i + 1] != NULL) {
+ package = NewString(argv[i + 1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if (strcmp(argv[i], "-gccgo") == 0) {
+ Swig_mark_arg(i);
+ gccgo_flag = true;
+ } else if (strcmp(argv[i], "-go-prefix") == 0) {
+ if (argv[i + 1] != NULL) {
+ go_prefix = NewString(argv[i + 1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if (strcmp(argv[i], "-soname") == 0) {
+ if (argv[i + 1] != NULL) {
+ soname = NewString(argv[i + 1]);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i + 1);
+ i++;
+ } else {
+ Swig_arg_error();
+ }
+ } else if (strcmp(argv[i], "-longsize") == 0) {
+ if (argv[i + 1] != NULL) {
+ long_type_size = atoi(argv[i + 1]);
+ if (long_type_size != 32 && long_type_size != 64) {
+ Printf(stderr, "-longsize not 32 or 64\n");
+ Swig_arg_error();
+ }
+ Swig_mark_arg(i);
+ Swig_mark_arg(i + 1);
+ ++i;
+ } else {
+ Swig_arg_error();
+ }
+ } else if (strcmp(argv[i], "-rename") == 0) {
+ if (argv[i + 1] != NULL) {
+ String *d = NewString(argv[i + 1]);
+ Replace(d, "=", " ", DOH_REPLACE_FIRST);
+ Preprocessor_define(d, 0);
+ if (renames == NULL) {
+ renames = NewString("");
+ }
+ Printv(renames, "#define ", d, "\n", NULL);
+ Delete(d);
+ Swig_mark_arg(i);
+ Swig_mark_arg(i + 1);
+ ++i;
+ // Prevent SWIG from trying to define this for the
+ // preprocessor, which breaks if there are multiple
+ // -rename options.
+ argv[i] = NULL;
+ } else {
+ Swig_arg_error();
+ }
+ } else if (strcmp(argv[i], "-help") == 0) {
+ Printf(stdout, "%s\n", usage);
+ }
+ }
+ }
+
+ if (gccgo_flag && go_prefix == NULL) {
+ go_prefix = NewString("go");
+ }
+
+ // Add preprocessor symbol to parser.
+ Preprocessor_define("SWIGGO 1", 0);
+
+ if (gccgo_flag) {
+ Preprocessor_define("SWIGGO_GCCGO 1", 0);
+ }
+
+ if (long_type_size == 32) {
+ Preprocessor_define("SWIGGO_LONG_TYPE_SIZE 32", 0);
+ } else {
+ Preprocessor_define("SWIGGO_LONG_TYPE_SIZE 64", 0);
+ }
+
+ // Add typemap definitions.
+ SWIG_typemap_lang("go");
+ SWIG_config_file("go.swg");
+
+ allow_overloading();
+ }
+
+ /* ---------------------------------------------------------------------
+ * top()
+ *
+ * For 6g/8g, we are going to create the following files:
+ *
+ * 1) A .c or .cxx file compiled with gcc. This file will contain
+ * function wrappers. Each wrapper will take a pointer to a
+ * struct holding the arguments, unpack them, and call the real
+ * function.
+ *
+ * 2) A .go file which defines the Go form of all types, and which
+ * defines Go function wrappers. Each wrapper will call the C
+ * function wrapper in the second file.
+ *
+ * 3) A .c file compiled with 6c/8c. This file will define
+ * Go-callable C function wrappers. Each wrapper will use
+ * cgocall to call the function wrappers in the first file.
+ *
+ * When generating code for gccgo, we don't need the third file, and
+ * the function wrappers in the first file have a different form.
+ *
+ * --------------------------------------------------------------------- */
+
+ virtual int top(Node *n) {
+ Node *optionsnode = Getattr(Getattr(n, "module"), "options");
+ if (optionsnode != NULL) {
+ if (Getattr(optionsnode, "directors")) {
+ allow_directors();
+ }
+ if (Getattr(optionsnode, "dirprot")) {
+ allow_dirprot();
+ }
+ allow_allprotected(GetFlag(optionsnode, "allprotected"));
+ }
+
+ String *module = Getattr(n, "name");
+ if (package == NULL) {
+ package = Copy(module);
+ }
+ if (soname == NULL) {
+ soname = Copy(package);
+ Append(soname, ".so");
+ }
+
+ // Get filenames.
+
+ String *c_filename = Getattr(n, "outfile");
+ String *c_filename_h = Getattr(n, "outfile_h");
+
+ String *go_filename = NewString("");
+ Printf(go_filename, "%s%s.go", SWIG_output_directory(), module);
+
+ String *gc_filename = NULL;
+ if (!gccgo_flag) {
+ gc_filename = NewString("");
+ Printf(gc_filename, "%s%s_gc.c", SWIG_output_directory(), module);
+ }
+
+ // Open files.
+
+ f_c_begin = NewFile(c_filename, "w", SWIG_output_files());
+ if (!f_c_begin) {
+ FileErrorDisplay(c_filename);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ if (directorsEnabled()) {
+ if (!c_filename_h) {
+ Printf(stderr, "Unable to determine outfile_h\n");
+ SWIG_exit(EXIT_FAILURE);
+ }
+ f_c_directors_h = NewFile(c_filename_h, "w", SWIG_output_files());
+ if (!f_c_directors_h) {
+ FileErrorDisplay(c_filename_h);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ }
+
+ f_go_begin = NewFile(go_filename, "w", SWIG_output_files());
+ if (!f_go_begin) {
+ FileErrorDisplay(go_filename);
+ SWIG_exit(EXIT_FAILURE);
+ }
+
+ if (!gccgo_flag) {
+ f_gc_begin = NewFile(gc_filename, "w", SWIG_output_files());
+ if (!f_gc_begin) {
+ FileErrorDisplay(gc_filename);
+ SWIG_exit(EXIT_FAILURE);
+ }
+ }
+
+ f_c_runtime = NewString("");
+ f_c_header = NewString("");
+ f_c_wrappers = NewString("");
+ f_c_init = NewString("");
+ f_c_directors = NewString("");
+ f_go_runtime = NewString("");
+ f_go_header = NewString("");
+ f_go_wrappers = NewString("");
+ f_go_once = NewString("");
+ if (!gccgo_flag) {
+ f_gc_runtime = NewString("");
+ f_gc_header = NewString("");
+ f_gc_wrappers = NewString("");
+ f_gc_once = NewString("");
+ }
+
+ Swig_register_filebyname("begin", f_c_begin);
+ Swig_register_filebyname("runtime", f_c_runtime);
+ Swig_register_filebyname("header", f_c_header);
+ Swig_register_filebyname("wrapper", f_c_wrappers);
+ Swig_register_filebyname("init", f_c_init);
+ Swig_register_filebyname("director", f_c_directors);
+ Swig_register_filebyname("director_h", f_c_directors_h);
+ Swig_register_filebyname("go_begin", f_go_begin);
+ Swig_register_filebyname("go_runtime", f_go_runtime);
+ Swig_register_filebyname("go_header", f_go_header);
+ Swig_register_filebyname("go_wrapper", f_go_wrappers);
+ Swig_register_filebyname("go_once", f_go_once);
+ if (!gccgo_flag) {
+ Swig_register_filebyname("gc_begin", f_gc_begin);
+ Swig_register_filebyname("gc_runtime", f_gc_runtime);
+ Swig_register_filebyname("gc_header", f_gc_header);
+ Swig_register_filebyname("gc_wrapper", f_gc_wrappers);
+ Swig_register_filebyname("gc_once", f_gc_once);
+ }
+
+ Swig_banner(f_c_begin);
+ if (!gccgo_flag) {
+ Printf(f_c_begin, "\n/* This file should be compiled with gcc. */\n");
+ }
+ if (renames != NULL) {
+ Printf(f_c_begin, "%s\n", renames);
+ }
+
+ if (directorsEnabled()) {
+ Printf(f_c_runtime, "#define SWIG_DIRECTORS\n");
+
+ Swig_banner(f_c_directors_h);
+ Printf(f_c_directors_h,
+ "\n/* This file should be compiled with gcc. */\n");
+ Printf(f_c_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", module);
+ Printf(f_c_directors_h, "#define SWIG_%s_WRAP_H_\n\n", module);
+
+ Printf(f_c_directors, "\n// C++ director class methods.\n");
+ Printf(f_c_directors, "#include \"%s\"\n\n",
+ Swig_file_filename(c_filename_h));
+ }
+
+ Swig_banner(f_go_begin);
+
+ if (!gccgo_flag) {
+ Swig_banner(f_gc_begin);
+ Printf(f_gc_begin, "\n/* This file should be compiled with 6c/8c. */\n");
+ }
+
+ // Output module initialization code.
+
+ Printf(f_go_begin, "\npackage %s\n\n", package);
+
+ // Set up the hash table for types not defined by SWIG.
+
+ undefined_types = NewHash();
+ defined_types = NewHash();
+
+ // Emit code.
+
+ Language::top(n);
+
+ // Write out definitions for the types not defined by SWIG.
+
+ Printv(f_go_wrappers, "\n", NULL);
+ for (Iterator p = First(undefined_types); p.key != NULL; p = Next(p)) {
+ String *ty = goType(NULL, p.key);
+ if (Getattr(defined_types, ty) == NULL) {
+ String *cp = goCPointerType(p.key, false);
+ if (Getattr(defined_types, cp) == NULL) {
+ Printv(f_go_wrappers, "type ", cp, " uintptr\n", NULL);
+ Printv(f_go_wrappers, "type ", ty, " interface {\n", NULL);
+ Printv(f_go_wrappers, "\tSwigcptr() uintptr;\n", NULL);
+ Printv(f_go_wrappers, "}\n", NULL);
+ Printv(f_go_wrappers, "func (p ", cp, ") Swigcptr() uintptr {\n",
+ NULL);
+ Printv(f_go_wrappers, "\treturn uintptr(p)\n", NULL);
+ Printv(f_go_wrappers, "}\n\n", NULL);
+ }
+ Delete(cp);
+ }
+ Delete(ty);
+ }
+ Delete(undefined_types);
+ Delete(defined_types);
+
+ /* Write and cleanup */
+
+ Dump(f_c_header, f_c_runtime);
+
+ if (directorsEnabled()) {
+ Printf(f_c_directors_h, "#endif\n");
+ Close(f_c_directors_h);
+ Delete(f_c_directors_h);
+ f_c_directors_h = NULL;
+
+ Dump(f_c_directors, f_c_runtime);
+ Close(f_c_directors);
+ Delete(f_c_directors);
+ f_c_directors = NULL;
+ }
+
+ Dump(f_c_runtime, f_c_begin);
+ Dump(f_c_wrappers, f_c_begin);
+ Dump(f_c_init, f_c_begin);
+ Dump(f_go_header, f_go_begin);
+ if (!saw_import) {
+ Dump(f_go_once, f_go_begin);
+ }
+ Dump(f_go_runtime, f_go_begin);
+ Dump(f_go_wrappers, f_go_begin);
+ if (!gccgo_flag) {
+ Dump(f_gc_header, f_gc_begin);
+ if (!saw_import) {
+ Dump(f_gc_once, f_gc_begin);
+ }
+ Dump(f_gc_runtime, f_gc_begin);
+ Dump(f_gc_wrappers, f_gc_begin);
+ }
+
+ Delete(f_c_runtime);
+ Delete(f_c_header);
+ Delete(f_c_wrappers);
+ Delete(f_c_init);
+ Delete(f_go_runtime);
+ Delete(f_go_header);
+ Delete(f_go_wrappers);
+ if (!gccgo_flag) {
+ Delete(f_gc_runtime);
+ Delete(f_gc_header);
+ Delete(f_gc_wrappers);
+ }
+
+ Close(f_c_begin);
+ Delete(f_c_begin);
+ Close(f_go_begin);
+ Delete(f_go_begin);
+ if (!gccgo_flag) {
+ Close(f_gc_begin);
+ Delete(f_gc_begin);
+ }
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * importDirective()
+ *
+ * Handle a SWIG import statement by generating a Go import
+ * statement.
+ * ------------------------------------------------------------ */
+
+ virtual int importDirective(Node *n) {
+ String *hold_import = imported_package;
+ String *modname = Getattr(n, "module");
+ if (modname != NULL) {
+ Printv(f_go_begin, "import \"", modname, "\"\n", NULL);
+ imported_package = modname;
+ saw_import = true;
+ }
+ int r = Language::importDirective(n);
+ imported_package = hold_import;
+ return r;
+ }
+
+ /* ----------------------------------------------------------------------
+ * functionWrapper()
+ *
+ * Implement a function.
+ * ---------------------------------------------------------------------- */
+
+ virtual int functionWrapper(Node *n) {
+ if (GetFlag(n, "feature:ignore")) {
+ return SWIG_OK;
+ }
+
+ // We don't need explicit calls.
+ if (GetFlag(n, "explicitcall")) {
+ return SWIG_OK;
+ }
+
+ String *name = Getattr(n, "sym:name");
+ String *nodetype = Getattr(n, "nodeType");
+ bool is_static = is_static_member_function || isStatic(n);
+ bool is_friend = isFriend(n);
+ bool is_ctor_dtor = false;
+
+ SwigType *result = Getattr(n, "type");
+
+ // For some reason SWIG changs the "type" value during the call to
+ // functionWrapper. We need to remember the type for possible
+ // overload processing.
+ Setattr(n, "go:type", Copy(result));
+
+ String *go_name;
+
+ String *r1 = NULL;
+ if (making_variable_wrappers) {
+ // Change the name of the variable setter and getter functions
+ // to be more Go like.
+
+ bool is_set = Strcmp(Char(name) + Len(name) - 4, "_set") == 0;
+ assert(is_set || Strcmp(Char(name) + Len(name) - 4, "_get") == 0);
+
+ // Start with Set or Get.
+ go_name = NewString(is_set ? "Set" : "Get");
+
+ // If this is a static variable, put in the class name,
+ // capitalized.
+ if (is_static && class_name != NULL) {
+ String *ccn = exportedName(class_name);
+ Append(go_name, ccn);
+ Delete(ccn);
+ }
+
+ // Add the rest of the name, capitalized, dropping the _set or
+ // _get.
+ String *c1 = removeClassname(name);
+ String *c2 = exportedName(c1);
+ char *p = Char(c2);
+ int len = Len(p);
+ for (int i = 0; i < len - 4; ++i) {
+ Putc(p[i], go_name);
+ }
+ Delete(c2);
+ Delete(c1);
+ } else if (Cmp(nodetype, "constructor") == 0) {
+ is_ctor_dtor = true;
+
+ // Change the name of a constructor to be more Go like. Change
+ // new_ to New, and capitalize the class name.
+ assert(Strncmp(name, "new_", 4) == 0);
+ String *c1 = NewString(Char(name) + 4);
+ String *c2 = exportedName(c1);
+ go_name = NewString("New");
+ Append(go_name, c2);
+ Delete(c2);
+ Delete(c1);
+
+ if (Swig_methodclass(n) != NULL
+ && Swig_directorclass(n)
+ && Strcmp(Char(Getattr(n, "wrap:action")),
+ director_prot_ctor_code) != 0) {
+ // The core SWIG code skips the first parameter when
+ // generating the $nondirector_new string. Recreate the
+ // action in this case. But don't it if we are using the
+ // special code for an abstract class.
+ String *call = Swig_cppconstructor_call(getClassType(),
+ Getattr(n, "parms"));
+ SwigType *type = Copy(getClassType());
+ SwigType_add_pointer(type);
+ String *cres = Swig_cresult(type, "result", call);
+ Setattr(n, "wrap:action", cres);
+ }
+ } else if (Cmp(nodetype, "destructor") == 0) {
+ // No need to emit protected destructors.
+ if (!is_public(n)) {
+ return SWIG_OK;
+ }
+
+ is_ctor_dtor = true;
+
+ // Change the name of a destructor to be more Go like. Change
+ // delete_ to Delete and capitalize the class name.
+ assert(Strncmp(name, "delete_", 7) == 0);
+ String *c1 = NewString(Char(name) + 7);
+ String *c2 = exportedName(c1);
+ go_name = NewString("Delete");
+ Append(go_name, c2);
+ Delete(c2);
+ Delete(c1);
+
+ result = NewString("void");
+ r1 = result;
+ } else {
+ if (!is_public(n)) {
+ return SWIG_OK;
+ }
+
+ go_name = buildGoName(name, is_static, is_friend);
+ }
+
+ String *overname = NULL;
+ if (Getattr(n, "sym:overloaded")) {
+ overname = Getattr(n, "sym:overname");
+ } else if (class_name == NULL || is_static) {
+ if (!addSymbol(go_name, n)) {
+ return SWIG_ERROR;
+ }
+ } else {
+ String *c = Copy(class_name);
+ Putc('+', c);
+ Append(c, go_name);
+ if (!addSymbol(c, n)) {
+ return SWIG_ERROR;
+ }
+ Delete(c);
+ }
+
+ String *wname = Swig_name_wrapper(name);
+ if (overname != NULL) {
+ Append(wname, overname);
+ }
+ Setattr(n, "wrap:name", wname);
+
+ ParmList *parms = Getattr(n, "parms");
+ Setattr(n, "wrap:parms", parms);
+
+ int r = makeWrappers(n, name, go_name, overname, wname, NULL, parms,
+ result, is_static);
+ if (r != SWIG_OK) {
+ return r;
+ }
+
+ if (Getattr(n, "sym:overloaded") && Getattr(n, "sym:nextSibling") == NULL) {
+ String *receiver = class_receiver;
+ if (is_static || is_ctor_dtor) {
+ receiver = NULL;
+ }
+ r = makeDispatchFunction(n, go_name, receiver, is_static, NULL, false);
+ if (r != SWIG_OK) {
+ return r;
+ }
+ }
+
+ Delete(wname);
+ Delete(go_name);
+ if (r1 != NULL) {
+ Delete(r1);
+ }
+
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * staticmemberfunctionHandler
+ *
+ * For some reason the language code removes the "storage" attribute
+ * for a static function before calling functionWrapper, which means
+ * that we have no way of knowing whether a function is static or
+ * not. That makes no sense in the Go context. Here we note that a
+ * function is static.
+ * ---------------------------------------------------------------------- */
+
+ int staticmemberfunctionHandler(Node *n) {
+ assert(!is_static_member_function);
+ is_static_member_function = true;
+ int r = Language::staticmemberfunctionHandler(n);
+ is_static_member_function = false;
+ return r;
+ }
+
+ /* ----------------------------------------------------------------------
+ * makeWrappers()
+ *
+ * Write out the various function wrappers.
+ * N: The function we are emitting.
+ * NAME: The function name.
+ * GO_NAME: The name of the function in Go.
+ * OVERNAME: The overload string for overloaded function.
+ * WNAME: The SWIG wrapped name--the name of the C function.
+ * BASE: A list of the names of base classes, in the case where this
+ * is is a vritual method not defined in the current class.
+ * PARMS: The parameters.
+ * RESULT: The result type.
+ * IS_STATIC: Whether this is a static method or member.
+ * ---------------------------------------------------------------------- */
+
+ int makeWrappers(Node *n, String *name, String *go_name, String *overname,
+ String *wname, List *base, ParmList *parms,
+ SwigType *result, bool is_static) {
+
+ assert(result != NULL);
+
+ bool needs_wrapper;
+ int r = goFunctionWrapper(n, name, go_name, overname, wname, base, parms,
+ result, is_static, &needs_wrapper);
+ if (r != SWIG_OK) {
+ return r;
+ }
+
+ if (!gccgo_flag) {
+ r = gcFunctionWrapper(n, name, go_name, overname, wname, parms, result,
+ is_static, needs_wrapper);
+ if (r != SWIG_OK) {
+ return r;
+ }
+ r = gccFunctionWrapper(n, base, wname, parms, result);
+ if (r != SWIG_OK) {
+ return r;
+ }
+ } else {
+ r = gccgoFunctionWrapper(n, base, wname, parms, result);
+ if (r != SWIG_OK) {
+ return r;
+ }
+ }
+
+ if (class_methods != NULL) {
+ Setattr(class_methods, Getattr(n, "name"), NewString(""));
+ }
+
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * goFunctionWrapper()
+ *
+ * Write out a function wrapper in Go. When not implementing a
+ * method, the actual code is all in C; here we just declare the C
+ * function. When implementing a method, we have to call the C
+ * function, because it will have a different name. If base is not
+ * NULL, then we are being called to forward a virtual method to a
+ * base class.
+ * ---------------------------------------------------------------------- */
+
+ int goFunctionWrapper(Node *n, String *name, String *go_name,
+ String *overname, String *wname, List *base,
+ ParmList *parms, SwigType *result, bool is_static,
+ bool *p_needs_wrapper) {
+ Wrapper *dummy = NewWrapper();
+ emit_attach_parmmaps(parms, dummy);
+ Swig_typemap_attach_parms("default", parms, dummy);
+ Swig_typemap_attach_parms("go", parms, dummy);
+ int parm_count = emit_num_arguments(parms);
+ int required_count = emit_num_required(parms);
+
+ String *receiver = class_receiver;
+ if (receiver != NULL && is_static) {
+ receiver = NULL;
+ }
+
+ String *nodetype = Getattr(n, "nodeType");
+ bool is_constructor = Cmp(nodetype, "constructor") == 0;
+ bool is_destructor = Cmp(nodetype, "destructor") == 0;
+ if (is_constructor || is_destructor) {
+ assert(class_receiver != NULL);
+ assert(base == NULL);
+ receiver = NULL;
+ }
+
+ bool add_to_interface = (interfaces != NULL
+ && !is_constructor
+ && !is_destructor
+ && !is_static
+ && overname == NULL
+ && is_public(n));
+
+ bool needs_wrapper = (gccgo_flag
+ || receiver != NULL
+ || is_constructor
+ || is_destructor
+ || parm_count > required_count);
+
+ // See whether any of the function parameters are represented by
+ // interface values When calling the C++ code, we need to convert
+ // back to a uintptr.
+ if (!needs_wrapper) {
+ Parm *p = parms;
+ for (int i = 0; i < parm_count; ++i) {
+ p = getParm(p);
+ String *ty = Getattr(p, "type");
+ if (goTypeIsInterface(p, ty)) {
+ needs_wrapper = true;
+ break;
+ }
+ p = nextParm(p);
+ }
+ }
+ if (goTypeIsInterface(NULL, result)) {
+ needs_wrapper = true;
+ }
+
+ *p_needs_wrapper = needs_wrapper;
+
+ // If this is a method, first declare the C function we will call.
+ // If we do not need a wrapper, then we will only be writing a
+ // declaration.
+ String *wrapper_name = NULL;
+ if (needs_wrapper) {
+ wrapper_name = buildGoWrapperName(name, overname);
+
+ Printv(f_go_wrappers, "func ", wrapper_name, "(", NULL);
+ if (parm_count > required_count) {
+ Printv(f_go_wrappers, "int", NULL);
+ }
+ Parm *p = getParm(parms);
+ Swig_cparm_name(p, 0);
+ int i = 0;
+ if (is_destructor) {
+ if (parm_count > required_count) {
+ Printv(f_go_wrappers, ", ", NULL);
+ }
+ Printv(f_go_wrappers, "uintptr", NULL);
+ ++i;
+ p = nextParm(p);
+ } else if (receiver != NULL && (base != NULL || !is_constructor)) {
+ if (parm_count > required_count) {
+ Printv(f_go_wrappers, ", ", NULL);
+ }
+ Printv(f_go_wrappers, receiver, NULL);
+ if (base == NULL) {
+ ++i;
+ p = nextParm(p);
+ }
+ }
+ for (; i < parm_count; ++i) {
+ p = getParm(p);
+ // Give the parameter a name we will use below.
+ Swig_cparm_name(p, i);
+ if (i > 0
+ || (base != NULL && receiver != NULL)
+ || parm_count > required_count) {
+ Printv(f_go_wrappers, ", ", NULL);
+ }
+ String *tm = goWrapperType(p, Getattr(p, "type"), false);
+ Printv(f_go_wrappers, tm, NULL);
+ Delete(tm);
+ p = nextParm(p);
+ }
+ Printv(f_go_wrappers, ")", NULL);
+ if (is_constructor) {
+ Printv(f_go_wrappers, " ", class_receiver, NULL);
+ } else {
+ if (SwigType_type(result) != T_VOID) {
+ String *tm = goWrapperType(n, result, true);
+ Printv(f_go_wrappers, " ", tm, NULL);
+ Delete(tm);
+ }
+ }
+
+ if (gccgo_flag) {
+ Printv(f_go_wrappers, " __asm__ (\"", go_prefix, "_", wname, "\")",
+ NULL);
+ }
+
+ Printv(f_go_wrappers, "\n\n", NULL);
+ }
+
+ // Start defining the Go function.
+
+ Printv(f_go_wrappers, "func ", NULL);
+
+ Parm *p = parms;
+ int pi = 0;
+
+ // Add the receiver if this is a method.
+ if (receiver != NULL) {
+ Printv(f_go_wrappers, "(", NULL);
+ if (base != NULL && receiver != NULL) {
+ Printv(f_go_wrappers, "_swig_base", NULL);
+ } else {
+ Printv(f_go_wrappers, Getattr(p, "lname"), NULL);
+ p = nextParm(p);
+ ++pi;
+ }
+ Printv(f_go_wrappers, " ", receiver, ") ", NULL);
+ }
+
+ Printv(f_go_wrappers, go_name, NULL);
+ if (overname != NULL) {
+ Printv(f_go_wrappers, overname, NULL);
+ }
+ Printv(f_go_wrappers, "(", NULL);
+
+ // If we are doing methods, add this function to the interface.
+ if (add_to_interface) {
+ Printv(interfaces, "\t", go_name, "(", NULL);
+ }
+
+ // Write out the parameters to both the function definition and
+ // the interface.
+
+ String *parm_print = NewString("");
+
+ for (; pi < parm_count; ++pi) {
+ p = getParm(p);
+ if (pi == 0 && is_destructor) {
+ String *cl = exportedName(class_name);
+ Printv(parm_print, Getattr(p, "lname"), " ", cl, NULL);
+ Delete(cl);
+ } else {
+ if (pi > (receiver != NULL && base == NULL ? 1 : 0)) {
+ Printv(parm_print, ", ", NULL);
+ }
+ if (pi >= required_count) {
+ Printv(parm_print, "_swig_args ...interface{}", NULL);
+ break;
+ }
+ if (needs_wrapper) {
+ Printv(parm_print, Getattr(p, "lname"), " ", NULL);
+ }
+ String *tm = goType(p, Getattr(p, "type"));
+ Printv(parm_print, tm, NULL);
+ Delete(tm);
+ }
+ p = nextParm(p);
+ }
+
+ Printv(parm_print, ")", NULL);
+
+ // Write out the result type.
+ if (is_constructor) {
+ String *cl = exportedName(class_name);
+ Printv(parm_print, " ", cl, NULL);
+ Delete(cl);
+ } else {
+ if (SwigType_type(result) != T_VOID) {
+ String *tm = goType(n, result);
+ Printv(parm_print, " ", tm, NULL);
+ Delete(tm);
+ }
+ }
+
+ Printv(f_go_wrappers, parm_print, NULL);
+ if (add_to_interface) {
+ Printv(interfaces, parm_print, "\n", NULL);
+ }
+
+ // If this is a wrapper, we need to actually call the C function.
+ if (needs_wrapper) {
+ Printv(f_go_wrappers, " {\n", NULL);
+
+ if (parm_count > required_count) {
+ Parm *p = parms;
+ int i;
+ for (i = 0; i < required_count; ++i) {
+ p = getParm(p);
+ p = nextParm(p);
+ }
+ for (; i < parm_count; ++i) {
+ p = getParm(p);
+ String *tm = goType(p, Getattr(p, "type"));
+ Printv(f_go_wrappers, "\tvar ", Getattr(p, "lname"), " ", tm, "\n",
+ NULL);
+ Printf(f_go_wrappers, "\tif len(_swig_args) > %d {\n",
+ i - required_count);
+ Printf(f_go_wrappers, "\t\t%s = _swig_args[%d].(%s)\n",
+ Getattr(p, "lname"), i - required_count, tm);
+ Printv(f_go_wrappers, "\t}\n", NULL);
+ Delete(tm);
+ p = nextParm(p);
+ }
+ }
+
+ Printv(f_go_wrappers, "\t", NULL);
+ if (SwigType_type(result) != T_VOID) {
+ Printv(f_go_wrappers, "return ", NULL);
+ }
+
+ Printv(f_go_wrappers, wrapper_name, "(", NULL);
+
+ if (parm_count > required_count) {
+ Printv(f_go_wrappers, "len(_swig_args)", NULL);
+ }
+
+ if (base != NULL && receiver != NULL) {
+ if (parm_count > required_count) {
+ Printv(f_go_wrappers, ", ", NULL);
+ }
+ Printv(f_go_wrappers, "_swig_base", NULL);
+ }
+
+ Parm *p = parms;
+ for (int i = 0; i < parm_count; ++i) {
+ p = getParm(p);
+ if (i > 0
+ || (base != NULL && receiver != NULL)
+ || parm_count > required_count) {
+ Printv(f_go_wrappers, ", ", NULL);
+ }
+ Printv(f_go_wrappers, Getattr(p, "lname"), NULL);
+
+ // If this is a destructor, then the C function expects the
+ // C++ value, and we have the interface. We need to get the
+ // C++ value. The same is true for a type represented as an
+ // interface.
+ if ((i == 0 && is_destructor)
+ || ((i > 0 || receiver == NULL || base != NULL || is_constructor)
+ && goTypeIsInterface(p, Getattr(p, "type")))) {
+ Printv(f_go_wrappers, ".Swigcptr()", NULL);
+ }
+
+ p = nextParm(p);
+ }
+ Printv(f_go_wrappers, ")\n", NULL);
+ Printv(f_go_wrappers, "}\n", NULL);
+ } else {
+ if (gccgo_flag) {
+ Printv(f_go_wrappers, " __asm__ (\"", go_prefix, "_",
+ wname, "\")\n", NULL);
+ }
+ }
+
+ Printv(f_go_wrappers, "\n", NULL);
+
+ Delete(wrapper_name);
+ DelWrapper(dummy);
+
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * gcFunctionWrapper()
+ *
+ * This is used for 6g/8g, not for gccgo. Write out the function
+ * wrapper which will be compiled with 6c/8c.
+ * ---------------------------------------------------------------------- */
+
+ int gcFunctionWrapper(Node *n, String *name, String *go_name,
+ String *overname, String *wname, ParmList *parms,
+ SwigType *result, bool is_static, bool needs_wrapper) {
+ Wrapper *f = NewWrapper();
+
+ Printv(f->def, "#pragma dynimport ", wname, " ", wname, " \"",
+ soname, "\"\n", NULL);
+ Printv(f->def, "void (*", wname, ")(void*);\n", NULL);
+ Printv(f->def, "\n", NULL);
+ Printv(f->def, "void\n", NULL);
+
+ Wrapper *dummy = NewWrapper();
+ emit_attach_parmmaps(parms, dummy);
+ Swig_typemap_attach_parms("default", parms, dummy);
+ Swig_typemap_attach_parms("gosize", parms, dummy);
+ int parm_count = emit_num_arguments(parms);
+ int required_count = emit_num_required(parms);
+
+ String *parm_size = NewString("");
+
+ if (parm_count > required_count) {
+ Append(parm_size, "SWIG_PARM_SIZE");
+ }
+
+ if (class_receiver != NULL && !is_static) {
+ if (Len(parm_size) > 0) {
+ Append(parm_size, " + ");
+ }
+ Append(parm_size, "SWIG_PARM_SIZE");
+ }
+
+ Parm *p = parms;
+ for (int i = 0; i < parm_count; ++i) {
+ p = getParm(p);
+ addGcTypeSize(p, Getattr(p, "type"), parm_size);
+ p = nextParm(p);
+ }
+
+ if (SwigType_type(result) != T_VOID) {
+ addGcTypeSize(n, result, parm_size);
+ }
+
+ if (Len(parm_size) == 0) {
+ Append(parm_size, "1");
+ }
+
+ String *fn_name;
+ if (!needs_wrapper) {
+ fn_name = Copy(go_name);
+ if (overname != NULL) {
+ Append(fn_name, overname);
+ }
+ } else {
+ fn_name = buildGoWrapperName(name, overname);
+ }
+
+ // \xc2\xb7 is UTF-8 for U+00B7 which is Unicode 'Middle Dot'
+ Printv(f->def, "\xc2\xb7", fn_name,
+ "(struct { uint8 x[", parm_size, "];} p)", NULL);
+
+ Delete(fn_name);
+ Delete(parm_size);
+
+ Printv(f->code, "{\n", NULL);
+ Printv(f->code, "\tcgocall(", wname, ", &p);\n", NULL);
+ Printv(f->code, "}\n", NULL);
+ Printv(f->code, "\n", NULL);
+
+ Wrapper_print(f, f_gc_wrappers);
+
+ DelWrapper(f);
+ DelWrapper(dummy);
+
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * getGcTypeSize()
+ *
+ * Return the size to use when passing a type from 6g/8g to 6c/8c.
+ * ---------------------------------------------------------------------- */
+
+ String *addGcTypeSize(Node *n, SwigType *type, String *orig) {
+ if (Len(orig) > 0) {
+ Append(orig, " + ");
+ }
+
+ String *go = goType(n, type);
+ if (Cmp(go, "string") == 0) {
+ // A string has a pointer and a length.
+ Append(orig, "(2 * SWIG_PARM_SIZE)");
+ } else if (Strncmp(go, "[]", 2) == 0) {
+ // A slice has a pointer, a length, and a capacity. The
+ // length and capacity are always 4 bytes.
+ Append(orig, "(SWIG_PARM_SIZE + 8)");
+ } else if (Strcmp(go, "float") == 0 || Strcmp(go, "float64") == 0) {
+ Append(orig, "8");
+ } else if (Strcmp(go, "complex") == 0 || Strcmp(go, "complex64") == 0) {
+ Append(orig, "8");
+ } else if (Strcmp(go, "complex128") == 0) {
+ Append(orig, "16");
+ } else {
+ Append(orig, "SWIG_PARM_SIZE");
+ }
+
+ return orig;
+ }
+
+ /* ----------------------------------------------------------------------
+ * gccFunctionWrapper()
+ *
+ * This is used for 6g/8g, not for gccgo. Write out the function
+ * wrapper which will be compiled with gcc. If the base parameter
+ * is not NULL, this is calls the base class method rather than
+ * executing the SWIG wrapper code.
+ * ---------------------------------------------------------------------- */
+
+ int gccFunctionWrapper(Node *n, List *base, String *wname, ParmList *parms,
+ SwigType *result) {
+ Wrapper *f = NewWrapper();
+
+ Swig_save("gccFunctionWrapper", n, "parms", NULL);
+
+ Parm *base_parm = NULL;
+ if (base != NULL && !isStatic(n)) {
+ SwigType *base_type = Copy(Getattr(class_node, "classtype"));
+ SwigType_add_pointer(base_type);
+ base_parm = NewParm(base_type, NewString("arg1"), n);
+ set_nextSibling(base_parm, parms);
+ parms = base_parm;
+ }
+
+ emit_parameter_variables(parms, f);
+ emit_attach_parmmaps(parms, f);
+ int parm_count = emit_num_arguments(parms);
+ int required_count = emit_num_required(parms);
+
+ emit_return_variable(n, result, f);
+
+ // Start the function definition.
+
+ Printv(f->def,
+ "#ifdef __cplusplus\n",
+ "extern \"C\"\n",
+ "#endif\n",
+ NULL);
+
+ Printv(f->def, "void\n", wname, "(void *swig_v)\n", "{\n", NULL);
+
+ // The single function parameter is a pointer to the real argument
+ // values. Define the structure that it points to.
+
+ Printv(f->code, "\tstruct swigargs {\n", NULL);
+
+ if (parm_count > required_count) {
+ Printv(f->code, "\t\tint _swig_optargc;\n", NULL);
+ }
+
+ Parm *p = parms;
+ for (int i = 0; i < parm_count; ++i) {
+ p = getParm(p);
+ String *ln = Getattr(p, "lname");
+ SwigType *pt = Getattr(p, "type");
+ String *ct = gcCTypeForGoValue(p, pt, ln);
+ Printv(f->code, "\t\t\t", ct, ";\n", NULL);
+ Delete(ct);
+ p = nextParm(p);
+ }
+ if (SwigType_type(result) != T_VOID) {
+ Printv(f->code, "\t\tint : 0;\n", NULL);
+ String *ln = NewString("result");
+ String *ct = gcCTypeForGoValue(n, result, ln);
+ Delete(ln);
+ Printv(f->code, "\t\t", ct, ";\n", NULL);
+ Delete(ct);
+ }
+ Printv(f->code, "\t} *swig_a = (struct swigargs *) swig_v;\n", NULL);
+
+ Printv(f->code, "\n", NULL);
+
+ // Copy the input arguments out of the structure into the
+ // parameter variables.
+
+ p = parms;
+ for (int i = 0; i < parm_count; ++i) {
+ p = getParm(p);
+
+ String *tm = Getattr(p, "tmap:in");
+ if (tm == NULL) {
+ Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number,
+ "Unable to use type %s as a function argument\n",
+ SwigType_str(Getattr(p, "type"), 0));
+ } else {
+ String *ln = Getattr(p, "lname");
+ String *input = NewString("");
+ Printv(input, "swig_a->", ln, NULL);
+ Replaceall(tm, "$input", input);
+ Setattr(p, "emit:input", input);
+ if (i < required_count) {
+ Printv(f->code, "\t", tm, "\n", NULL);
+ } else {
+ Printf(f->code, "\tif (swig_a->_swig_optargc > %d) {\n",
+ i - required_count);
+ Printv(f->code, "\t\t", tm, "\n", NULL);
+ Printv(f->code, "\t}\n", NULL);
+ }
+ }
+ p = nextParm(p);
+ }
+
+ Printv(f->code, "\n", NULL);
+
+ // Do the real work of the function.
+
+ checkConstraints(parms, f);
+
+ emitGoAction(n, base, parms, result, f);
+
+ argout(parms, f);
+
+ cleanupFunction(n, f, parms);
+
+ Printv(f->code, "}\n", NULL);
+
+ Wrapper_print(f, f_c_wrappers);
+
+ Swig_restore(n);
+
+ DelWrapper(f);
+ if (base_parm != NULL) {
+ Delete(base_parm);
+ }
+
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * gccgoFunctionWrapper()
+ *
+ * This is used for gccgo, not 6g/8g. Write out the function
+ * wrapper which will be compiled with gcc. If the base parameter
+ * is not NULL, this is calls the base class method rather than
+ * executing the SWIG wrapper code.
+ * ---------------------------------------------------------------------- */
+
+ int gccgoFunctionWrapper(Node *n, List *base, String *wname, ParmList *parms,
+ SwigType *result) {
+ Wrapper *f = NewWrapper();
+
+ Swig_save("gccgoFunctionWrapper", n, "parms", NULL);
+
+ Parm *base_parm = NULL;
+ if (base != NULL && !isStatic(n)) {
+ SwigType *base_type = Copy(Getattr(class_node, "classtype"));
+ SwigType_add_pointer(base_type);
+ base_parm = NewParm(base_type, NewString("arg1"), n);
+ set_nextSibling(base_parm, parms);
+ parms = base_parm;
+ }
+
+ emit_parameter_variables(parms, f);
+ emit_attach_parmmaps(parms, f);
+ int parm_count = emit_num_arguments(parms);
+ int required_count = emit_num_required(parms);
+
+ emit_return_variable(n, result, f);
+
+ // Start the function definition.
+
+ Printv(f->def,
+ "#ifdef __cplusplus\n",
+ "extern \"C\"\n",
+ "#endif\n",
+ NULL);
+
+ String *fnname = NewString("");
+ Printv(fnname, go_prefix, "_", wname, "(", NULL);
+
+ if (parm_count > required_count) {
+ Printv(fnname, "int _swig_optargc", NULL);
+ }
+
+ Parm *p = parms;
+ for (int i = 0; i < parm_count; ++i) {
+ p = getParm(p);
+ SwigType *pt = Getattr(p, "type");
+ String *pn = NewString("g");
+ Append(pn, Getattr(p, "lname"));
+ String *ct = gccgoCTypeForGoValue(p, pt, pn);
+ if (i > 0 || parm_count > required_count) {
+ Printv(fnname, ", ", NULL);
+ }
+ Printv(fnname, ct, NULL);
+ Delete(ct);
+ Delete(pn);
+ p = nextParm(p);
+ }
+
+ Printv(fnname, ")", NULL);
+
+ if (SwigType_type(result) == T_VOID) {
+ Printv(f->def, "void ", fnname, NULL);
+ } else {
+ String *ct = gccgoCTypeForGoValue(n, result, fnname);
+ Printv(f->def, ct, NULL);
+ Delete(ct);
+ }
+
+ Printv(f->def, " {\n", NULL);
+
+ Delete(fnname);
+
+ if (SwigType_type(result) != T_VOID) {
+ String *ln = NewString("go_result");
+ String *ct = gccgoCTypeForGoValue(n, result, ln);
+ Wrapper_add_local(f, "go_result", ct);
+ Delete(ct);
+ Delete(ln);
+ }
+
+ // Copy the parameters into the variables which hold their values,
+ // applying appropriate transformations.
+
+ p = parms;
+ for (int i = 0; i < parm_count; ++i) {
+ p = getParm(p);
+
+ String *tm = Getattr(p, "tmap:in");
+ if (tm == NULL) {
+ Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number,
+ "Unable to use type %s as a function argument\n",
+ SwigType_str(Getattr(p, "type"), 0));
+ } else {
+ String *ln = Getattr(p, "lname");
+ String *pn = NewString("g");
+ Append(pn, ln);
+ Replaceall(tm, "$input", pn);
+ Setattr(p, "emit:input", pn);
+ if (i < required_count) {
+ Printv(f->code, " ", tm, "\n", NULL);
+ } else {
+ Printf(f->code, " if (_swig_optargc > %d) {\n", i - required_count);
+ Printv(f->code, " ", tm, "\n", NULL);
+ Printv(f->code, " }\n", NULL);
+ }
+ }
+
+ p = nextParm(p);
+ }
+
+ Printv(f->code, "\n", NULL);
+
+ // Do the real work of the function.
+
+ checkConstraints(parms, f);
+
+ emitGoAction(n, base, parms, result, f);
+
+ argout(parms, f);
+
+ cleanupFunction(n, f, parms);
+
+ if (SwigType_type(result) != T_VOID) {
+ Printv(f->code, " return go_result;\n", NULL);
+ }
+
+ Printv(f->code, "}\n", NULL);
+
+ Wrapper_print(f, f_c_wrappers);
+
+ Swig_restore(n);
+
+ DelWrapper(f);
+ if (base_parm != NULL) {
+ Delete(base_parm);
+ }
+
+ return SWIG_OK;
+ }
+
+ /* -----------------------------------------------------------------------
+ * checkConstraints()
+ *
+ * Check parameter constraints if any. This is used for the C/C++
+ * function. This assumes that each parameter has an "emit:input"
+ * property with the name to use to refer to that parameter.
+ * ----------------------------------------------------------------------- */
+
+ void checkConstraints(ParmList *parms, Wrapper *f) {
+ Parm *p = parms;
+ while (p != NULL) {
+ String *tm = Getattr(p, "tmap:check");
+ if (tm == NULL) {
+ p = nextSibling(p);
+ } else {
+ Replaceall(tm, "$input", Getattr(p, "emit:input"));
+ Printv(f->code, tm, "\n\n", NULL);
+ p = Getattr(p, "tmap:check:next");
+ }
+ }
+ }
+
+ /* -----------------------------------------------------------------------
+ * getGoAction()
+ *
+ * Get the action of the function. This is used for C/C++ function.
+ * ----------------------------------------------------------------------- */
+
+ void emitGoAction(Node *n, List *base, ParmList *parms, SwigType *result,
+ Wrapper *f) {
+ String *actioncode;
+ if (base == NULL || isStatic(n)) {
+ Swig_director_emit_dynamic_cast(n, f);
+ actioncode = emit_action(n);
+ } else {
+ // Call the base class method.
+ actioncode = NewString("");
+
+ String *current = NewString("");
+ if (!gccgo_flag) {
+ Printv(current, "swig_a->", NULL);
+ }
+ Printv(current, Getattr(parms, "lname"), NULL);
+
+ String *last = NULL;
+ int vc = 0;
+ for (Iterator bi = First(base); bi.item != NULL; bi = Next(bi)) {
+ Printf(actioncode, " %s *swig_b%d = (%s *)%s;\n", bi.item, vc,
+ bi.item, current);
+ Delete(current);
+ current = NewString("");
+ Printf(current, "swig_b%d", vc);
+ ++vc;
+ last = bi.item;
+ }
+
+ String *code = Copy(Getattr(n, "wrap:action"));
+ Replaceall(code, Getattr(parms, "lname"), current);
+ Printv(actioncode, code, "\n", NULL);
+ }
+
+ Swig_save("emitGoAction", n, "type", "tmap:out", NULL);
+
+ Setattr(n, "type", result);
+
+ String *tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode);
+ if (tm == NULL) {
+ Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number,
+ "Unable to use return type %s\n",
+ SwigType_str(result, 0));
+ } else {
+ if (!gccgo_flag) {
+ Replaceall(tm, "$result", "swig_a->result");
+ } else {
+ Replaceall(tm, "$result", "go_result");
+ }
+ if (GetFlag(n, "feature:new")) {
+ Replaceall(tm, "$owner", "1");
+ } else {
+ Replaceall(tm, "$owner", "0");
+ }
+ Printv(f->code, tm, "\n", NULL);
+ Delete(tm);
+ }
+
+ Swig_restore(n);
+ }
+
+ /* -----------------------------------------------------------------------
+ * argout()
+ *
+ * Handle argument output code if any. This is used for the C/C++
+ * function. This assumes that each parameter has an "emit:input"
+ * property with the name to use to refer to that parameter.
+ * ----------------------------------------------------------------------- */
+
+ void argout(ParmList *parms, Wrapper *f) {
+ Parm *p = parms;
+ while (p != NULL) {
+ String *tm = Getattr(p, "tmap:argout");
+ if (tm == NULL) {
+ p = nextSibling(p);
+ } else {
+ Replaceall(tm, "$result", "result");
+ Replaceall(tm, "$input", Getattr(p, "emit:input"));
+ Printv(f->code, tm, "\n", NULL);
+ p = Getattr(p, "tmap:argout:next");
+ }
+ }
+ }
+
+ /* -----------------------------------------------------------------------
+ * freearg()
+ *
+ * Handle argument cleanup code if any. This is used for the C/C++
+ * function. This assumes that each parameter has an "emit:input"
+ * property with the name to use to refer to that parameter.
+ * ----------------------------------------------------------------------- */
+
+ String *freearg(ParmList *parms) {
+ String *ret = NewString("");
+ Parm *p = parms;
+ while (p != NULL) {
+ String *tm = Getattr(p, "tmap:freearg");
+ if (tm == NULL) {
+ p = nextSibling(p);
+ } else {
+ Replaceall(tm, "$input", Getattr(p, "emit:input"));
+ Printv(ret, tm, "\n", NULL);
+ p = Getattr(p, "tmap:freearg:next");
+ }
+ }
+ return ret;
+ }
+
+ /* -----------------------------------------------------------------------
+ * cleanupFunction()
+ *
+ * Final function cleanup code.
+ * ----------------------------------------------------------------------- */
+
+ void cleanupFunction(Node *n, Wrapper *f, ParmList *parms) {
+ String *cleanup = freearg(parms);
+ Printv(f->code, cleanup, NULL);
+
+ if (GetFlag(n, "feature:new")) {
+ String *tm = Swig_typemap_lookup("newfree", n, "result", 0);
+ if (tm != NULL) {
+ Replaceall(tm, "$source", "result");
+ Printv(f->code, tm, "\n", NULL);
+ Delete(tm);
+ }
+ }
+
+ Replaceall(f->code, "$cleanup", cleanup);
+ Delete(cleanup);
+
+ Replaceall(f->code, "$symname", Getattr(n, "sym:name"));
+ }
+
+ /* -----------------------------------------------------------------------
+ * variableHandler()
+ *
+ * This exists just to set the making_variable_wrappers flag.
+ * ----------------------------------------------------------------------- */
+
+ virtual int variableHandler(Node *n) {
+ assert(!making_variable_wrappers);
+ making_variable_wrappers = true;
+ int r = Language::variableHandler(n);
+ making_variable_wrappers = false;
+ return r;
+ }
+
+ /* -----------------------------------------------------------------------
+ * constantWrapper()
+ *
+ * Product a const declaration.
+ * ------------------------------------------------------------------------ */
+
+ virtual int constantWrapper(Node *n) {
+ SwigType *type = Getattr(n, "type");
+
+ if (!SwigType_issimple(type) && SwigType_type(type) != T_STRING) {
+ return goComplexConstant(n, type);
+ }
+
+ if (Getattr(n, "storage") != NULL
+ && Strcmp(Getattr(n, "storage"), "static") == 0) {
+ return goComplexConstant(n, type);
+ }
+
+ String *go_name = buildGoName(Getattr(n, "sym:name"), false, false);
+
+ if (!addSymbol(go_name, n)) {
+ Delete(go_name);
+ return SWIG_ERROR;
+ }
+
+ String *tm = goType(n, type);
+ String *value = Getattr(n, "value");
+
+ String *copy = NULL;
+ if (SwigType_type(type) == T_BOOL) {
+ if (Cmp(value, "true") != 0 && Cmp(value, "false") != 0) {
+ return goComplexConstant(n, type);
+ }
+ } else if (SwigType_type(type) == T_STRING
+ || SwigType_type(type) == T_CHAR) {
+ // Backslash sequences are somewhat different in Go and C/C++.
+ if (Strchr(value, '\\') != NULL) {
+ return goComplexConstant(n, type);
+ }
+ } else {
+ // Accept a 0x prefix, and strip combinations of u and l
+ // suffixes. Otherwise accept digits, decimal point, and
+ // exponentiation. Treat anything else as too complicated to
+ // handle as a Go constant.
+ char *p = Char(value);
+ int len = strlen(p);
+ bool need_copy = false;
+ while (len > 0) {
+ char c = p[len - 1];
+ if (c != 'l' && c != 'L' && c != 'u' && c != 'U') {
+ break;
+ }
+ --len;
+ need_copy = true;
+ }
+ bool is_hex = false;
+ int i = 0;
+ if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
+ i = 2;
+ is_hex = true;
+ }
+ for (; i < len; ++i) {
+ switch (p[i]) {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ break;
+ case 'a': case 'b': case 'c': case 'd': case 'f':
+ case 'A': case 'B': case 'C': case 'D': case 'F':
+ if (!is_hex) {
+ return goComplexConstant(n, type);
+ }
+ break;
+ case '.': case 'e': case 'E': case '+': case '-':
+ break;
+ default:
+ return goComplexConstant(n, type);
+ }
+ }
+ if (need_copy) {
+ copy = Copy(value);
+ Replaceall(copy, p + len, "");
+ value = copy;
+ }
+ }
+
+ Printv(f_go_wrappers, "const ", go_name, " ", tm, " = ", NULL);
+ if (SwigType_type(type) == T_STRING) {
+ Printv(f_go_wrappers, "\"", value, "\"", NULL);
+ } else if (SwigType_type(type) == T_CHAR) {
+ Printv(f_go_wrappers, "'", value, "'", NULL);
+ } else {
+ Printv(f_go_wrappers, value, NULL);
+ }
+
+ Printv(f_go_wrappers, "\n", NULL);
+
+ Delete(tm);
+ Delete(go_name);
+ if (copy != NULL) {
+ Delete(copy);
+ }
+
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * enumDeclaration()
+ *
+ * A C++ enum type turns into a Named go int type.
+ * ---------------------------------------------------------------------- */
+
+ virtual int enumDeclaration(Node *n) {
+ String *name = goEnumName(n);
+ if (Strcmp(name, "int") != 0) {
+ if (!ImportMode || imported_package == NULL) {
+ Printv(f_go_wrappers, "type ", name, " int\n", NULL);
+ } else {
+ String *nw = NewString("");
+ Printv(nw, imported_package, ".", name, NULL);
+ Setattr(n, "go:enumname", nw);
+ }
+ }
+ Delete(name);
+
+ return Language::enumDeclaration(n);
+ }
+
+ /* -----------------------------------------------------------------------
+ * enumvalueDeclaration()
+ *
+ * Declare a single value of an enum type. We fetch the value by
+ * calling a C/C++ function.
+ * ------------------------------------------------------------------------ */
+
+ virtual int enumvalueDeclaration(Node *n) {
+ if (!is_public(n)) {
+ return SWIG_OK;
+ }
+ if (Getattr(parentNode(n), "unnamed") != NULL) {
+ Setattr(n, "type", NewString("int"));
+ } else {
+ Setattr(n, "type", Getattr(parentNode(n), "enumtype"));
+ }
+ return goComplexConstant(n, Getattr(n, "type"));
+ }
+
+ /* -----------------------------------------------------------------------
+ * goComplexConstant()
+ *
+ * Handle a const declaration for something which is not a Go constant.
+ * ------------------------------------------------------------------------ */
+
+ int goComplexConstant(Node *n, SwigType *type) {
+ String *get = NewString("");
+ Printv(get, "result = ", NULL);
+
+ char quote;
+ if (Getattr(n, "wrappedasconstant") != NULL) {
+ quote = '\0';
+ } else if (SwigType_type(type) == T_CHAR) {
+ quote = '\'';
+ } else if (SwigType_type(type) == T_STRING) {
+ quote = '"';
+ } else {
+ quote = '\0';
+ }
+
+ if (quote != '\0') {
+ Printf(get, "%c", quote);
+ }
+
+ Printv(get, Getattr(n, "value"), NULL);
+
+ if (quote != '\0') {
+ Printf(get, "%c", quote);
+ }
+
+ Printv(get, ";\n", NULL);
+ Setattr(n, "wrap:action", get);
+
+ String* symname = Getattr(n, "sym:name");
+ if (symname == NULL) {
+ symname = Getattr(n, "name");
+ }
+
+ String *sname = Copy(symname);
+ if (class_name != NULL) {
+ Append(sname, "_");
+ Append(sname, class_name);
+ }
+
+ String *go_name = NewString("_swig_get");
+ if (class_name != NULL) {
+ Append(go_name, class_name);
+ Append(go_name, "_");
+ }
+ Append(go_name, sname);
+
+ String *wname = Swig_name_wrapper(sname);
+ Setattr(n, "wrap:name", wname);
+
+ int r = makeWrappers(n, sname, go_name, NULL, wname, NULL, NULL, type,
+ true);
+
+ if (r != SWIG_OK) {
+ return r;
+ }
+
+ String *varname = buildGoName(symname, true, false);
+ String *t = goType(n, type);
+ Printv(f_go_wrappers, "var ", varname, " ", t, " = ", go_name, "()\n",
+ NULL);
+
+ Delete(varname);
+ Delete(t);
+ Delete(go_name);
+ Delete(sname);
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * classHandler()
+ *
+ * For a C++ class, in Go we generate both a struct and an
+ * interface. The interface will declare all the class public
+ * methods. We will define all the methods on the struct, so that
+ * the struct meets the interface. We then expect users of the
+ * class to use the interface.
+ * ------------------------------------------------------------ */
+
+ virtual int classHandler(Node *n) {
+ class_node = n;
+
+ List *baselist = Getattr(n, "bases");
+ bool has_base_classes = baselist != NULL && Len(baselist) > 0;
+
+ String *name = Getattr(n, "sym:name");
+
+ String *go_name = exportedName(name);
+
+ String *go_type_name = goCPointerType(Getattr(n, "classtypeobj"), true);
+
+ class_name = name;
+ class_receiver = go_type_name;
+ class_methods = NewHash();
+
+ int isdir = GetFlag(n, "feature:director");
+ int isnodir = GetFlag(n, "feature:nodirector");
+ bool is_director = isdir && !isnodir;
+
+ Printv(f_go_wrappers, "type ", go_type_name, " uintptr\n\n", NULL);
+
+ // A method to return the pointer to the C++ class. This is used
+ // by generated code to convert between the interface and the C++
+ // value.
+ Printv(f_go_wrappers, "func (p ", go_type_name, ") Swigcptr() uintptr {\n",
+ NULL);
+ Printv(f_go_wrappers, "\treturn (uintptr)(p)\n", NULL);
+ Printv(f_go_wrappers, "}\n\n", NULL);
+
+ // A method used as a marker for the class, to avoid invalid
+ // interface conversions when using multiple inheritance.
+ Printv(f_go_wrappers, "func (p ", go_type_name, ") SwigIs", go_name,
+ "() {\n", NULL);
+ Printv(f_go_wrappers, "}\n\n", NULL);
+
+ if (is_director) {
+ // Return the interface passed to the NewDirector function.
+ Printv(f_go_wrappers, "func (p ", go_type_name,
+ ") DirectorInterface() interface{} {\n", NULL);
+ Printv(f_go_wrappers, "\treturn nil\n", NULL);
+ Printv(f_go_wrappers, "}\n\n", NULL);
+ }
+
+ // We have seen a definition for this type.
+ Setattr(defined_types, go_name, go_name);
+ Setattr(defined_types, go_type_name, go_type_name);
+
+ interfaces = NewString("");
+
+ int r = Language::classHandler(n);
+ if (r != SWIG_OK) {
+ return r;
+ }
+
+ if (has_base_classes) {
+ // For each method defined in a base class but not defined in
+ // this class, we need to define the method in this class. We
+ // can't use anonymous field inheritance because it works
+ // differently in Go and in C++.
+
+ Hash *local = NewHash();
+ for (Node *ni = Getattr(n, "firstChild");
+ ni != NULL;
+ ni = nextSibling(ni)) {
+
+ if (!is_public(ni)) {
+ continue;
+ }
+
+ String *type = Getattr(ni, "nodeType");
+ if (Cmp(type, "constructor") == 0 || Cmp(type, "destructor") == 0) {
+ continue;
+ }
+
+ String *cname = Getattr(ni, "sym:name");
+ if (cname == NULL) {
+ cname = Getattr(ni, "name");
+ }
+ if (cname != NULL) {
+ Setattr(local, cname, NewString(""));
+ }
+ }
+
+ for (Iterator b = First(baselist); b.item != NULL; b = Next(b)) {
+ List *bases = NewList();
+ Append(bases, Getattr(b.item, "classtype"));
+ int r = addBase(n, b.item, bases, local);
+ if (r != SWIG_OK) {
+ return r;
+ }
+ Delete(bases);
+ }
+
+ Delete(local);
+
+ Hash *parents = NewHash();
+ addFirstBaseInterface(n, parents, baselist);
+ int r = addExtraBaseInterfaces(n, parents, baselist);
+ Delete(parents);
+ if (r != SWIG_OK) {
+ return r;
+ }
+ }
+
+ Printv(f_go_wrappers, "type ", go_name, " interface {\n", NULL);
+ Printv(f_go_wrappers, "\tSwigcptr() uintptr\n", NULL);
+ Printv(f_go_wrappers, "\tSwigIs", go_name, "()\n", NULL);
+
+ if (is_director) {
+ Printv(f_go_wrappers, "\tDirectorInterface() interface{}\n", NULL);
+ }
+
+ Append(f_go_wrappers, interfaces);
+ Printf(f_go_wrappers, "}\n\n", NULL);
+ Delete(interfaces);
+
+ interfaces = NULL;
+ class_name = NULL;
+ class_receiver = NULL;
+ class_node = NULL;
+ Delete(class_methods);
+ class_methods = NULL;
+
+ Delete(go_type_name);
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * addBase()
+ *
+ * Implement methods and members defined in a parent class for a
+ * child class.
+ * ------------------------------------------------------------ */
+
+ int addBase(Node *n, Node *base, List *bases, Hash *local) {
+ if (GetFlag(base, "feature:ignore")) {
+ return SWIG_OK;
+ }
+
+ for (Node *ni = Getattr(base, "firstChild");
+ ni != NULL;
+ ni = nextSibling(ni)) {
+
+ if (GetFlag(ni, "feature:ignore")) {
+ continue;
+ }
+
+ if (!is_public(ni)) {
+ continue;
+ }
+
+ String *type = Getattr(ni, "nodeType");
+ if (Strcmp(type, "constructor") == 0
+ || Strcmp(type, "destructor") == 0
+ || Strcmp(type, "enum") == 0
+ || Strcmp(type, "using") == 0) {
+ continue;
+ }
+ String *storage = Getattr(ni, "storage");
+ if (Strcmp(storage, "typedef") == 0 || Strcmp(storage, "friend") == 0) {
+ continue;
+ }
+
+ String *mname = Getattr(ni, "sym:name");
+ if (mname == NULL) {
+ continue;
+ }
+
+ String *lname = Getattr(ni, "name");
+ if (Getattr(class_methods, lname) != NULL) {
+ continue;
+ }
+ if (Getattr(local, lname) != NULL) {
+ continue;
+ }
+ Setattr(local, lname, NewString(""));
+
+ String *ty = NewString(Getattr(ni, "type"));
+ SwigType_push(ty, Getattr(ni, "decl"));
+ String *fullty = SwigType_typedef_resolve_all(ty);
+ bool is_function = SwigType_isfunction(fullty);
+ Delete(ty);
+ Delete(fullty);
+
+ if (is_function) {
+ int r = goBaseMethod(n, bases, ni);
+ if (r != SWIG_OK) {
+ return r;
+ }
+
+ if (Getattr(ni, "sym:overloaded") != NULL) {
+ for (Node *on = Getattr(ni, "sym:nextSibling");
+ on != NULL;
+ on = Getattr(on, "sym:nextSibling")) {
+ r = goBaseMethod(n, bases, on);
+ if (r != SWIG_OK) {
+ return r;
+ }
+ }
+
+ String *receiver = class_receiver;
+ bool is_static = isStatic(ni);
+ if (is_static) {
+ receiver = NULL;
+ }
+ String *go_name = buildGoName(Getattr(ni, "sym:name"), is_static,
+ false);
+ r = makeDispatchFunction(ni, go_name, receiver, is_static, NULL,
+ false);
+ Delete(go_name);
+ if (r != SWIG_OK) {
+ return r;
+ }
+ }
+ } else {
+ int r = goBaseVariable(n, bases, ni);
+ if (r != SWIG_OK) {
+ return r;
+ }
+ }
+ }
+
+ List *baselist = Getattr(base, "bases");
+ if (baselist != NULL && Len(baselist) > 0) {
+ for (Iterator b = First(baselist); b.item != NULL; b = Next(b)) {
+ List *nb = Copy(bases);
+ Append(nb, Getattr(b.item, "classtype"));
+ int r = addBase(n, b.item, nb, local);
+ Delete(nb);
+ if (r != SWIG_OK) {
+ return r;
+ }
+ }
+ }
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * goBaseMethod()
+ *
+ * Implement a method defined in a parent class for a child class.
+ * ------------------------------------------------------------ */
+
+ int goBaseMethod(Node *method_class, List *bases, Node *method) {
+ String *symname = Getattr(method, "sym:name");
+ if (!validIdentifier(symname)) {
+ return SWIG_OK;
+ }
+
+ String *name = NewString("");
+ Printv(name, Getattr(method_class, "sym:name"), "_", symname, NULL);
+
+ bool is_static = isStatic(method);
+
+ String *go_name = buildGoName(name, is_static, false);
+
+ String *overname = NULL;
+ if (Getattr(method, "sym:overloaded")) {
+ overname = Getattr(method, "sym:overname");
+ }
+ String *wname = Swig_name_wrapper(name);
+ if (overname != NULL) {
+ Append(wname, overname);
+ }
+
+ String *result = NewString(Getattr(method, "type"));
+ SwigType_push(result, Getattr(method, "decl"));
+ if (SwigType_isqualifier(result)) {
+ Delete(SwigType_pop(result));
+ }
+ Delete(SwigType_pop_function(result));
+
+ // If the base method is imported, wrap:action may not be set.
+ Swig_save("goBaseMethod", method, "wrap:action", "parms", NULL);
+ if (Getattr(method, "wrap:action") == NULL) {
+ if (!is_static) {
+ Swig_MethodToFunction(method, getNSpace(), getClassType(),
+ (Getattr(method, "template") != NULL
+ ? SmartPointer
+ : Extend | SmartPointer),
+ NULL, false);
+ // Remove any self parameter that was just added.
+ ParmList *parms = Getattr(method, "parms");
+ if (parms != NULL && Getattr(parms, "self") != NULL) {
+ parms = CopyParmList(nextSibling(parms));
+ Setattr(method, "parms", parms);
+ }
+ } else {
+ String *call = Swig_cfunction_call(Getattr(method, "name"),
+ Getattr(method, "parms"));
+ Setattr(method, "wrap:action", Swig_cresult(Getattr(method, "type"),
+ "result", call));
+ }
+ }
+
+ int r = makeWrappers(method, name, go_name, overname, wname, bases,
+ Getattr(method, "parms"), result, is_static);
+
+ Swig_restore(method);
+
+ Delete(result);
+ Delete(go_name);
+ Delete(name);
+
+ return r;
+ }
+
+ /* ------------------------------------------------------------
+ * goBaseVariable()
+ *
+ * Add accessors for a member variable defined in a parent class for
+ * a child class.
+ * ------------------------------------------------------------ */
+
+ int goBaseVariable(Node *var_class, List *bases, Node *var) {
+ if (isStatic(var)) {
+ return SWIG_OK;
+ }
+
+ String *var_name = buildGoName(Getattr(var, "sym:name"), false, false);
+
+ Swig_save("goBaseVariable", var, "type", "wrap:action", NULL);
+
+ // For a pointer type we apparently have to wrap in the decl.
+ SwigType *var_type = NewString(Getattr(var, "type"));
+ SwigType_push(var_type, Getattr(var, "decl"));
+ Setattr(var, "type", var_type);
+
+ SwigType *vt = Copy(var_type);
+ if (SwigType_isclass(vt)) {
+ SwigType_add_pointer(vt);
+ }
+
+ int flags = Extend | SmartPointer | use_naturalvar_mode(var);
+ if (is_non_virtual_protected_access(var)) {
+ flags |= CWRAP_ALL_PROTECTED_ACCESS;
+ }
+
+ String *mname = Swig_name_member(getNSpace(),
+ Getattr(var_class, "sym:name"),
+ var_name);
+
+ if (is_assignable(var)) {
+ for (Iterator ki = First(var); ki.key != NULL; ki = Next(ki)) {
+ if (Strncmp(ki.key, "tmap:", 5) == 0) {
+ Delattr(var, ki.key);
+ }
+ }
+ Swig_save("goBaseVariableSet", var, "name", "sym:name", "type", NULL);
+
+ String *mname_set = NewString("Set");
+ Append(mname_set, mname);
+
+ String *go_name = NewString("Set");
+ Append(go_name, var_name);
+
+ Swig_MembersetToFunction(var, class_name, flags);
+
+ String *wname = Swig_name_wrapper(mname_set);
+ ParmList *parms = NewParm(vt, var_name, var);
+ String *result = NewString("void");
+ int r = makeWrappers(var, mname_set, go_name, NULL, wname, bases, parms,
+ result, false);
+ if (r != SWIG_OK) {
+ return r;
+ }
+ Delete(wname);
+ Delete(parms);
+ Delete(result);
+ Delete(go_name);
+ Delete(mname_set);
+
+ Swig_restore(var);
+ for (Iterator ki = First(var); ki.key != NULL; ki = Next(ki)) {
+ if (Strncmp(ki.key, "tmap:", 5) == 0) {
+ Delattr(var, ki.key);
+ }
+ }
+ }
+
+ Swig_MembergetToFunction(var, class_name, flags);
+
+ String *mname_get = NewString("Get");
+ Append(mname_get, mname);
+
+ String *go_name = NewString("Get");
+ Append(go_name, var_name);
+
+ String *wname = Swig_name_wrapper(mname_get);
+
+ int r = makeWrappers(var, mname_get, go_name, NULL, wname, bases, NULL,
+ vt, false);
+ if (r != SWIG_OK) {
+ return r;
+ }
+
+ Delete(wname);
+ Delete(mname_get);
+ Delete(go_name);
+ Delete(mname);
+ Delete(var_name);
+ Delete(var_type);
+ Delete(vt);
+
+ Swig_restore(var);
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * addFirstBaseInterface()
+ *
+ * When a C++ class uses multiple inheritance, we can use the C++
+ * pointer for the first base class but not for any subsequent base
+ * classes. However, the Go interface will match the interface for
+ * all the base classes. To avoid accidentally treating a class as
+ * a pointer to a base class other than the first one, we use an
+ * isClassname method. This function adds those methods as
+ * required.
+ *
+ * For convenience when using multiple inheritance, we also add
+ * functions to retrieve the base class pointers.
+ * ------------------------------------------------------------ */
+
+ void addFirstBaseInterface(Node *n, Hash *parents, List *bases) {
+ if (bases == NULL || Len(bases) == 0) {
+ return;
+ }
+ Iterator b = First(bases);
+ if (!GetFlag(b.item, "feature:ignore")) {
+ String *go_name = buildGoName(Getattr(n, "sym:name"), false, false);
+ String *go_type_name = goCPointerType(Getattr(n, "classtypeobj"), true);
+ String *go_base_name = exportedName(Getattr(b.item, "sym:name"));
+ String *go_base_type = goType(n, Getattr(b.item, "classtypeobj"));
+ String *go_base_type_name = goCPointerType(Getattr(b.item,
+ "classtypeobj"),
+ true);
+
+ Printv(f_go_wrappers, "func (p ", go_type_name, ") SwigIs", go_base_name,
+ "() {\n", NULL);
+ Printv(f_go_wrappers, "}\n\n", NULL);
+
+ Printv(interfaces, "\tSwigIs", go_base_name, "()\n", NULL);
+
+ Printv(f_go_wrappers, "func (p ", go_type_name, ") SwigGet", go_base_name,
+ "() ", go_base_type, " {\n", NULL);
+ Printv(f_go_wrappers, "\treturn ", go_base_type_name,
+ "(p.Swigcptr())\n", NULL);
+ Printv(f_go_wrappers, "}\n\n", NULL);
+
+ Printv(interfaces, "\tSwigGet", go_base_name, "() ", go_base_type, "\n",
+ NULL);
+
+ Setattr(parents, go_base_name, NewString(""));
+
+ Delete(go_name);
+ Delete(go_type_name);
+ Delete(go_base_type);
+ Delete(go_base_type_name);
+ }
+
+ addFirstBaseInterface(n, parents, Getattr(b.item, "bases"));
+ }
+
+ /* ------------------------------------------------------------
+ * addExtraBaseInterfaces()
+ *
+ * Add functions to retrieve the base class pointers for all base
+ * classes other than the first.
+ * ------------------------------------------------------------ */
+
+ int addExtraBaseInterfaces(Node *n, Hash *parents, List *bases) {
+ Iterator b = First(bases);
+
+ Node *fb = b.item;
+
+ for (b = Next(b); b.item != NULL; b = Next(b)) {
+ if (GetFlag(b.item, "feature:ignore")) {
+ continue;
+ }
+
+ String *go_base_name = exportedName(Getattr(b.item, "sym:name"));
+
+ Swig_save("addExtraBaseInterface", n, "wrap:action", "wrap:name",
+ "wrap:parms", NULL);
+
+ SwigType *type = Copy(Getattr(n, "classtypeobj"));
+ SwigType_add_pointer(type);
+ Parm *parm = NewParm(type, "self", n);
+ Setattr(n, "wrap:parms", parm);
+
+ String *pn = Swig_cparm_name(parm, 0);
+ String *action = NewString("");
+ Printv(action, "result = (", Getattr(b.item, "classtype"), "*)", pn,
+ ";", NULL);
+ Delete(pn);
+
+ Setattr(n, "wrap:action", action);
+
+ String *name = Copy(class_name);
+ Append(name, "_SwigGet");
+ Append(name, go_base_name);
+
+ String *go_name = NewString("SwigGet");
+ String *c1 = exportedName(go_base_name);
+ Append(go_name, c1);
+ Delete(c1);
+
+ String *wname = Swig_name_wrapper(name);
+ Setattr(n, "wrap:name", wname);
+
+ SwigType *result = Copy(Getattr(b.item, "classtypeobj"));
+ SwigType_add_pointer(result);
+
+ int r = makeWrappers(n, name, go_name, NULL, wname, NULL, parm, result,
+ false);
+ if (r != SWIG_OK) {
+ return r;
+ }
+
+ Swig_restore(n);
+
+ Setattr(parents, go_base_name, NewString(""));
+
+ Delete(go_name);
+ Delete(type);
+ Delete(parm);
+ Delete(action);
+ Delete(result);
+
+ String *ns = NewString("");
+ addParentExtraBaseInterfaces(n, parents, b.item, false, ns);
+ Delete(ns);
+ }
+
+ if (!GetFlag(fb, "feature:ignore")) {
+ String *ns = NewString("");
+ addParentExtraBaseInterfaces(n, parents, fb, true, ns);
+ Delete(ns);
+ }
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * addParentExtraBaseInterfaces()
+ *
+ * Add functions to retrieve the base class pointers for all base
+ * classes of parents other than the first base class at each level.
+ * ------------------------------------------------------------ */
+
+ void addParentExtraBaseInterfaces(Node *n, Hash *parents, Node *base,
+ bool is_base_first, String *sofar) {
+ List *baselist = Getattr(base, "bases");
+ if (baselist == NULL || Len(baselist) == 0) {
+ return;
+ }
+
+ String *go_this_base_name = exportedName(Getattr(base, "sym:name"));
+
+ String *sf = NewString("");
+ Printv(sf, sofar, ".SwigGet", go_this_base_name, "()", NULL);
+
+ Iterator b = First(baselist);
+
+ if (is_base_first) {
+ if (!GetFlag(b.item, "feature:ignore")) {
+ addParentExtraBaseInterfaces(n, parents, b.item, true, sf);
+ }
+
+ b = Next(b);
+ if (b.item == NULL) {
+ return;
+ }
+ }
+
+ String *go_name = buildGoName(Getattr(n, "sym:name"), false, false);
+ String *go_type_name = goCPointerType(Getattr(n, "classtypeobj"), true);
+
+ for (; b.item != NULL; b = Next(b)) {
+ if (GetFlag(b.item, "feature:ignore")) {
+ continue;
+ }
+
+ String *go_base_name = exportedName(Getattr(b.item, "sym:name"));
+
+ if (Getattr(parents, go_base_name) == NULL) {
+ Printv(f_go_wrappers, "func (p ", go_type_name, ") SwigGet",
+ go_base_name, "() ", go_base_name, " {\n", NULL);
+ Printv(f_go_wrappers, "\treturn p", sf, ".SwigGet", go_base_name,
+ "()\n", NULL);
+ Printv(f_go_wrappers, "}\n\n", NULL);
+
+ Printv(interfaces, "\tSwigGet", go_base_name, "() ", go_base_name, "\n",
+ NULL);
+
+ addParentExtraBaseInterfaces(n, parents, b.item, false, sf);
+
+ Setattr(parents, go_base_name, NewString(""));
+ }
+ }
+
+ Delete(go_name);
+ Delete(go_type_name);
+ Delete(go_this_base_name);
+ Delete(sf);
+ }
+
+ /* ------------------------------------------------------------
+ * classDirectorInit
+ *
+ * Add support for a director class.
+ *
+ * Virtual inheritance is different in Go and C++. We implement
+ * director classes by defining a new function in Go,
+ * NewDirectorClassname, which takes a empty interface value and
+ * creates an instance of a new child class. The new child class
+ * refers all methods back to Go. The Go code checks whether the
+ * value passed to NewDirectorClassname implements that method; if
+ * it does, it calls it, otherwise it calls back into C++.
+ * ------------------------------------------------------------ */
+
+ int classDirectorInit(Node *n) {
+ // Because we use a different function to handle inheritance in
+ // Go, ordinary creations of the object should not create a
+ // director object.
+ Delete(director_ctor_code);
+ director_ctor_code = NewString("$nondirector_new");
+
+ class_node = n;
+
+ String *name = Getattr(n, "sym:name");
+
+ assert(class_name == NULL);
+ class_name = name;
+
+ String *go_name = exportedName(name);
+
+ String *go_type_name = goCPointerType(Getattr(n, "classtypeobj"), true);
+
+ assert(class_receiver == NULL);
+ class_receiver = go_type_name;
+
+ String *director_struct_name = NewString("_swig_Director");
+ Append(director_struct_name, go_name);
+
+ String* cxx_director_name = NewString("SwigDirector_");
+ Append(cxx_director_name, name);
+
+ // The Go type of the director class.
+ Printv(f_go_wrappers, "type ", director_struct_name, " struct {\n", NULL);
+ Printv(f_go_wrappers, "\t", go_type_name, "\n", NULL);
+ Printv(f_go_wrappers, "\tv interface{}\n", NULL);
+ Printv(f_go_wrappers, "}\n\n", NULL);
+
+ Printv(f_go_wrappers, "func (p *", director_struct_name,
+ ") Swigcptr() uintptr {\n", NULL);
+ Printv(f_go_wrappers, "\treturn p.", go_type_name, ".Swigcptr()\n", NULL);
+ Printv(f_go_wrappers, "}\n\n", NULL);
+
+ Printv(f_go_wrappers, "func (p *", director_struct_name, ") SwigIs",
+ go_name, "() {\n", NULL);
+ Printv(f_go_wrappers, "}\n\n", NULL);
+
+ Printv(f_go_wrappers, "func (p *", director_struct_name,
+ ") DirectorInterface() interface{} {\n", NULL);
+ Printv(f_go_wrappers, "\treturn p.v\n", NULL);
+ Printv(f_go_wrappers, "}\n\n", NULL);
+
+ // Start defining the director class.
+ Printv(f_c_directors_h, "class ", cxx_director_name, " : public ",
+ Getattr(n, "classtype"), "\n", NULL);
+ Printv(f_c_directors_h, "{\n", NULL);
+ Printv(f_c_directors_h, " public:\n", NULL);
+
+ Delete(director_struct_name);
+ Delete(cxx_director_name);
+
+ class_methods = NewHash();
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * classDirectorConstructor
+ *
+ * Emit a constructor for a director class.
+ * ------------------------------------------------------------ */
+
+ int classDirectorConstructor(Node *n) {
+ bool is_ignored = GetFlag(n, "feature:ignore");
+
+ String *name = Getattr(n, "sym:name");
+ if (name == NULL) {
+ assert(is_ignored);
+ name = Getattr(n, "name");
+ }
+
+ String *overname = NULL;
+ if (Getattr(n, "sym:overloaded")) {
+ overname = Getattr(n, "sym:overname");
+ }
+
+ String *go_name = exportedName(name);
+
+ ParmList *parms = Getattr(n, "parms");
+ Setattr(n, "wrap:parms", parms);
+
+ String *cn = exportedName(Getattr(parentNode(n), "sym:name"));
+
+ String *go_type_name = goCPointerType(Getattr(parentNode(n),
+ "classtypeobj"),
+ true);
+
+ String *director_struct_name = NewString("_swig_Director");
+ Append(director_struct_name, cn);
+
+ String *fn_name = NewString("_swig_NewDirector");
+ Append(fn_name, cn);
+ Append(fn_name, go_name);
+
+ if (overname == NULL && !is_ignored) {
+ if (!addSymbol(fn_name, n)) {
+ return SWIG_ERROR;
+ }
+ }
+
+ String *wname = Swig_name_wrapper(fn_name);
+
+ if (overname != NULL) {
+ Append(wname, overname);
+ }
+ Setattr(n, "wrap:name", wname);
+
+ bool is_static = isStatic(n);
+
+ Wrapper *dummy = NewWrapper();
+ emit_attach_parmmaps(parms, dummy);
+ DelWrapper(dummy);
+
+ Swig_typemap_attach_parms("go", parms, NULL);
+ int parm_count = emit_num_arguments(parms);
+
+ String *func_name = NewString("NewDirector");
+ Append(func_name, go_name);
+
+ String *func_with_over_name = Copy(func_name);
+ if (overname != NULL) {
+ Append(func_with_over_name, overname);
+ }
+
+ SwigType *first_type = NewString("void");
+ SwigType_add_pointer(first_type);
+ Parm *first_parm = NewParm(first_type, "swig_p", n);
+ set_nextSibling(first_parm, parms);
+ Setattr(first_parm, "lname", "p");
+
+ Parm *p = parms;
+ for (int i = 0; i < parm_count; ++i) {
+ p = getParm(p);
+ Swig_cparm_name(p, i);
+ p = nextParm(p);
+ }
+
+ if (!is_ignored) {
+ // Declare the C++ wrapper.
+ Printv(f_go_wrappers, "func ", fn_name, NULL);
+ if (overname != NULL) {
+ Printv(f_go_wrappers, overname, NULL);
+ }
+ Printv(f_go_wrappers, "(*", director_struct_name, NULL);
+
+ p = parms;
+ for (int i = 0; i < parm_count; ++i) {
+ p = getParm(p);
+ String *tm = goType(p, Getattr(p, "type"));
+ Printv(f_go_wrappers, ", ", tm, NULL);
+ Delete(tm);
+ p = nextParm(p);
+ }
+
+ Printv(f_go_wrappers, ") ", go_type_name, NULL);
+
+ if (gccgo_flag) {
+ Printv(f_go_wrappers, " __asm__(\"", go_prefix, "_", wname, "\")",
+ NULL);
+ }
+
+ Printv(f_go_wrappers, "\n\n", NULL);
+
+ Printv(f_go_wrappers, "func ", func_with_over_name, "(v interface{}",
+ NULL);
+
+ p = parms;
+ for (int i = 0; i < parm_count; ++i) {
+ p = getParm(p);
+ // Set the lname parameter.
+ Printv(f_go_wrappers, ", ", Getattr(p, "lname"), " ", NULL);
+ String *tm = goType(p, Getattr(p, "type"));
+ Printv(f_go_wrappers, tm, NULL);
+ Delete(tm);
+ p = nextParm(p);
+ }
+
+ Printv(f_go_wrappers, ") ", cn, " {\n", NULL);
+
+ Printv(f_go_wrappers, "\tp := &", director_struct_name, "{0, v}\n",
+ NULL);
+ Printv(f_go_wrappers, "\tp.", class_receiver, " = ", fn_name, NULL);
+ if (overname != NULL) {
+ Printv(f_go_wrappers, overname, NULL);
+ }
+ Printv(f_go_wrappers, "(p", NULL);
+
+ p = parms;
+ for (int i = 0; i < parm_count; ++i) {
+ p = getParm(p);
+ Printv(f_go_wrappers, ", ", Getattr(p, "lname"), NULL);
+ p = nextParm(p);
+ }
+
+ Printv(f_go_wrappers, ")\n", NULL);
+ Printv(f_go_wrappers, "\treturn p\n", NULL);
+ Printv(f_go_wrappers, "}\n\n", NULL);
+
+ SwigType *result = Copy(Getattr(parentNode(n), "classtypeobj"));
+ SwigType_add_pointer(result);
+
+ Swig_save("classDirectorConstructor", n, "wrap:name", "wrap:action",
+ NULL);
+
+ Setattr(n, "wrap:name", Swig_name_wrapper(name));
+
+ String *action = NewString("");
+ Printv(action, "result = new SwigDirector_", class_name, "(", NULL);
+ String *pname = Swig_cparm_name(NULL, 0);
+ Printv(action, pname, NULL);
+ Delete(pname);
+ p = parms;
+ for (int i = 0; i < parm_count; ++i) {
+ p = getParm(p);
+ String *pname = Swig_cparm_name(NULL, i + 1);
+ Printv(action, ", ", NULL);
+ if (SwigType_isreference(Getattr(p, "type"))) {
+ Printv(action, "*", NULL);
+ }
+ Printv(action, pname, NULL);
+ Delete(pname);
+ p = nextParm(p);
+ }
+ Printv(action, ");", NULL);
+ Setattr(n, "wrap:action", action);
+
+ if (!gccgo_flag) {
+ int r = gcFunctionWrapper(n, fn_name, fn_name, overname, wname,
+ first_parm, result, is_static, false);
+ if (r != SWIG_OK) {
+ return r;
+ }
+ r = gccFunctionWrapper(n, NULL, wname, first_parm, result);
+ if (r != SWIG_OK) {
+ return r;
+ }
+ } else {
+ int r = gccgoFunctionWrapper(n, NULL, wname, first_parm, result);
+ if (r != SWIG_OK) {
+ return r;
+ }
+ }
+
+ Swig_restore(n);
+
+ Delete(result);
+ }
+
+ String *cxx_director_name = NewString("SwigDirector_");
+ Append(cxx_director_name, class_name);
+
+ String *decl = Swig_method_decl(NULL, Getattr(n, "decl"),
+ cxx_director_name, first_parm, 0, 0);
+ Printv(f_c_directors_h, " ", decl, ";\n", NULL);
+ Delete(decl);
+
+ decl = Swig_method_decl(NULL, Getattr(n, "decl"),
+ cxx_director_name, first_parm, 0, 0);
+ Printv(f_c_directors, cxx_director_name, "::", decl, "\n", NULL);
+ Delete(decl);
+
+ Printv(f_c_directors, " : ", Getattr(parentNode(n), "classtype"), "(",
+ NULL);
+
+ p = parms;
+ for (int i = 0; i < parm_count; ++i) {
+ p = getParm(p);
+ if (i > 0) {
+ Printv(f_c_directors, ", ", NULL);
+ }
+ String *pn = Getattr(p, "name");
+ assert(pn != NULL);
+ Printv(f_c_directors, pn, NULL);
+ p = nextParm(p);
+ }
+ Printv(f_c_directors, "),\n", NULL);
+ Printv(f_c_directors, " go_val(swig_p)\n", NULL);
+ Printv(f_c_directors, "{ }\n\n", NULL);
+
+ if (Getattr(n, "sym:overloaded") && Getattr(n, "sym:nextSibling") == NULL) {
+ int r = makeDispatchFunction(n, func_name, cn, is_static,
+ Getattr(parentNode(n), "classtypeobj"),
+ false);
+ if (r != SWIG_OK) {
+ return r;
+ }
+ }
+
+ Delete(cxx_director_name);
+ Delete(go_name);
+ Delete(cn);
+ Delete(go_type_name);
+ Delete(director_struct_name);
+ Delete(fn_name);
+ Delete(func_name);
+ Delete(func_with_over_name);
+ Delete(wname);
+ Delete(first_type);
+ Delete(first_parm);
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * classDirectorDestructor
+ *
+ * Emit a destructor for a director class.
+ * ------------------------------------------------------------ */
+
+ int classDirectorDestructor(Node *n) {
+ if (!is_public(n)) {
+ return SWIG_OK;
+ }
+
+ bool is_ignored = GetFlag(n, "feature:ignore");
+
+ if (!is_ignored) {
+ String *fnname = NewString("DeleteDirector");
+ String *c1 = exportedName(class_name);
+ Append(fnname, c1);
+ Delete(c1);
+
+ String *wname = Swig_name_wrapper(fnname);
+
+ Setattr(n, "wrap:name", fnname);
+
+ Swig_DestructorToFunction(n, getNSpace(),
+ Getattr(parentNode(n), "classtype"),
+ CPlusPlus, Extend);
+
+ ParmList *parms = Getattr(n, "parms");
+ Setattr(n, "wrap:parms", parms);
+
+ String *result = NewString("void");
+ int r = makeWrappers(n, fnname, fnname, NULL, wname, NULL, parms, result,
+ isStatic(n));
+ if (r != SWIG_OK) {
+ return r;
+ }
+
+ Delete(result);
+ Delete(fnname);
+ Delete(wname);
+ }
+
+ // Generate the destructor for the C++ director class. Since the
+ // Go code is keeping a pointer to the C++ object, we need to call
+ // back to the Go code to let it know that the C++ object is gone.
+
+ String *wname = NewString("_swiggo_wrap_DeleteDirector_");
+ Append(wname, class_name);
+
+ String *go_name = NewString("Swiggo_DeleteDirector_");
+ Append(go_name, class_name);
+
+ String *cn = exportedName(class_name);
+
+ String *director_struct_name = NewString("_swig_Director");
+ Append(director_struct_name, cn);
+
+ Printv(f_c_directors_h, " virtual ~SwigDirector_", class_name, "()",
+ NULL);
+
+ String *throws = buildThrow(n);
+ if (throws != NULL) {
+ Printv(f_c_directors_h, " ", throws, NULL);
+ }
+
+ Printv(f_c_directors_h, ";\n", NULL);
+
+ if (!is_ignored) {
+ if (!gccgo_flag) {
+ Printv(f_c_directors, "extern \"C\" void ", wname, "(void*, int);\n",
+ NULL);
+ } else {
+ Printv(f_c_directors, "extern \"C\" void ", wname, "(void*) __asm__(\"",
+ go_prefix, ".", package, ".", go_name, "\");\n", NULL);
+ }
+ }
+
+ Printv(f_c_directors, "SwigDirector_", class_name, "::~SwigDirector_",
+ class_name, "()", NULL);
+
+ if (throws != NULL) {
+ Printv(f_c_directors, " ", throws, NULL);
+ Delete(throws);
+ }
+
+ Printv(f_c_directors, "\n", NULL);
+ Printv(f_c_directors, "{\n", NULL);
+
+ if (!is_ignored) {
+ if (!gccgo_flag) {
+ Printv(f_c_directors, " struct { void *p; } a;\n", NULL);
+ Printv(f_c_directors, " a.p = go_val;\n", NULL);
+ Printv(f_c_directors, " crosscall2(", wname,
+ ", &a, (int) sizeof a);\n", NULL);
+
+ Printv(f_gc_wrappers, "#pragma dynexport ", wname, " ", wname, "\n",
+ NULL);
+ Printv(f_gc_wrappers, "extern void \xc2\xb7", go_name, "();\n", NULL);
+ Printv(f_gc_wrappers, "void\n", NULL);
+ Printv(f_gc_wrappers, wname, "(void *a, int32 n)\n", NULL);
+ Printv(f_gc_wrappers, "{\n", NULL);
+ Printv(f_gc_wrappers, "\tcgocallback(\xc2\xb7", go_name, ", a, n);\n",
+ NULL);
+ Printv(f_gc_wrappers, "}\n\n", NULL);
+ } else {
+ Printv(f_c_directors, " ", wname, "(go_val);\n", NULL);
+ }
+ }
+
+ Printv(f_c_directors, "}\n\n", NULL);
+
+ if (!is_ignored) {
+ Printv(f_go_wrappers, "func ", go_name, "(p *", director_struct_name,
+ ") {\n", NULL);
+ Printv(f_go_wrappers, "\tp.", class_receiver, " = 0\n", NULL);
+ Printv(f_go_wrappers, "}\n\n", NULL);
+ }
+
+ Delete(wname);
+ Delete(go_name);
+ Delete(cn);
+ Delete(director_struct_name);
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * classDirectorMethod
+ *
+ * Emit a method for a director class, plus its overloads.
+ * ------------------------------------------------------------ */
+
+ int classDirectorMethod(Node *n, Node *parent, String *super) {
+ (void) super;
+
+ bool is_ignored = GetFlag(n, "feature:ignore");
+ bool is_pure_virtual = (Cmp(Getattr(n, "storage"), "virtual") == 0
+ && Cmp(Getattr(n, "value"), "0") == 0);
+
+ // We don't need explicit calls.
+ if (GetFlag(n, "explicitcall")) {
+ return SWIG_OK;
+ }
+
+ String *name = Getattr(n, "sym:name");
+ if (name == NULL) {
+ assert(is_ignored);
+ name = Getattr(n, "name");
+ }
+
+ if (Getattr(class_methods, name) != NULL) {
+ // We need to emit a pure virtual function, even if it is
+ // overloaded. Otherwise we won't be able to create an instance
+ // of the director class. The function doesn't need to actually
+ // do anything.
+ if (!is_pure_virtual || Getattr(n, "sym:overloaded") != NULL) {
+ return SWIG_OK;
+ }
+ }
+ Setattr(class_methods, name, NewString(""));
+
+ if (Getattr(n, "sym:overloaded") == NULL) {
+ int r = oneClassDirectorMethod(n, parent);
+ if (r != SWIG_OK) {
+ return r;
+ }
+ } else {
+ // Handle overloaded methods here, because otherwise we will
+ // reject them in the class_methods hash table. We need to use
+ // class_methods so that we correctly handle cases where a
+ // function in one class hides a function of the same name in a
+ // parent class.
+ for (Node *on = Getattr(n, "sym:overloaded");
+ on != NULL;
+ on = Getattr(on, "sym:nextSibling")) {
+ int r = oneClassDirectorMethod(on, parent);
+ if (r != SWIG_OK) {
+ return r;
+ }
+
+ // Swig_overload_rank expects wrap:name and wrap:parms to be
+ // set.
+ String *wn = Swig_name_wrapper(Getattr(on, "sym:name"));
+ Append(wn, Getattr(on, "sym:overname"));
+ Setattr(on, "wrap:name", wn);
+ Delete(wn);
+ Setattr(on, "wrap:parms", Getattr(on, "parms"));
+ }
+
+ bool is_static = isStatic(n);
+
+ String *cn = exportedName(Getattr(parent, "sym:name"));
+ String *go_name = buildGoName(name, is_static, false);
+
+ String *director_struct_name = NewString("_swig_Director");
+ Append(director_struct_name, cn);
+
+ int r = makeDispatchFunction(n, go_name, director_struct_name, is_static,
+ director_struct_name, false);
+ if (r != SWIG_OK) {
+ return r;
+ }
+
+ String *go_upcall = NewString("Director");
+ Append(go_upcall, cn);
+ Append(go_upcall, go_name);
+ r = makeDispatchFunction(n, go_upcall, director_struct_name, is_static,
+ director_struct_name, true);
+ if (r != SWIG_OK) {
+ return r;
+ }
+
+ Delete(cn);
+ Delete(go_name);
+ Delete(director_struct_name);
+ Delete(go_upcall);
+ }
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * oneClassDirectorMethod
+ *
+ * Emit a method for a director class.
+ * ------------------------------------------------------------ */
+
+ int oneClassDirectorMethod(Node *n, Node *parent) {
+ bool is_ignored = GetFlag(n, "feature:ignore");
+ bool is_pure_virtual = (Cmp(Getattr(n, "storage"), "virtual") == 0
+ && Cmp(Getattr(n, "value"), "0") == 0);
+
+ String *name = Getattr(n, "sym:name");
+ if (name == NULL) {
+ assert(is_ignored);
+ name = Getattr(n, "name");
+ }
+
+ String *overname = NULL;
+ if (Getattr(n, "sym:overloaded")) {
+ overname = Getattr(n, "sym:overname");
+ }
+
+ String *cn = exportedName(Getattr(parent, "sym:name"));
+
+ String *go_type_name = goCPointerType(Getattr(parent, "classtypeobj"),
+ true);
+
+ String *director_struct_name = NewString("_swig_Director");
+ Append(director_struct_name, cn);
+
+ bool is_static = isStatic(n);
+
+ String *go_name = buildGoName(name, is_static, false);
+
+ ParmList *parms = Getattr(n, "parms");
+ Setattr(n, "wrap:parms", parms);
+
+ Wrapper *dummy = NewWrapper();
+ emit_attach_parmmaps(parms, dummy);
+ DelWrapper(dummy);
+
+ Swig_typemap_attach_parms("go", parms, NULL);
+ int parm_count = emit_num_arguments(parms);
+
+ SwigType *result = Getattr(n, "returntype");
+ if (result == NULL) {
+ // This can happen when following overloads.
+ result = NewString(Getattr(n, "type"));
+ SwigType_push(result, Getattr(n, "decl"));
+ if (SwigType_isqualifier(result)) {
+ Delete(SwigType_pop(result));
+ }
+ Delete(SwigType_pop_function(result));
+ Setattr(n, "returntype", result);
+ }
+
+ // Save the type for overload processing.
+ Setattr(n, "go:type", result);
+
+ String *interface_name = NewString("_swig_DirectorInterface");
+ Append(interface_name, cn);
+ Append(interface_name, go_name);
+ if (overname != NULL) {
+ Append(interface_name, overname);
+ }
+
+ String *callback_name = Copy(director_struct_name);
+ Append(callback_name, "_callback_");
+ Append(callback_name, name);
+ Replace(callback_name, "_swig", "Swig", DOH_REPLACE_FIRST);
+ if (overname != NULL) {
+ Append(callback_name, overname);
+ }
+
+ String *callback_wname = Swig_name_wrapper(callback_name);
+
+ String *upcall_name = Copy(director_struct_name);
+ Append(upcall_name, "_upcall_");
+ Append(upcall_name, go_name);
+
+ String *upcall_wname = Swig_name_wrapper(upcall_name);
+
+ String *go_with_over_name = Copy(go_name);
+ if (overname != NULL) {
+ Append(go_with_over_name, overname);
+ }
+
+ Wrapper *f = NewWrapper();
+
+ Parm *p = parms;
+ for (int i = 0; i < parm_count; ++i) {
+ p = getParm(p);
+ Swig_cparm_name(p, i);
+ if (Getattr(p, "name") == NULL) {
+ String *pn = NewString("");
+ Printf(pn, "arg%d", i);
+ Setattr(p, "name", pn);
+ }
+ p = nextParm(p);
+ }
+
+ Swig_typemap_attach_parms("directorin", parms, f);
+
+ if (!is_ignored) {
+ // We use an interface to see if this method is defined in Go.
+ Printv(f_go_wrappers, "type ", interface_name, " interface {\n", NULL);
+ Printv(f_go_wrappers, "\t", go_with_over_name, "(", NULL);
+
+ p = parms;
+ for (int i = 0; i < parm_count; ++i) {
+ p = getParm(p);
+ if (i > 0) {
+ Printv(f_go_wrappers, ", ", NULL);
+ }
+ String *tm = goType(p, Getattr(p, "type"));
+ Printv(f_go_wrappers, tm, NULL);
+ Delete(tm);
+ p = nextParm(p);
+ }
+
+ Printv(f_go_wrappers, ")", NULL);
+
+ if (SwigType_type(result) != T_VOID) {
+ String *tm = goType(n, result);
+ Printv(f_go_wrappers, " ", tm, NULL);
+ Delete(tm);
+ }
+
+ Printv(f_go_wrappers, "\n", NULL);
+ Printv(f_go_wrappers, "}\n\n", NULL);
+
+ // Declare the upcall function, which calls the method on the
+ // parent class.
+
+ if (overname != NULL) {
+ Append(upcall_wname, overname);
+ }
+
+ String *upcall_gc_name = buildGoWrapperName(upcall_name, overname);
+
+ Printv(f_go_wrappers, "func ", upcall_gc_name, "(",
+ go_type_name, NULL);
+
+ p = parms;
+ for (int i = 0; i < parm_count; ++i) {
+ p = getParm(p);
+ String *tm = goWrapperType(p, Getattr(p, "type"), false);
+ Printv(f_go_wrappers, ", ", tm, NULL);
+ Delete(tm);
+ p = nextParm(p);
+ }
+
+ Printv(f_go_wrappers, ")", NULL);
+
+ if (SwigType_type(result) != T_VOID) {
+ String *tm = goWrapperType(n, result, true);
+ Printv(f_go_wrappers, " ", tm, NULL);
+ Delete(tm);
+ }
+
+ if (gccgo_flag) {
+ Printv(f_go_wrappers, " __asm__(\"", go_prefix, "_", upcall_wname,
+ "\")", NULL);
+ }
+
+ Printv(f_go_wrappers, "\n", NULL);
+
+ // Define the method on the director class in Go.
+
+ Printv(f_go_wrappers, "func (swig_p *", director_struct_name, ") ",
+ go_with_over_name, "(", NULL);
+
+ p = parms;
+ for (int i = 0; i < parm_count; ++i) {
+ p = getParm(p);
+ if (i > 0) {
+ Printv(f_go_wrappers, ", ", NULL);
+ }
+ Printv(f_go_wrappers, Getattr(p, "lname"), " ", NULL);
+ String *tm = goType(p, Getattr(p, "type"));
+ Printv(f_go_wrappers, tm, NULL);
+ Delete(tm);
+ p = nextParm(p);
+ }
+
+ Printv(f_go_wrappers, ")", NULL);
+
+ if (SwigType_type(result) != T_VOID) {
+ String *tm = goType(n, result);
+ Printv(f_go_wrappers, " ", tm, NULL);
+ Delete(tm);
+ }
+
+ Printv(f_go_wrappers, " {\n", NULL);
+
+ Printv(f_go_wrappers, "\tif swig_g, swig_ok := swig_p.v.(",
+ interface_name, "); swig_ok {\n", NULL);
+ Printv(f_go_wrappers, "\t\t", NULL);
+ if (SwigType_type(result) != T_VOID) {
+ Printv(f_go_wrappers, "return ", NULL);
+ }
+ Printv(f_go_wrappers, "swig_g.", go_with_over_name, "(", NULL);
+
+ p = parms;
+ for (int i = 0; i < parm_count; ++i) {
+ p = getParm(p);
+ if (i > 0) {
+ Printv(f_go_wrappers, ", ", NULL);
+ }
+ Printv(f_go_wrappers, Getattr(p, "lname"), NULL);
+ p = nextParm(p);
+ }
+
+ Printv(f_go_wrappers, ")\n", NULL);
+ if (SwigType_type(result) == T_VOID) {
+ Printv(f_go_wrappers, "\t\treturn\n", NULL);
+ }
+ Printv(f_go_wrappers, "\t}\n", NULL);
+ Printv(f_go_wrappers, "\t", NULL);
+ if (SwigType_type(result) != T_VOID) {
+ Printv(f_go_wrappers, "return ", NULL);
+ }
+ Printv(f_go_wrappers, upcall_gc_name, "(swig_p.", go_type_name, NULL);
+
+ p = parms;
+ for (int i = 0; i < parm_count; ++i) {
+ p = getParm(p);
+ SwigType *pt = Getattr(p, "type");
+ Printv(f_go_wrappers, ", ", Getattr(p, "lname"), NULL);
+ if (goTypeIsInterface(p, pt)) {
+ Printv(f_go_wrappers, ".Swigcptr()", NULL);
+ }
+ p = nextParm(p);
+ }
+
+ Printv(f_go_wrappers, ")\n", NULL);
+ Printv(f_go_wrappers, "}\n\n", NULL);
+
+ // Define a method in the C++ director class that the C++ upcall
+ // function can call. This permits an upcall to a protected
+ // method.
+
+ String *upcall_method_name = NewString("_swig_upcall_");
+ Append(upcall_method_name, name);
+ if (overname != NULL) {
+ Append(upcall_method_name, overname);
+ }
+ String *upcall_decl = Swig_method_decl(Getattr(n, "type"),
+ Getattr(n, "decl"),
+ upcall_method_name, parms, 0, 0);
+ Printv(f_c_directors_h, " ", upcall_decl, " {\n", NULL);
+ Delete(upcall_decl);
+
+ Printv(f_c_directors_h, " ", NULL);
+ if (SwigType_type(result) != T_VOID) {
+ Printv(f_c_directors_h, "return ", NULL);
+ }
+ Printv(f_c_directors_h, Getattr(parent, "classtype"), "::",
+ Getattr(n, "name"), "(", NULL);
+
+ p = parms;
+ for (int i = 0; i < parm_count; ++i) {
+ p = getParm(p);
+ if (i > 0) {
+ Printv(f_c_directors_h, ", ", NULL);
+ }
+ String *pn = Getattr(p, "name");
+ assert(pn != NULL);
+ Printv(f_c_directors_h, pn, NULL);
+ p = nextParm(p);
+ }
+
+ Printv(f_c_directors_h, ");\n", NULL);
+ Printv(f_c_directors_h, " }\n", NULL);
+
+
+ // Define the C++ function that the Go function calls.
+
+ SwigType *first_type = NULL;
+ Parm *first_parm = parms;
+ if (!is_static) {
+ first_type = NewString("SwigDirector_");
+ Append(first_type, class_name);
+ SwigType_add_pointer(first_type);
+ first_parm = NewParm(first_type, "p", n);
+ set_nextSibling(first_parm, parms);
+ }
+
+ Swig_save("classDirectorMethod", n, "wrap:name", "wrap:action", NULL);
+
+ Setattr(n, "wrap:name", upcall_wname);
+
+ String *action = NewString("");
+ if (SwigType_type(result) != T_VOID) {
+ Printv(action, "result = (", SwigType_lstr(result, 0), ")", NULL);
+ if (SwigType_isreference(result)) {
+ Printv(action, "&", NULL);
+ }
+ }
+ Printv(action, Swig_cparm_name(NULL, 0), "->", upcall_method_name, "(",
+ NULL);
+
+ p = parms;
+ for (int i = 0; i < parm_count; ++i) {
+ p = getParm(p);
+ String *pname = Swig_cparm_name(NULL, i + 1);
+ if (i > 0) {
+ Printv(action, ", ", NULL);
+ }
+ // A parameter whose type is a reference is converted into a
+ // pointer type by gcCTypeForGoValue. We are calling a
+ // function which expects a reference so we need to convert
+ // back.
+ if (SwigType_isreference(Getattr(p, "type"))) {
+ Printv(action, "*", NULL);
+ }
+ Printv(action, pname, NULL);
+ Delete(pname);
+ p = nextParm(p);
+ }
+ Printv(action, ");", NULL);
+ Setattr(n, "wrap:action", action);
+
+ if (!gccgo_flag) {
+ // Write the upcall wrapper function. This is compiled by gc
+ // and calls the C++ function.
+ int r = gcFunctionWrapper(n, upcall_name, upcall_name,
+ overname, upcall_wname, first_parm, result,
+ is_static, true);
+ if (r != SWIG_OK) {
+ return r;
+ }
+ r = gccFunctionWrapper(n, NULL, upcall_wname, first_parm, result);
+ if (r != SWIG_OK) {
+ return r;
+ }
+ } else {
+ int r = gccgoFunctionWrapper(n, NULL, upcall_wname, first_parm, result);
+ if (r != SWIG_OK) {
+ return r;
+ }
+ }
+
+ if (first_type != NULL) {
+ Delete(first_type);
+ }
+ if (first_parm != parms) {
+ Delete(first_parm);
+ }
+
+ Swig_restore(n);
+
+ // Define a function which uses the Go director type that other
+ // methods in the Go type can call to get parent methods.
+
+ Printv(f_go_wrappers, "func Director", cn, go_with_over_name, "(p ", cn,
+ NULL);
+
+ p = parms;
+ for (int i = 0; i < parm_count; ++i) {
+ p = getParm(p);
+ Printv(f_go_wrappers, ", ", Getattr(p, "lname"), " ", NULL);
+ String *tm = goType(p, Getattr(p, "type"));
+ Printv(f_go_wrappers, tm, NULL);
+ Delete(tm);
+ p = nextParm(p);
+ }
+
+ Printv(f_go_wrappers, ")", NULL);
+
+ if (SwigType_type(result) != T_VOID) {
+ String *tm = goType(n, result);
+ Printv(f_go_wrappers, " ", tm, NULL);
+ Delete(tm);
+ }
+
+ Printv(f_go_wrappers, " {\n", NULL);
+
+ Printv(f_go_wrappers, "\t", NULL);
+ if (SwigType_type(result) != T_VOID) {
+ Printv(f_go_wrappers, "return ", NULL);
+ }
+ Printv(f_go_wrappers, upcall_gc_name, "(p.(*",
+ director_struct_name, ").", go_type_name, NULL);
+
+ p = parms;
+ for (int i = 0; i < parm_count; ++i) {
+ p = getParm(p);
+ SwigType *pt = Getattr(p, "type");
+ Printv(f_go_wrappers, ", ", Getattr(p, "lname"), NULL);
+ if (goTypeIsInterface(p, pt)) {
+ Printv(f_go_wrappers, ".Swigcptr()", NULL);
+ }
+ p = nextParm(p);
+ }
+
+ Printv(f_go_wrappers, ")\n", NULL);
+ Printv(f_go_wrappers, "}\n\n", NULL);
+
+ // The Go function which invokes the method. This is called
+ // from by the C++ method on the director class.
+
+ Printv(f_go_wrappers, "func ", callback_name, "(p *",
+ director_struct_name, NULL);
+
+ p = parms;
+ for (int i = 0; i < parm_count; ++i) {
+ p = getParm(p);
+ String *tm = goWrapperType(p, Getattr(p, "type"), false);
+ Printv(f_go_wrappers, ", ", Getattr(p, "lname"), " ", tm, NULL);
+ Delete(tm);
+ p = nextParm(p);
+ }
+
+ Printv(f_go_wrappers, ") ", NULL);
+ String *result_wrapper = NULL;
+ if (SwigType_type(result) != T_VOID) {
+ result_wrapper = goWrapperType(n, result, true);
+ Printv(f_go_wrappers, "(swig_result ", result_wrapper, ") ", NULL);
+ }
+ Printv(f_go_wrappers, "{\n", NULL);
+ Printv(f_go_wrappers, "\t", NULL);
+
+ if (is_ignored) {
+ Printv(f_go_wrappers, "return\n", NULL);
+ } else {
+ bool result_is_interface = false;
+ if (SwigType_type(result) != T_VOID) {
+ Printv(f_go_wrappers, "return ", NULL);
+ result_is_interface = goTypeIsInterface(NULL, result);
+ if (result_is_interface) {
+ Printv(f_go_wrappers, result_wrapper, "(", NULL);
+ }
+ }
+ Printv(f_go_wrappers, "p.", go_with_over_name, "(", NULL);
+
+ p = parms;
+ for (int i = 0; i < parm_count; ++i) {
+ p = getParm(p);
+ if (i > 0) {
+ Printv(f_go_wrappers, ", ", NULL);
+ }
+ SwigType *pt = Getattr(p, "type");
+
+ // If the Go representation is an interface type class, then
+ // we are receiving a uintptr, and must convert to the
+ // interface.
+ bool is_interface = goTypeIsInterface(p, pt);
+ if (is_interface) {
+ // Passing is_result as true to goWrapperType gives us the
+ // name of the Go type we need to convert to an interface.
+ String *wt = goWrapperType(p, pt, true);
+ Printv(f_go_wrappers, wt, "(", NULL);
+ Delete(wt);
+ }
+
+ Printv(f_go_wrappers, Getattr(p, "lname"), NULL);
+
+ if (is_interface) {
+ Printv(f_go_wrappers, ")", NULL);
+ }
+
+ p = nextParm(p);
+ }
+
+ Printv(f_go_wrappers, ")", NULL);
+
+ if (result_is_interface) {
+ Printv(f_go_wrappers, ".Swigcptr())", NULL);
+ }
+
+ Printv(f_go_wrappers, "\n", NULL);
+
+ Delete(upcall_gc_name);
+ }
+
+ Printv(f_go_wrappers, "}\n\n", NULL);
+
+ if (result_wrapper != NULL) {
+ Delete(result_wrapper);
+ }
+
+ // Build the C++ functions.
+
+ Delete(upcall_wname);
+
+ if (!gccgo_flag) {
+ Printv(f_c_directors, "extern \"C\" void ", callback_wname,
+ "(void*, int);\n", NULL);
+ } else {
+ Printv(f_c_directors, "extern \"C\" ", NULL);
+
+ String *fnname = NewString("");
+ Printv(fnname, callback_wname, "(void*", NULL);
+
+ p = parms;
+ while (p != NULL) {
+ while (checkAttribute(p, "tmap:directorin:numinputs", "0")) {
+ p = Getattr(p, "tmap:directorin:next");
+ }
+ String *cg = gccgoCTypeForGoValue(p, Getattr(p, "type"),
+ Getattr(p, "lname"));
+ Printv(fnname, ", ", cg, NULL);
+ Delete(cg);
+ p = Getattr(p, "tmap:directorin:next");
+ }
+
+ Printv(fnname, ")", NULL);
+
+ if (SwigType_type(result) == T_VOID) {
+ Printv(f_c_directors, "void ", fnname, NULL);
+ } else {
+ String *tm = gccgoCTypeForGoValue(n, result, fnname);
+ Printv(f_c_directors, tm, NULL);
+ Delete(tm);
+ }
+
+ Delete(fnname);
+
+ Printv(f_c_directors, " __asm__(\"", go_prefix, ".", package, ".",
+ callback_name, "\");\n", NULL);
+ }
+
+ Delete(upcall_method_name);
+ Delete(go_with_over_name);
+ }
+
+ if (!is_ignored || is_pure_virtual) {
+ // Declare the method for the director class.
+
+ SwigType *rtype = (Getattr(n, "conversion_operator")
+ ? NULL
+ : Getattr(n, "type"));
+ String *decl = Swig_method_decl(rtype, Getattr(n, "decl"),
+ Getattr(n, "name"), parms,
+ 0, 0);
+ Printv(f_c_directors_h, " virtual ", decl, NULL);
+ Delete(decl);
+
+ String *qname = NewString("");
+ Printv(qname, "SwigDirector_", class_name, "::", Getattr(n, "name"),
+ NULL);
+ decl = Swig_method_decl(rtype, Getattr(n, "decl"), qname, parms, 0, 0);
+ Printv(f->def, decl, NULL);
+ Delete(decl);
+ Delete(qname);
+
+ String *throws = buildThrow(n);
+ if (throws != NULL) {
+ Printv(f_c_directors_h, " ", throws, NULL);
+ Printv(f->def, " ", throws, NULL);
+ Delete(throws);
+ }
+
+ Printv(f_c_directors_h, ";\n", NULL);
+
+ Printv(f->def, " {\n", NULL);
+
+ if (SwigType_type(result) != T_VOID) {
+ Wrapper_add_local(f, "c_result",
+ SwigType_lstr(Getattr(n, "returntype"), "c_result"));
+ }
+
+ if (!is_ignored) {
+ if (!gccgo_flag) {
+ Printv(f->code, " struct {\n", NULL);
+ Printv(f->code, " void *go_val;\n", NULL);
+
+ p = parms;
+ while (p != NULL) {
+ while (checkAttribute(p, "tmap:directorin:numinputs", "0")) {
+ p = Getattr(p, "tmap:directorin:next");
+ }
+ String *ln = Getattr(p, "lname");
+ String *cg = gcCTypeForGoValue(p, Getattr(p, "type"), ln);
+ Printv(f->code, " ", cg, ";\n", NULL);
+ Delete(cg);
+ p = Getattr(p, "tmap:directorin:next");
+ }
+ if (SwigType_type(result) != T_VOID) {
+ Printv(f->code, " int : 0;\n", NULL);
+ String *rname = NewString("result");
+ String *cg = gcCTypeForGoValue(n, result, rname);
+ Printv(f->code, " ", cg, ";\n", NULL);
+ Delete(cg);
+ Delete(rname);
+ }
+
+ Printv(f->code, " } swig_a;\n", NULL);
+ Printv(f->code, " swig_a.go_val = go_val;\n", NULL);
+
+ p = parms;
+ while (p != NULL) {
+ while (checkAttribute(p, "tmap:directorin:numinputs", "0")) {
+ p = Getattr(p, "tmap:directorin:next");
+ }
+ String *tm = Getattr(p, "tmap:directorin");
+ if (tm == NULL) {
+ Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file,
+ line_number,
+ "Unable to use type %s as director method argument\n",
+ SwigType_str(Getattr(p, "type"), 0));
+ } else {
+ String *ln = Getattr(p, "lname");
+ String *input = NewString("");
+ Printv(input, "swig_a.", ln, NULL);
+ Replaceall(tm, "$input", input);
+ Replaceall(tm, "$owner", "0");
+ Delete(input);
+ Printv(f->code, "\t", tm, "\n", NULL);
+ }
+ p = Getattr(p, "tmap:directorin:next");
+ }
+
+ Printv(f->code, " crosscall2(", callback_wname,
+ ", &swig_a, (int) sizeof swig_a);\n", NULL);
+
+ if (SwigType_type(result) != T_VOID) {
+ String *rname = NewString("c_result");
+ Parm *rp = NewParm(Getattr(n, "returntype"), rname, n);
+ String *tm = Swig_typemap_lookup("directorout", rp, rname, NULL);
+ if (tm == NULL) {
+ Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
+ "Unable to use type %s as director method result\n",
+ SwigType_str(result, 0));
+ } else {
+ Replaceall(tm, "$input", "swig_a.result");
+ Replaceall(tm, "$result", "c_result");
+ Printv(f->code, " ", tm, "\n", NULL);
+ String *retstr = SwigType_rcaststr(Getattr(n, "returntype"),
+ "c_result");
+ Printv(f->code, " return ", retstr, ";\n", NULL);
+ Delete(retstr);
+ Delete(tm);
+ }
+ Delete(rp);
+ Delete(rname);
+ }
+
+ // The C wrapper code which calls the Go function.
+ Printv(f_gc_wrappers, "#pragma dynexport ", callback_wname, " ",
+ callback_wname, "\n", NULL);
+ Printv(f_gc_wrappers, "extern void \xc2\xb7", callback_name, "();\n",
+ NULL);
+ Printv(f_gc_wrappers, "void\n", NULL);
+ Printv(f_gc_wrappers, callback_wname, "(void *a, int32 n)\n", NULL);
+ Printv(f_gc_wrappers, "{\n", NULL);
+ Printv(f_gc_wrappers, "\tcgocallback(\xc2\xb7", callback_name,
+ ", a, n);\n", NULL);
+ Printv(f_gc_wrappers, "}\n\n", NULL);
+ } else {
+ if (SwigType_type(result) != T_VOID) {
+ String *r = NewString("result");
+ String *tm = gccgoCTypeForGoValue(n, result, r);
+ Wrapper_add_local(f, r, tm);
+ Delete(tm);
+ Delete(r);
+ }
+
+ String *args = NewString("");
+
+ p = parms;
+ while (p != NULL) {
+ while (checkAttribute(p, "tmap:directorin:numinputs", "0")) {
+ p = Getattr(p, "tmap:directorin:next");
+ }
+
+ String *pn = NewString("g");
+ Append(pn, Getattr(p, "lname"));
+ Setattr(p, "emit:input", pn);
+
+ String *tm = gccgoCTypeForGoValue(n, Getattr(p, "type"), pn);
+ Wrapper_add_local(f, pn, tm);
+ Delete(tm);
+
+ tm = Getattr(p, "tmap:directorin");
+ if (tm == NULL) {
+ Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file,
+ line_number,
+ "Unable to use type %s as director method argument\n",
+ SwigType_str(Getattr(p, "type"), 0));
+ } else {
+ Replaceall(tm, "$input", pn);
+ Replaceall(tm, "$owner", 0);
+ Printv(f->code, " ", tm, "\n", NULL);
+
+ Printv(args, ", ", pn, NULL);
+ }
+
+ p = Getattr(p, "tmap:directorin:next");
+ }
+
+ Printv(f->code, " ", NULL);
+ if (SwigType_type(result) != T_VOID) {
+ Printv(f->code, "result = ", NULL);
+ }
+ Printv(f->code, callback_wname, "(go_val", args, ");\n", NULL);
+
+ if (SwigType_type(result) != T_VOID) {
+ String *rname = NewString("c_result");
+ Parm *rp = NewParm(Getattr(n, "returntype"), rname, n);
+ String *tm = Swig_typemap_lookup("directorout", rp, rname, NULL);
+ if (tm == NULL) {
+ Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
+ "Unable to use type %s as director method result\n",
+ SwigType_str(result, 0));
+ } else {
+ Replaceall(tm, "$input", "result");
+ Replaceall(tm, "$result", "c_result");
+ Printv(f->code, " ", tm, "\n", NULL);
+ String *retstr = SwigType_rcaststr(Getattr(n, "returntype"),
+ "c_result");
+ Printv(f->code, " return ", retstr, ";\n", NULL);
+ Delete(retstr);
+ Delete(tm);
+ }
+ Delete(rp);
+ Delete(rname);
+ }
+ }
+ } else {
+ assert(is_pure_virtual);
+ Printv(f->code, " _swig_gopanic(\"call to pure virtual function ",
+ Getattr(parent, "sym:name"), name, "\");\n");
+ if (SwigType_type(result) != T_VOID) {
+ String *retstr = SwigType_rcaststr(Getattr(n, "returntype"),
+ "c_result");
+ Printv(f->code, " return ", retstr, ";\n", NULL);
+ Delete(retstr);
+ }
+ }
+
+ Printv(f->code, "}", NULL);
+
+ Wrapper_print(f, f_c_directors);
+
+ DelWrapper(f);
+ }
+
+ Delete(cn);
+ Delete(go_type_name);
+ Delete(director_struct_name);
+ Delete(interface_name);
+ Delete(upcall_name);
+ Delete(callback_wname);
+ Delete(go_name);
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * classDirectorEnd
+ *
+ * Complete support for a director class.
+ * ------------------------------------------------------------ */
+
+ int classDirectorEnd(Node *n) {
+ (void) n;
+
+ Printv(f_c_directors_h, " private:\n", NULL);
+ Printv(f_c_directors_h, " void *go_val;\n", NULL);
+ Printv(f_c_directors_h, "};\n\n", NULL);
+
+ class_name = NULL;
+ class_node = NULL;
+
+ Delete(class_receiver);
+ class_receiver = NULL;
+
+ Delete(class_methods);
+ class_methods = NULL;
+
+ return SWIG_OK;
+ }
+
+ /* ------------------------------------------------------------
+ * classDirectorDisown
+ *
+ * I think Go does not require a disown method.
+ * ------------------------------------------------------------ */
+
+ int classDirectorDisown(Node *n) {
+ (void) n;
+ return SWIG_OK;
+ }
+
+ /*----------------------------------------------------------------------
+ * buildThrow()
+ *
+ * Build and return a throw clause if needed.
+ *--------------------------------------------------------------------*/
+
+ String *buildThrow(Node *n) {
+ ParmList *throw_parm_list = Getattr(n, "throws");
+ if (throw_parm_list == NULL && Getattr(n, "throw") == NULL)
+ return NULL;
+ String *ret = NewString("throw(");
+ if (throw_parm_list != NULL) {
+ Swig_typemap_attach_parms("throws", throw_parm_list, NULL);
+ }
+ bool first = true;
+ for (Parm *p = throw_parm_list; p != NULL; p = nextSibling(p)) {
+ if (Getattr(p, "tmap:throws") != NULL) {
+ if (first) {
+ first = false;
+ } else {
+ Printv(ret, ", ", NULL);
+ }
+ String *s = SwigType_str(Getattr(p, "type"), 0);
+ Printv(ret, s, NULL);
+ Delete(s);
+ }
+ }
+ Printv(ret, ")", NULL);
+ return ret;
+ }
+
+ /*----------------------------------------------------------------------
+ * extraDirectorProtectedCPPMethodsRequired()
+ *
+ * We don't need to check upcall when calling methods.
+ *--------------------------------------------------------------------*/
+
+ bool extraDirectorProtectedCPPMethodsRequired() const {
+ return false;
+ }
+
+ /*----------------------------------------------------------------------
+ * makeDispatchFunction
+ *
+ * Make a dispatch function for an overloaded C++ function. The
+ * receiver parameter is the receiver for a method, unless is_upcall
+ * is true. If is_upcall is true, then the receiver parameter is
+ * the type of the first argument to the function.
+ *--------------------------------------------------------------------*/
+
+ int makeDispatchFunction(Node *n, String *go_name, String *receiver,
+ bool is_static, SwigType *director_struct,
+ bool is_upcall) {
+ bool is_director = director_struct != NULL;
+
+ String *nodetype = Getattr(n, "nodeType");
+ bool is_constructor = Cmp(nodetype, "constructor") == 0;
+ bool is_destructor = Cmp(nodetype, "destructor") == 0;
+
+ bool can_use_receiver = (!is_constructor
+ && !is_destructor
+ && !is_upcall);
+
+ bool use_receiver = (!is_static
+ && can_use_receiver);
+
+ bool add_to_interface = (interfaces != NULL
+ && !is_constructor
+ && !is_destructor
+ && !is_static
+ && !is_upcall);
+
+ List *dispatch = Swig_overload_rank(n, false);
+ int nfunc = Len(dispatch);
+
+ SwigType *all_result;
+ bool mismatch;
+ if (is_constructor) {
+ assert(!is_upcall);
+ if (!is_director) {
+ all_result = Getattr(class_node, "classtypeobj");
+ } else {
+ all_result = director_struct;
+ }
+ mismatch = false;
+ } else {
+ all_result = NULL;
+ mismatch = false;
+ bool any_void = false;
+ for (int i = 0; i < nfunc; ++i) {
+ Node *ni = Getitem(dispatch, i);
+ SwigType *result = Getattr(ni, "go:type");
+ assert(result != NULL);
+
+ if (SwigType_type(result) == T_VOID) {
+ if (all_result != NULL) {
+ mismatch = true;
+ }
+ any_void = true;
+ } else {
+ if (any_void) {
+ mismatch = true;
+ } else if (all_result == NULL) {
+ all_result = Copy(result);
+ } else if (Cmp(result, all_result) != 0) {
+ mismatch = true;
+ }
+ }
+ }
+ if (mismatch) {
+ if (all_result != NULL) {
+ Delete(all_result);
+ }
+ all_result = NULL;
+ } else if (all_result != NULL) {
+ ;
+ } else {
+ all_result = NewString("void");
+ }
+ }
+
+ Printv(f_go_wrappers, "func ", NULL);
+
+ if (receiver != NULL && use_receiver) {
+ Printv(f_go_wrappers, "(p ", receiver, ") ", NULL);
+ }
+
+ Printv(f_go_wrappers, go_name, "(", NULL);
+ if (is_director && is_constructor) {
+ Printv(f_go_wrappers, "abi interface{}, ", NULL);
+ assert(!add_to_interface);
+ }
+ if (is_upcall) {
+ Printv(f_go_wrappers, "p *", receiver, ", ", NULL);
+ assert(!add_to_interface);
+ }
+ Printv(f_go_wrappers, "a ...interface{})", NULL);
+
+ if (add_to_interface) {
+ Printv(interfaces, "\t", go_name, "(a ...interface{})", NULL);
+ }
+
+ if (mismatch) {
+ Printv(f_go_wrappers, " interface{}", NULL);
+ if (add_to_interface) {
+ Printv(interfaces, " interface{}", NULL);
+ }
+ } else if (all_result != NULL && SwigType_type(all_result) != T_VOID) {
+ if (is_director && is_constructor) {
+ Printv(f_go_wrappers, " ", receiver, NULL);
+ if (add_to_interface) {
+ Printv(interfaces, " ", receiver, NULL);
+ }
+ } else {
+ String *tm = goType(n, all_result);
+ Printv(f_go_wrappers, " ", tm, NULL);
+ if (add_to_interface) {
+ Printv(interfaces, " ", tm, NULL);
+ }
+ Delete(tm);
+ }
+ }
+ Printv(f_go_wrappers, " {\n", NULL);
+ if (add_to_interface) {
+ Printv(interfaces, "\n", NULL);
+ }
+
+ Printv(f_go_wrappers, "\targc := len(a)\n", NULL);
+
+ for (int i = 0; i < nfunc; ++i) {
+ int fn = 0;
+ Node *ni = Getitem(dispatch, i);
+ Parm *pi = Getattr(ni, "wrap:parms");
+
+ // If we are using a receiver, we want to ignore a leading self
+ // parameter. Because of the way this is called, there may or
+ // may not be a self parameter at this point.
+ if (use_receiver && pi != NULL && Getattr(pi, "self") != NULL) {
+ pi = getParm(pi);
+ if (pi != NULL) {
+ pi = nextParm(pi);
+ }
+ }
+
+ int num_required = emit_num_required(pi);
+ int num_arguments = emit_num_arguments(pi);
+ bool varargs = emit_isvarargs(pi);
+
+ if (varargs) {
+ Printf(f_go_wrappers, "\tif argc >= %d {\n", num_required);
+ } else {
+ if (num_required == num_arguments) {
+ Printf(f_go_wrappers, "\tif argc == %d {\n", num_required);
+ } else {
+ Printf(f_go_wrappers, "\tif argc >= %d && argc <= %d {\n",
+ num_required, num_arguments);
+ }
+ }
+
+ // Build list of collisions with the same number of arguments.
+ List *coll = NewList();
+ for (int k = i + 1; k < nfunc; ++k) {
+ Node *nk = Getitem(dispatch, k);
+ Parm *pk = Getattr(nk, "wrap:parms");
+ if (use_receiver && pk != NULL && Getattr(pk, "self") != NULL) {
+ pk = getParm(pk);
+ if (pk != NULL) {
+ pk = nextParm(pk);
+ }
+ }
+ int nrk = emit_num_required(pk);
+ int nak = emit_num_arguments(pk);
+ if ((nrk >= num_required && nrk <= num_arguments)
+ || (nak >= num_required && nak <= num_arguments)
+ || (nrk <= num_required && nak >= num_arguments)) {
+ Append(coll, nk);
+ }
+ }
+
+ int num_braces = 0;
+ if (Len(coll) > 0 && num_arguments > 0) {
+ int j = 0;
+ Parm *pj = pi;
+ while (pj != NULL) {
+ pj = getParm(pj);
+ if (pj == NULL) {
+ break;
+ }
+
+ // If all the wrappers have the same type in this position,
+ // we can omit the check.
+ SwigType *tm = goWrapperType(pj, Getattr(pj, "type"), true);
+ bool emitcheck = false;
+ for (int k = 0; k < Len(coll) && !emitcheck; ++k) {
+ Node *nk = Getitem(coll, k);
+ Parm *pk = Getattr(nk, "wrap:parms");
+ if (use_receiver && pk != NULL && Getattr(pk, "self") != NULL) {
+ pk = getParm(pk);
+ if (pk != NULL) {
+ pk = nextParm(pk);
+ }
+ }
+ int nak = emit_num_arguments(pk);
+ if (nak <= j)
+ continue;
+ int l = 0;
+ Parm *pl = pk;
+ while (pl != NULL && l <= j) {
+ pl = getParm(pl);
+ if (pl == NULL) {
+ break;
+ }
+ if (l == j) {
+ SwigType *tml = goWrapperType(pl, Getattr(pl, "type"), true);
+ if (Cmp(tm, tml) != 0) {
+ emitcheck = true;
+ }
+ Delete(tml);
+ }
+ pl = nextParm(pl);
+ ++l;
+ }
+ }
+
+ if (emitcheck) {
+ if (j >= num_required) {
+ Printf(f_go_wrappers, "\t\tif argc > %d {\n", j);
+ ++num_braces;
+ }
+
+ fn = i + 1;
+ Printf(f_go_wrappers, "\t\tif _, ok := a[%d].(%s); !ok {\n", j, tm);
+ Printf(f_go_wrappers, "\t\t\tgoto check_%d\n", fn);
+ Printv(f_go_wrappers, "\t\t}\n", NULL);
+ }
+
+ Delete(tm);
+
+ pj = nextParm(pj);
+
+ ++j;
+ }
+ }
+
+ for (; num_braces > 0; --num_braces) {
+ Printv(f_go_wrappers, "\t\t}\n", NULL);
+ }
+
+ // We may need to generate multiple calls if there are variable
+ // argument lists involved. Build the start of the call.
+
+ String *start = NewString("");
+
+ SwigType *result = Getattr(ni, "go:type");
+
+ if (is_constructor) {
+ result = all_result;
+ } else if (is_destructor) {
+ result = NULL;
+ }
+
+ if (result != NULL
+ && SwigType_type(result) != T_VOID
+ && (all_result == NULL
+ || SwigType_type(all_result) != T_VOID)) {
+ Printv(start, "return ", NULL);
+ }
+
+ bool advance_parm = false;
+
+ if (receiver != NULL && use_receiver) {
+ Printv(start, "p.", go_name, NULL);
+ } else if (can_use_receiver
+ && !isStatic(ni)
+ && pi != NULL
+ && Getattr(pi, "self") != NULL) {
+ // This is an overload of a static function and a non-static
+ // function.
+ assert(num_required > 0);
+ SwigType *tm = goWrapperType(pi, Getattr(pi, "type"), true);
+ String *nm = buildGoName(Getattr(ni, "sym:name"), false,
+ isFriend(ni));
+ Printv(start, "a[0].(", tm, ").", nm, NULL);
+ Delete(nm);
+ Delete(tm);
+ advance_parm = true;
+ } else {
+ Printv(start, go_name, NULL);
+ }
+
+ Printv(start, Getattr(ni, "sym:overname"), "(", NULL);
+
+ bool need_comma = false;
+
+ if (is_director && is_constructor) {
+ Printv(start, "abi", NULL);
+ need_comma = true;
+ }
+ if (is_upcall) {
+ Printv(start, "p", NULL);
+ need_comma = true;
+ }
+ Parm *p = pi;
+ int pn = 0;
+ if (advance_parm) {
+ p = getParm(p);
+ if (p != NULL) {
+ p = nextParm(p);
+ }
+ ++pn;
+ }
+ while (pn < num_required) {
+ p = getParm(p);
+
+ if (need_comma) {
+ Printv(start, ", ", NULL);
+ }
+
+ SwigType *tm = goType(p, Getattr(p, "type"));
+ Printf(start, "a[%d].(%s)", pn, tm);
+ Delete(tm);
+
+ need_comma = true;
+ ++pn;
+ p = nextParm(p);
+ }
+
+ String *end = NULL;
+ if (result == NULL
+ || SwigType_type(result) == T_VOID
+ || (all_result != NULL && SwigType_type(all_result) == T_VOID)) {
+ end = NewString("");
+ Printv(end, "return", NULL);
+ if (all_result == NULL || SwigType_type(all_result) != T_VOID) {
+ Printv(end, " 0", NULL);
+ }
+ }
+
+ if (num_required == num_arguments) {
+ Printv(f_go_wrappers, "\t\t", start, ")\n", NULL);
+ if (end != NULL) {
+ Printv(f_go_wrappers, "\t\t", end, "\n", NULL);
+ }
+ } else {
+ Printv(f_go_wrappers, "\t\tswitch argc {\n", NULL);
+ for (int j = num_required; j <= num_arguments; ++j) {
+ Printf(f_go_wrappers, "\t\tcase %d:\n", j);
+ Printv(f_go_wrappers, "\t\t\t", start, NULL);
+ bool nc = need_comma;
+ for (int k = num_required; k < j; ++k) {
+ if (nc) {
+ Printv(f_go_wrappers, ", ", NULL);
+ }
+ Printf(f_go_wrappers, "a[%d]", k);
+ nc = true;
+ }
+ Printv(f_go_wrappers, ")\n", NULL);
+ if (end != NULL) {
+ Printv(f_go_wrappers, "\t\t\t", end, "\n", NULL);
+ }
+ }
+ Printv(f_go_wrappers, "\t\t}\n", NULL);
+ }
+
+ Printv(f_go_wrappers, "\t}\n", NULL);
+
+ if (fn != 0) {
+ Printf(f_go_wrappers, "check_%d:\n", fn);
+ }
+
+ Delete(coll);
+ }
+
+ Printv(f_go_wrappers, "fail:\n", NULL);
+ Printv(f_go_wrappers,
+ "\tpanic(\"No match for overloaded function call\")\n", NULL);
+ Printv(f_go_wrappers, "}\n\n", NULL);
+
+ if (all_result != NULL) {
+ Delete(all_result);
+ }
+ Delete(dispatch);
+
+ return SWIG_OK;
+ }
+
+ /* ----------------------------------------------------------------------
+ * exportedName()
+ *
+ * Given a C/C++ name, return a name in Go which will be exported.
+ * If the first character is an upper case letter, this returns a
+ * copy of its argment. If the first character is a lower case
+ * letter, this forces it to upper case. Otherwise, this prepends
+ * 'X'.
+ * ---------------------------------------------------------------------- */
+
+ String *exportedName(String *name) {
+ String *copy = Copy(name);
+ char c = *Char(copy);
+ if (islower(c)) {
+ char l[2];
+ char u[2];
+ l[0] = c;
+ l[1] = '\0';
+ u[0] = toupper(c);
+ u[1] = '\0';
+ Replace(copy, l, u, DOH_REPLACE_FIRST);
+ } else if (!isalpha(c)) {
+ char l[2];
+ char u[3];
+ l[0] = c;
+ l[1] = '\0';
+ u[0] = 'X';
+ u[1] = c;
+ u[2] = '\0';
+ Replace(copy, l, u, DOH_REPLACE_FIRST);
+ }
+ String *ret = Swig_name_mangle(copy);
+ Delete(copy);
+ return ret;
+ }
+
+ /* ----------------------------------------------------------------------
+ * removeClassname()
+ *
+ * If the name starts with the current class name, followed by an
+ * underscore, remove it. If there is no current class name, this
+ * simply returns a copy of the name. This undoes Swig's way of
+ * recording the class name in a member name.
+ * ---------------------------------------------------------------------- */
+
+ String *removeClassname(String *name) {
+ String *copy = Copy(name);
+ if (class_name != NULL) {
+ char *p = Char(name);
+ if (Strncmp(name, class_name, Len(class_name)) == 0
+ && p[Len(class_name)] == '_') {
+ Replace(copy, class_name, "", DOH_REPLACE_FIRST);
+ Replace(copy, "_", "", DOH_REPLACE_FIRST);
+ }
+ }
+ return copy;
+ }
+
+ /* ----------------------------------------------------------------------
+ * buildGoName()
+ *
+ * Build the name to use for an ordinary function, variable, or
+ * whatever in Go. The name argument is something like the sym:name
+ * attribute of the node. If is_static is false, this could be a
+ * method, and the returned name will be the name of the
+ * method--i.e., it will not include the class name.
+ * ---------------------------------------------------------------------- */
+
+ String *buildGoName(String *name, bool is_static, bool is_friend) {
+ String *nw = NewString("");
+ if (is_static && !is_friend && class_name != NULL) {
+ String *c1 = exportedName(class_name);
+ Append(nw, c1);
+ Delete(c1);
+ }
+ String *c2 = removeClassname(name);
+ String *c3 = exportedName(c2);
+ Append(nw, c3);
+ Delete(c2);
+ Delete(c3);
+ String *ret = Swig_name_mangle(nw);
+ Delete(nw);
+ return ret;
+ }
+
+ /* ----------------------------------------------------------------------
+ * buildGoWrapperName()
+ *
+ * Build the name to use for a Go wrapper function. This is a
+ * function called by the real Go function in order to convert C++
+ * classes from interfaces to pointers, and other such conversions
+ * between the Go type and the C++ type.
+ * ---------------------------------------------------------------------- */
+
+ String *buildGoWrapperName(String *name, String *overname) {
+ String *s1 = NewString("_swig_wrap_");
+ Append(s1, name);
+ String *s2 = Swig_name_mangle(s1);
+ Delete(s1);
+ if (overname != NULL) {
+ Append(s2, overname);
+ }
+ return s2;
+ }
+
+ /* ----------------------------------------------------------------------
+ * goType()
+ *
+ * Given a SWIG type, return a string for the type in Go.
+ * ---------------------------------------------------------------------- */
+
+ String *goType(Node *n, SwigType *type) {
+ return goTypeWithInfo(n, type, NULL);
+ }
+
+ /* ----------------------------------------------------------------------
+ * goTypeWithInfo()
+ *
+ * Like goType, but return some more information.
+ *
+ * If the p_is_interface parameter is not NULL, this sets
+ * *p_is_interface to indicate whether this type is going to be
+ * represented by a Go interface type. These are cases where the Go
+ * code needs to make some adjustments when passing values back and
+ * forth with C/C++.
+ * ---------------------------------------------------------------------- */
+
+ String *goTypeWithInfo(Node *n, SwigType *type, bool *p_is_interface) {
+ if (p_is_interface != NULL) {
+ *p_is_interface = false;
+ }
+
+ String *ret;
+ if (n != NULL && Cmp(type, Getattr(n, "type")) == 0) {
+ ret = NULL;
+ if (Strcmp(Getattr(n, "nodeType"), "parm") == 0) {
+ ret = Getattr(n, "tmap:go");
+ }
+ if (ret == NULL) {
+ ret = Swig_typemap_lookup("go", n, "", NULL);
+ }
+ } else {
+ Parm *p = NewParmWithoutFileLineInfo(type, "goType");
+ ret = Swig_typemap_lookup("go", p, "", NULL);
+ Delete(p);
+ }
+
+ if (Strstr(ret, "$gotypename") != NULL) {
+ ret = NULL;
+ }
+
+ if (ret != NULL) {
+ return Copy(ret);
+ }
+
+ SwigType *t = SwigType_typedef_resolve_all(type);
+
+ Node *e = Language::enumLookup(t);
+ if (e != NULL) {
+ ret = goEnumName(e);
+ } else if (Strcmp(t, "enum ") == 0) {
+ ret = NewString("int");
+ } else if (SwigType_isfunctionpointer(type) || SwigType_isfunction(type)) {
+ ret = NewString("_swig_fnptr");
+ } else if (SwigType_ismemberpointer(type)) {
+ ret = NewString("_swig_memberptr");
+ } else if (SwigType_issimple(t)) {
+ Node *cn = classLookup(t);
+ if (cn != NULL) {
+ ret = Getattr(cn, "sym:name");
+ if (ret == NULL) {
+ ret = Getattr(cn, "name");
+ }
+ ret = exportedName(ret);
+
+ Node *cnmod = Getattr(cn, "module");
+ if (cnmod == NULL || Strcmp(Getattr(cnmod, "name"), package) == 0) {
+ Setattr(undefined_types, t, t);
+ } else {
+ String *nw = NewString("");
+ Printv(nw, Getattr(cnmod, "name"), ".", ret, NULL);
+ Delete(ret);
+ ret = nw;
+ }
+ } else {
+ // SWIG does not know about this type.
+ ret = exportedName(t);
+ Setattr(undefined_types, t, t);
+ }
+ if (p_is_interface != NULL) {
+ *p_is_interface = true;
+ }
+ } else if (SwigType_ispointer(t) || SwigType_isarray(t)) {
+ SwigType *r = Copy(t);
+ if (SwigType_ispointer(r)) {
+ SwigType_del_pointer(r);
+ } else {
+ SwigType_del_array(r);
+ }
+
+ if (SwigType_type(r) == T_VOID) {
+ ret = NewString("uintptr");
+ } else {
+ bool is_interface;
+ String *base = goTypeWithInfo(n, r, &is_interface);
+
+ // At the Go level, an unknown or class type is handled as an
+ // interface wrapping a pointer. This means that if a
+ // function returns the C type X, we will be wrapping the C
+ // type X*. In Go we will call that type X. That means that
+ // if a C function expects X*, we can pass the Go type X. And
+ // that means that when we see the C type X*, we should use
+ // the Go type X.
+
+ // The is_interface variable tells us this. However, it will
+ // be true both for the case of X and for the case of X*. If
+ // r is a pointer here, then we are looking at X**. There is
+ // really no good way for us to handle that.
+ bool is_pointer_to_pointer = false;
+ if (is_interface) {
+ SwigType *c = Copy(r);
+ if (SwigType_isqualifier(c)) {
+ SwigType_del_qualifier(c);
+ if (SwigType_ispointer(c) || SwigType_isarray(c)) {
+ is_pointer_to_pointer = true;
+ }
+ }
+ Delete(c);
+ }
+
+ if (is_interface) {
+ if (!is_pointer_to_pointer) {
+ ret = base;
+ if (p_is_interface != NULL) {
+ *p_is_interface = true;
+ }
+ } else {
+ ret = NewString("uintptr");
+ }
+ } else {
+ ret = NewString("*");
+ Append(ret, base);
+ Delete(base);
+ }
+ }
+
+ Delete(r);
+ } else if (SwigType_isreference(t)) {
+ SwigType *r = Copy(t);
+ SwigType_del_reference(r);
+
+ // If this is a const reference, and we are looking at a pointer
+ // to it, then we just use the pointer we already have.
+ bool add_pointer = true;
+ if (SwigType_isqualifier(r)) {
+ String *q = SwigType_parm(r);
+ if (Strcmp(q, "const") == 0) {
+ SwigType *c = Copy(r);
+ SwigType_del_qualifier(c);
+ if (SwigType_ispointer(c)) {
+ add_pointer = false;
+ }
+ Delete(c);
+ }
+ }
+ if (add_pointer) {
+ SwigType_add_pointer(r);
+ }
+ ret = goTypeWithInfo(n, r, p_is_interface);
+ Delete(r);
+ } else if (SwigType_isqualifier(t)) {
+ SwigType *r = Copy(t);
+ SwigType_del_qualifier(r);
+ ret = goTypeWithInfo(n, r, p_is_interface);
+ Delete(r);
+ }
+
+ Delete(t);
+
+ if (ret == NULL) {
+ Swig_warning(WARN_LANG_NATIVE_UNIMPL, input_file, line_number,
+ "No Go typemap defined for %s\n",
+ SwigType_str(type, 0));
+ ret = NewString("uintptr");
+ }
+
+ return ret;
+ }
+
+ /* ----------------------------------------------------------------------
+ * goWrapperType()
+ *
+ * Given a type, return a string for the type to use for the wrapped
+ * Go function. This function exists because for a C++ class we
+ * need to convert interface and reference types.
+ * ---------------------------------------------------------------------- */
+
+ String *goWrapperType(Node *n, SwigType *type, bool is_result) {
+ bool is_interface;
+ String *ret = goTypeWithInfo(n, type, &is_interface);
+
+ // If this is an interface, we want to pass the real type.
+ if (is_interface) {
+ Delete(ret);
+ if (!is_result) {
+ ret = NewString("uintptr");
+ } else {
+ SwigType *ty = SwigType_typedef_resolve_all(type);
+ while (true) {
+ if (SwigType_ispointer(ty)) {
+ SwigType_del_pointer(ty);
+ } else if (SwigType_isarray(ty)) {
+ SwigType_del_array(ty);
+ } else if (SwigType_isreference(ty)) {
+ SwigType_del_reference(ty);
+ } else if (SwigType_isqualifier(ty)) {
+ SwigType_del_qualifier(ty);
+ } else {
+ break;
+ }
+ }
+ assert(SwigType_issimple(ty));
+ String *p = goCPointerType(ty, true);
+ Delete(ty);
+ ret = p;
+ }
+ }
+
+ return ret;
+ }
+
+ /* ----------------------------------------------------------------------
+ * goCPointerType()
+ *
+ * Return the name of the Go type to use for the C pointer value.
+ * The regular C type is the name of an interface type which wraps a
+ * pointer whose name is returned by this function.
+ * ---------------------------------------------------------------------- */
+
+ String *goCPointerType(SwigType *type, bool add_to_hash) {
+ SwigType *ty = SwigType_typedef_resolve_all(type);
+ Node *cn = classLookup(ty);
+ String *ex;
+ String *ret;
+ if (cn == NULL) {
+ if (add_to_hash) {
+ Setattr(undefined_types, ty, ty);
+ }
+ ret = NewString("Swigcptr");
+ ex = exportedName(ty);
+ Append(ret, ex);
+ } else {
+ String *cname = Getattr(cn, "sym:name");
+ if (cname == NULL) {
+ cname = Getattr(cn, "name");
+ }
+ ex = exportedName(cname);
+ Node *cnmod = Getattr(cn, "module");
+ if (cnmod == NULL || Strcmp(Getattr(cnmod, "name"), package) == 0) {
+ if (add_to_hash) {
+ Setattr(undefined_types, ty, ty);
+ }
+ ret = NewString("Swigcptr");
+ Append(ret, ex);
+ } else {
+ ret = NewString("");
+ Printv(ret, Getattr(cnmod, "name"), ".Swigcptr", ex, NULL);
+ }
+ }
+ Delete(ty);
+ Delete(ex);
+ return ret;
+ }
+
+ /* ----------------------------------------------------------------------
+ * gcCTypeForGoValue()
+ *
+ * Given a type, return the C/C++ type which will be used to catch
+ * the value in Go. This is the 6g/8g version.
+ * ---------------------------------------------------------------------- */
+
+ String *gcCTypeForGoValue(Node *n, SwigType *type, String *name) {
+ bool is_interface;
+ String *gt = goTypeWithInfo(n, type, &is_interface);
+ bool is_string = Strcmp(gt, "string") == 0;
+ bool is_slice = Strncmp(gt, "[]", 2) == 0;
+ bool is_function = Strcmp(gt, "_swig_fnptr") == 0;
+ bool is_member = Strcmp(gt, "_swig_memberptr") == 0;
+ bool is_complex = Strcmp(gt, "complex") == 0;
+ bool is_complex64 = Strcmp(gt, "complex64") == 0;
+ bool is_complex128 = Strcmp(gt, "complex128") == 0;
+ Delete(gt);
+
+ String *ret;
+ if (is_string) {
+ // Note that we don't turn a reference to a string into a
+ // pointer to a string. Strings are immutable anyhow.
+ ret = NewString("_gostring_ ");
+ Append(ret, name);
+ return ret;
+ } else if (is_slice) {
+ ret = NewString("_goslice_ ");
+ } else if (is_function || is_member) {
+ ret = NewString("void *");
+ Append(ret, name);
+ return ret;
+ } else if (is_complex || is_complex64) {
+ ret = NewString("_Complex float ");
+ } else if (is_complex128) {
+ ret = NewString("_Complex double ");
+ } else if (is_interface) {
+ SwigType *t = SwigType_typedef_resolve_all(type);
+ SwigType_strip_qualifiers(t);
+ if (SwigType_ispointer(t)) {
+ SwigType_del_pointer(t);
+ SwigType_strip_qualifiers(t);
+ }
+ if (SwigType_isreference(t)) {
+ SwigType_del_reference(t);
+ SwigType_strip_qualifiers(t);
+ }
+ SwigType_add_pointer(t);
+ ret = SwigType_lstr(t, name);
+ Delete(t);
+ return ret;
+ } else {
+ SwigType *t = SwigType_typedef_resolve_all(type);
+ if (SwigType_isreference(t)) {
+ // A const reference to a known type, or to a pointer, is not
+ // mapped to a pointer.
+ SwigType_del_reference(t);
+ if (SwigType_isqualifier(t)) {
+ String *q = SwigType_parm(t);
+ if (Strcmp(q, "const") == 0) {
+ SwigType_del_qualifier(t);
+ if (hasGoTypemap(t) || SwigType_ispointer(t)) {
+ ret = SwigType_lstr(t, name);
+ Delete(q);
+ Delete(t);
+ return ret;
+ }
+ }
+ Delete(q);
+ }
+ }
+ Delete(t);
+ return SwigType_lstr(type, name);
+ }
+
+ if (SwigType_isreference(type)) {
+ Append(ret, "* ");
+ }
+ Append(ret, name);
+ return ret;
+ }
+
+ /* ----------------------------------------------------------------------
+ * gcCTypeForGoValue()
+ *
+ * Given a type, return the C/C++ type which will be used to catch
+ * the value in Go. This is the gccgo version.
+ * ---------------------------------------------------------------------- */
+
+ String *gccgoCTypeForGoValue(Node *n, SwigType *type, String *name) {
+ return gcCTypeForGoValue(n, type, name);
+ }
+
+ /* ------------------------------------------------------------
+ * goTypeIsInterface
+ *
+ * Return whether this C++ type is represented as an interface type
+ * in Go. These types require adjustments in the Go code when
+ * passing them back and forth between Go and C++.
+ * ------------------------------------------------------------ */
+
+ bool goTypeIsInterface(Node *n, SwigType *type) {
+ bool is_interface;
+ Delete(goTypeWithInfo(n, type, &is_interface));
+ return is_interface;
+ }
+
+ /* ------------------------------------------------------------
+ * hasGoTypemap
+ *
+ * Return whether a type has a "go" typemap entry.
+ * ------------------------------------------------------------ */
+
+ bool hasGoTypemap(SwigType *type) {
+ Parm *p = NewParmWithoutFileLineInfo(type, "test");
+ SwigType *tm = Swig_typemap_lookup("go", p, "", NULL);
+ Delete(p);
+ if (tm != NULL && Strstr(tm, "$gotypename") == NULL) {
+ Delete(tm);
+ return true;
+ }
+ if (tm != NULL) {
+ Delete(tm);
+ }
+ return false;
+ }
+
+ /* ----------------------------------------------------------------------
+ * goEnumName()
+ *
+ * Given an enum node, return a string to use for the enum type in
+ * Go.
+ * ---------------------------------------------------------------------- */
+
+ String *goEnumName(Node *n) {
+ String *ret = Getattr(n, "go:enumname");
+ if (ret != NULL) {
+ return Copy(ret);
+ }
+
+ if (Strcmp(Getattr(n, "type"), "enum ") == 0) {
+ return NewString("int");
+ }
+
+ String *type = Getattr(n, "enumtype");
+ assert(type != NULL);
+ char *p = Char(type);
+ int len = Len(type);
+ String *s = NewString("");
+ bool capitalize = true;
+ for (int i = 0; i < len; ++i, ++p) {
+ if (*p == ':') {
+ ++i;
+ ++p;
+ assert(*p == ':');
+ capitalize = true;
+ } else if (capitalize) {
+ Putc(toupper(*p), s);
+ capitalize = false;
+ } else {
+ Putc(*p, s);
+ }
+ }
+
+ ret = Swig_name_mangle(s);
+ Delete(s);
+ return ret;
+ }
+
+
+ /* ------------------------------------------------------------
+ * getParm()
+ *
+ * Get the real parameter to use.
+ * ------------------------------------------------------------ */
+
+ Parm *getParm(Parm *p) {
+ while (p != NULL && checkAttribute(p, "tmap:in:numinputs", "0")) {
+ p = Getattr(p, "tmap:in:next");
+ }
+ return p;
+ }
+
+ /* ------------------------------------------------------------
+ * nextParm()
+ *
+ * Return the next parameter.
+ * ------------------------------------------------------------ */
+
+ Parm *nextParm(Parm *p) {
+ if (p == NULL) {
+ return NULL;
+ } else if (Getattr(p, "tmap:in") != NULL) {
+ return Getattr(p, "tmap:in:next");
+ } else {
+ return nextSibling(p);
+ }
+ }
+
+ /* ------------------------------------------------------------
+ * isStatic
+ *
+ * Return whether a node should be considered as static rather than
+ * as a member.
+ * ------------------------------------------------------------ */
+
+ bool isStatic(Node *n) {
+ String *storage = Getattr(n, "storage");
+ return (storage != NULL
+ && (Strcmp(storage, "static") == 0
+ || Strcmp(storage, "friend") == 0)
+ && (!SmartPointer
+ || Getattr(n, "allocate:smartpointeraccess") == NULL));
+ }
+
+ /* ------------------------------------------------------------
+ * isFriend
+ *
+ * Return whether a node is a friend.
+ * ------------------------------------------------------------ */
+
+ bool isFriend(Node *n) {
+ String *storage = Getattr(n, "storage");
+ return storage != NULL && Strcmp(storage, "friend") == 0;
+ }
+
+}; /* class GO */
+
+/* -----------------------------------------------------------------------------
+ * swig_go() - Instantiate module
+ * ----------------------------------------------------------------------------- */
+
+static Language *new_swig_go() {
+ return new GO();
+}
+extern "C" Language *swig_go(void) {
+ return new_swig_go();
+}
+
+/* -----------------------------------------------------------------------------
+ * Static member variables
+ * ----------------------------------------------------------------------------- */
+
+// Usage message.
+const char * const GO::usage = (char *) "\
+Go Options (available with -go)\n\
+ -package - set name of the Go package to \n\
+ -gccgo - generate code for gccgo rather than 6g/8g\n\
+ -go-prefix - like gccgo -fgo-prefix option\n\
+ -soname - name for shared library holding C/C++ code\n\
+ -longsize - set size of C/C++ long type--32 or 64 bits\n\
+ -rename = - rename symbols\n\
+\n";
diff --git a/Source/Modules/overload.cxx b/Source/Modules/overload.cxx
index 65deee2de..a62bdc1bf 100644
--- a/Source/Modules/overload.cxx
+++ b/Source/Modules/overload.cxx
@@ -59,7 +59,7 @@ void Wrapper_cast_dispatch_mode_set(int flag) {
* languages ignore the first method parsed.
* ----------------------------------------------------------------------------- */
-static List *Swig_overload_rank(Node *n, bool script_lang_wrapping) {
+List *Swig_overload_rank(Node *n, bool script_lang_wrapping) {
Overloaded nodes[MAX_OVERLOAD];
int nnodes = 0;
Node *o = Getattr(n, "sym:overloaded");
diff --git a/Source/Modules/r.cxx b/Source/Modules/r.cxx
index e4b246c4e..8f5503743 100644
--- a/Source/Modules/r.cxx
+++ b/Source/Modules/r.cxx
@@ -1299,6 +1299,8 @@ void R::addAccessor(String *memberName, Wrapper *wrapper, String *name,
Printf(stderr, "Adding accessor: %s (%s) => %s\n", memberName, name, tmp);
}
+#define Swig_overload_rank R_swig_overload_rank
+
#define MAX_OVERLOAD 256
struct Overloaded {
diff --git a/Source/Modules/swigmain.cxx b/Source/Modules/swigmain.cxx
index 1ed85e82e..86cccdf88 100644
--- a/Source/Modules/swigmain.cxx
+++ b/Source/Modules/swigmain.cxx
@@ -51,6 +51,7 @@ extern "C" {
Language *swig_cffi(void);
Language *swig_uffi(void);
Language *swig_r(void);
+ Language *swig_go(void);
}
struct swig_module {
@@ -69,6 +70,7 @@ static swig_module modules[] = {
{"-clisp", swig_clisp, "CLISP"},
{"-cffi", swig_cffi, "CFFI"},
{"-csharp", swig_csharp, "C#"},
+ {"-go", swig_go, "Go"},
{"-guile", swig_guile, "Guile"},
{"-java", swig_java, "Java"},
{"-lua", swig_lua, "Lua"},
diff --git a/Source/Modules/swigmod.h b/Source/Modules/swigmod.h
index 016ccc8d4..b0b488d6f 100644
--- a/Source/Modules/swigmod.h
+++ b/Source/Modules/swigmod.h
@@ -344,6 +344,7 @@ void Swig_overload_check(Node *n);
String *Swig_overload_dispatch(Node *n, const_String_or_char_ptr fmt, int *);
String *Swig_overload_dispatch_cast(Node *n, const_String_or_char_ptr fmt, int *);
String *Swig_overload_dispatch_fast(Node *n, const_String_or_char_ptr fmt, int *);
+List *Swig_overload_rank(Node *n, bool script_lang_wrapping);
SwigType *cplus_value_type(SwigType *t);
/* directors.cxx start */
diff --git a/configure.in b/configure.in
index fe95fa7c0..f08ad4615 100644
--- a/configure.in
+++ b/configure.in
@@ -1950,6 +1950,35 @@ fi
AC_SUBST(RBIN)
+#----------------------------------------------------------------
+# Look for Go compilers
+#----------------------------------------------------------------
+
+AC_ARG_WITH(go, AS_HELP_STRING([--without-go], [Disable Go])
+AS_HELP_STRING([--with-go=path], [Set location of Go compiler]),[GOBIN="$withval"], [GOBIN=yes])
+
+if test x"${GOBIN}" = xno -o x"${with_alllang}" = xno ; then
+AC_MSG_NOTICE([Disabling Go])
+GO=
+GOGCC=false
+else
+
+ if test "x$GOBIN" = xyes; then
+ AC_CHECK_PROGS(GO, 6g 8g gccgo)
+ else
+ GO="$GOBIN"
+ fi
+
+ GOGCC=false
+ if $GO --help 2>/dev/null | grep gccgo >/dev/null 2>&1 ; then
+ GOGCC=true
+ fi
+
+fi
+
+AC_SUBST(GOGCC)
+AC_SUBST(GO)
+
#----------------------------------------------------------------
# Determine which languages to use for examples/test-suite
#----------------------------------------------------------------
@@ -2100,6 +2129,12 @@ SKIP_UFFI=
#fi
AC_SUBST(SKIP_UFFI)
+SKIP_GO=
+if test -z "$GO" ; then
+ SKIP_GO="1"
+fi
+AC_SUBST(SKIP_GO)
+
#----------------------------------------------------------------
# Additional language dependencies
#----------------------------------------------------------------
@@ -2178,6 +2213,7 @@ AC_CONFIG_FILES([ \
Examples/test-suite/cffi/Makefile \
Examples/test-suite/uffi/Makefile \
Examples/test-suite/r/Makefile \
+ Examples/test-suite/go/Makefile \
Lib/ocaml/swigp4.ml
])
AC_CONFIG_FILES([preinst-swig], [chmod +x preinst-swig])