Some support for overloading, simplified wrapping of pure C functions, some improvements in argument passing typemaps.
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/branches/gsoc2008-maciekd@10653 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
125f362852
commit
f585c69d02
4 changed files with 346 additions and 183 deletions
|
|
@ -4,6 +4,13 @@ class A {
|
||||||
public:
|
public:
|
||||||
int i;
|
int i;
|
||||||
A(int i) : i(i) {}
|
A(int i) : i(i) {}
|
||||||
|
void foo() {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class B : public A {
|
||||||
|
public:
|
||||||
|
B(int i) : A(i) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class MyClass {
|
class MyClass {
|
||||||
|
|
@ -18,7 +25,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void bar(int x, int* px, int* xs[5]) {
|
void bar(int x, int* px, int** xs) {
|
||||||
printf("x = %d\n", x);
|
printf("x = %d\n", x);
|
||||||
printf("*px = %d\n", *px);
|
printf("*px = %d\n", *px);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
@ -28,5 +35,18 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void foo_1(A& a, A& b) {
|
||||||
|
printf("a.i = %d\n", a.i);
|
||||||
|
printf("b.i = %d\n", b.i);
|
||||||
|
a.i++;
|
||||||
|
b.i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void foo_2(int& x, double& d) {
|
||||||
|
printf("x = %d d = %f\n", x, d);
|
||||||
|
x++;
|
||||||
|
d++;
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,10 @@
|
||||||
#include "example_proxy.h"
|
#include "example_proxy.h"
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
|
|
||||||
MyClass* mc = new_MyClass();
|
MyClass* mc = new_MyClass();
|
||||||
A* a = new_A(123), *b = new_A(234), *as[5];
|
A* a = new_A(123), *b = new_A(234), *as[5];
|
||||||
int i, j = 321, *js[5];
|
int i, j = 321, *js[5];
|
||||||
|
double d = 55.0;
|
||||||
|
|
||||||
for (i = 0; i < 4; ++i) {
|
for (i = 0; i < 4; ++i) {
|
||||||
as[i] = new_A(20 + i);
|
as[i] = new_A(20 + i);
|
||||||
|
|
@ -18,9 +18,18 @@ int main(int argc, char** argv) {
|
||||||
js[i] = 0;
|
js[i] = 0;
|
||||||
|
|
||||||
MyClass_bar(mc, j, &j, js);
|
MyClass_bar(mc, j, &j, js);
|
||||||
MyClass_foo(mc, *a, b, as);
|
MyClass_foo(mc, a, b, as);
|
||||||
|
MyClass_foo_1(mc, a, b);
|
||||||
|
MyClass_foo_1(mc, a, b);
|
||||||
|
|
||||||
|
MyClass_foo_2(mc, &j, &d);
|
||||||
|
MyClass_foo_2(mc, &j, &d);
|
||||||
|
|
||||||
delete_A(a);
|
delete_A(a);
|
||||||
|
delete_A(b);
|
||||||
delete_MyClass(mc);
|
delete_MyClass(mc);
|
||||||
|
|
||||||
|
for (i = 0; i < 4; ++i)
|
||||||
|
delete_A(as[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
10
Lib/c/c.swg
10
Lib/c/c.swg
|
|
@ -12,25 +12,27 @@
|
||||||
|
|
||||||
%typemap(ctype) void, short, int, long, char, float, double "$1_type"
|
%typemap(ctype) void, short, int, long, char, float, double "$1_type"
|
||||||
%typemap(ctype) void*, short*, int*, long*, char*, float*, double* "$1_type"
|
%typemap(ctype) void*, short*, int*, long*, char*, float*, double* "$1_type"
|
||||||
|
%typemap(ctype) short&, int&, long&, char&, float&, double& "$1_basetype *"
|
||||||
%typemap(ctype) const short, const int, const long, const char, const float, const double "$1_basetype"
|
%typemap(ctype) const short, const int, const long, const char, const float, const double "$1_basetype"
|
||||||
%typemap(ctype) bool "_Bool"
|
%typemap(ctype) bool "_Bool"
|
||||||
%typemap(ctype) SWIGTYPE "$1_type"
|
%typemap(ctype) SWIGTYPE "$1_type"
|
||||||
%typemap(ctype) SWIGTYPE * "$1_type"
|
%typemap(ctype) SWIGTYPE * "$1_type"
|
||||||
%typemap(ctype) SWIGTYPE & "$1_type"
|
%typemap(ctype) SWIGTYPE & "$1_type"
|
||||||
%typemap(ctype) SWIGTYPE * [ANY] "$1_basetype*"
|
%typemap(ctype) SWIGTYPE * [ANY] "$1_basetype*"
|
||||||
%typemap(ctype) SWIGCLASSTYPE "struct Obj$1_type"
|
%typemap(ctype) SWIGCLASSTYPE "struct Obj$1_type *"
|
||||||
%typemap(ctype) SWIGCLASSTYPE * "struct Obj$1_type"
|
%typemap(ctype) SWIGCLASSTYPE * "struct Obj$1_type"
|
||||||
%typemap(ctype) SWIGCLASSTYPE & "struct Obj$1_type"
|
%typemap(ctype) SWIGCLASSTYPE & "struct Obj$*1_ltype *"
|
||||||
%typemap(ctype) SWIGCLASSTYPE * [ANY] "struct Obj$1_basetype*"
|
%typemap(ctype) SWIGCLASSTYPE * [ANY] "struct Obj$1_basetype*"
|
||||||
|
|
||||||
%typemap(in) short, int, long, char, float, double, bool "$1 = ($1_basetype) $input;"
|
%typemap(in) short, int, long, char, float, double, bool "$1 = ($1_basetype) $input;"
|
||||||
%typemap(in) void*, short*, int*, long*, char*, float*, double*, bool* "$1 = ($1_basetype*) $input;"
|
%typemap(in) void*, short*, int*, long*, char*, float*, double*, bool* "$1 = ($1_basetype *) $input;"
|
||||||
|
%typemap(in) short&, int&, long&, char&, float&, double&, bool& "$1 = ($1_basetype *) $input;"
|
||||||
%typemap(in) SWIGTYPE "$1 = ($1_type) $input;"
|
%typemap(in) SWIGTYPE "$1 = ($1_type) $input;"
|
||||||
%typemap(in) SWIGTYPE * "$1 = ($1_type) $input;"
|
%typemap(in) SWIGTYPE * "$1 = ($1_type) $input;"
|
||||||
%typemap(in) SWIGTYPE & "$1 = ($1_type) $input;"
|
%typemap(in) SWIGTYPE & "$1 = ($1_type) $input;"
|
||||||
%typemap(in) SWIGTYPE * [ANY] "$1 = ($1_basetype*) $input;"
|
%typemap(in) SWIGTYPE * [ANY] "$1 = ($1_basetype*) $input;"
|
||||||
%typemap(in) SWIGCLASSTYPE {
|
%typemap(in) SWIGCLASSTYPE {
|
||||||
$1 = * ($1_type *) ($input.obj);
|
$1 = * ($1_type *) ($input->obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
%typemap(in) SWIGCLASSTYPE * {
|
%typemap(in) SWIGCLASSTYPE * {
|
||||||
|
|
|
||||||
|
|
@ -73,6 +73,11 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!CPlusPlus)
|
||||||
|
runtime_flag = false;
|
||||||
|
|
||||||
|
allow_overloading();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------
|
/* ---------------------------------------------------------------------
|
||||||
|
|
@ -114,7 +119,6 @@ public:
|
||||||
Printf(f_header, "}\n\n");
|
Printf(f_header, "}\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// generate shadow files if enabled
|
// generate shadow files if enabled
|
||||||
if (shadow_flag) {
|
if (shadow_flag) {
|
||||||
f_shadow_code_init = NewString("");
|
f_shadow_code_init = NewString("");
|
||||||
|
|
@ -192,8 +196,8 @@ public:
|
||||||
virtual int globalvariableHandler(Node *n) {
|
virtual int globalvariableHandler(Node *n) {
|
||||||
SwigType *type = Getattr(n, "type");
|
SwigType *type = Getattr(n, "type");
|
||||||
String *type_str = SwigType_str(type, 0);
|
String *type_str = SwigType_str(type, 0);
|
||||||
// FIXME
|
//if (!CPlusPlus)
|
||||||
//Printv(f_wrappers, "SWIGEXPORTC ", type_str, " ", Getattr(n, "name"), ";\n", NIL);
|
// Printv(f_wrappers, "SWIGEXPORTC ", type_str, " ", Getattr(n, "name"), ";\n", NIL);
|
||||||
if (shadow_flag) {
|
if (shadow_flag) {
|
||||||
Printv(f_shadow_header, "SWIGIMPORT ", type_str, " ", Getattr(n, "name"), ";\n", NIL);
|
Printv(f_shadow_header, "SWIGIMPORT ", type_str, " ", Getattr(n, "name"), ";\n", NIL);
|
||||||
}
|
}
|
||||||
|
|
@ -230,6 +234,54 @@ public:
|
||||||
return SWIG_OK;
|
return SWIG_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
* prepend_feature()
|
||||||
|
* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
String* prepend_feature(Node *n) {
|
||||||
|
String *prepend_str = Getattr(n, "feature:prepend");
|
||||||
|
if (prepend_str) {
|
||||||
|
char *t = Char(prepend_str);
|
||||||
|
if (*t == '{') {
|
||||||
|
Delitem(prepend_str, 0);
|
||||||
|
Delitem(prepend_str, DOH_END);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (prepend_str ? prepend_str : empty_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
* append_feature()
|
||||||
|
* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
String* append_feature(Node *n) {
|
||||||
|
String *append_str = Getattr(n, "feature:append");
|
||||||
|
if (append_str) {
|
||||||
|
char *t = Char(append_str);
|
||||||
|
if (*t == '{') {
|
||||||
|
Delitem(append_str, 0);
|
||||||
|
Delitem(append_str, DOH_END);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (append_str ? append_str : empty_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------------
|
||||||
|
* getTypeSymbol()
|
||||||
|
*
|
||||||
|
* incomplete for now...
|
||||||
|
* ---------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
const char* getTypeSymbol(String* type) {
|
||||||
|
char* c = Char(type);
|
||||||
|
if (strcmp(c, "int") == 0)
|
||||||
|
return "i";
|
||||||
|
if (strcmp(c, "double") == 0)
|
||||||
|
return "d";
|
||||||
|
|
||||||
|
return "UNKNOWN";
|
||||||
|
}
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------
|
/* ----------------------------------------------------------------------
|
||||||
* functionWrapper()
|
* functionWrapper()
|
||||||
* ---------------------------------------------------------------------- */
|
* ---------------------------------------------------------------------- */
|
||||||
|
|
@ -238,153 +290,199 @@ public:
|
||||||
String *name = Getattr(n, "sym:name");
|
String *name = Getattr(n, "sym:name");
|
||||||
SwigType *type = Getattr(n, "type");
|
SwigType *type = Getattr(n, "type");
|
||||||
SwigType *return_type = NewString("");
|
SwigType *return_type = NewString("");
|
||||||
|
String *wname;
|
||||||
String *arg_names = NewString("");
|
String *arg_names = NewString("");
|
||||||
ParmList *parms = Getattr(n, "parms");
|
ParmList *parms = Getattr(n, "parms");
|
||||||
Parm *p;
|
Parm *p;
|
||||||
String* tm;
|
String *tm;
|
||||||
String* proto = NewString("");
|
String *proto = NewString("");
|
||||||
bool is_void_return;
|
String *over_suffix = NewString("");
|
||||||
|
int gencomma;
|
||||||
|
bool is_void_return = (SwigType_type(Getattr(n, "type")) == T_VOID);
|
||||||
|
|
||||||
// create new function wrapper object
|
// create new function wrapper object
|
||||||
Wrapper *wrapper = NewWrapper();
|
Wrapper *wrapper = NewWrapper();
|
||||||
|
|
||||||
// create new wrapper name
|
if (!CPlusPlus) {
|
||||||
String *wname = Swig_name_wrapper(name);
|
// this is C function, we don't apply typemaps to it
|
||||||
Setattr(n, "wrap:name", wname);
|
|
||||||
|
|
||||||
// attach the standard typemaps
|
// create new wrapper name
|
||||||
emit_attach_parmmaps(parms, wrapper);
|
wname = Swig_name_wrapper(name);
|
||||||
Setattr(n, "wrap:parms", parms);
|
Setattr(n, "wrap:name", wname);
|
||||||
|
|
||||||
// set the return type
|
// create function call
|
||||||
if (Cmp(Getattr(n, "c:objstruct"), "1") == 0) {
|
arg_names = Swig_cfunction_call(empty_string, parms);
|
||||||
Printv(return_type, SwigType_str(type, 0), NIL);
|
if (arg_names) {
|
||||||
}
|
Delitem(arg_names, 0);
|
||||||
else if ((tm = Swig_typemap_lookup("couttype", n, "", 0))) {
|
Delitem(arg_names, DOH_END);
|
||||||
String *ctypeout = Getattr(n, "tmap:ctype:out"); // the type in the ctype typemap's out attribute overrides the type in the typemap
|
}
|
||||||
if (ctypeout)
|
return_type = SwigType_str(Getattr(n, "type"), 0);
|
||||||
tm = ctypeout;
|
|
||||||
Printf(return_type, "%s", tm);
|
// emit wrapper prototype and code
|
||||||
|
gencomma = 0;
|
||||||
|
for (p = parms; p; p = nextSibling(p)) {
|
||||||
|
Printv(proto, gencomma ? ", " : "", SwigType_str(Getattr(p, "type"), 0), " ", Getattr(p, "lname"), NIL);
|
||||||
|
gencomma = 1;
|
||||||
|
}
|
||||||
|
Printv(wrapper->def, return_type, " ", wname, "(", proto, ") {\n", NIL);
|
||||||
|
Append(wrapper->code, prepend_feature(n));
|
||||||
|
if (!is_void_return) {
|
||||||
|
Printv(wrapper->code, return_type, " result;\n", NIL);
|
||||||
|
Printf(wrapper->code, "result = ");
|
||||||
|
}
|
||||||
|
Printv(wrapper->code, name, "(", arg_names, ");\n", NIL);
|
||||||
|
Append(wrapper->code, append_feature(n));
|
||||||
|
if (!is_void_return)
|
||||||
|
Printf(wrapper->code, "return result;\n");
|
||||||
|
Printf(wrapper->code, "}");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Swig_warning(WARN_C_TYPEMAP_CTYPE_UNDEF, input_file, line_number, "No ctype typemap defined for %s\n", SwigType_str(type, 0));
|
// mangle name if functions is overloaded
|
||||||
}
|
if (Getattr(n, "sym:overloaded")) {
|
||||||
|
if (!Getattr(n, "copy_constructor")) {
|
||||||
// attach 'ctype' typemaps
|
if (parms)
|
||||||
Swig_typemap_attach_parms("ctype", parms, wrapper);
|
Append(over_suffix, "_");
|
||||||
|
for (p = parms; p; p = nextSibling(p)) {
|
||||||
// emit variables for holding parameters
|
Append(over_suffix, getTypeSymbol(Getattr(p, "type")));
|
||||||
emit_parameter_variables(parms, wrapper);
|
}
|
||||||
|
Append(name, over_suffix);
|
||||||
// is the function void?
|
}
|
||||||
is_void_return = (SwigType_type(Getattr(n, "type")) == T_VOID);
|
|
||||||
|
|
||||||
// add variable for holding result of original function
|
|
||||||
if (!is_void_return && (Cmp(Getattr(n, "c:objstruct"), "1") != 0)) {
|
|
||||||
if (SwigType_isconst(type))
|
|
||||||
SwigType_del_qualifier(type);
|
|
||||||
Wrapper_add_localv(wrapper, "cppresult", SwigType_str(type, 0), "cppresult", NIL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// create wrapper function prototype
|
|
||||||
Printv(wrapper->def, "SWIGEXPORTC ", return_type, " ", wname, "(", NIL);
|
|
||||||
|
|
||||||
// prepare function definition
|
|
||||||
int gencomma = 0;
|
|
||||||
for (p = parms; p; ) {
|
|
||||||
|
|
||||||
while (checkAttribute(p, "tmap:in:numinputs", "0")) {
|
|
||||||
p = Getattr(p, "tmap:in:next");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SwigType* type = Getattr(p, "type");
|
// create new wrapper name
|
||||||
String* lname = Getattr(p, "lname");
|
wname = Swig_name_wrapper(name);
|
||||||
String* c_parm_type = NewString("");
|
Setattr(n, "wrap:name", wname);
|
||||||
String* shadow_parm_type = NewString("");
|
|
||||||
String* arg_name = NewString("");
|
|
||||||
|
|
||||||
Printf(arg_name, "c%s", lname);
|
// attach the standard typemaps
|
||||||
|
emit_attach_parmmaps(parms, wrapper);
|
||||||
|
Setattr(n, "wrap:parms", parms);
|
||||||
|
|
||||||
// set the appropriate type for parameter
|
// set the return type
|
||||||
if (Cmp(Getattr(p, "c:objstruct"), "1") == 0) {
|
if (Cmp(Getattr(n, "c:objstruct"), "1") == 0) {
|
||||||
Printv(c_parm_type, SwigType_str(type, 0), NIL);
|
Printv(return_type, SwigType_str(type, 0), NIL);
|
||||||
}
|
}
|
||||||
else if ((tm = Getattr(p, "tmap:ctype"))) {
|
else if ((tm = Swig_typemap_lookup("couttype", n, "", 0))) {
|
||||||
Printv(c_parm_type, tm, NIL);
|
String *ctypeout = Getattr(n, "tmap:ctype:out"); // the type in the ctype typemap's out attribute overrides the type in the typemap
|
||||||
|
if (ctypeout)
|
||||||
|
tm = ctypeout;
|
||||||
|
Printf(return_type, "%s", tm);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Swig_warning(WARN_C_TYPEMAP_CTYPE_UNDEF, input_file, line_number, "No ctype typemap defined for %s\n", SwigType_str(type, 0));
|
Swig_warning(WARN_C_TYPEMAP_CTYPE_UNDEF, input_file, line_number, "No ctype typemap defined for %s\n", SwigType_str(type, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
// use shadow-type for parameter if supplied
|
// attach 'ctype' typemaps
|
||||||
String* stype = Getattr(p, "c:stype");
|
Swig_typemap_attach_parms("ctype", parms, wrapper);
|
||||||
if (stype) {
|
|
||||||
Printv(shadow_parm_type, SwigType_str(stype, 0), NIL);
|
// emit variables for holding parameters
|
||||||
}
|
emit_parameter_variables(parms, wrapper);
|
||||||
else {
|
|
||||||
Printv(shadow_parm_type, c_parm_type, NIL);
|
// add variable for holding result of original function
|
||||||
|
if (!is_void_return && (Cmp(Getattr(n, "c:objstruct"), "1") != 0)) {
|
||||||
|
if (SwigType_isconst(type))
|
||||||
|
SwigType_del_qualifier(type);
|
||||||
|
Wrapper_add_localv(wrapper, "cppresult", SwigType_str(type, 0), "cppresult", NIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
Replaceall(c_parm_type, "::", "_");
|
// create wrapper function prototype
|
||||||
|
Printv(wrapper->def, "SWIGEXPORTC ", return_type, " ", wname, "(", NIL);
|
||||||
|
|
||||||
Printv(arg_names, gencomma ? ", " : "", Getattr(p, "name"), NIL);
|
// prepare function definition
|
||||||
Printv(wrapper->def, gencomma ? ", " : "", c_parm_type, " ", arg_name, NIL);
|
gencomma = 0;
|
||||||
Printv(proto, gencomma ? ", " : "", shadow_parm_type, " ", Getattr(p, "name"), NIL);
|
for (p = parms; p; ) {
|
||||||
gencomma = 1;
|
|
||||||
|
|
||||||
// apply typemaps for input parameter
|
while (checkAttribute(p, "tmap:in:numinputs", "0")) {
|
||||||
if ((tm = Getattr(p, "tmap:in"))) {
|
p = Getattr(p, "tmap:in:next");
|
||||||
|
}
|
||||||
|
|
||||||
|
SwigType* type = Getattr(p, "type");
|
||||||
|
String* lname = Getattr(p, "lname");
|
||||||
|
String* c_parm_type = NewString("");
|
||||||
|
String* shadow_parm_type = NewString("");
|
||||||
|
String* arg_name = NewString("");
|
||||||
|
|
||||||
|
Printf(arg_name, "c%s", lname);
|
||||||
|
|
||||||
|
// set the appropriate type for parameter
|
||||||
if (Cmp(Getattr(p, "c:objstruct"), "1") == 0) {
|
if (Cmp(Getattr(p, "c:objstruct"), "1") == 0) {
|
||||||
// FIXME: should work as typemaps for basic types
|
Printv(c_parm_type, SwigType_str(type, 0), NIL);
|
||||||
Printv(wrapper->code, lname, " = ", arg_name, ";\n", NIL);
|
}
|
||||||
|
else if ((tm = Getattr(p, "tmap:ctype"))) {
|
||||||
|
Printv(c_parm_type, tm, NIL);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Replaceall(tm, "$input", arg_name);
|
Swig_warning(WARN_C_TYPEMAP_CTYPE_UNDEF, input_file, line_number, "No ctype typemap defined for %s\n", SwigType_str(type, 0));
|
||||||
Setattr(p, "emit:input", arg_name);
|
}
|
||||||
Printf(wrapper->code, "%s\n", tm);
|
|
||||||
|
// use shadow-type for parameter if supplied
|
||||||
|
String* stype = Getattr(p, "c:stype");
|
||||||
|
if (stype) {
|
||||||
|
Printv(shadow_parm_type, SwigType_str(stype, 0), NIL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Printv(shadow_parm_type, c_parm_type, NIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
Replaceall(c_parm_type, "::", "_");
|
||||||
|
|
||||||
|
Printv(arg_names, gencomma ? ", " : "", Getattr(p, "name"), NIL);
|
||||||
|
Printv(wrapper->def, gencomma ? ", " : "", c_parm_type, " ", arg_name, NIL);
|
||||||
|
Printv(proto, gencomma ? ", " : "", shadow_parm_type, " ", Getattr(p, "name"), NIL);
|
||||||
|
gencomma = 1;
|
||||||
|
|
||||||
|
// apply typemaps for input parameter
|
||||||
|
if ((tm = Getattr(p, "tmap:in"))) {
|
||||||
|
if (Cmp(Getattr(p, "c:objstruct"), "1") == 0) {
|
||||||
|
// FIXME: should work as typemaps for basic types
|
||||||
|
Printv(wrapper->code, lname, " = ", arg_name, ";\n", NIL);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Replaceall(tm, "$input", arg_name);
|
||||||
|
Setattr(p, "emit:input", arg_name);
|
||||||
|
Printf(wrapper->code, "%s\n", tm);
|
||||||
|
}
|
||||||
|
p = Getattr(p, "tmap:in:next");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(type, 0));
|
||||||
|
p = nextSibling(p);
|
||||||
|
}
|
||||||
|
Delete(arg_name);
|
||||||
|
Delete(shadow_parm_type);
|
||||||
|
Delete(c_parm_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
Printf(wrapper->def, ") {");
|
||||||
|
|
||||||
|
// emit variable for holding function return value
|
||||||
|
emit_return_variable(n, return_type, wrapper);
|
||||||
|
|
||||||
|
// emit action code
|
||||||
|
String *action = emit_action(n);
|
||||||
|
Replaceall(action, "$cppresult", "cppresult");
|
||||||
|
|
||||||
|
// emit output typemap if needed
|
||||||
|
if (!is_void_return && (Cmp(Getattr(n, "c:objstruct"), "1") != 0)) {
|
||||||
|
if ((tm = Swig_typemap_lookup_out("out", n, "cppresult", wrapper, action))) {
|
||||||
|
Replaceall(tm, "$result", "result");
|
||||||
|
Printf(wrapper->code, "%s", tm);
|
||||||
|
if (Len(tm))
|
||||||
|
Printf(wrapper->code, "\n");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(type, 0), Getattr(n, "name"));
|
||||||
}
|
}
|
||||||
p = Getattr(p, "tmap:in:next");
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(type, 0));
|
Append(wrapper->code, action);
|
||||||
p = nextSibling(p);
|
|
||||||
}
|
}
|
||||||
Delete(arg_name);
|
|
||||||
Delete(shadow_parm_type);
|
if (!is_void_return)
|
||||||
Delete(c_parm_type);
|
Append(wrapper->code, "return result;\n");
|
||||||
|
|
||||||
|
Append(wrapper->code, "}\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
Printf(wrapper->def, ") {");
|
|
||||||
|
|
||||||
// emit variable for holding function return value
|
|
||||||
emit_return_variable(n, return_type, wrapper);
|
|
||||||
|
|
||||||
// emit action code
|
|
||||||
String *action = emit_action(n);
|
|
||||||
Replaceall(action, "$cppresult", "cppresult");
|
|
||||||
|
|
||||||
// emit output typemap if needed
|
|
||||||
if (!is_void_return && (Cmp(Getattr(n, "c:objstruct"), "1") != 0)) {
|
|
||||||
if ((tm = Swig_typemap_lookup_out("out", n, "cppresult", wrapper, action))) {
|
|
||||||
Replaceall(tm, "$result", "result");
|
|
||||||
Printf(wrapper->code, "%s", tm);
|
|
||||||
if (Len(tm))
|
|
||||||
Printf(wrapper->code, "\n");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(type, 0), Getattr(n, "name"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Append(wrapper->code, action);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_void_return)
|
|
||||||
Append(wrapper->code, "return result;\n");
|
|
||||||
|
|
||||||
Append(wrapper->code, "}\n");
|
|
||||||
Wrapper_print(wrapper, f_wrappers);
|
|
||||||
|
|
||||||
// take care of shadow function
|
// take care of shadow function
|
||||||
if (shadow_flag) {
|
if (shadow_flag) {
|
||||||
// use shadow-type for return type if supplied
|
// use shadow-type for return type if supplied
|
||||||
|
|
@ -397,38 +495,17 @@ public:
|
||||||
Printv(f_shadow_code_init, "extern ", return_type, " ", wname, "(", proto, ");\n", NIL);
|
Printv(f_shadow_code_init, "extern ", return_type, " ", wname, "(", proto, ");\n", NIL);
|
||||||
Printv(f_shadow_code_body, return_type, " ", name, "(", proto, ") {\n", NIL);
|
Printv(f_shadow_code_body, return_type, " ", name, "(", proto, ") {\n", NIL);
|
||||||
|
|
||||||
// handle 'prepend' feature
|
|
||||||
String *prepend_str = Getattr(n, "feature:prepend");
|
|
||||||
if (prepend_str) {
|
|
||||||
char *t = Char(prepend_str);
|
|
||||||
if (*t == '{') {
|
|
||||||
Delitem(prepend_str, 0);
|
|
||||||
Delitem(prepend_str, DOH_END);
|
|
||||||
}
|
|
||||||
Printv(f_shadow_code_body, prepend_str, "\n", NIL);
|
|
||||||
}
|
|
||||||
|
|
||||||
// call to the wrapper function
|
// call to the wrapper function
|
||||||
Printv(f_shadow_code_body, " return ", wname, "(", arg_names, ");\n", NIL);
|
Printv(f_shadow_code_body, " return ", wname, "(", arg_names, ");\n}\n", NIL);
|
||||||
|
|
||||||
// handle 'append' feature
|
|
||||||
String *append_str = Getattr(n, "feature:append");
|
|
||||||
if (append_str) {
|
|
||||||
char *t = Char(append_str);
|
|
||||||
if (*t == '{') {
|
|
||||||
Delitem(append_str, 0);
|
|
||||||
Delitem(append_str, DOH_END);
|
|
||||||
}
|
|
||||||
Printv(f_shadow_code_body, append_str, "\n", NIL);
|
|
||||||
}
|
|
||||||
|
|
||||||
Printv(f_shadow_code_body, "}\n", NIL);
|
|
||||||
|
|
||||||
// add function declaration to the proxy header file
|
// add function declaration to the proxy header file
|
||||||
Printv(f_shadow_header, return_type, " ", name, "(", proto, ");\n");
|
Printv(f_shadow_header, return_type, " ", name, "(", proto, ");\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Wrapper_print(wrapper, f_wrappers);
|
||||||
|
|
||||||
// cleanup
|
// cleanup
|
||||||
|
Delete(over_suffix);
|
||||||
Delete(proto);
|
Delete(proto);
|
||||||
Delete(arg_names);
|
Delete(arg_names);
|
||||||
Delete(wname);
|
Delete(wname);
|
||||||
|
|
@ -471,6 +548,21 @@ public:
|
||||||
return new_node;
|
return new_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ---------------------------------------------------------------------
|
||||||
|
* copy_node()
|
||||||
|
*
|
||||||
|
* tests if given name already exists in one of child nodes of n
|
||||||
|
* --------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
bool is_in(String* name, Node* n) {
|
||||||
|
Hash* h;
|
||||||
|
for (h = firstChild(n); h; h = nextSibling(h)) {
|
||||||
|
if (Cmp(name, Getattr(h, "name")) == 0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------
|
/* ---------------------------------------------------------------------
|
||||||
* classHandler()
|
* classHandler()
|
||||||
* --------------------------------------------------------------------- */
|
* --------------------------------------------------------------------- */
|
||||||
|
|
@ -481,43 +573,76 @@ public:
|
||||||
List* baselist = Getattr(n, "bases");
|
List* baselist = Getattr(n, "bases");
|
||||||
Replaceall(name, "::", "_");
|
Replaceall(name, "::", "_");
|
||||||
|
|
||||||
// inheritance support: attach all members from base classes to this class
|
if (CPlusPlus) {
|
||||||
if (baselist) {
|
// inheritance support: attach all members from base classes to this class
|
||||||
Iterator i;
|
if (baselist) {
|
||||||
for (i = First(baselist); i.item; i = Next(i)) {
|
Iterator i;
|
||||||
// look for member variables (TODO: support for other constructs)
|
for (i = First(baselist); i.item; i = Next(i)) {
|
||||||
Node* node;
|
// look for member variables and functions
|
||||||
for (node = firstChild(i.item); node; node = nextSibling(node)) {
|
Node* node;
|
||||||
if ((Cmp(Getattr(node, "kind"), "variable") == 0)
|
for (node = firstChild(i.item); node; node = nextSibling(node)) {
|
||||||
&& (Cmp(Getattr(node, "access"), "private") != 0)
|
if ((Cmp(Getattr(node, "kind"), "variable") == 0)
|
||||||
&& (Cmp(Getattr(node, "storage"), "static") != 0)) {
|
|| (Cmp(Getattr(node, "kind"), "function") == 0)) {
|
||||||
Node* new_node = copy_node(node);
|
if ((Cmp(Getattr(node, "access"), "public") == 0)
|
||||||
Setattr(new_node, "sym:name", Getattr(new_node, "name"));
|
&& (Cmp(Getattr(node, "storage"), "static") != 0)) {
|
||||||
set_nodeType(new_node, "cdecl");
|
if (!is_in(Getattr(node, "name"), n)) {
|
||||||
appendChild(n, new_node);
|
Node* new_node = copy_node(node);
|
||||||
|
Setattr(new_node, "sym:name", Getattr(new_node, "name"));
|
||||||
|
set_nodeType(new_node, "cdecl");
|
||||||
|
// make sure there are no copyied object-structs params
|
||||||
|
ParmList* all_parms = Getattr(new_node, "parms"), * parms;
|
||||||
|
if (Getattr(all_parms, "c:objstruct")) {
|
||||||
|
parms = Copy(nextSibling(all_parms));
|
||||||
|
Delete(all_parms);
|
||||||
|
Setattr(new_node, "parms", parms);
|
||||||
|
}
|
||||||
|
appendChild(n, new_node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// emit "class"-struct definition
|
||||||
|
Printv(sobj, "struct Obj", name, " {\n void* obj;\n", NIL);
|
||||||
|
if (runtime_flag)
|
||||||
|
Printf(sobj, " const char* typenames[%d];\n}", Len(baselist) + 2);
|
||||||
|
else
|
||||||
|
Printf(sobj, "};\n\n");
|
||||||
|
|
||||||
|
Printv(f_header, sobj, ";\n\n", NIL);
|
||||||
|
Printv(f_header, "const char* __typename_", name, " = \"", name, "\";\n\n", NIL);
|
||||||
|
|
||||||
|
// declare it in the proxy header
|
||||||
|
if (shadow_flag)
|
||||||
|
Printv(f_shadow_header, "typedef ", sobj, " ", name, ";\n\n", NIL);
|
||||||
|
|
||||||
|
Delete(sobj);
|
||||||
|
Delete(name);
|
||||||
|
return Language::classHandler(n);
|
||||||
}
|
}
|
||||||
|
else if (Cmp(Getattr(n, "kind"), "struct") == 0) {
|
||||||
|
// this is C struct, just declare it in proxy
|
||||||
|
if (shadow_flag) {
|
||||||
|
Printv(f_shadow_header, "struct ", name, " {\n", NIL);
|
||||||
|
Node* node;
|
||||||
|
for (node = firstChild(n); node; node = nextSibling(node)) {
|
||||||
|
String* kind = Getattr(node, "kind");
|
||||||
|
if ((Cmp(kind, "variable") == 0) || (Cmp(kind, "function") == 0)) {
|
||||||
|
String* type = NewString("");
|
||||||
|
Printv(type, Getattr(node, "decl"), Getattr(node, "type"), NIL);
|
||||||
|
Printv(f_shadow_header, " ", SwigType_str(type, 0), " ", Getattr(node, "name"), ";\n", NIL);
|
||||||
|
Delete(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Append(f_shadow_header, "};\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
// emit "class"-struct definition
|
Delete(sobj);
|
||||||
Printv(sobj, "struct Obj", name, " {\n void* obj;\n", NIL);
|
Delete(name);
|
||||||
if (runtime_flag)
|
|
||||||
Printf(sobj, " const char* typenames[%d];\n}", Len(baselist) + 2);
|
|
||||||
else
|
|
||||||
Printf(sobj, "};\n\n");
|
|
||||||
|
|
||||||
Printv(f_header, sobj, ";\n\n", NIL);
|
|
||||||
Printv(f_header, "const char* __typename_", name, " = \"", name, "\";\n\n", NIL);
|
|
||||||
|
|
||||||
// declare it in the proxy header
|
|
||||||
if (shadow_flag) {
|
|
||||||
Printv(f_shadow_header, "typedef ", sobj, " ", name, ";\n\n", NIL);
|
|
||||||
}
|
}
|
||||||
|
return SWIG_OK;
|
||||||
Delete(sobj);
|
|
||||||
Delete(name);
|
|
||||||
return Language::classHandler(n);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------
|
/* ---------------------------------------------------------------------
|
||||||
|
|
@ -594,7 +719,9 @@ public:
|
||||||
Append(arg_lnames, Swig_cfunction_call(empty_string, parms));
|
Append(arg_lnames, Swig_cfunction_call(empty_string, parms));
|
||||||
|
|
||||||
// omit first argument in method call
|
// omit first argument in method call
|
||||||
String* arg_call_lnames = Strstr(arg_lnames, "arg2");
|
String* arg_call_lnames = Strstr(arg_lnames, "*arg2");
|
||||||
|
if (!arg_call_lnames)
|
||||||
|
arg_call_lnames = Strstr(arg_lnames, "arg2");
|
||||||
if (!arg_call_lnames)
|
if (!arg_call_lnames)
|
||||||
arg_call_lnames = empty_string;
|
arg_call_lnames = empty_string;
|
||||||
else
|
else
|
||||||
|
|
@ -795,6 +922,9 @@ public:
|
||||||
* --------------------------------------------------------------------- */
|
* --------------------------------------------------------------------- */
|
||||||
|
|
||||||
virtual int constructorHandler(Node* n) {
|
virtual int constructorHandler(Node* n) {
|
||||||
|
if (Getattr(n, "copy_constructor"))
|
||||||
|
return copyconstructorHandler(n);
|
||||||
|
|
||||||
String* classname = Getattr(parentNode(n), "name");
|
String* classname = Getattr(parentNode(n), "name");
|
||||||
String* newclassname = Copy(classname);
|
String* newclassname = Copy(classname);
|
||||||
String* sobj_name = NewString("");
|
String* sobj_name = NewString("");
|
||||||
|
|
@ -822,6 +952,7 @@ public:
|
||||||
|
|
||||||
// modify the constructor name
|
// modify the constructor name
|
||||||
Printv(constr_name, "new_", newclassname, NIL);
|
Printv(constr_name, "new_", newclassname, NIL);
|
||||||
|
Setattr(n, "name", constr_name);
|
||||||
Setattr(n, "sym:name", constr_name);
|
Setattr(n, "sym:name", constr_name);
|
||||||
|
|
||||||
// generate action code
|
// generate action code
|
||||||
|
|
@ -873,6 +1004,7 @@ public:
|
||||||
|
|
||||||
// modify the constructor name
|
// modify the constructor name
|
||||||
Printv(constr_name, "copy_", newclassname, NIL);
|
Printv(constr_name, "copy_", newclassname, NIL);
|
||||||
|
Setattr(n, "name", constr_name);
|
||||||
Setattr(n, "sym:name", constr_name);
|
Setattr(n, "sym:name", constr_name);
|
||||||
|
|
||||||
// generate action code
|
// generate action code
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue