mirror of https://github.com/swig/swig
252 lines
4.4 KiB
OpenEdge ABL
252 lines
4.4 KiB
OpenEdge ABL
// Test the goin and goout typemaps for directors.
|
|
|
|
%module(directors="1") go_director_inout
|
|
|
|
%include <std_string.i>
|
|
|
|
%{
|
|
#include <string>
|
|
%}
|
|
|
|
%inline
|
|
%{
|
|
|
|
struct MyStruct {
|
|
std::string str;
|
|
};
|
|
|
|
struct RetStruct {
|
|
std::string str;
|
|
};
|
|
|
|
%}
|
|
|
|
%go_import("encoding/json")
|
|
|
|
%insert(go_header)
|
|
%{
|
|
|
|
type GoRetStruct struct {
|
|
Str string
|
|
}
|
|
|
|
%}
|
|
|
|
%typemap(gotype) RetStruct "GoRetStruct"
|
|
|
|
%typemap(imtype) RetStruct "string"
|
|
|
|
%typemap(goin) RetStruct
|
|
%{
|
|
$result = $input.Str
|
|
%}
|
|
|
|
%typemap(in) RetStruct
|
|
%{
|
|
$result.str.assign($input.p, $input.n);
|
|
%}
|
|
|
|
%typemap(out,fragment="AllocateString") RetStruct
|
|
%{
|
|
$result = Swig_AllocateString($1.str.data(), $1.str.length());
|
|
%}
|
|
|
|
%typemap(goout,fragment="CopyString") RetStruct
|
|
%{
|
|
$result = GoRetStruct{Str: swigCopyString($input)}
|
|
%}
|
|
|
|
%typemap(godirectorout) RetStruct
|
|
%{
|
|
$result = $input.Str
|
|
%}
|
|
|
|
%typemap(directorout) RetStruct
|
|
%{
|
|
$result.str.assign($input.p, $input.n);
|
|
%}
|
|
|
|
%typemap(godirectorin) RetStruct
|
|
%{
|
|
%}
|
|
|
|
%typemap(gotype) MyStruct "map[string]interface{}"
|
|
|
|
%typemap(imtype) MyStruct "string"
|
|
|
|
%typemap(goin) MyStruct
|
|
%{
|
|
if b, err := json.Marshal($input); err != nil {
|
|
panic(err)
|
|
} else {
|
|
$result = string(b)
|
|
}
|
|
%}
|
|
|
|
%typemap(directorin,fragment="AllocateString") MyStruct
|
|
%{
|
|
$input = Swig_AllocateString($1.str.data(), $1.str.length());
|
|
%}
|
|
|
|
%typemap(godirectorin,fragment="CopyString") MyStruct
|
|
%{
|
|
if err := json.Unmarshal([]byte(swigCopyString($input)), &$result); err != nil {
|
|
panic(err)
|
|
}
|
|
%}
|
|
|
|
%typemap(out,fragment="AllocateString") MyStruct
|
|
%{
|
|
$result = Swig_AllocateString($1.str.data(), $1.str.length());
|
|
%}
|
|
|
|
%typemap(goout,fragment="CopyString") MyStruct
|
|
%{
|
|
$result = swigCopyString($input)
|
|
%}
|
|
|
|
%typemap(in) MyStruct
|
|
%{
|
|
$1.str.assign($input.p, $input.n);
|
|
%}
|
|
|
|
%typemap(directorin) std::string & (_gostring_ temp) {
|
|
$input = &temp;
|
|
temp.p = (char *) $1.data();
|
|
temp.n = $1.size();
|
|
}
|
|
%typemap(directorargout) std::string & {
|
|
_gostring_ *tmp = $input;
|
|
$1.assign(tmp->p, tmp->p + tmp->n);
|
|
}
|
|
|
|
%inline %{
|
|
// Helper functions for converting string arrays
|
|
#include <stdlib.h>
|
|
void *alloc_ptr_array(unsigned int len)
|
|
{
|
|
return calloc(len, sizeof(void *));
|
|
}
|
|
void set_ptr_array(void *ain, unsigned int pos, void *val)
|
|
{
|
|
void **a = (void **) ain;
|
|
a[pos] = val;
|
|
}
|
|
void *get_ptr_array(void *ain, unsigned int pos)
|
|
{
|
|
void **a = (void **) ain;
|
|
return a[pos];
|
|
}
|
|
void free_ptr_array(void *ain)
|
|
{
|
|
void **a = (void **) ain;
|
|
unsigned int i;
|
|
|
|
if (!a)
|
|
return;
|
|
for (i = 0; a[i]; i++) {
|
|
free(a[i]);
|
|
}
|
|
free(a);
|
|
}
|
|
char *uintptr_to_string(void *in)
|
|
{
|
|
return (char *) in;
|
|
}
|
|
void *string_to_uintptr(char *in)
|
|
{
|
|
return strdup(in);
|
|
}
|
|
%}
|
|
|
|
// These typemaps convert between an array of strings in Go and a
|
|
// const char** that is NULL terminated in C++.
|
|
%typemap(gotype) (const char * const *) "[]string"
|
|
%typemap(imtype) (const char * const *) "uintptr"
|
|
%typemap(goin) (const char * const *) {
|
|
if $input == nil || len($input) == 0 {
|
|
$result = 0
|
|
} else {
|
|
$result = Alloc_ptr_array(uint(len($input) + 1))
|
|
defer func() {
|
|
Free_ptr_array($result)
|
|
}()
|
|
var i uint
|
|
for i = 0; i < uint(len($input)); i++ {
|
|
Set_ptr_array($result, i, String_to_uintptr($input[i]))
|
|
}
|
|
}
|
|
}
|
|
%typemap(in) (const char * const *) {
|
|
$1 = (char **) $input;
|
|
}
|
|
%typemap(godirectorin) (const char * const *) {
|
|
if ($input == 0) {
|
|
$result = nil
|
|
} else {
|
|
var i uint
|
|
for i = 0; ; i++ {
|
|
var v uintptr = Get_ptr_array($input, i)
|
|
if v == 0 {
|
|
break
|
|
}
|
|
}
|
|
if i == 0 {
|
|
$result = nil
|
|
} else {
|
|
$result = make([]string, i)
|
|
for i = 0; ; i++ {
|
|
var v uintptr = Get_ptr_array($input, i)
|
|
if v == 0 {
|
|
break
|
|
}
|
|
$result[i] = Uintptr_to_string(v)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
%feature("director") MyClass;
|
|
|
|
%inline
|
|
%{
|
|
|
|
class MyClass {
|
|
public:
|
|
virtual ~MyClass() {}
|
|
virtual RetStruct Adjust(MyStruct s) {
|
|
RetStruct r;
|
|
r.str = s.str;
|
|
return r;
|
|
}
|
|
|
|
void CallS4(const char * const *strarray);
|
|
virtual void S1(std::string s);
|
|
virtual void S2(std::string& s) = 0;
|
|
virtual void S3(std::string* s) = 0;
|
|
virtual void S4(const char * const *strarray);
|
|
virtual int S5(const std::string* s);
|
|
};
|
|
|
|
void MyClass::S1(std::string s) {
|
|
throw "Base S1 called!";
|
|
}
|
|
|
|
void MyClass::S4(const char * const *strarray) {
|
|
throw "Base S4 called!";
|
|
}
|
|
|
|
void MyClass::CallS4(const char * const *strarray) {
|
|
this->S4(strarray);
|
|
}
|
|
|
|
int MyClass::S5(const std::string* s) {
|
|
if (s) {
|
|
return (*s)[0];
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
%}
|