Add support for the Go programming language.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12108 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
09f14197ac
commit
5af2978f77
259 changed files with 16159 additions and 14 deletions
135
Lib/go/cdata.i
Normal file
135
Lib/go/cdata.i
Normal file
|
|
@ -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);
|
||||
7
Lib/go/exception.i
Normal file
7
Lib/go/exception.i
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
%typemap(throws,noblock=1) (...) {
|
||||
SWIG_exception(SWIG_RuntimeError,"unknown exception");
|
||||
}
|
||||
|
||||
%insert("runtime") %{
|
||||
#define SWIG_exception(code, msg) _swig_gopanic(msg)
|
||||
%}
|
||||
514
Lib/go/go.swg
Normal file
514
Lib/go/go.swg
Normal file
|
|
@ -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 <gokw.swg>
|
||||
|
||||
%include <goruntime.swg>
|
||||
31
Lib/go/gokw.swg
Normal file
31
Lib/go/gokw.swg
Normal file
|
|
@ -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
|
||||
208
Lib/go/goruntime.swg
Normal file
208
Lib/go/goruntime.swg
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
/* ------------------------------------------------------------
|
||||
* goruntime.swg
|
||||
*
|
||||
* Go runtime code for the various generated files.
|
||||
* ------------------------------------------------------------ */
|
||||
|
||||
%insert(runtime) %{
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
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
|
||||
4
Lib/go/std_common.i
Normal file
4
Lib/go/std_common.i
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
%include <std_except.i>
|
||||
|
||||
%apply size_t { std::size_t };
|
||||
%apply const size_t& { const std::size_t& };
|
||||
1
Lib/go/std_deque.i
Normal file
1
Lib/go/std_deque.i
Normal file
|
|
@ -0,0 +1 @@
|
|||
%include <std/_std_deque.i>
|
||||
29
Lib/go/std_except.i
Normal file
29
Lib/go/std_except.i
Normal file
|
|
@ -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 <stdexcept>
|
||||
%}
|
||||
|
||||
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());%}
|
||||
64
Lib/go/std_map.i
Normal file
64
Lib/go/std_map.i
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* std_map.i
|
||||
*
|
||||
* SWIG typemaps for std::map
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
%include <std_common.i>
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// std::map
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
// "map" is a keyword in Go.
|
||||
#define map cmap
|
||||
|
||||
%{
|
||||
#define map cmap
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
%}
|
||||
|
||||
// exported class
|
||||
|
||||
namespace std {
|
||||
|
||||
template<class K, class T> 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<K,T> &);
|
||||
|
||||
unsigned int size() const;
|
||||
bool empty() const;
|
||||
void clear();
|
||||
%extend {
|
||||
const T& get(const K& key) throw (std::out_of_range) {
|
||||
std::map<K,T >::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<K,T >::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<K,T >::iterator i = self->find(key);
|
||||
return i != self->end();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
34
Lib/go/std_pair.i
Normal file
34
Lib/go/std_pair.i
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* std_pair.i
|
||||
*
|
||||
* SWIG typemaps for std::pair
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
%include <std_common.i>
|
||||
%include <exception.i>
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// std::pair
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
%{
|
||||
#include <utility>
|
||||
%}
|
||||
|
||||
namespace std {
|
||||
|
||||
template<class T, class U> struct pair {
|
||||
|
||||
pair();
|
||||
pair(T first, U second);
|
||||
pair(const pair& p);
|
||||
|
||||
template <class U1, class U2> pair(const pair<U1, U2> &p);
|
||||
|
||||
T first;
|
||||
U second;
|
||||
};
|
||||
|
||||
// add specializations here
|
||||
|
||||
}
|
||||
55
Lib/go/std_string.i
Normal file
55
Lib/go/std_string.i
Normal file
|
|
@ -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 <string>
|
||||
%}
|
||||
|
||||
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()); %}
|
||||
|
||||
}
|
||||
78
Lib/go/std_vector.i
Normal file
78
Lib/go/std_vector.i
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* std_vector.i
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
%{
|
||||
#include <vector>
|
||||
#include <stdexcept>
|
||||
%}
|
||||
|
||||
namespace std {
|
||||
|
||||
template<class T> 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 && i<size)
|
||||
return (*self)[i];
|
||||
else
|
||||
throw std::out_of_range("vector index out of range");
|
||||
}
|
||||
void set(int i, const value_type& val) throw (std::out_of_range) {
|
||||
int size = int(self->size());
|
||||
if (i>=0 && i<size)
|
||||
(*self)[i] = val;
|
||||
else
|
||||
throw std::out_of_range("vector index out of range");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// bool specialization
|
||||
template<> class vector<bool> {
|
||||
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 && i<size)
|
||||
return (*self)[i];
|
||||
else
|
||||
throw std::out_of_range("vector index out of range");
|
||||
}
|
||||
void set(int i, const value_type& val) throw (std::out_of_range) {
|
||||
int size = int(self->size());
|
||||
if (i>=0 && i<size)
|
||||
(*self)[i] = val;
|
||||
else
|
||||
throw std::out_of_range("vector index out of range");
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
9
Lib/go/stl.i
Normal file
9
Lib/go/stl.i
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/* -----------------------------------------------------------------------------
|
||||
* stl.i
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
%include <std_common.i>
|
||||
%include <std_string.i>
|
||||
%include <std_vector.i>
|
||||
%include <std_map.i>
|
||||
%include <std_pair.i>
|
||||
335
Lib/go/typemaps.i
Normal file
335
Lib/go/typemaps.i
Normal file
|
|
@ -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 <typemaps.i>
|
||||
double fadd(double *INPUT, double *INPUT);
|
||||
|
||||
or you can use the %apply directive :
|
||||
|
||||
%include <typemaps.i>
|
||||
%apply double *INPUT { double *a, double *b };
|
||||
double fadd(double *a, double *b);
|
||||
|
||||
In Go you could then use it like this:
|
||||
answer := modulename.Fadd(10.0, 20.0)
|
||||
|
||||
There are no char *INPUT typemaps, however you can apply the signed
|
||||
char * typemaps instead:
|
||||
%include <typemaps.i>
|
||||
%apply signed char *INPUT {char *input};
|
||||
void f(char *input);
|
||||
*/
|
||||
|
||||
%define INPUT_TYPEMAP(TYPE, GOTYPE)
|
||||
%typemap(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 <typemaps.i>
|
||||
double modf(double x, double *OUTPUT);
|
||||
|
||||
or you can use the %apply directive :
|
||||
|
||||
%include <typemaps.i>
|
||||
%apply double *OUTPUT { double *ip };
|
||||
double modf(double x, double *ip);
|
||||
|
||||
The Go output of the function would be the function return value and the
|
||||
value in the single element array. In Go you would use it like this:
|
||||
|
||||
ptr := []float64{0.0}
|
||||
fraction := modulename.Modf(5.0,ptr)
|
||||
|
||||
There are no char *OUTPUT typemaps, however you can apply the signed
|
||||
char * typemaps instead:
|
||||
%include <typemaps.i>
|
||||
%apply signed char *OUTPUT {char *output};
|
||||
void f(char *output);
|
||||
*/
|
||||
|
||||
%define OUTPUT_TYPEMAP(TYPE, GOTYPE)
|
||||
%typemap(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 <typemaps.i>
|
||||
void neg(double *INOUT);
|
||||
|
||||
or you can use the %apply directive :
|
||||
|
||||
%include <typemaps.i>
|
||||
%apply double *INOUT { double *x };
|
||||
void neg(double *x);
|
||||
|
||||
This works similarly to C in that the mapping directly modifies the
|
||||
input value - the input must be an array with a minimum of one element.
|
||||
The element in the array is the input and the output is the element in
|
||||
the array.
|
||||
|
||||
x := []float64{5.0}
|
||||
Neg(x);
|
||||
|
||||
The implementation of the OUTPUT and INOUT typemaps is different to
|
||||
other languages in that other languages will return the output value
|
||||
as part of the function return value. This difference is due to Go
|
||||
being a typed language.
|
||||
|
||||
There are no char *INOUT typemaps, however you can apply the signed
|
||||
char * typemaps instead:
|
||||
%include <typemaps.i>
|
||||
%apply signed char *INOUT {char *inout};
|
||||
void f(char *inout);
|
||||
*/
|
||||
|
||||
%define INOUT_TYPEMAP(TYPE, GOTYPE)
|
||||
%typemap(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
|
||||
Loading…
Add table
Add a link
Reference in a new issue