diff options
author | vitalyisaev <vitalyisaev@ydb.tech> | 2023-11-30 13:26:22 +0300 |
---|---|---|
committer | vitalyisaev <vitalyisaev@ydb.tech> | 2023-11-30 15:44:45 +0300 |
commit | 0a98fece5a9b54f16afeb3a94b3eb3105e9c3962 (patch) | |
tree | 291d72dbd7e9865399f668c84d11ed86fb190bbf /contrib/tools/swig/Lib/go | |
parent | cb2c8d75065e5b3c47094067cb4aa407d4813298 (diff) | |
download | ydb-0a98fece5a9b54f16afeb3a94b3eb3105e9c3962.tar.gz |
YQ Connector:Use docker-compose in integrational tests
Diffstat (limited to 'contrib/tools/swig/Lib/go')
-rw-r--r-- | contrib/tools/swig/Lib/go/exception.i | 7 | ||||
-rw-r--r-- | contrib/tools/swig/Lib/go/go.swg | 744 | ||||
-rw-r--r-- | contrib/tools/swig/Lib/go/gokw.swg | 33 | ||||
-rw-r--r-- | contrib/tools/swig/Lib/go/goruntime.swg | 217 | ||||
-rw-r--r-- | contrib/tools/swig/Lib/go/gostring.swg | 29 | ||||
-rw-r--r-- | contrib/tools/swig/Lib/go/std_common.i | 4 | ||||
-rw-r--r-- | contrib/tools/swig/Lib/go/std_except.i | 31 | ||||
-rw-r--r-- | contrib/tools/swig/Lib/go/std_string.i | 162 | ||||
-rw-r--r-- | contrib/tools/swig/Lib/go/std_vector.i | 92 | ||||
-rw-r--r-- | contrib/tools/swig/Lib/go/typemaps.i | 298 |
10 files changed, 1617 insertions, 0 deletions
diff --git a/contrib/tools/swig/Lib/go/exception.i b/contrib/tools/swig/Lib/go/exception.i new file mode 100644 index 0000000000..5abd306a4e --- /dev/null +++ b/contrib/tools/swig/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/contrib/tools/swig/Lib/go/go.swg b/contrib/tools/swig/Lib/go/go.swg new file mode 100644 index 0000000000..348ae5f0d9 --- /dev/null +++ b/contrib/tools/swig/Lib/go/go.swg @@ -0,0 +1,744 @@ +/* ------------------------------------------------------------ + * go.swg + * + * Go configuration module. + * ------------------------------------------------------------ */ + +%include <gostring.swg> + +/* Code insertion directives */ +#define %go_import(...) %insert(go_imports) %{__VA_ARGS__%} + +/* Basic types */ + +%typemap(gotype) bool, const bool & "bool" +%typemap(gotype) char, const char & "byte" +%typemap(gotype) signed char, const signed char & "int8" +%typemap(gotype) unsigned char, const unsigned char & "byte" +%typemap(gotype) short, const short & "int16" +%typemap(gotype) unsigned short, const unsigned short & "uint16" +%typemap(gotype) int, const int & "int" +%typemap(gotype) unsigned int, const unsigned int & "uint" +%typemap(gotype) long, const long & "int64" +%typemap(gotype) unsigned long, const unsigned long & "uint64" +%typemap(gotype) long long, const long long & "int64" +%typemap(gotype) unsigned long long, const unsigned long long & "uint64" +%typemap(gotype) float, const float & "float32" +%typemap(gotype) double, const double & "float64" + +%typemap(in) bool, + char, + signed char, + unsigned char, + short, + unsigned short, + int, + unsigned int, + long, + unsigned long, + long long, + unsigned long long, + float, + double +%{ $1 = ($1_ltype)$input; %} + +%typemap(in) const bool &, + const char &, + const signed char &, + const unsigned char &, + const short &, + const unsigned short &, + const int &, + const unsigned int &, + const long long &, + const unsigned long long &, + const float &, + const double & +%{ $1 = ($1_ltype)&$input; %} + +%typemap(in) const long & ($*1_ltype temp), + const unsigned long & ($*1_ltype temp) +%{ temp = ($*1_ltype)$input; + $1 = ($1_ltype)&temp; %} + +%typemap(out) bool, + char, + signed char, + unsigned char, + short, + unsigned short, + int, + unsigned int, + long, + unsigned long, + long long, + unsigned long long, + float, + double +%{ $result = $1; %} + +%typemap(goout) bool, + char, + signed char, + unsigned char, + short, + unsigned short, + int, + unsigned int, + long, + unsigned long, + long long, + unsigned long long, + float, + double +"" + +%typemap(out) const bool &, + const char &, + const signed char &, + const unsigned char &, + const short &, + const unsigned short &, + const int &, + const unsigned int &, + const long &, + const unsigned long &, + const long long &, + const unsigned long long &, + const float &, + const double & +%{ $result = ($*1_ltype)*$1; %} + +%typemap(goout) const bool &, + const char &, + const signed char &, + const unsigned char &, + const short &, + const unsigned short &, + const int &, + const unsigned int &, + const long &, + const unsigned long &, + const long long &, + const unsigned long long &, + const float &, + const double & +"" + +%typemap(out) void "" + +%typemap(goout) void "" + +%typemap(directorin) bool, + char, + signed char, + unsigned char, + short, + unsigned short, + int, + unsigned int, + long, + unsigned long, + long long, + unsigned long long, + float, + double +%{ $input = ($1_ltype)$1; %} + +%typemap(godirectorin) bool, + char, + signed char, + unsigned char, + short, + unsigned short, + int, + unsigned int, + long, + unsigned long, + long long, + unsigned long long, + float, + double +"" + +%typemap(directorin) const bool &, + const char &, + const signed char &, + const unsigned char &, + const short &, + const unsigned short &, + const int &, + const unsigned int &, + const long &, + const unsigned long &, + const long long &, + const unsigned long long &, + const float &, + const double & +%{ $input = ($*1_ltype)$1; %} + +%typemap(godirectorin) const bool &, + const char &, + const signed char &, + const unsigned char &, + const short &, + const unsigned short &, + const int &, + const unsigned int &, + const long &, + const unsigned long &, + const long long &, + const unsigned long long &, + const float &, + const double & +"" + +%typemap(directorout) bool, + char, + signed char, + unsigned char, + short, + unsigned short, + int, + unsigned int, + long, + unsigned long, + long long, + unsigned long long, + float, + double +%{ $result = ($1_ltype)$input; %} + +%typemap(directorout,warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) const bool &, + const char &, + const signed char &, + const unsigned char &, + const short &, + const unsigned short &, + const int &, + const unsigned int &, + const long &, + const unsigned long &, + const long long &, + const unsigned long long &, + const float &, + const double & +%{ + $result = new $*1_ltype($input); + swig_acquire_pointer(&swig_mem, $result); +%} + +/* The size_t type. */ + +%typemap(gotype) size_t, const size_t & %{int64%} + +%typemap(in) size_t +%{ $1 = (size_t)$input; %} + +%typemap(in) const size_t & +%{ $1 = ($1_ltype)&$input; %} + +%typemap(out) size_t +%{ $result = $1; %} + +%typemap(goout) size_t "" + +%typemap(out) const size_t & +%{ $result = ($*1_ltype)*$1; %} + +%typemap(goout) const size_t & "" + +%typemap(directorin) size_t +%{ $input = (size_t)$1; %} + +%typemap(godirectorin) size_t "" + +%typemap(directorin) const size_t & +%{ $input = ($*1_ltype)$1; %} + +%typemap(godirectorin) const size_t & "" + +%typemap(directorout) size_t +%{ $result = ($1_ltype)$input; %} + +%typemap(directorout,warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) const size_t & +%{ + $result = new $*1_ltype($input); + swig_acquire_pointer(&swig_mem, $result); +%} + +/* Member pointers. */ + +%typemap(gotype) SWIGTYPE (CLASS::*) +%{$gotypename%} + +%typemap(in) SWIGTYPE (CLASS::*) +%{ $1 = *($&1_ltype)$input; %} + +%typemap(out) SWIGTYPE (CLASS::*) +%{ + struct swig_out_type { intgo size; void* val; } *swig_out; + swig_out = (struct swig_out_type*)malloc(sizeof(*swig_out)); + if (swig_out) { + swig_out->size = sizeof($1_ltype); + swig_out->val = malloc(swig_out->size); + if (swig_out->val) { + *($&1_ltype)(swig_out->val) = $1; + } + } + $result = swig_out; +%} + +%typemap(goout) SWIGTYPE (CLASS::*) +%{ + { + type swig_out_type struct { size int; val uintptr } + p := (*swig_out_type)(unsafe.Pointer($1)) + if p == nil || p.val == 0 { + $result = nil + } else { + m := make([]byte, p.size) + a := (*[1024]byte)(unsafe.Pointer(p.val))[:p.size] + copy(m, a) + Swig_free(p.val) + Swig_free(uintptr(unsafe.Pointer(p))) + $result = &m[0] + } + } +%} + +%typemap(directorin) SWIGTYPE (CLASS::*) +%{ $input = *($&1_ltype)$1; %} + +%typemap(godirectorin) SWIGTYPE (CLASS::*) "" + +%typemap(directorout) SWIGTYPE (CLASS::*) +%{ + $result = new $1_ltype($input); + swig_acquire_pointer(&swig_mem, $result); +%} + +/* Pointers. */ + +/* We can't translate pointers using a typemap, so that is handled in + the C++ code. */ +%typemap(gotype) SWIGTYPE * +%{$gotypename%} + +%typemap(in) SWIGTYPE * +%{ $1 = *($&1_ltype)&$input; %} + +%typemap(out) SWIGTYPE * +%{ *($&1_ltype)&$result = ($1_ltype)$1; %} + +%typemap(goout) SWIGTYPE * "" + +%typemap(directorin) SWIGTYPE * +%{ *($&1_ltype)&$input = ($1_ltype)$1; %} + +%typemap(godirectorin) SWIGTYPE * "" + +%typemap(directorout) SWIGTYPE * +%{ $result = *($&1_ltype)&$input; %} + +/* Pointer references. */ + +%typemap(gotype) SWIGTYPE *const& +%{$gotypename%} + +%typemap(in) SWIGTYPE *const& ($*1_ltype temp = 0) +%{ + temp = *($1_ltype)&$input; + $1 = ($1_ltype)&temp; +%} + +%typemap(out) SWIGTYPE *const& +%{ *($1_ltype)&$result = *$1; %} + +%typemap(goout) SWIGTYPE *const& "" + +/* References. */ + +/* Converting a C++ reference to Go has to be handled in the C++ + code. */ +%typemap(gotype) SWIGTYPE & +%{$gotypename%} + +%typemap(in) SWIGTYPE & +%{ $1 = *($&1_ltype)&$input; %} + +%typemap(out) SWIGTYPE & +%{ *($&1_ltype)&$result = $1; %} + +%typemap(goout) SWIGTYPE & "" + +%typemap(directorin) SWIGTYPE & +%{ $input = ($1_ltype)&$1; %} + +%typemap(godirectorin) SWIGTYPE & "" + +%typemap(directorout) SWIGTYPE & +%{ *($&1_ltype)&$result = $input; %} + +%typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) SWIGTYPE *const& +%{ static $*1_ltype swig_temp; + swig_temp = *($1_ltype)&$input; + $result = &swig_temp; %} + +%typemap(gotype) SWIGTYPE && +%{$gotypename%} + +%typemap(in, fragment="<memory>") SWIGTYPE && (std::unique_ptr<$*1_ltype> rvrdeleter) +%{ $1 = *($&1_ltype)&$input; +rvrdeleter.reset($1); %} + +%typemap(out) SWIGTYPE && +%{ *($&1_ltype)&$result = $1; %} + +%typemap(goout) SWIGTYPE && "" + +%typemap(directorin) SWIGTYPE && +%{ $input = ($1_ltype)&$1_name; %} + +%typemap(godirectorin) SWIGTYPE && "" + +%typemap(directorout) SWIGTYPE && +%{ *($&1_ltype)&$result = $input; %} + +/* C arrays turn into Go pointers. If we know the length we can use a + slice. */ + +%typemap(gotype) SWIGTYPE [] +%{$gotypename%} + +%typemap(in) SWIGTYPE [] +%{ $1 = *($&1_ltype)&$input; %} + +%typemap(out) SWIGTYPE [] +%{ *($&1_ltype)&$result = $1; %} + +%typemap(goout) SWIGTYPE [] "" + +%typemap(directorin) SWIGTYPE [] +%{ $input = *($1_ltype)&$1; %} + +%typemap(godirectorin) SWIGTYPE [] "" + +%typemap(directorout) SWIGTYPE [] +%{ *($&1_ltype)&$result = $input; %} + +/* Strings. */ + +%typemap(gotype) + char *, char *&, char[ANY], char[] "string" + +/* Needed to avoid confusion with the way the go module handles + references. */ +%typemap(gotype) char&, unsigned char& "*byte" +%typemap(gotype) signed char& "*int8" + +%typemap(in) + char *, char[ANY], char[] +%{ + $1 = ($1_ltype)malloc($input.n + 1); + memcpy($1, $input.p, $input.n); + $1[$input.n] = '\0'; +%} + +%typemap(in) char *& (char *temp) +%{ + temp = (char *)malloc($input.n + 1); + memcpy(temp, $input.p, $input.n); + temp[$input.n] = '\0'; + $1 = ($1_ltype)&temp; +%} + +%typemap(freearg) + char *, char[ANY], char[] +%{ free($1); %} + +%typemap(freearg) char *& +%{ free(temp$argnum); %} + +%typemap(out,fragment="AllocateString") + char *, char *&, char[ANY], char[] +%{ $result = Swig_AllocateString((char*)$1, $1 ? strlen((char*)$1) : 0); %} + +%typemap(goout,fragment="CopyString") + char *, char *&, char[ANY], char[] +%{ $result = swigCopyString($1) %} + +%typemap(directorin,fragment="AllocateString") + char *, char *&, char[ANY], char[] +%{ + $input = Swig_AllocateString((char*)$1, $1 ? strlen((char*)$1) : 0); +%} + +%typemap(godirectorin,fragment="CopyString") + char *, char *&, char[ANY], char[] +%{ + $result = swigCopyString($input) +%} + +%typemap(godirectorout) + char *, char *&, char[ANY], char[] +%{ + { + p := Swig_malloc(len($input) + 1) + s := (*[1<<30]byte)(unsafe.Pointer(p))[:len($input) + 1] + copy(s, $input) + s[len($input)] = 0 + $result = *(*string)(unsafe.Pointer(&s)) + } +%} + +%typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) + char *, char *&, char[ANY], char[] +%{ $result = ($1_ltype)$input.p; %} + +/* String & length */ + +%typemap(gotype) (char *STRING, size_t LENGTH) "string" + +%typemap(in) (char *STRING, size_t LENGTH) +%{ + $1 = ($1_ltype)$input.p; + $2 = ($2_ltype)$input.n; +%} + +%typemap(out,fragment="AllocateString") (char *STRING, size_t LENGTH) +%{ $result = Swig_AllocateString((char*)$1, (size_t)$2); %} + +%typemap(goout,fragment="CopyString") (char *STRING, size_t LENGTH) +%{ $result = swigCopyString($1) %} + +%typemap(directorin,fragment="AllocateString") (char *STRING, size_t LENGTH) +%{ $input = Swig_AllocateString((char*)$1, $2); %} + +%typemap(godirectorin,fragment="CopyString") (char *STRING, size_t LENGTH) +%{ $result = swigCopyString($input) %} + +%typemap(directorout) (char *STRING, size_t LENGTH) +%{ + $1 = ($1_ltype)$input.p; + $2 = ($2_ltype)$input.n; +%} + +/* The int & type needs to convert to intgo. */ + +%typemap(gotype) int & "*int" + +%typemap(in) int & (int e) +%{ + e = (int)*$input; + $1 = &e; +%} + +%typemap(out) int & +%{ $result = new intgo(*$1); %} + +%typemap(argout) int & +%{ *$input = (intgo)e$argnum; %} + +%typemap(goout) int & "" + +%typemap(directorin) int & (intgo e) +%{ + e = (intgo)$1; + $input = &e; +%} + +%typemap(godirectorin) int & "" + +%typemap(directorout) int & +%{ + $*1_ltype f = ($*1_ltype)*$input; + $result = ($1_ltype)&f; +%} + +%typemap(directorargout) int & +%{ $1 = (int)*$input; %} + +%typemap(argout) const int & "" +%typemap(directorargout) const int & "" + +/* Enums. We can't do the right thing for enums in typemap(gotype) so + we deliberately don't define them. The right thing would be to + capitalize the name. This is instead done in go.cxx. */ + +%typemap(gotype) enum SWIGTYPE +%{$gotypename%} + +%typemap(in) enum SWIGTYPE +%{ $1 = ($1_ltype)$input; %} + +%typemap(out) enum SWIGTYPE +%{ $result = (intgo)$1; %} + +%typemap(goout) enum SWIGTYPE "" + +%typemap(directorin) enum SWIGTYPE +%{ $input = (intgo)$1; %} + +%typemap(godirectorin) enum SWIGTYPE "" + +%typemap(directorout) enum SWIGTYPE +%{ $result = ($1_ltype)$input; %} + +%typemap(directorin) enum SWIGTYPE & (intgo e) +%{ + e = (intgo)$1; + $input = ($1_ltype)&e; +%} + +%typemap(godirectorin) enum SWIGTYPE & "" + +%typemap(directorout) enum SWIGTYPE & +%{ $result = $input; %} + +/* Arbitrary type. This is a type passed by value in the C/C++ code. + We convert it to a pointer for the Go code. Note that all basic + types are explicitly handled above. */ + +%typemap(gotype) SWIGTYPE +%{$gotypename%} + +%typemap(in) SWIGTYPE ($&1_type argp) +%{ + argp = ($&1_ltype)$input; + if (argp == NULL) { + _swig_gopanic("Attempt to dereference null $1_type"); + } + $1 = ($1_ltype)*argp; +%} + +%typemap(out) SWIGTYPE +#ifdef __cplusplus +%{ *($&1_ltype*)&$result = new $1_ltype($1); %} +#else +{ + $&1_ltype $1ptr = ($&1_ltype)malloc(sizeof($1_ltype)); + memmove($1ptr, &$1, sizeof($1_type)); + *($&1_ltype*)&$result = $1ptr; +} +#endif + +%typemap(goout) SWIGTYPE "" + +%typemap(directorin) SWIGTYPE +%{ $input = new $1_ltype(SWIG_STD_MOVE($1)); %} + +%typemap(godirectorin) SWIGTYPE "" + +%typemap(directorout) SWIGTYPE +%{ $result = *($&1_ltype)$input; %} + +/* Exception handling */ + +%typemap(throws) char * +%{ _swig_gopanic($1); %} + +%typemap(throws) SWIGTYPE, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE *, SWIGTYPE [], SWIGTYPE [ANY] +%{ + (void)$1; + _swig_gopanic("C++ $1_type exception thrown"); +%} + +/* Typecheck typemaps. The purpose of these is merely to issue a + warning for overloaded C++ functions that cannot be overloaded in + Go as more than one C++ type maps to a single Go type. */ + +%typecheck(SWIG_TYPECHECK_BOOL) /* Go bool */ + bool, + const bool & + "" + +%typecheck(SWIG_TYPECHECK_CHAR) /* Go byte */ + char, + const char &, + unsigned char, + const unsigned char & + "" + +%typecheck(SWIG_TYPECHECK_INT8) /* Go int8 */ + signed char, + const signed char & + "" + +%typecheck(SWIG_TYPECHECK_INT16) /* Go int16 */ + short, + const short & + "" + +%typecheck(SWIG_TYPECHECK_INT16) /* Go uint16 */ + unsigned short, + const unsigned short & + "" + +%typecheck(SWIG_TYPECHECK_INT32) /* Go int */ + int, + const int & + "" + +%typecheck(SWIG_TYPECHECK_INT32) /* Go uint */ + unsigned int, + const unsigned int & + "" + +%typecheck(SWIG_TYPECHECK_INT64) /* Go int64 */ + long, + const long &, + long long, + const long long & + "" + +%typecheck(SWIG_TYPECHECK_INT64) /* Go uint64 */ + unsigned long, + const unsigned long &, + unsigned long long, + const unsigned long long & + "" + +%typecheck(SWIG_TYPECHECK_FLOAT) /* Go float32 */ + float, + const float & + "" + +%typecheck(SWIG_TYPECHECK_DOUBLE) /* Go float64 */ + double, + const double & + "" + +%typecheck(SWIG_TYPECHECK_STRING) /* Go string */ + char *, + char *&, + char[ANY], + char [], + signed char *, + signed char *&, + signed char[ANY], + signed char [], + unsigned char *, + unsigned char *&, + unsigned char[ANY], + unsigned char [] + "" + +%typecheck(SWIG_TYPECHECK_POINTER) + SWIGTYPE, + SWIGTYPE *, + SWIGTYPE &, + SWIGTYPE &&, + SWIGTYPE *const&, + SWIGTYPE [], + SWIGTYPE (CLASS::*) + "" + +%apply SWIGTYPE * { SWIGTYPE *const } +%apply SWIGTYPE (CLASS::*) { SWIGTYPE (CLASS::*const) } +%apply SWIGTYPE & { SWIGTYPE (CLASS::*const&) } + +/* Go keywords. */ +%include <gokw.swg> + +%include <goruntime.swg> diff --git a/contrib/tools/swig/Lib/go/gokw.swg b/contrib/tools/swig/Lib/go/gokw.swg new file mode 100644 index 0000000000..3542830024 --- /dev/null +++ b/contrib/tools/swig/Lib/go/gokw.swg @@ -0,0 +1,33 @@ +/* Rename keywords. */ + +#define GOKW(x) %keywordwarn("'" `x` "' is a Go keyword",rename="X%s") `x` +#define GOBN(x) %builtinwarn("'" `x` "' conflicts with a built-in name in Go") "::"`x` + +GOKW(break); +GOKW(case); +GOKW(chan); +GOKW(const); +GOKW(continue); +GOKW(default); +GOKW(defer); +GOKW(else); +GOKW(fallthrough); +GOKW(for); +GOKW(func); +GOKW(go); +GOKW(goto); +GOKW(if); +GOKW(import); +GOKW(interface); +GOKW(package); +GOKW(range); +GOKW(return); +GOKW(select); +GOKW(struct); +GOKW(switch); +GOKW(type); +GOKW(var); + +GOBN(map); + +#undef GOKW diff --git a/contrib/tools/swig/Lib/go/goruntime.swg b/contrib/tools/swig/Lib/go/goruntime.swg new file mode 100644 index 0000000000..7bf083bd3d --- /dev/null +++ b/contrib/tools/swig/Lib/go/goruntime.swg @@ -0,0 +1,217 @@ +/* ------------------------------------------------------------ + * goruntime.swg + * + * Go runtime code for the various generated files. + * ------------------------------------------------------------ */ + +%inline %{ +static void Swig_free(void* p) { + free(p); +} + +static void* Swig_malloc(int c) { + return malloc(c); +} +%} + +%insert(runtime) %{ +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> + +%} + +%insert(cgo_comment_typedefs) %{ +#include <stddef.h> +#include <stdint.h> +%} + +#if SWIGGO_INTGO_SIZE == 32 +%insert(runtime) %{ +typedef int intgo; +typedef unsigned int uintgo; +%} +%insert(cgo_comment_typedefs) %{ +typedef int intgo; +typedef unsigned int uintgo; +%} +#elif SWIGGO_INTGO_SIZE == 64 +%insert(runtime) %{ +typedef long long intgo; +typedef unsigned long long uintgo; +%} +%insert(cgo_comment_typedefs) %{ +typedef long long intgo; +typedef unsigned long long uintgo; +%} +#else +%insert(runtime) %{ +typedef ptrdiff_t intgo; +typedef size_t uintgo; +%} +%insert(cgo_comment_typedefs) %{ +typedef ptrdiff_t intgo; +typedef size_t uintgo; +%} +#endif + +#ifndef SWIGGO_GCCGO +// Set the host compiler struct attribute that will be +// used to match gc's struct layout. For example, on 386 Windows, +// gcc wants to 8-align int64s, but gc does not. +// Use __gcc_struct__ to work around http://gcc.gnu.org/PR52991 on x86, +// and https://golang.org/issue/5603. +// See: https://github.com/golang/go/blob/fcbf04f9b93b4cd8addd05c2ed784118eb50a46c/src/cmd/cgo/out.go#L663 +%insert(runtime) %{ +# if !defined(__clang__) && (defined(__i386__) || defined(__x86_64__)) +# define SWIGSTRUCTPACKED __attribute__((__packed__, __gcc_struct__)) +# else +# define SWIGSTRUCTPACKED __attribute__((__packed__)) +# endif +%} +#else +# define SWIGSTRUCTPACKED +#endif + +%insert(runtime) %{ + +typedef struct { char *p; intgo n; } _gostring_; +typedef struct { void* array; intgo len; intgo cap; } _goslice_; + +%} + +%insert(cgo_comment_typedefs) %{ + +typedef struct { char *p; intgo n; } _gostring_; +typedef struct { void* array; intgo len; intgo cap; } _goslice_; + +%} + +#ifdef SWIGGO_GCCGO + +/* Boilerplate for C/C++ code when using gccgo. */ +%insert(runtime) %{ +#define SWIGGO_GCCGO + +#ifdef __cplusplus +extern "C" { +#endif +extern void *_cgo_allocate(size_t); +extern void _cgo_panic(const char *); +#ifdef __cplusplus +} +#endif + +#define _swig_goallocate _cgo_allocate +#define _swig_gopanic _cgo_panic +%} + +#endif + +#ifndef SWIGGO_GCCGO + +%go_import("unsafe", _ "runtime/cgo") + +#else + +%go_import("syscall", "unsafe") + +%insert(go_header) %{ + +type _ syscall.Sockaddr + +%} + +#endif + +%insert(go_header) %{ + +type _ unsafe.Pointer + +%} + +/* Swig_always_false is used to conditionally assign parameters to + Swig_escape_val so that the compiler thinks that they escape. We + only assign them if Swig_always_false is true, which it never is. + We export the variable so that the compiler doesn't realize that it + is never set. */ +%insert(go_header) %{ +var Swig_escape_always_false bool +var Swig_escape_val interface{} +%} + +/* Function pointers are translated by the code in go.cxx into + _swig_fnptr. Member pointers are translated to _swig_memberptr. */ + +%insert(go_header) %{ +type _swig_fnptr *byte +type _swig_memberptr *byte +%} + +/* Convert a Go interface value into a C++ pointer. */ + +%insert(go_header) %{ +func getSwigcptr(v interface { Swigcptr() uintptr }) uintptr { + if v == nil { + return 0 + } + return v.Swigcptr() +} +%} + +/* For directors we need C++ to track a Go pointer. Since we can't + pass a Go pointer into C++, we use a map to track the pointers on + the Go side. */ + +%go_import("sync") + +%insert(go_header) %{ +type _ sync.Mutex +%} + +%insert(go_director) %{ + +var swigDirectorTrack struct { + sync.Mutex + m map[int]interface{} + c int +} + +func swigDirectorAdd(v interface{}) int { + swigDirectorTrack.Lock() + defer swigDirectorTrack.Unlock() + if swigDirectorTrack.m == nil { + swigDirectorTrack.m = make(map[int]interface{}) + } + swigDirectorTrack.c++ + ret := swigDirectorTrack.c + swigDirectorTrack.m[ret] = v + return ret +} + +func swigDirectorLookup(c int) interface{} { + swigDirectorTrack.Lock() + defer swigDirectorTrack.Unlock() + ret := swigDirectorTrack.m[c] + if ret == nil { + panic("C++ director pointer not found (possible use-after-free)") + } + return ret +} + +func swigDirectorDelete(c int) { + swigDirectorTrack.Lock() + defer swigDirectorTrack.Unlock() + if swigDirectorTrack.m[c] == nil { + if c > swigDirectorTrack.c { + panic("C++ director pointer invalid (possible memory corruption") + } else { + panic("C++ director pointer not found (possible use-after-free)") + } + } + delete(swigDirectorTrack.m, c) +} + +%} diff --git a/contrib/tools/swig/Lib/go/gostring.swg b/contrib/tools/swig/Lib/go/gostring.swg new file mode 100644 index 0000000000..d9c47d2858 --- /dev/null +++ b/contrib/tools/swig/Lib/go/gostring.swg @@ -0,0 +1,29 @@ +/* ------------------------------------------------------------ + * gostring.swg + * + * Support for returning strings from C to Go. + * ------------------------------------------------------------ */ + +// C/C++ code to convert a memory buffer into a Go string allocated in +// C/C++ memory. +%fragment("AllocateString", "runtime") %{ +static _gostring_ Swig_AllocateString(const char *p, size_t l) { + _gostring_ ret; + ret.p = (char*)malloc(l); + memcpy(ret.p, p, l); + ret.n = l; + return ret; +} +%} + +// Go code to convert a string allocated in C++ memory to one +// allocated in Go memory. +%fragment("CopyString", "go_runtime") %{ +type swig_gostring struct { p unsafe.Pointer; n int } +func swigCopyString(s string) string { + p := *(*swig_gostring)(unsafe.Pointer(&s)) + r := string((*[0x7fffffff]byte)(p.p)[:p.n]) + Swig_free(uintptr(p.p)) + return r +} +%} diff --git a/contrib/tools/swig/Lib/go/std_common.i b/contrib/tools/swig/Lib/go/std_common.i new file mode 100644 index 0000000000..c010facacd --- /dev/null +++ b/contrib/tools/swig/Lib/go/std_common.i @@ -0,0 +1,4 @@ +%include <std_except.i> + +%apply size_t { std::size_t }; +%apply const size_t& { const std::size_t& }; diff --git a/contrib/tools/swig/Lib/go/std_except.i b/contrib/tools/swig/Lib/go/std_except.i new file mode 100644 index 0000000000..4f021a1264 --- /dev/null +++ b/contrib/tools/swig/Lib/go/std_except.i @@ -0,0 +1,31 @@ +/* ----------------------------------------------------------------------------- + * 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 <typeinfo> +#include <stdexcept> +%} + +namespace std +{ + %ignore exception; + struct exception {}; +} + +%typemap(throws) std::bad_cast %{_swig_gopanic($1.what());%} +%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/contrib/tools/swig/Lib/go/std_string.i b/contrib/tools/swig/Lib/go/std_string.i new file mode 100644 index 0000000000..35b4a5e46b --- /dev/null +++ b/contrib/tools/swig/Lib/go/std_string.i @@ -0,0 +1,162 @@ +/* ----------------------------------------------------------------------------- + * 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(gotype) string, const string & "string" + +%typemap(in) string +%{ $1.assign($input.p, $input.n); %} + +%typemap(godirectorout) string +%{ + { + p := Swig_malloc(len($input)) + s := (*[1<<30]byte)(unsafe.Pointer(p))[:len($input)] + copy(s, $input) + $result = *(*string)(unsafe.Pointer(&s)) + } +%} + +%typemap(directorout) string +%{ + $result.assign($input.p, $input.n); + free($input.p); +%} + +%typemap(out,fragment="AllocateString") string +%{ $result = Swig_AllocateString($1.data(), $1.length()); %} + +%typemap(goout,fragment="CopyString") string +%{ $result = swigCopyString($1) %} + +%typemap(directorin,fragment="AllocateString") string +%{ $input = Swig_AllocateString($1.data(), $1.length()); %} + +%typemap(godirectorin,fragment="CopyString") string +%{ $result = swigCopyString($input) %} + +%typemap(throws) string +%{ _swig_gopanic($1.c_str()); %} + +%typemap(in) const string & +%{ + $*1_ltype $1_str($input.p, $input.n); + $1 = &$1_str; +%} + +%typemap(godirectorout) const string & +%{ + { + p := Swig_malloc(len($input)) + s := (*[1<<30]byte)(unsafe.Pointer(p))[:len($input)] + copy(s, $input) + $result = *(*string)(unsafe.Pointer(&s)) + } +%} + +%typemap(directorout,warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) const string & +%{ + static $*1_ltype $1_str; + $1_str.assign($input.p, $input.n); + free($input.p); + $result = &$1_str; +%} + +%typemap(out,fragment="AllocateString") const string & +%{ $result = Swig_AllocateString((*$1).data(), (*$1).length()); %} + +%typemap(goout,fragment="CopyString") const string & +%{ $result = swigCopyString($1) %} + +%typemap(directorin,fragment="AllocateString") const string & +%{ $input = Swig_AllocateString($1.data(), $1.length()); %} + +%typemap(godirectorin,fragment="CopyString") const string & +%{ $result = swigCopyString($input) %} + +%typemap(throws) const string & +%{ _swig_gopanic($1.c_str()); %} + + +%typemap(gotype) string * "*string" + +%typemap(in) string * (string temp) +%{ + if ($input) { + temp.assign($input->p, $input->n); + $1 = &temp; + } else + $1 = 0; +%} + +%typemap(godirectorout) string * +%{ + if $input != nil { + p := Swig_malloc(len(*$input)) + s := (*[1<<30]byte)(unsafe.Pointer(p))[:len(*$input)] + copy(s, *$input) + $result = (*string)(unsafe.Pointer(&s)) + } else { + $result = nil + } +%} + +%typemap(directorout) string * (string temp) +%{ + temp.assign($input->p, $input->n); + $result = &temp; + free($input.p); +%} + +%typemap(out,fragment="AllocateString") string * (_gostring_ temp) +%{ + temp = Swig_AllocateString($1->data(), $1->length()); + $result = &temp; +%} + +%typemap(goout,fragment="CopyString") string * +%{ *$result = swigCopyString(*$1) %} + +%typemap(directorin,fragment="AllocateString") string * (_gostring_ temp) +%{ + if ($1) { + temp = Swig_AllocateString($1->data(), $1->length()); + $input = &temp; + } else + $input = 0; +%} + +%typemap(godirectorin,fragment="CopyString") string * +%{ *$result = swigCopyString(*$input); %} + +%typemap(argout,fragment="AllocateString") string * +%{ + if ($1) + *$input = Swig_AllocateString($1->data(), $1->length()); +%} + +%typemap(goargout,fragment="CopyString") string * +%{ + if $input != nil { + *$1 = swigCopyString(*$input) + } +%} + +} diff --git a/contrib/tools/swig/Lib/go/std_vector.i b/contrib/tools/swig/Lib/go/std_vector.i new file mode 100644 index 0000000000..679c707596 --- /dev/null +++ b/contrib/tools/swig/Lib/go/std_vector.i @@ -0,0 +1,92 @@ +/* ----------------------------------------------------------------------------- + * std_vector.i + * ----------------------------------------------------------------------------- */ + +%{ +#include <vector> +#include <stdexcept> +%} + +namespace std { + + template<class T> class vector { + public: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + + vector(); + vector(size_type n); + vector(const vector& other); + + 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 ptrdiff_t difference_type; + typedef bool value_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef bool const_reference; + + vector(); + vector(size_type n); + vector(const vector& other); + + 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 { + bool 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"); + } + } + }; +} diff --git a/contrib/tools/swig/Lib/go/typemaps.i b/contrib/tools/swig/Lib/go/typemaps.i new file mode 100644 index 0000000000..d2e60d37c8 --- /dev/null +++ b/contrib/tools/swig/Lib/go/typemaps.i @@ -0,0 +1,298 @@ +/* ----------------------------------------------------------------------------- + * typemaps.i + * + * Pointer and reference handling typemap library + * + * These mappings provide support for input/output arguments and common + * uses for C/C++ pointers and C++ references. + * ----------------------------------------------------------------------------- */ + +/* +INPUT typemaps +-------------- + +These typemaps remap a C pointer or C++ reference to be an "INPUT" value which is +passed by value instead of reference. + +The following typemaps can be applied to turn a pointer or reference into a simple +input value. That is, instead of passing a pointer or reference to an object, +you would use a real value instead. + + bool *INPUT, bool &INPUT + signed char *INPUT, signed char &INPUT + unsigned char *INPUT, unsigned char &INPUT + short *INPUT, short &INPUT + unsigned short *INPUT, unsigned short &INPUT + int *INPUT, int &INPUT + unsigned int *INPUT, unsigned int &INPUT + long *INPUT, long &INPUT + unsigned long *INPUT, unsigned long &INPUT + long long *INPUT, long long &INPUT + unsigned long long *INPUT, unsigned long long &INPUT + float *INPUT, float &INPUT + double *INPUT, double &INPUT + +To use these, suppose you had a C function like this : + + double fadd(double *a, double *b) { + return *a+*b; + } + +You could wrap it with SWIG as follows : + + %include <typemaps.i> + double fadd(double *INPUT, double *INPUT); + +or you can use the %apply directive : + + %include <typemaps.i> + %apply double *INPUT { double *a, double *b }; + double fadd(double *a, double *b); + +In Go you could then use it like this: + answer := modulename.Fadd(10.0, 20.0) + +There are no char *INPUT typemaps, however you can apply the signed +char * typemaps instead: + %include <typemaps.i> + %apply signed char *INPUT {char *input}; + void f(char *input); +*/ + +%define INPUT_TYPEMAP(TYPE, GOTYPE) +%typemap(gotype) TYPE *INPUT, TYPE &INPUT "GOTYPE" + + %typemap(in) TYPE *INPUT, TYPE &INPUT +%{ $1 = ($1_ltype)&$input; %} + +%typemap(out) TYPE *INPUT, TYPE &INPUT "" + +%typemap(goout) TYPE *INPUT, TYPE &INPUT "" + +%typemap(freearg) TYPE *INPUT, TYPE &INPUT "" + +%typemap(argout) TYPE *INPUT, TYPE &INPUT "" + +// %typemap(typecheck) TYPE *INPUT = TYPE; +// %typemap(typecheck) TYPE &INPUT = TYPE; +%enddef + +INPUT_TYPEMAP(bool, bool); +INPUT_TYPEMAP(signed char, int8); +INPUT_TYPEMAP(char, byte); +INPUT_TYPEMAP(unsigned char, byte); +INPUT_TYPEMAP(short, int16); +INPUT_TYPEMAP(unsigned short, uint16); +INPUT_TYPEMAP(int, int); +INPUT_TYPEMAP(unsigned int, uint); +INPUT_TYPEMAP(long, int64); +INPUT_TYPEMAP(unsigned long, uint64); +INPUT_TYPEMAP(long long, int64); +INPUT_TYPEMAP(unsigned long long, uint64); +INPUT_TYPEMAP(float, float32); +INPUT_TYPEMAP(double, float64); + +#undef INPUT_TYPEMAP + +// OUTPUT typemaps. These typemaps are used for parameters that +// are output only. An array replaces the c pointer or reference parameter. +// The output value is returned in this array passed in. + +/* +OUTPUT typemaps +--------------- + +The following typemaps can be applied to turn a pointer or reference +into an "output" value. When calling a function, no input value would +be given for a parameter, but an output value would be returned. This +works by a Go slice being passed as a parameter where a c pointer or +reference is required. As with any Go function, the array is passed +by reference so that any modifications to the array will be picked up +in the calling function. Note that the array passed in MUST have at +least one element, but as the c function does not require any input, +the value can be set to anything. + + bool *OUTPUT, bool &OUTPUT + signed char *OUTPUT, signed char &OUTPUT + unsigned char *OUTPUT, unsigned char &OUTPUT + short *OUTPUT, short &OUTPUT + unsigned short *OUTPUT, unsigned short &OUTPUT + int *OUTPUT, int &OUTPUT + unsigned int *OUTPUT, unsigned int &OUTPUT + long *OUTPUT, long &OUTPUT + unsigned long *OUTPUT, unsigned long &OUTPUT + long long *OUTPUT, long long &OUTPUT + unsigned long long *OUTPUT, unsigned long long &OUTPUT + float *OUTPUT, float &OUTPUT + double *OUTPUT, double &OUTPUT + +For example, suppose you were trying to wrap the modf() function in the +C math library which splits x into integral and fractional parts (and +returns the integer part in one of its parameters): + + double modf(double x, double *ip); + +You could wrap it with SWIG as follows : + + %include <typemaps.i> + double modf(double x, double *OUTPUT); + +or you can use the %apply directive : + + %include <typemaps.i> + %apply double *OUTPUT { double *ip }; + double modf(double x, double *ip); + +The Go output of the function would be the function return value and the +value in the single element array. In Go you would use it like this: + + ptr := []float64{0.0} + fraction := modulename.Modf(5.0,ptr) + +There are no char *OUTPUT typemaps, however you can apply the signed +char * typemaps instead: + %include <typemaps.i> + %apply signed char *OUTPUT {char *output}; + void f(char *output); +*/ + +%define OUTPUT_TYPEMAP(TYPE, GOTYPE) +%typemap(gotype) TYPE *OUTPUT, TYPE &OUTPUT %{[]GOTYPE%} + +%typemap(in) TYPE *OUTPUT($*1_ltype temp), TYPE &OUTPUT($*1_ltype temp) +{ + if ($input.len == 0) { + _swig_gopanic("array must contain at least 1 element"); + } + $1 = &temp; +} + +%typemap(out) TYPE *OUTPUT, TYPE &OUTPUT "" + +%typemap(goout) TYPE *INPUT, TYPE &INPUT "" + +%typemap(freearg) TYPE *OUTPUT, TYPE &OUTPUT "" + +%typemap(argout) TYPE *OUTPUT, TYPE &OUTPUT +{ + TYPE* a = (TYPE *) $input.array; + a[0] = temp$argnum; +} + +%enddef + +OUTPUT_TYPEMAP(bool, bool); +OUTPUT_TYPEMAP(signed char, int8); +OUTPUT_TYPEMAP(char, byte); +OUTPUT_TYPEMAP(unsigned char, byte); +OUTPUT_TYPEMAP(short, int16); +OUTPUT_TYPEMAP(unsigned short, uint16); +OUTPUT_TYPEMAP(int, int); +OUTPUT_TYPEMAP(unsigned int, uint); +OUTPUT_TYPEMAP(long, int64); +OUTPUT_TYPEMAP(unsigned long, uint64); +OUTPUT_TYPEMAP(long long, int64); +OUTPUT_TYPEMAP(unsigned long long, uint64); +OUTPUT_TYPEMAP(float, float32); +OUTPUT_TYPEMAP(double, float64); + +#undef OUTPUT_TYPEMAP + +/* +INOUT typemaps +-------------- + +Mappings for a parameter that is both an input and an output parameter + +The following typemaps can be applied to make a function parameter both +an input and output value. This combines the behavior of both the +"INPUT" and "OUTPUT" typemaps described earlier. Output values are +returned as an element in a Go slice. + + bool *INOUT, bool &INOUT + signed char *INOUT, signed char &INOUT + unsigned char *INOUT, unsigned char &INOUT + short *INOUT, short &INOUT + unsigned short *INOUT, unsigned short &INOUT + int *INOUT, int &INOUT + unsigned int *INOUT, unsigned int &INOUT + long *INOUT, long &INOUT + unsigned long *INOUT, unsigned long &INOUT + long long *INOUT, long long &INOUT + unsigned long long *INOUT, unsigned long long &INOUT + float *INOUT, float &INOUT + double *INOUT, double &INOUT + +For example, suppose you were trying to wrap the following function : + + void neg(double *x) { + *x = -(*x); + } + +You could wrap it with SWIG as follows : + + %include <typemaps.i> + void neg(double *INOUT); + +or you can use the %apply directive : + + %include <typemaps.i> + %apply double *INOUT { double *x }; + void neg(double *x); + +This works similarly to C in that the mapping directly modifies the +input value - the input must be an array with a minimum of one element. +The element in the array is the input and the output is the element in +the array. + + x := []float64{5.0} + Neg(x); + +The implementation of the OUTPUT and INOUT typemaps is different to +other languages in that other languages will return the output value +as part of the function return value. This difference is due to Go +being a typed language. + +There are no char *INOUT typemaps, however you can apply the signed +char * typemaps instead: + %include <typemaps.i> + %apply signed char *INOUT {char *inout}; + void f(char *inout); +*/ + +%define INOUT_TYPEMAP(TYPE, GOTYPE) +%typemap(gotype) TYPE *INOUT, TYPE &INOUT %{[]GOTYPE%} + +%typemap(in) TYPE *INOUT, TYPE &INOUT { + if ($input.len == 0) { + _swig_gopanic("array must contain at least 1 element"); + } + $1 = ($1_ltype) $input.array; +} + +%typemap(out) TYPE *INOUT, TYPE &INOUT "" + +%typemap(goout) TYPE *INOUT, TYPE &INOUT "" + +%typemap(freearg) TYPE *INOUT, TYPE &INOUT "" + +%typemap(argout) TYPE *INOUT, TYPE &INOUT "" + +%enddef + +INOUT_TYPEMAP(bool, bool); +INOUT_TYPEMAP(signed char, int8); +INOUT_TYPEMAP(char, byte); +INOUT_TYPEMAP(unsigned char, byte); +INOUT_TYPEMAP(short, int16); +INOUT_TYPEMAP(unsigned short, uint16); +INOUT_TYPEMAP(int, int); +INOUT_TYPEMAP(unsigned int, uint); +INOUT_TYPEMAP(long, int64); +INOUT_TYPEMAP(unsigned long, uint64); +INOUT_TYPEMAP(long long, int64); +INOUT_TYPEMAP(unsigned long long, uint64); +INOUT_TYPEMAP(float, float32); +INOUT_TYPEMAP(double, float64); + +#undef INOUT_TYPEMAP |