More %ignore director fixes
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@9370 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
parent
d6c5455edc
commit
95958855cf
7 changed files with 787 additions and 710 deletions
|
|
@ -12,6 +12,14 @@
|
||||||
%ignore DIgnoreOnlyConstructor(bool b);
|
%ignore DIgnoreOnlyConstructor(bool b);
|
||||||
%ignore Pointers;
|
%ignore Pointers;
|
||||||
%ignore References;
|
%ignore References;
|
||||||
|
%ignore PublicMethod1;
|
||||||
|
%ignore PublicMethod2;
|
||||||
|
%ignore PublicPureVirtualMethod1;
|
||||||
|
%ignore PublicPureVirtualMethod2;
|
||||||
|
%ignore ProtectedMethod1;
|
||||||
|
%ignore ProtectedMethod2;
|
||||||
|
%ignore ProtectedPureVirtualMethod1;
|
||||||
|
%ignore ProtectedPureVirtualMethod2;
|
||||||
|
|
||||||
%inline %{
|
%inline %{
|
||||||
|
|
||||||
|
|
@ -25,9 +33,18 @@ class DIgnores
|
||||||
virtual int Triple(int n) { return n*3; }
|
virtual int Triple(int n) { return n*3; }
|
||||||
virtual int& References(int& n) { static int nn; nn=n; return nn; }
|
virtual int& References(int& n) { static int nn; nn=n; return nn; }
|
||||||
virtual int* Pointers(int* n) { static int nn; nn=*n; return &nn; }
|
virtual int* Pointers(int* n) { static int nn; nn=*n; return &nn; }
|
||||||
|
virtual double PublicMethod1() {}
|
||||||
|
virtual double PublicPureVirtualMethod1() = 0;
|
||||||
|
virtual void PublicMethod2() {}
|
||||||
|
virtual void PublicPureVirtualMethod2() = 0;
|
||||||
|
virtual void TempMethod() = 0;
|
||||||
protected:
|
protected:
|
||||||
virtual void OverloadedProtectedMethod(int n, int xoffset = 0, int yoffset = 0) {}
|
virtual void OverloadedProtectedMethod(int n, int xoffset = 0, int yoffset = 0) {}
|
||||||
virtual void OverloadedProtectedMethod() {}
|
virtual void OverloadedProtectedMethod() {}
|
||||||
|
virtual double ProtectedMethod1() {}
|
||||||
|
virtual double ProtectedPureVirtualMethod1() = 0;
|
||||||
|
virtual void ProtectedMethod2() {}
|
||||||
|
virtual void ProtectedPureVirtualMethod2() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DAbstractIgnores
|
class DAbstractIgnores
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,15 @@ namespace Swig {
|
||||||
class DirectorMethodException : public Swig::DirectorException {};
|
class DirectorMethodException : public Swig::DirectorException {};
|
||||||
|
|
||||||
/* attempt to call a pure virtual method via a director method */
|
/* attempt to call a pure virtual method via a director method */
|
||||||
class DirectorPureVirtualException : public Swig::DirectorException {};
|
class DirectorPureVirtualException : public Swig::DirectorException {
|
||||||
|
public:
|
||||||
|
DirectorTypeMismatchException(const char* msg="") {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void raise(const char *msg) {
|
||||||
|
throw DirectorPureVirtualException(msg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/* simple thread abstraction for pthreads on win32 */
|
/* simple thread abstraction for pthreads on win32 */
|
||||||
#ifdef __THREAD__
|
#ifdef __THREAD__
|
||||||
|
|
|
||||||
|
|
@ -3118,14 +3118,14 @@ class CSHARP : public Language {
|
||||||
Printf(w->code, "if (!swig_callback%s) {\n", overloaded_name);
|
Printf(w->code, "if (!swig_callback%s) {\n", overloaded_name);
|
||||||
|
|
||||||
if (!pure_virtual) {
|
if (!pure_virtual) {
|
||||||
|
String *super_call = Swig_method_call(super, l);
|
||||||
if (is_void) {
|
if (is_void) {
|
||||||
Printf(w->code, "%s;\n", Swig_method_call(super,l));
|
Printf(w->code, "%s;\n", super_call);
|
||||||
Printf(w->code, "return;\n");
|
Printf(w->code, "return;\n");
|
||||||
} else {
|
} else {
|
||||||
String *super_call = Swig_method_call(super, l);
|
|
||||||
Printf(w->code, "return %s;\n", super_call);
|
Printf(w->code, "return %s;\n", super_call);
|
||||||
Delete(super_call);
|
|
||||||
}
|
}
|
||||||
|
Delete(super_call);
|
||||||
} else {
|
} else {
|
||||||
Printf(w->code, " throw Swig::DirectorPureVirtualException(\"%s::%s\");\n", c_classname, name);
|
Printf(w->code, " throw Swig::DirectorPureVirtualException(\"%s::%s\");\n", c_classname, name);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3196,14 +3196,14 @@ class JAVA : public Language {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pure_virtual) {
|
if (!pure_virtual) {
|
||||||
|
String *super_call = Swig_method_call(super, l);
|
||||||
if (is_void) {
|
if (is_void) {
|
||||||
Printf(w->code, "%s;\n", Swig_method_call(super,l));
|
Printf(w->code, "%s;\n", super_call);
|
||||||
Printf(w->code, "return;\n");
|
Printf(w->code, "return;\n");
|
||||||
} else {
|
} else {
|
||||||
String *super_call = Swig_method_call(super, l);
|
|
||||||
Printf(w->code, "return %s;\n", super_call);
|
Printf(w->code, "return %s;\n", super_call);
|
||||||
Delete(super_call);
|
|
||||||
}
|
}
|
||||||
|
Delete(super_call);
|
||||||
} else {
|
} else {
|
||||||
Printf(w->code, "SWIG_JavaThrowException(JNIEnvWrapper(this).getJNIEnv(), SWIG_JavaDirectorPureVirtual, ");
|
Printf(w->code, "SWIG_JavaThrowException(JNIEnvWrapper(this).getJNIEnv(), SWIG_JavaDirectorPureVirtual, ");
|
||||||
Printf(w->code, "\"Attempted to invoke pure virtual method %s::%s.\");\n", c_classname, name);
|
Printf(w->code, "\"Attempted to invoke pure virtual method %s::%s.\");\n", c_classname, name);
|
||||||
|
|
|
||||||
|
|
@ -1490,11 +1490,12 @@ public:
|
||||||
ParmList *l;
|
ParmList *l;
|
||||||
Wrapper *w;
|
Wrapper *w;
|
||||||
String *tm;
|
String *tm;
|
||||||
String *wrap_args;
|
String *wrap_args = NewString("");
|
||||||
String *return_type;
|
String *return_type;
|
||||||
int status = SWIG_OK;
|
int status = SWIG_OK;
|
||||||
int idx;
|
int idx;
|
||||||
bool pure_virtual = false;
|
bool pure_virtual = false;
|
||||||
|
bool ignored_method = GetFlag(n, "feature:ignore") ? true : false;
|
||||||
|
|
||||||
storage = Getattr(n, "storage");
|
storage = Getattr(n, "storage");
|
||||||
value = Getattr(n, "value");
|
value = Getattr(n, "value");
|
||||||
|
|
@ -1545,205 +1546,223 @@ public:
|
||||||
Printf(declaration, " virtual %s %s;\n", rtype, target);
|
Printf(declaration, " virtual %s %s;\n", rtype, target);
|
||||||
Delete(target);
|
Delete(target);
|
||||||
|
|
||||||
/* attach typemaps to arguments (C/C++ -> Ocaml) */
|
|
||||||
String *arglist = NewString("");
|
|
||||||
|
|
||||||
Swig_typemap_attach_parms("in", l, 0);
|
|
||||||
Swig_typemap_attach_parms("directorin", l, 0);
|
|
||||||
Swig_typemap_attach_parms("directorargout", l, w);
|
|
||||||
|
|
||||||
Parm* p;
|
|
||||||
int num_arguments = emit_num_arguments(l);
|
|
||||||
int i;
|
|
||||||
char source[256];
|
|
||||||
|
|
||||||
wrap_args = NewString("");
|
|
||||||
int outputs = 0;
|
|
||||||
if (!is_void) outputs++;
|
|
||||||
|
|
||||||
/* build argument list and type conversion string */
|
|
||||||
for (i=0, idx=0, p = l; i < num_arguments; i++) {
|
|
||||||
|
|
||||||
while (Getattr(p, "tmap:ignore")) {
|
|
||||||
p = Getattr(p, "tmap:ignore:next");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Getattr(p, "tmap:directorargout") != 0) outputs++;
|
|
||||||
|
|
||||||
String* pname = Getattr(p, "name");
|
|
||||||
String* ptype = Getattr(p, "type");
|
|
||||||
|
|
||||||
Putc(',',arglist);
|
|
||||||
if ((tm = Getattr(p, "tmap:directorin")) != 0) {
|
|
||||||
Replaceall(tm, "$input", pname);
|
|
||||||
Replaceall(tm, "$owner", "0");
|
|
||||||
if (Len(tm) == 0) Append(tm, pname);
|
|
||||||
Printv(wrap_args, tm, "\n", NIL);
|
|
||||||
p = Getattr(p, "tmap:directorin:next");
|
|
||||||
continue;
|
|
||||||
} else
|
|
||||||
if (Cmp(ptype, "void")) {
|
|
||||||
/* special handling for pointers to other C++ director classes.
|
|
||||||
* ideally this would be left to a typemap, but there is currently no
|
|
||||||
* way to selectively apply the dynamic_cast<> to classes that have
|
|
||||||
* directors. in other words, the type "SwigDirector_$1_lname" only exists
|
|
||||||
* for classes with directors. we avoid the problem here by checking
|
|
||||||
* module.wrap::directormap, but it's not clear how to get a typemap to
|
|
||||||
* do something similar. perhaps a new default typemap (in addition
|
|
||||||
* to SWIGTYPE) called DIRECTORTYPE?
|
|
||||||
*/
|
|
||||||
if (SwigType_ispointer(ptype) || SwigType_isreference(ptype)) {
|
|
||||||
Node *module = Getattr(parent, "module");
|
|
||||||
Node *target = Swig_directormap(module, ptype);
|
|
||||||
sprintf(source, "obj%d", idx++);
|
|
||||||
String *nonconst = 0;
|
|
||||||
/* strip pointer/reference --- should move to Swig/stype.c */
|
|
||||||
String *nptype = NewString(Char(ptype)+2);
|
|
||||||
/* name as pointer */
|
|
||||||
String *ppname = Copy(pname);
|
|
||||||
if (SwigType_isreference(ptype)) {
|
|
||||||
Insert(ppname,0,"&");
|
|
||||||
}
|
|
||||||
/* if necessary, cast away const since Python doesn't support it! */
|
|
||||||
if (SwigType_isconst(nptype)) {
|
|
||||||
nonconst = NewStringf("nc_tmp_%s", pname);
|
|
||||||
String *nonconst_i = NewStringf("= const_cast<%s>(%s)", SwigType_lstr(ptype, 0), ppname);
|
|
||||||
Wrapper_add_localv(w, nonconst, SwigType_lstr(ptype, 0), nonconst, nonconst_i, NIL);
|
|
||||||
Delete(nonconst_i);
|
|
||||||
Swig_warning(WARN_LANG_DISCARD_CONST, input_file, line_number,
|
|
||||||
"Target language argument '%s' discards const in director method %s::%s.\n", SwigType_str(ptype, pname), classname, name);
|
|
||||||
} else {
|
|
||||||
nonconst = Copy(ppname);
|
|
||||||
}
|
|
||||||
Delete(nptype);
|
|
||||||
Delete(ppname);
|
|
||||||
String *mangle = SwigType_manglestr(ptype);
|
|
||||||
if (target) {
|
|
||||||
String *director = NewStringf("director_%s", mangle);
|
|
||||||
Wrapper_add_localv(w, director, "Swig::Director *", director, "= 0", NIL);
|
|
||||||
Wrapper_add_localv(w, source, "CAML_VALUE", source, "= Val_unit", NIL);
|
|
||||||
Printf(wrap_args, "%s = dynamic_cast<Swig::Director *>(%s);\n", director, nonconst);
|
|
||||||
Printf(wrap_args, "if (!%s) {\n", director);
|
|
||||||
Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
|
|
||||||
Printf(wrap_args, "} else {\n");
|
|
||||||
Printf(wrap_args, "%s = %s->swig_get_self();\n", source, director);
|
|
||||||
Printf(wrap_args, "}\n");
|
|
||||||
Delete(director);
|
|
||||||
Printv(arglist, source, NIL);
|
|
||||||
} else {
|
|
||||||
Wrapper_add_localv(w, source, "CAML_VALUE", source, "= Val_unit", NIL);
|
|
||||||
Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n",
|
|
||||||
source, nonconst, mangle);
|
|
||||||
//Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE_p_%s, 0);\n",
|
|
||||||
// source, nonconst, base);
|
|
||||||
Printv(arglist, source, NIL);
|
|
||||||
}
|
|
||||||
Delete(mangle);
|
|
||||||
Delete(nonconst);
|
|
||||||
} else {
|
|
||||||
Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
|
|
||||||
"Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0), classname, name);
|
|
||||||
status = SWIG_NOWRAP;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p = nextSibling(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* declare method return value
|
/* declare method return value
|
||||||
* if the return value is a reference or const reference, a specialized typemap must
|
* if the return value is a reference or const reference, a specialized typemap must
|
||||||
* handle it, including declaration of c_result ($result).
|
* handle it, including declaration of c_result ($result).
|
||||||
*/
|
*/
|
||||||
if (!is_void) {
|
if (!is_void) {
|
||||||
|
if (!(ignored_method && !pure_virtual)) {
|
||||||
Wrapper_add_localv(w, "c_result", SwigType_lstr(return_type, "c_result"), NIL);
|
Wrapper_add_localv(w, "c_result", SwigType_lstr(return_type, "c_result"), NIL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Printv(w->code, "swig_result = Val_unit;\n",0);
|
if (ignored_method) {
|
||||||
Printf(w->code,"args = Val_unit;\n");
|
if (!pure_virtual) {
|
||||||
|
if (is_void)
|
||||||
|
Printf(w->code, "return ");
|
||||||
|
String *super_call = Swig_method_call(super, l);
|
||||||
|
Printf(w->code, "%s;\n", super_call);
|
||||||
|
Delete(super_call);
|
||||||
|
} else {
|
||||||
|
Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", classname, name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* attach typemaps to arguments (C/C++ -> Ocaml) */
|
||||||
|
String *arglist = NewString("");
|
||||||
|
|
||||||
/* wrap complex arguments to values */
|
Swig_typemap_attach_parms("in", l, 0);
|
||||||
Printv(w->code, wrap_args, NIL);
|
Swig_typemap_attach_parms("directorin", l, 0);
|
||||||
|
Swig_typemap_attach_parms("directorargout", l, w);
|
||||||
|
|
||||||
/* pass the method call on to the Python object */
|
Parm* p;
|
||||||
Printv(w->code,
|
int num_arguments = emit_num_arguments(l);
|
||||||
"swig_result = caml_swig_alloc(1,C_list);\n"
|
int i;
|
||||||
"SWIG_Store_field(swig_result,0,args);\n"
|
char source[256];
|
||||||
"args = swig_result;\n"
|
|
||||||
"swig_result = Val_unit;\n",0);
|
|
||||||
Printf(w->code,
|
|
||||||
"swig_result = "
|
|
||||||
"callback3(*caml_named_value(\"swig_runmethod\"),"
|
|
||||||
"swig_get_self(),copy_string(\"%s\"),args);\n",
|
|
||||||
Getattr(n,"name"));
|
|
||||||
/* exception handling */
|
|
||||||
tm = Swig_typemap_lookup_new("director:except", n, "result", 0);
|
|
||||||
if (!tm) {
|
|
||||||
tm = Getattr(n, "feature:director:except");
|
|
||||||
}
|
|
||||||
if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) {
|
|
||||||
Printf(w->code, "if (result == NULL) {\n");
|
|
||||||
Printf(w->code, " CAML_VALUE error = *caml_named_value(\"director_except\");\n");
|
|
||||||
Replaceall(tm, "$error", "error");
|
|
||||||
Printv(w->code, Str(tm), "\n", NIL);
|
|
||||||
Printf(w->code, "}\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
int outputs = 0;
|
||||||
* Python method may return a simple object, or a tuple.
|
if (!is_void) outputs++;
|
||||||
* for in/out aruments, we have to extract the appropriate values from the
|
|
||||||
* argument list, then marshal everything back to C/C++ (return value and
|
|
||||||
* output arguments).
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* marshal return value and other outputs (if any) from value to C/C++
|
/* build argument list and type conversion string */
|
||||||
* type */
|
for (i=0, idx=0, p = l; i < num_arguments; i++) {
|
||||||
|
|
||||||
String* cleanup = NewString("");
|
while (Getattr(p, "tmap:ignore")) {
|
||||||
String* outarg = NewString("");
|
p = Getattr(p, "tmap:ignore:next");
|
||||||
|
}
|
||||||
|
|
||||||
idx = 0;
|
if (Getattr(p, "tmap:directorargout") != 0) outputs++;
|
||||||
|
|
||||||
|
String* pname = Getattr(p, "name");
|
||||||
|
String* ptype = Getattr(p, "type");
|
||||||
|
|
||||||
|
Putc(',',arglist);
|
||||||
|
if ((tm = Getattr(p, "tmap:directorin")) != 0) {
|
||||||
|
Replaceall(tm, "$input", pname);
|
||||||
|
Replaceall(tm, "$owner", "0");
|
||||||
|
if (Len(tm) == 0) Append(tm, pname);
|
||||||
|
Printv(wrap_args, tm, "\n", NIL);
|
||||||
|
p = Getattr(p, "tmap:directorin:next");
|
||||||
|
continue;
|
||||||
|
} else
|
||||||
|
if (Cmp(ptype, "void")) {
|
||||||
|
/* special handling for pointers to other C++ director classes.
|
||||||
|
* ideally this would be left to a typemap, but there is currently no
|
||||||
|
* way to selectively apply the dynamic_cast<> to classes that have
|
||||||
|
* directors. in other words, the type "SwigDirector_$1_lname" only exists
|
||||||
|
* for classes with directors. we avoid the problem here by checking
|
||||||
|
* module.wrap::directormap, but it's not clear how to get a typemap to
|
||||||
|
* do something similar. perhaps a new default typemap (in addition
|
||||||
|
* to SWIGTYPE) called DIRECTORTYPE?
|
||||||
|
*/
|
||||||
|
if (SwigType_ispointer(ptype) || SwigType_isreference(ptype)) {
|
||||||
|
Node *module = Getattr(parent, "module");
|
||||||
|
Node *target = Swig_directormap(module, ptype);
|
||||||
|
sprintf(source, "obj%d", idx++);
|
||||||
|
String *nonconst = 0;
|
||||||
|
/* strip pointer/reference --- should move to Swig/stype.c */
|
||||||
|
String *nptype = NewString(Char(ptype)+2);
|
||||||
|
/* name as pointer */
|
||||||
|
String *ppname = Copy(pname);
|
||||||
|
if (SwigType_isreference(ptype)) {
|
||||||
|
Insert(ppname,0,"&");
|
||||||
|
}
|
||||||
|
/* if necessary, cast away const since Python doesn't support it! */
|
||||||
|
if (SwigType_isconst(nptype)) {
|
||||||
|
nonconst = NewStringf("nc_tmp_%s", pname);
|
||||||
|
String *nonconst_i = NewStringf("= const_cast<%s>(%s)", SwigType_lstr(ptype, 0), ppname);
|
||||||
|
Wrapper_add_localv(w, nonconst, SwigType_lstr(ptype, 0), nonconst, nonconst_i, NIL);
|
||||||
|
Delete(nonconst_i);
|
||||||
|
Swig_warning(WARN_LANG_DISCARD_CONST, input_file, line_number,
|
||||||
|
"Target language argument '%s' discards const in director method %s::%s.\n", SwigType_str(ptype, pname), classname, name);
|
||||||
|
} else {
|
||||||
|
nonconst = Copy(ppname);
|
||||||
|
}
|
||||||
|
Delete(nptype);
|
||||||
|
Delete(ppname);
|
||||||
|
String *mangle = SwigType_manglestr(ptype);
|
||||||
|
if (target) {
|
||||||
|
String *director = NewStringf("director_%s", mangle);
|
||||||
|
Wrapper_add_localv(w, director, "Swig::Director *", director, "= 0", NIL);
|
||||||
|
Wrapper_add_localv(w, source, "CAML_VALUE", source, "= Val_unit", NIL);
|
||||||
|
Printf(wrap_args, "%s = dynamic_cast<Swig::Director *>(%s);\n", director, nonconst);
|
||||||
|
Printf(wrap_args, "if (!%s) {\n", director);
|
||||||
|
Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
|
||||||
|
Printf(wrap_args, "} else {\n");
|
||||||
|
Printf(wrap_args, "%s = %s->swig_get_self();\n", source, director);
|
||||||
|
Printf(wrap_args, "}\n");
|
||||||
|
Delete(director);
|
||||||
|
Printv(arglist, source, NIL);
|
||||||
|
} else {
|
||||||
|
Wrapper_add_localv(w, source, "CAML_VALUE", source, "= Val_unit", NIL);
|
||||||
|
Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n",
|
||||||
|
source, nonconst, mangle);
|
||||||
|
//Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE_p_%s, 0);\n",
|
||||||
|
// source, nonconst, base);
|
||||||
|
Printv(arglist, source, NIL);
|
||||||
|
}
|
||||||
|
Delete(mangle);
|
||||||
|
Delete(nonconst);
|
||||||
|
} else {
|
||||||
|
Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
|
||||||
|
"Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0), classname, name);
|
||||||
|
status = SWIG_NOWRAP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p = nextSibling(p);
|
||||||
|
}
|
||||||
|
|
||||||
/* this seems really silly. the node's type excludes
|
Printv(w->code, "swig_result = Val_unit;\n",0);
|
||||||
* qualifier/pointer/reference markers, which have to be retrieved
|
Printf(w->code,"args = Val_unit;\n");
|
||||||
* from the decl field to construct return_type. but the typemap
|
|
||||||
* lookup routine uses the node's type, so we have to swap in and
|
/* wrap complex arguments to values */
|
||||||
* out the correct type. it's not just me, similar silliness also
|
Printv(w->code, wrap_args, NIL);
|
||||||
* occurs in Language::cDeclaration().
|
|
||||||
*/
|
/* pass the method call on to the Python object */
|
||||||
Setattr(n, "type", return_type);
|
Printv(w->code,
|
||||||
tm = Swig_typemap_lookup_new("directorout", n, "c_result", w);
|
"swig_result = caml_swig_alloc(1,C_list);\n"
|
||||||
Setattr(n, "type", type);
|
"SWIG_Store_field(swig_result,0,args);\n"
|
||||||
if (tm == 0) {
|
"args = swig_result;\n"
|
||||||
String *name = NewString("c_result");
|
"swig_result = Val_unit;\n",0);
|
||||||
tm = Swig_typemap_search("directorout", return_type, name, NULL);
|
Printf(w->code,
|
||||||
Delete(name);
|
"swig_result = "
|
||||||
}
|
"callback3(*caml_named_value(\"swig_runmethod\"),"
|
||||||
if (tm != 0) {
|
"swig_get_self(),copy_string(\"%s\"),args);\n",
|
||||||
Replaceall(tm, "$input", "swig_result");
|
Getattr(n,"name"));
|
||||||
/* TODO check this */
|
/* exception handling */
|
||||||
if (Getattr(n,"wrap:disown")) {
|
tm = Swig_typemap_lookup_new("director:except", n, "result", 0);
|
||||||
Replaceall(tm,"$disown","SWIG_POINTER_DISOWN");
|
if (!tm) {
|
||||||
} else {
|
tm = Getattr(n, "feature:director:except");
|
||||||
Replaceall(tm,"$disown","0");
|
}
|
||||||
}
|
if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) {
|
||||||
Replaceall(tm, "$result", "c_result");
|
Printf(w->code, "if (result == NULL) {\n");
|
||||||
Printv(w->code, tm, "\n", NIL);
|
Printf(w->code, " CAML_VALUE error = *caml_named_value(\"director_except\");\n");
|
||||||
}
|
Replaceall(tm, "$error", "error");
|
||||||
|
Printv(w->code, Str(tm), "\n", NIL);
|
||||||
/* marshal outputs */
|
Printf(w->code, "}\n");
|
||||||
for (p = l; p; ) {
|
}
|
||||||
if ((tm = Getattr(p, "tmap:directorargout")) != 0) {
|
|
||||||
Replaceall(tm, "$input", "swig_result");
|
/*
|
||||||
Replaceall(tm, "$result", Getattr(p, "name"));
|
* Python method may return a simple object, or a tuple.
|
||||||
Printv(w->code, tm, "\n", NIL);
|
* for in/out aruments, we have to extract the appropriate values from the
|
||||||
p = Getattr(p, "tmap:directorargout:next");
|
* argument list, then marshal everything back to C/C++ (return value and
|
||||||
} else {
|
* output arguments).
|
||||||
p = nextSibling(p);
|
*/
|
||||||
}
|
|
||||||
|
/* marshal return value and other outputs (if any) from value to C/C++
|
||||||
|
* type */
|
||||||
|
|
||||||
|
String* cleanup = NewString("");
|
||||||
|
String* outarg = NewString("");
|
||||||
|
|
||||||
|
idx = 0;
|
||||||
|
|
||||||
|
/* this seems really silly. the node's type excludes
|
||||||
|
* qualifier/pointer/reference markers, which have to be retrieved
|
||||||
|
* from the decl field to construct return_type. but the typemap
|
||||||
|
* lookup routine uses the node's type, so we have to swap in and
|
||||||
|
* out the correct type. it's not just me, similar silliness also
|
||||||
|
* occurs in Language::cDeclaration().
|
||||||
|
*/
|
||||||
|
Setattr(n, "type", return_type);
|
||||||
|
tm = Swig_typemap_lookup_new("directorout", n, "c_result", w);
|
||||||
|
Setattr(n, "type", type);
|
||||||
|
if (tm == 0) {
|
||||||
|
String *name = NewString("c_result");
|
||||||
|
tm = Swig_typemap_search("directorout", return_type, name, NULL);
|
||||||
|
Delete(name);
|
||||||
|
}
|
||||||
|
if (tm != 0) {
|
||||||
|
Replaceall(tm, "$input", "swig_result");
|
||||||
|
/* TODO check this */
|
||||||
|
if (Getattr(n,"wrap:disown")) {
|
||||||
|
Replaceall(tm,"$disown","SWIG_POINTER_DISOWN");
|
||||||
|
} else {
|
||||||
|
Replaceall(tm,"$disown","0");
|
||||||
|
}
|
||||||
|
Replaceall(tm, "$result", "c_result");
|
||||||
|
Printv(w->code, tm, "\n", NIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* marshal outputs */
|
||||||
|
for (p = l; p; ) {
|
||||||
|
if ((tm = Getattr(p, "tmap:directorargout")) != 0) {
|
||||||
|
Replaceall(tm, "$input", "swig_result");
|
||||||
|
Replaceall(tm, "$result", Getattr(p, "name"));
|
||||||
|
Printv(w->code, tm, "\n", NIL);
|
||||||
|
p = Getattr(p, "tmap:directorargout:next");
|
||||||
|
} else {
|
||||||
|
p = nextSibling(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Delete(arglist);
|
||||||
|
Delete(cleanup);
|
||||||
|
Delete(outarg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* any existing helper functions to handle this? */
|
/* any existing helper functions to handle this? */
|
||||||
if (!is_void) {
|
if (!is_void) {
|
||||||
|
if (!(ignored_method && !pure_virtual)) {
|
||||||
/* A little explanation:
|
/* A little explanation:
|
||||||
* The director_enum test case makes a method whose return type
|
* The director_enum test case makes a method whose return type
|
||||||
* is an enum type. return_type here is "int". gcc complains
|
* is an enum type. return_type here is "int". gcc complains
|
||||||
|
|
@ -1754,11 +1773,12 @@ public:
|
||||||
* always essentially work.
|
* always essentially work.
|
||||||
*/
|
*/
|
||||||
if( !SwigType_isreference(return_type) ) {
|
if( !SwigType_isreference(return_type) ) {
|
||||||
Printf(w->code, "CAMLreturn((%s)c_result);\n",
|
Printf(w->code, "CAMLreturn((%s)c_result);\n",
|
||||||
SwigType_lstr(return_type, ""));
|
SwigType_lstr(return_type, ""));
|
||||||
} else {
|
} else {
|
||||||
Printf(w->code, "CAMLreturn(*c_result);\n");
|
Printf(w->code, "CAMLreturn(*c_result);\n");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Printf(w->code, "}\n");
|
Printf(w->code, "}\n");
|
||||||
|
|
@ -1790,12 +1810,9 @@ public:
|
||||||
|
|
||||||
/* clean up */
|
/* clean up */
|
||||||
Delete(wrap_args);
|
Delete(wrap_args);
|
||||||
Delete(arglist);
|
|
||||||
Delete(rtype);
|
Delete(rtype);
|
||||||
Delete(return_type);
|
Delete(return_type);
|
||||||
Delete(pclassname);
|
Delete(pclassname);
|
||||||
Delete(cleanup);
|
|
||||||
Delete(outarg);
|
|
||||||
DelWrapper(w);
|
DelWrapper(w);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3345,13 +3345,14 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) {
|
||||||
ParmList *l;
|
ParmList *l;
|
||||||
Wrapper *w;
|
Wrapper *w;
|
||||||
String *tm;
|
String *tm;
|
||||||
String *wrap_args;
|
String *wrap_args = NewString("");
|
||||||
String *return_type;
|
String *return_type;
|
||||||
String *value = Getattr(n, "value");
|
String *value = Getattr(n, "value");
|
||||||
String *storage = Getattr(n,"storage");
|
String *storage = Getattr(n,"storage");
|
||||||
bool pure_virtual = false;
|
bool pure_virtual = false;
|
||||||
int status = SWIG_OK;
|
int status = SWIG_OK;
|
||||||
int idx;
|
int idx;
|
||||||
|
bool ignored_method = GetFlag(n, "feature:ignore") ? true : false;
|
||||||
|
|
||||||
if (Cmp(storage,"virtual") == 0) {
|
if (Cmp(storage,"virtual") == 0) {
|
||||||
if (Cmp(value,"0") == 0) {
|
if (Cmp(value,"0") == 0) {
|
||||||
|
|
@ -3425,341 +3426,362 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) {
|
||||||
Append(declaration, ")");
|
Append(declaration, ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Append(w->def, " {");
|
Append(w->def, " {");
|
||||||
Append(declaration, ";\n");
|
Append(declaration, ";\n");
|
||||||
|
|
||||||
/* attach typemaps to arguments (C/C++ -> Python) */
|
|
||||||
String *arglist = NewString("");
|
|
||||||
String* parse_args = NewString("");
|
|
||||||
|
|
||||||
/* remove the wrapper 'w' since it was producing spurious temps */
|
|
||||||
Swig_typemap_attach_parms("in", l, 0);
|
|
||||||
Swig_typemap_attach_parms("directorin", l, 0);
|
|
||||||
Swig_typemap_attach_parms("directorargout", l, w);
|
|
||||||
|
|
||||||
Parm* p;
|
|
||||||
char source[256];
|
|
||||||
|
|
||||||
wrap_args = NewString("");
|
|
||||||
int outputs = 0;
|
|
||||||
if (!is_void) outputs++;
|
|
||||||
|
|
||||||
/* build argument list and type conversion string */
|
|
||||||
idx = 0;
|
|
||||||
p = l;
|
|
||||||
int use_parse = 0;
|
|
||||||
while (p != NULL) {
|
|
||||||
if (checkAttribute(p,"tmap:in:numinputs","0")) {
|
|
||||||
p = Getattr(p,"tmap:in:next");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* old style? caused segfaults without the p!=0 check
|
|
||||||
in the for() condition, and seems dangerous in the
|
|
||||||
while loop as well.
|
|
||||||
while (Getattr(p, "tmap:ignore")) {
|
|
||||||
p = Getattr(p, "tmap:ignore:next");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (Getattr(p, "tmap:directorargout") != 0) outputs++;
|
|
||||||
|
|
||||||
String* pname = Getattr(p, "name");
|
|
||||||
String* ptype = Getattr(p, "type");
|
|
||||||
|
|
||||||
Putc(',',arglist);
|
|
||||||
if ((tm = Getattr(p, "tmap:directorin")) != 0) {
|
|
||||||
String* parse = Getattr(p, "tmap:directorin:parse");
|
|
||||||
if (!parse) {
|
|
||||||
sprintf(source, "obj%d", idx++);
|
|
||||||
String *input = NewString(source);
|
|
||||||
Replaceall(tm, "$input", input);
|
|
||||||
Delete(input);
|
|
||||||
Replaceall(tm, "$owner", "0");
|
|
||||||
/* Wrapper_add_localv(w, source, "swig::PyObject_var", source, "= 0", NIL);*/
|
|
||||||
Printv(wrap_args, "swig::PyObject_var ", source, ";\n", NIL);
|
|
||||||
|
|
||||||
Printv(wrap_args, tm, "\n", NIL);
|
|
||||||
Printv(arglist, "(PyObject *)",source, NIL);
|
|
||||||
Putc('O', parse_args);
|
|
||||||
} else {
|
|
||||||
use_parse = 1;
|
|
||||||
Append(parse_args, parse);
|
|
||||||
Replaceall(tm, "$input", pname);
|
|
||||||
Replaceall(tm, "$owner", "0");
|
|
||||||
if (Len(tm) == 0) Append(tm, pname);
|
|
||||||
Append(arglist, tm);
|
|
||||||
}
|
|
||||||
p = Getattr(p, "tmap:directorin:next");
|
|
||||||
continue;
|
|
||||||
} else
|
|
||||||
if (Cmp(ptype, "void")) {
|
|
||||||
/* special handling for pointers to other C++ director classes.
|
|
||||||
* ideally this would be left to a typemap, but there is currently no
|
|
||||||
* way to selectively apply the dynamic_cast<> to classes that have
|
|
||||||
* directors. in other words, the type "SwigDirector_$1_lname" only exists
|
|
||||||
* for classes with directors. we avoid the problem here by checking
|
|
||||||
* module.wrap::directormap, but it's not clear how to get a typemap to
|
|
||||||
* do something similar. perhaps a new default typemap (in addition
|
|
||||||
* to SWIGTYPE) called DIRECTORTYPE?
|
|
||||||
*/
|
|
||||||
if (SwigType_ispointer(ptype) || SwigType_isreference(ptype)) {
|
|
||||||
Node *module = Getattr(parent, "module");
|
|
||||||
Node *target = Swig_directormap(module, ptype);
|
|
||||||
sprintf(source, "obj%d", idx++);
|
|
||||||
String *nonconst = 0;
|
|
||||||
/* strip pointer/reference --- should move to Swig/stype.c */
|
|
||||||
String *nptype = NewString(Char(ptype)+2);
|
|
||||||
/* name as pointer */
|
|
||||||
String *ppname = Copy(pname);
|
|
||||||
if (SwigType_isreference(ptype)) {
|
|
||||||
Insert(ppname,0,"&");
|
|
||||||
}
|
|
||||||
/* if necessary, cast away const since Python doesn't support it! */
|
|
||||||
if (SwigType_isconst(nptype)) {
|
|
||||||
nonconst = NewStringf("nc_tmp_%s", pname);
|
|
||||||
String *nonconst_i = NewStringf("= const_cast<%s>(%s)", SwigType_lstr(ptype, 0), ppname);
|
|
||||||
Wrapper_add_localv(w, nonconst, SwigType_lstr(ptype, 0), nonconst, nonconst_i, NIL);
|
|
||||||
Delete(nonconst_i);
|
|
||||||
Swig_warning(WARN_LANG_DISCARD_CONST, input_file, line_number,
|
|
||||||
"Target language argument '%s' discards const in director method %s::%s.\n",
|
|
||||||
SwigType_str(ptype, pname), classname, name);
|
|
||||||
} else {
|
|
||||||
nonconst = Copy(ppname);
|
|
||||||
}
|
|
||||||
Delete(nptype);
|
|
||||||
Delete(ppname);
|
|
||||||
String *mangle = SwigType_manglestr(ptype);
|
|
||||||
if (target) {
|
|
||||||
String *director = NewStringf("director_%s", mangle);
|
|
||||||
Wrapper_add_localv(w, director, "Swig::Director *", director, "= 0", NIL);
|
|
||||||
Wrapper_add_localv(w, source, "swig::PyObject_var", source, "= 0", NIL);
|
|
||||||
Printf(wrap_args, "%s = SWIG_DIRECTOR_CAST(%s);\n", director, nonconst);
|
|
||||||
Printf(wrap_args, "if (!%s) {\n", director);
|
|
||||||
Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
|
|
||||||
Append(wrap_args, "} else {\n");
|
|
||||||
Printf(wrap_args, "%s = %s->swig_get_self();\n", source, director);
|
|
||||||
Printf(wrap_args, "Py_INCREF((PyObject *)%s);\n", source);
|
|
||||||
Append(wrap_args, "}\n");
|
|
||||||
Delete(director);
|
|
||||||
Printv(arglist, source, NIL);
|
|
||||||
} else {
|
|
||||||
Wrapper_add_localv(w, source, "swig::PyObject_var", source, "= 0", NIL);
|
|
||||||
Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n",
|
|
||||||
source, nonconst, mangle);
|
|
||||||
//Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE_p_%s, 0);\n",
|
|
||||||
// source, nonconst, base);
|
|
||||||
Printv(arglist, source, NIL);
|
|
||||||
}
|
|
||||||
Putc('O', parse_args);
|
|
||||||
Delete(mangle);
|
|
||||||
Delete(nonconst);
|
|
||||||
} else {
|
|
||||||
Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
|
|
||||||
"Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0), classname, name);
|
|
||||||
status = SWIG_NOWRAP;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p = nextSibling(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* add the method name as a PyString */
|
|
||||||
String *pyname = Getattr(n,"sym:name");
|
|
||||||
|
|
||||||
int allow_thread = threads_enable(n);
|
|
||||||
|
|
||||||
if (allow_thread) thread_begin_block(n, w->code);
|
|
||||||
|
|
||||||
/* declare method return value
|
/* declare method return value
|
||||||
* if the return value is a reference or const reference, a specialized typemap must
|
* if the return value is a reference or const reference, a specialized typemap must
|
||||||
* handle it, including declaration of c_result ($result).
|
* handle it, including declaration of c_result ($result).
|
||||||
*/
|
*/
|
||||||
if (!is_void) {
|
if (!is_void) {
|
||||||
String *cres = SwigType_lstr(return_type, "swig_c_result");
|
if (!(ignored_method && !pure_virtual)) {
|
||||||
Printf(w->code, "%s;\n", cres);
|
String *cres = SwigType_lstr(return_type, "c_result");
|
||||||
Delete(cres);
|
Printf(w->code, "%s;\n", cres);
|
||||||
|
Delete(cres);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (allow_thread) {
|
|
||||||
Append(w->code, "{\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* wrap complex arguments to PyObjects */
|
|
||||||
Printv(w->code, wrap_args, NIL);
|
|
||||||
|
|
||||||
/* pass the method call on to the Python object */
|
if (ignored_method) {
|
||||||
if (dirprot_mode() && !is_public(n)) {
|
if (!pure_virtual) {
|
||||||
Printf(w->code, "swig_set_inner(\"%s\", true);\n", name);
|
if (is_void)
|
||||||
}
|
Printf(w->code, "return ");
|
||||||
|
String *super_call = Swig_method_call(super, l);
|
||||||
|
Printf(w->code, "%s;\n", super_call);
|
||||||
Append(w->code, "if (!swig_get_self()) {\n");
|
Delete(super_call);
|
||||||
Printf(w->code, " Swig::DirectorException::raise(\"'self' uninitialized, maybe you forgot to call %s.__init__.\");\n", classname);
|
|
||||||
Append(w->code, "}\n");
|
|
||||||
Append(w->code,"#if defined(SWIG_PYTHON_DIRECTOR_VTABLE)\n");
|
|
||||||
Printf(w->code, "const size_t swig_method_index = %d;\n", director_method_index++);
|
|
||||||
Printf(w->code, "const char * const swig_method_name = \"%s\";\n", pyname);
|
|
||||||
|
|
||||||
Append(w->code, "PyObject* method = swig_get_method(swig_method_index, swig_method_name);\n");
|
|
||||||
if (Len(parse_args) > 0) {
|
|
||||||
if (use_parse || !modernargs) {
|
|
||||||
Printf(w->code, "swig::PyObject_var result = PyObject_CallFunction(method, (char *)\"(%s)\" %s);\n", parse_args, arglist);
|
|
||||||
} else {
|
} else {
|
||||||
Printf(w->code, "swig::PyObject_var result = PyObject_CallFunctionObjArgs(method %s, NULL);\n", arglist);
|
Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", classname, name);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (modernargs) {
|
/* attach typemaps to arguments (C/C++ -> Python) */
|
||||||
Append(w->code, "swig::PyObject_var args = PyTuple_New(0);\n");
|
String *arglist = NewString("");
|
||||||
Append(w->code, "swig::PyObject_var result = PyObject_Call(method, (PyObject*) args, NULL);\n");
|
String* parse_args = NewString("");
|
||||||
} else {
|
|
||||||
Printf(w->code, "swig::PyObject_var result = PyObject_CallFunction(method, NULL, NULL);\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Append(w->code,"#else\n");
|
|
||||||
if (Len(parse_args) > 0) {
|
|
||||||
if (use_parse || !modernargs) {
|
|
||||||
Printf(w->code, "swig::PyObject_var result = PyObject_CallMethod(swig_get_self(), (char *)\"%s\", (char *)\"(%s)\" %s);\n",
|
|
||||||
pyname, parse_args, arglist);
|
|
||||||
} else {
|
|
||||||
Printf(w->code, "swig::PyObject_var swig_method_name = PyString_FromString((char *)\"%s\");\n", pyname);
|
|
||||||
Printf(w->code, "swig::PyObject_var result = PyObject_CallMethodObjArgs(swig_get_self(), (PyObject *) swig_method_name %s, NULL);\n",
|
|
||||||
arglist);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!modernargs) {
|
|
||||||
Printf(w->code, "swig::PyObject_var result = PyObject_CallMethod(swig_get_self(), (char *) \"%s\", NULL);\n", pyname);
|
|
||||||
} else {
|
|
||||||
Printf(w->code, "swig::PyObject_var swig_method_name = PyString_FromString((char *)\"%s\");\n", pyname);
|
|
||||||
Append(w->code, "swig::PyObject_var result = PyObject_CallMethodObjArgs(swig_get_self(), (PyObject *) swig_method_name, NULL);\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Append(w->code,"#endif\n");
|
|
||||||
|
|
||||||
if (dirprot_mode() && !is_public(n))
|
/* remove the wrapper 'w' since it was producing spurious temps */
|
||||||
Printf(w->code, "swig_set_inner(\"%s\", false);\n", name);
|
Swig_typemap_attach_parms("in", l, 0);
|
||||||
|
Swig_typemap_attach_parms("directorin", l, 0);
|
||||||
|
Swig_typemap_attach_parms("directorargout", l, w);
|
||||||
|
|
||||||
/* exception handling */
|
Parm* p;
|
||||||
tm = Swig_typemap_lookup_new("director:except", n, "result", 0);
|
char source[256];
|
||||||
if (!tm) {
|
|
||||||
tm = Getattr(n, "feature:director:except");
|
|
||||||
if (tm) tm = Copy(tm);
|
|
||||||
}
|
|
||||||
Append(w->code, "if (result == NULL) {\n");
|
|
||||||
Append(w->code, " PyObject *error = PyErr_Occurred();\n");
|
|
||||||
if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) {
|
|
||||||
Replaceall(tm, "$error", "error");
|
|
||||||
Printv(w->code, Str(tm), "\n", NIL);
|
|
||||||
} else {
|
|
||||||
Append(w->code, " if (error != NULL) {\n");
|
|
||||||
Printf(w->code, " Swig::DirectorMethodException::raise(\"Error detected when calling '%s.%s'\");\n",
|
|
||||||
classname, pyname);
|
|
||||||
Append(w->code, " }\n");
|
|
||||||
}
|
|
||||||
Append(w->code, "}\n");
|
|
||||||
Delete(tm);
|
|
||||||
|
|
||||||
/*
|
int outputs = 0;
|
||||||
* Python method may return a simple object, or a tuple.
|
if (!is_void) outputs++;
|
||||||
* for in/out aruments, we have to extract the appropriate PyObjects from the tuple,
|
|
||||||
* then marshal everything back to C/C++ (return value and output arguments).
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* marshal return value and other outputs (if any) from PyObject to C/C++ type */
|
|
||||||
|
|
||||||
String* cleanup = NewString("");
|
|
||||||
String* outarg = NewString("");
|
|
||||||
|
|
||||||
if (outputs > 1) {
|
|
||||||
Wrapper_add_local(w, "output", "PyObject *output");
|
|
||||||
Append(w->code, "if (!PyTuple_Check(result)) {\n");
|
|
||||||
Printf(w->code, " Swig::DirectorTypeMismatchException::raise(\"Python method %s.%sfailed to return a tuple.\");\n",
|
|
||||||
classname, pyname);
|
|
||||||
Append(w->code, "}\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
idx = 0;
|
|
||||||
|
|
||||||
/* marshal return value */
|
|
||||||
if (!is_void) {
|
|
||||||
/* this seems really silly. the node's type excludes
|
|
||||||
* qualifier/pointer/reference markers, which have to be retrieved
|
|
||||||
* from the decl field to construct return_type. but the typemap
|
|
||||||
* lookup routine uses the node's type, so we have to swap in and
|
|
||||||
* out the correct type. it's not just me, similar silliness also
|
|
||||||
* occurs in Language::cDeclaration().
|
|
||||||
*/
|
|
||||||
Setattr(n, "type", return_type);
|
|
||||||
tm = Swig_typemap_lookup_new("directorout", n, "result", w);
|
|
||||||
Setattr(n, "type", type);
|
|
||||||
if (tm == 0) {
|
|
||||||
String *name = NewString("result");
|
|
||||||
tm = Swig_typemap_search("directorout", return_type, name, NULL);
|
|
||||||
Delete(name);
|
|
||||||
}
|
|
||||||
if (tm != 0) {
|
|
||||||
if (outputs > 1) {
|
|
||||||
Printf(w->code, "output = PyTuple_GetItem(result, %d);\n", idx++);
|
|
||||||
Replaceall(tm, "$input", "output");
|
|
||||||
} else {
|
|
||||||
Replaceall(tm, "$input", "result");
|
|
||||||
}
|
|
||||||
char temp[24];
|
|
||||||
sprintf(temp,"%d",idx);
|
|
||||||
Replaceall(tm,"$argnum",temp);
|
|
||||||
|
|
||||||
/* TODO check this */
|
|
||||||
if (Getattr(n,"wrap:disown")) {
|
|
||||||
Replaceall(tm,"$disown","SWIG_POINTER_DISOWN");
|
|
||||||
} else {
|
|
||||||
Replaceall(tm,"$disown","0");
|
|
||||||
}
|
|
||||||
if (Getattr(n,"tmap:directorout:implicitconv")) {
|
|
||||||
Replaceall(tm,"$implicitconv", get_implicitconv_flag(n));
|
|
||||||
}
|
|
||||||
Replaceall(tm, "$result", "swig_c_result");
|
|
||||||
Printv(w->code, tm, "\n", NIL);
|
|
||||||
Delete(tm);
|
|
||||||
} else {
|
|
||||||
Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
|
|
||||||
"Unable to use return type %s in director method %s::%s (skipping method).\n", SwigType_str(return_type, 0), classname, name);
|
|
||||||
status = SWIG_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* marshal outputs */
|
/* build argument list and type conversion string */
|
||||||
for (p = l; p; ) {
|
idx = 0;
|
||||||
if ((tm = Getattr(p, "tmap:directorargout")) != 0) {
|
p = l;
|
||||||
if (outputs > 1) {
|
int use_parse = 0;
|
||||||
Printf(w->code, "output = PyTuple_GetItem(result, %d);\n", idx++);
|
while (p != NULL) {
|
||||||
Replaceall(tm, "$input", "output");
|
if (checkAttribute(p,"tmap:in:numinputs","0")) {
|
||||||
} else {
|
p = Getattr(p,"tmap:in:next");
|
||||||
Replaceall(tm, "$input", "result");
|
continue;
|
||||||
}
|
}
|
||||||
Replaceall(tm, "$result", Getattr(p, "name"));
|
|
||||||
Printv(w->code, tm, "\n", NIL);
|
/* old style? caused segfaults without the p!=0 check
|
||||||
p = Getattr(p, "tmap:directorargout:next");
|
in the for() condition, and seems dangerous in the
|
||||||
} else {
|
while loop as well.
|
||||||
|
while (Getattr(p, "tmap:ignore")) {
|
||||||
|
p = Getattr(p, "tmap:ignore:next");
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (Getattr(p, "tmap:directorargout") != 0) outputs++;
|
||||||
|
|
||||||
|
String* pname = Getattr(p, "name");
|
||||||
|
String* ptype = Getattr(p, "type");
|
||||||
|
|
||||||
|
Putc(',',arglist);
|
||||||
|
if ((tm = Getattr(p, "tmap:directorin")) != 0) {
|
||||||
|
String* parse = Getattr(p, "tmap:directorin:parse");
|
||||||
|
if (!parse) {
|
||||||
|
sprintf(source, "obj%d", idx++);
|
||||||
|
String *input = NewString(source);
|
||||||
|
Replaceall(tm, "$input", input);
|
||||||
|
Delete(input);
|
||||||
|
Replaceall(tm, "$owner", "0");
|
||||||
|
/* Wrapper_add_localv(w, source, "swig::PyObject_var", source, "= 0", NIL);*/
|
||||||
|
Printv(wrap_args, "swig::PyObject_var ", source, ";\n", NIL);
|
||||||
|
|
||||||
|
Printv(wrap_args, tm, "\n", NIL);
|
||||||
|
Printv(arglist, "(PyObject *)",source, NIL);
|
||||||
|
Putc('O', parse_args);
|
||||||
|
} else {
|
||||||
|
use_parse = 1;
|
||||||
|
Append(parse_args, parse);
|
||||||
|
Replaceall(tm, "$input", pname);
|
||||||
|
Replaceall(tm, "$owner", "0");
|
||||||
|
if (Len(tm) == 0) Append(tm, pname);
|
||||||
|
Append(arglist, tm);
|
||||||
|
}
|
||||||
|
p = Getattr(p, "tmap:directorin:next");
|
||||||
|
continue;
|
||||||
|
} else
|
||||||
|
if (Cmp(ptype, "void")) {
|
||||||
|
/* special handling for pointers to other C++ director classes.
|
||||||
|
* ideally this would be left to a typemap, but there is currently no
|
||||||
|
* way to selectively apply the dynamic_cast<> to classes that have
|
||||||
|
* directors. in other words, the type "SwigDirector_$1_lname" only exists
|
||||||
|
* for classes with directors. we avoid the problem here by checking
|
||||||
|
* module.wrap::directormap, but it's not clear how to get a typemap to
|
||||||
|
* do something similar. perhaps a new default typemap (in addition
|
||||||
|
* to SWIGTYPE) called DIRECTORTYPE?
|
||||||
|
*/
|
||||||
|
if (SwigType_ispointer(ptype) || SwigType_isreference(ptype)) {
|
||||||
|
Node *module = Getattr(parent, "module");
|
||||||
|
Node *target = Swig_directormap(module, ptype);
|
||||||
|
sprintf(source, "obj%d", idx++);
|
||||||
|
String *nonconst = 0;
|
||||||
|
/* strip pointer/reference --- should move to Swig/stype.c */
|
||||||
|
String *nptype = NewString(Char(ptype)+2);
|
||||||
|
/* name as pointer */
|
||||||
|
String *ppname = Copy(pname);
|
||||||
|
if (SwigType_isreference(ptype)) {
|
||||||
|
Insert(ppname,0,"&");
|
||||||
|
}
|
||||||
|
/* if necessary, cast away const since Python doesn't support it! */
|
||||||
|
if (SwigType_isconst(nptype)) {
|
||||||
|
nonconst = NewStringf("nc_tmp_%s", pname);
|
||||||
|
String *nonconst_i = NewStringf("= const_cast<%s>(%s)", SwigType_lstr(ptype, 0), ppname);
|
||||||
|
Wrapper_add_localv(w, nonconst, SwigType_lstr(ptype, 0), nonconst, nonconst_i, NIL);
|
||||||
|
Delete(nonconst_i);
|
||||||
|
Swig_warning(WARN_LANG_DISCARD_CONST, input_file, line_number,
|
||||||
|
"Target language argument '%s' discards const in director method %s::%s.\n",
|
||||||
|
SwigType_str(ptype, pname), classname, name);
|
||||||
|
} else {
|
||||||
|
nonconst = Copy(ppname);
|
||||||
|
}
|
||||||
|
Delete(nptype);
|
||||||
|
Delete(ppname);
|
||||||
|
String *mangle = SwigType_manglestr(ptype);
|
||||||
|
if (target) {
|
||||||
|
String *director = NewStringf("director_%s", mangle);
|
||||||
|
Wrapper_add_localv(w, director, "Swig::Director *", director, "= 0", NIL);
|
||||||
|
Wrapper_add_localv(w, source, "swig::PyObject_var", source, "= 0", NIL);
|
||||||
|
Printf(wrap_args, "%s = SWIG_DIRECTOR_CAST(%s);\n", director, nonconst);
|
||||||
|
Printf(wrap_args, "if (!%s) {\n", director);
|
||||||
|
Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
|
||||||
|
Append(wrap_args, "} else {\n");
|
||||||
|
Printf(wrap_args, "%s = %s->swig_get_self();\n", source, director);
|
||||||
|
Printf(wrap_args, "Py_INCREF((PyObject *)%s);\n", source);
|
||||||
|
Append(wrap_args, "}\n");
|
||||||
|
Delete(director);
|
||||||
|
Printv(arglist, source, NIL);
|
||||||
|
} else {
|
||||||
|
Wrapper_add_localv(w, source, "swig::PyObject_var", source, "= 0", NIL);
|
||||||
|
Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n",
|
||||||
|
source, nonconst, mangle);
|
||||||
|
//Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE_p_%s, 0);\n",
|
||||||
|
// source, nonconst, base);
|
||||||
|
Printv(arglist, source, NIL);
|
||||||
|
}
|
||||||
|
Putc('O', parse_args);
|
||||||
|
Delete(mangle);
|
||||||
|
Delete(nonconst);
|
||||||
|
} else {
|
||||||
|
Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
|
||||||
|
"Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(ptype, 0), classname, name);
|
||||||
|
status = SWIG_NOWRAP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
p = nextSibling(p);
|
p = nextSibling(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* add the method name as a PyString */
|
||||||
|
String *pyname = Getattr(n,"sym:name");
|
||||||
|
|
||||||
|
int allow_thread = threads_enable(n);
|
||||||
|
|
||||||
|
if (allow_thread) thread_begin_block(n, w->code);
|
||||||
|
|
||||||
|
if (allow_thread) {
|
||||||
|
Append(w->code, "{\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* wrap complex arguments to PyObjects */
|
||||||
|
Printv(w->code, wrap_args, NIL);
|
||||||
|
|
||||||
|
/* pass the method call on to the Python object */
|
||||||
|
if (dirprot_mode() && !is_public(n)) {
|
||||||
|
Printf(w->code, "swig_set_inner(\"%s\", true);\n", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Append(w->code, "if (!swig_get_self()) {\n");
|
||||||
|
Printf(w->code, " Swig::DirectorException::raise(\"'self' uninitialized, maybe you forgot to call %s.__init__.\");\n", classname);
|
||||||
|
Append(w->code, "}\n");
|
||||||
|
Append(w->code,"#if defined(SWIG_PYTHON_DIRECTOR_VTABLE)\n");
|
||||||
|
Printf(w->code, "const size_t swig_method_index = %d;\n", director_method_index++);
|
||||||
|
Printf(w->code, "const char * const swig_method_name = \"%s\";\n", pyname);
|
||||||
|
|
||||||
|
Append(w->code, "PyObject* method = swig_get_method(swig_method_index, swig_method_name);\n");
|
||||||
|
if (Len(parse_args) > 0) {
|
||||||
|
if (use_parse || !modernargs) {
|
||||||
|
Printf(w->code, "swig::PyObject_var result = PyObject_CallFunction(method, (char *)\"(%s)\" %s);\n", parse_args, arglist);
|
||||||
|
} else {
|
||||||
|
Printf(w->code, "swig::PyObject_var result = PyObject_CallFunctionObjArgs(method %s, NULL);\n", arglist);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (modernargs) {
|
||||||
|
Append(w->code, "swig::PyObject_var args = PyTuple_New(0);\n");
|
||||||
|
Append(w->code, "swig::PyObject_var result = PyObject_Call(method, (PyObject*) args, NULL);\n");
|
||||||
|
} else {
|
||||||
|
Printf(w->code, "swig::PyObject_var result = PyObject_CallFunction(method, NULL, NULL);\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Append(w->code,"#else\n");
|
||||||
|
if (Len(parse_args) > 0) {
|
||||||
|
if (use_parse || !modernargs) {
|
||||||
|
Printf(w->code, "swig::PyObject_var result = PyObject_CallMethod(swig_get_self(), (char *)\"%s\", (char *)\"(%s)\" %s);\n",
|
||||||
|
pyname, parse_args, arglist);
|
||||||
|
} else {
|
||||||
|
Printf(w->code, "swig::PyObject_var swig_method_name = PyString_FromString((char *)\"%s\");\n", pyname);
|
||||||
|
Printf(w->code, "swig::PyObject_var result = PyObject_CallMethodObjArgs(swig_get_self(), (PyObject *) swig_method_name %s, NULL);\n",
|
||||||
|
arglist);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!modernargs) {
|
||||||
|
Printf(w->code, "swig::PyObject_var result = PyObject_CallMethod(swig_get_self(), (char *) \"%s\", NULL);\n", pyname);
|
||||||
|
} else {
|
||||||
|
Printf(w->code, "swig::PyObject_var swig_method_name = PyString_FromString((char *)\"%s\");\n", pyname);
|
||||||
|
Append(w->code, "swig::PyObject_var result = PyObject_CallMethodObjArgs(swig_get_self(), (PyObject *) swig_method_name, NULL);\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Append(w->code,"#endif\n");
|
||||||
|
|
||||||
|
if (dirprot_mode() && !is_public(n))
|
||||||
|
Printf(w->code, "swig_set_inner(\"%s\", false);\n", name);
|
||||||
|
|
||||||
|
/* exception handling */
|
||||||
|
tm = Swig_typemap_lookup_new("director:except", n, "result", 0);
|
||||||
|
if (!tm) {
|
||||||
|
tm = Getattr(n, "feature:director:except");
|
||||||
|
if (tm) tm = Copy(tm);
|
||||||
|
}
|
||||||
|
Append(w->code, "if (result == NULL) {\n");
|
||||||
|
Append(w->code, " PyObject *error = PyErr_Occurred();\n");
|
||||||
|
if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) {
|
||||||
|
Replaceall(tm, "$error", "error");
|
||||||
|
Printv(w->code, Str(tm), "\n", NIL);
|
||||||
|
} else {
|
||||||
|
Append(w->code, " if (error != NULL) {\n");
|
||||||
|
Printf(w->code, " Swig::DirectorMethodException::raise(\"Error detected when calling '%s.%s'\");\n",
|
||||||
|
classname, pyname);
|
||||||
|
Append(w->code, " }\n");
|
||||||
|
}
|
||||||
|
Append(w->code, "}\n");
|
||||||
|
Delete(tm);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Python method may return a simple object, or a tuple.
|
||||||
|
* for in/out aruments, we have to extract the appropriate PyObjects from the tuple,
|
||||||
|
* then marshal everything back to C/C++ (return value and output arguments).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* marshal return value and other outputs (if any) from PyObject to C/C++ type */
|
||||||
|
|
||||||
|
String* cleanup = NewString("");
|
||||||
|
String* outarg = NewString("");
|
||||||
|
|
||||||
|
if (outputs > 1) {
|
||||||
|
Wrapper_add_local(w, "output", "PyObject *output");
|
||||||
|
Append(w->code, "if (!PyTuple_Check(result)) {\n");
|
||||||
|
Printf(w->code, " Swig::DirectorTypeMismatchException::raise(\"Python method %s.%sfailed to return a tuple.\");\n",
|
||||||
|
classname, pyname);
|
||||||
|
Append(w->code, "}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
idx = 0;
|
||||||
|
|
||||||
|
/* marshal return value */
|
||||||
|
if (!is_void) {
|
||||||
|
/* this seems really silly. the node's type excludes
|
||||||
|
* qualifier/pointer/reference markers, which have to be retrieved
|
||||||
|
* from the decl field to construct return_type. but the typemap
|
||||||
|
* lookup routine uses the node's type, so we have to swap in and
|
||||||
|
* out the correct type. it's not just me, similar silliness also
|
||||||
|
* occurs in Language::cDeclaration().
|
||||||
|
*/
|
||||||
|
Setattr(n, "type", return_type);
|
||||||
|
tm = Swig_typemap_lookup_new("directorout", n, "result", w);
|
||||||
|
Setattr(n, "type", type);
|
||||||
|
if (tm == 0) {
|
||||||
|
String *name = NewString("result");
|
||||||
|
tm = Swig_typemap_search("directorout", return_type, name, NULL);
|
||||||
|
Delete(name);
|
||||||
|
}
|
||||||
|
if (tm != 0) {
|
||||||
|
if (outputs > 1) {
|
||||||
|
Printf(w->code, "output = PyTuple_GetItem(result, %d);\n", idx++);
|
||||||
|
Replaceall(tm, "$input", "output");
|
||||||
|
} else {
|
||||||
|
Replaceall(tm, "$input", "result");
|
||||||
|
}
|
||||||
|
char temp[24];
|
||||||
|
sprintf(temp,"%d",idx);
|
||||||
|
Replaceall(tm,"$argnum",temp);
|
||||||
|
|
||||||
|
/* TODO check this */
|
||||||
|
if (Getattr(n,"wrap:disown")) {
|
||||||
|
Replaceall(tm,"$disown","SWIG_POINTER_DISOWN");
|
||||||
|
} else {
|
||||||
|
Replaceall(tm,"$disown","0");
|
||||||
|
}
|
||||||
|
if (Getattr(n,"tmap:directorout:implicitconv")) {
|
||||||
|
Replaceall(tm,"$implicitconv", get_implicitconv_flag(n));
|
||||||
|
}
|
||||||
|
Replaceall(tm, "$result", "c_result");
|
||||||
|
Printv(w->code, tm, "\n", NIL);
|
||||||
|
Delete(tm);
|
||||||
|
} else {
|
||||||
|
Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
|
||||||
|
"Unable to use return type %s in director method %s::%s (skipping method).\n", SwigType_str(return_type, 0), classname, name);
|
||||||
|
status = SWIG_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* marshal outputs */
|
||||||
|
for (p = l; p; ) {
|
||||||
|
if ((tm = Getattr(p, "tmap:directorargout")) != 0) {
|
||||||
|
if (outputs > 1) {
|
||||||
|
Printf(w->code, "output = PyTuple_GetItem(result, %d);\n", idx++);
|
||||||
|
Replaceall(tm, "$input", "output");
|
||||||
|
} else {
|
||||||
|
Replaceall(tm, "$input", "result");
|
||||||
|
}
|
||||||
|
Replaceall(tm, "$result", Getattr(p, "name"));
|
||||||
|
Printv(w->code, tm, "\n", NIL);
|
||||||
|
p = Getattr(p, "tmap:directorargout:next");
|
||||||
|
} else {
|
||||||
|
p = nextSibling(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* any existing helper functions to handle this? */
|
||||||
|
if (allow_thread) {
|
||||||
|
Append(w->code, "}\n");
|
||||||
|
thread_end_block(n, w->code);
|
||||||
|
}
|
||||||
|
|
||||||
|
Delete(parse_args);
|
||||||
|
Delete(arglist);
|
||||||
|
Delete(cleanup);
|
||||||
|
Delete(outarg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* any existing helper functions to handle this? */
|
|
||||||
if (allow_thread) {
|
|
||||||
Append(w->code, "}\n");
|
|
||||||
thread_end_block(n, w->code);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_void) {
|
if (!is_void) {
|
||||||
String* rettype = SwigType_str(return_type, 0);
|
if (!(ignored_method && !pure_virtual)) {
|
||||||
if (!SwigType_isreference(return_type)) {
|
String* rettype = SwigType_str(return_type, 0);
|
||||||
Printf(w->code, "return (%s) swig_c_result;\n", rettype);
|
if (!SwigType_isreference(return_type)) {
|
||||||
} else {
|
Printf(w->code, "return (%s) c_result;\n", rettype);
|
||||||
Printf(w->code, "return (%s) *swig_c_result;\n", rettype);
|
} else {
|
||||||
|
Printf(w->code, "return (%s) *c_result;\n", rettype);
|
||||||
|
}
|
||||||
|
Delete(rettype);
|
||||||
}
|
}
|
||||||
Delete(rettype);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Append(w->code, "}\n");
|
Append(w->code, "}\n");
|
||||||
|
|
||||||
// We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method
|
// We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method
|
||||||
|
|
@ -3789,13 +3811,9 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) {
|
||||||
|
|
||||||
/* clean up */
|
/* clean up */
|
||||||
Delete(wrap_args);
|
Delete(wrap_args);
|
||||||
Delete(parse_args);
|
|
||||||
Delete(arglist);
|
|
||||||
Delete(rtype);
|
Delete(rtype);
|
||||||
Delete(return_type);
|
Delete(return_type);
|
||||||
Delete(pclassname);
|
Delete(pclassname);
|
||||||
Delete(cleanup);
|
|
||||||
Delete(outarg);
|
|
||||||
DelWrapper(w);
|
DelWrapper(w);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2289,7 +2289,7 @@ public:
|
||||||
ParmList *l;
|
ParmList *l;
|
||||||
Wrapper *w;
|
Wrapper *w;
|
||||||
String *tm;
|
String *tm;
|
||||||
String *wrap_args;
|
String *wrap_args = NewString("");
|
||||||
String *return_type;
|
String *return_type;
|
||||||
Parm* p;
|
Parm* p;
|
||||||
String *value = Getattr(n, "value");
|
String *value = Getattr(n, "value");
|
||||||
|
|
@ -2297,6 +2297,7 @@ public:
|
||||||
bool pure_virtual = false;
|
bool pure_virtual = false;
|
||||||
int status = SWIG_OK;
|
int status = SWIG_OK;
|
||||||
int idx;
|
int idx;
|
||||||
|
bool ignored_method = GetFlag(n, "feature:ignore") ? true : false;
|
||||||
|
|
||||||
if (Cmp(storage,"virtual") == 0) {
|
if (Cmp(storage,"virtual") == 0) {
|
||||||
if (Cmp(value,"0") == 0) {
|
if (Cmp(value,"0") == 0) {
|
||||||
|
|
@ -2372,222 +2373,241 @@ public:
|
||||||
Append(w->def, " {");
|
Append(w->def, " {");
|
||||||
Append(declaration, ";\n");
|
Append(declaration, ";\n");
|
||||||
|
|
||||||
|
|
||||||
/* attach typemaps to arguments (C/C++ -> Ruby) */
|
|
||||||
String *arglist = NewString("");
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For each parameter to the C++ member function, copy the parameter name
|
|
||||||
* to its "lname"; this ensures that Swig_typemap_attach_parms() will do
|
|
||||||
* the right thing when it sees strings like "$1" in your "directorin" typemaps.
|
|
||||||
* Not sure if it's OK to leave it like this, but seems OK so far.
|
|
||||||
*/
|
|
||||||
typemap_copy_pname_to_lname(l);
|
|
||||||
|
|
||||||
Swig_typemap_attach_parms("in", l, 0);
|
|
||||||
Swig_typemap_attach_parms("directorin", l, 0);
|
|
||||||
Swig_typemap_attach_parms("directorargout", l, w);
|
|
||||||
|
|
||||||
int num_arguments = emit_num_arguments(l);
|
|
||||||
int i;
|
|
||||||
char source[256];
|
|
||||||
|
|
||||||
wrap_args = NewString("");
|
|
||||||
int outputs = 0;
|
|
||||||
if (!is_void) outputs++;
|
|
||||||
|
|
||||||
/* build argument list and type conversion string */
|
|
||||||
for (i=0, idx=0, p = l; i < num_arguments; i++) {
|
|
||||||
|
|
||||||
while (Getattr(p, "tmap:ignore")) {
|
|
||||||
p = Getattr(p, "tmap:ignore:next");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Getattr(p, "tmap:directorargout") != 0) outputs++;
|
|
||||||
|
|
||||||
String* parameterName = Getattr(p, "name");
|
|
||||||
String* parameterType = Getattr(p, "type");
|
|
||||||
|
|
||||||
Putc(',',arglist);
|
|
||||||
if ((tm = Getattr(p, "tmap:directorin")) != 0) {
|
|
||||||
sprintf(source, "obj%d", idx++);
|
|
||||||
Replaceall(tm, "$input", source);
|
|
||||||
Replaceall(tm, "$owner", "0");
|
|
||||||
Printv(wrap_args, tm, "\n", NIL);
|
|
||||||
Wrapper_add_localv(w, source, "VALUE", source, "= Qnil", NIL);
|
|
||||||
Printv(arglist, source, NIL);
|
|
||||||
p = Getattr(p, "tmap:directorin:next");
|
|
||||||
continue;
|
|
||||||
} else if (Cmp(parameterType, "void")) {
|
|
||||||
/**
|
|
||||||
* Special handling for pointers to other C++ director classes.
|
|
||||||
* Ideally this would be left to a typemap, but there is currently no
|
|
||||||
* way to selectively apply the dynamic_cast<> to classes that have
|
|
||||||
* directors. In other words, the type "SwigDirector_$1_lname" only exists
|
|
||||||
* for classes with directors. We avoid the problem here by checking
|
|
||||||
* module.wrap::directormap, but it's not clear how to get a typemap to
|
|
||||||
* do something similar. Perhaps a new default typemap (in addition
|
|
||||||
* to SWIGTYPE) called DIRECTORTYPE?
|
|
||||||
*/
|
|
||||||
if (SwigType_ispointer(parameterType) || SwigType_isreference(parameterType)) {
|
|
||||||
Node *modname = Getattr(parent, "module");
|
|
||||||
Node *target = Swig_directormap(modname, parameterType);
|
|
||||||
sprintf(source, "obj%d", idx++);
|
|
||||||
String *nonconst = 0;
|
|
||||||
/* strip pointer/reference --- should move to Swig/stype.c */
|
|
||||||
String *nptype = NewString(Char(parameterType)+2);
|
|
||||||
/* name as pointer */
|
|
||||||
String *ppname = Copy(parameterName);
|
|
||||||
if (SwigType_isreference(parameterType)) {
|
|
||||||
Insert(ppname,0,"&");
|
|
||||||
}
|
|
||||||
/* if necessary, cast away const since Ruby doesn't support it! */
|
|
||||||
if (SwigType_isconst(nptype)) {
|
|
||||||
nonconst = NewStringf("nc_tmp_%s", parameterName);
|
|
||||||
String *nonconst_i = NewStringf("= const_cast<%s>(%s)", SwigType_lstr(parameterType, 0), ppname);
|
|
||||||
Wrapper_add_localv(w, nonconst, SwigType_lstr(parameterType, 0), nonconst, nonconst_i, NIL);
|
|
||||||
Delete(nonconst_i);
|
|
||||||
Swig_warning(WARN_LANG_DISCARD_CONST, input_file, line_number,
|
|
||||||
"Target language argument '%s' discards const in director method %s::%s.\n", SwigType_str(parameterType, parameterName), classname, name);
|
|
||||||
} else {
|
|
||||||
nonconst = Copy(ppname);
|
|
||||||
}
|
|
||||||
Delete(nptype);
|
|
||||||
Delete(ppname);
|
|
||||||
String *mangle = SwigType_manglestr(parameterType);
|
|
||||||
if (target) {
|
|
||||||
String *director = NewStringf("director_%s", mangle);
|
|
||||||
Wrapper_add_localv(w, director, "Swig::Director *", director, "= 0", NIL);
|
|
||||||
Wrapper_add_localv(w, source, "VALUE", source, "= Qnil", NIL);
|
|
||||||
Printf(wrap_args, "%s = dynamic_cast<Swig::Director *>(%s);\n", director, nonconst);
|
|
||||||
Printf(wrap_args, "if (!%s) {\n", director);
|
|
||||||
Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
|
|
||||||
Printf(wrap_args, "} else {\n");
|
|
||||||
Printf(wrap_args, "%s = %s->swig_get_self();\n", source, director);
|
|
||||||
Printf(wrap_args, "}\n");
|
|
||||||
Delete(director);
|
|
||||||
Printv(arglist, source, NIL);
|
|
||||||
} else {
|
|
||||||
Wrapper_add_localv(w, source, "VALUE", source, "= Qnil", NIL);
|
|
||||||
Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n",
|
|
||||||
source, nonconst, mangle);
|
|
||||||
//Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE_p_%s, 0);\n",
|
|
||||||
// source, nonconst, base);
|
|
||||||
Printv(arglist, source, NIL);
|
|
||||||
}
|
|
||||||
Delete(mangle);
|
|
||||||
Delete(nonconst);
|
|
||||||
} else {
|
|
||||||
Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
|
|
||||||
"Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(parameterType, 0), classname, name);
|
|
||||||
status = SWIG_NOWRAP;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p = nextSibling(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* declare method return value
|
/* declare method return value
|
||||||
* if the return value is a reference or const reference, a specialized typemap must
|
* if the return value is a reference or const reference, a specialized typemap must
|
||||||
* handle it, including declaration of c_result ($result).
|
* handle it, including declaration of c_result ($result).
|
||||||
*/
|
*/
|
||||||
if (!is_void) {
|
if (!is_void) {
|
||||||
Wrapper_add_localv(w, "c_result", SwigType_lstr(return_type, "c_result"), NIL);
|
if (!(ignored_method && !pure_virtual)) {
|
||||||
}
|
Wrapper_add_localv(w, "c_result", SwigType_lstr(return_type, "c_result"), NIL);
|
||||||
/* declare Ruby return value */
|
}
|
||||||
Wrapper_add_local(w, "result", "VALUE result");
|
|
||||||
|
|
||||||
/* wrap complex arguments to VALUEs */
|
|
||||||
Printv(w->code, wrap_args, NIL);
|
|
||||||
|
|
||||||
/* pass the method call on to the Ruby object */
|
|
||||||
exceptionSafeMethodCall(classname, n, w, idx, arglist);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Ruby method may return a simple object, or an Array of objects.
|
|
||||||
* For in/out arguments, we have to extract the appropriate VALUEs from the Array,
|
|
||||||
* then marshal everything back to C/C++ (return value and output arguments).
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Marshal return value and other outputs (if any) from VALUE to C/C++ type */
|
|
||||||
|
|
||||||
String* cleanup = NewString("");
|
|
||||||
String* outarg = NewString("");
|
|
||||||
|
|
||||||
if (outputs > 1) {
|
|
||||||
Wrapper_add_local(w, "output", "VALUE output");
|
|
||||||
Printf(w->code, "if (TYPE(result) != T_ARRAY) {\n");
|
|
||||||
Printf(w->code, "throw Swig::DirectorTypeMismatchException(\"Ruby method failed to return an array.\");\n");
|
|
||||||
Printf(w->code, "}\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
idx = 0;
|
if (ignored_method) {
|
||||||
|
if (!pure_virtual) {
|
||||||
|
if (is_void)
|
||||||
|
Printf(w->code, "return ");
|
||||||
|
String *super_call = Swig_method_call(super, l);
|
||||||
|
Printf(w->code, "%s;\n", super_call);
|
||||||
|
Delete(super_call);
|
||||||
|
} else {
|
||||||
|
Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", classname, name);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* attach typemaps to arguments (C/C++ -> Ruby) */
|
||||||
|
String *arglist = NewString("");
|
||||||
|
|
||||||
/* Marshal return value */
|
/**
|
||||||
if (!is_void) {
|
* For each parameter to the C++ member function, copy the parameter name
|
||||||
/* This seems really silly. The node's type excludes qualifier/pointer/reference markers,
|
* to its "lname"; this ensures that Swig_typemap_attach_parms() will do
|
||||||
* which have to be retrieved from the decl field to construct return_type. But the typemap
|
* the right thing when it sees strings like "$1" in your "directorin" typemaps.
|
||||||
* lookup routine uses the node's type, so we have to swap in and out the correct type.
|
* Not sure if it's OK to leave it like this, but seems OK so far.
|
||||||
* It's not just me, similar silliness also occurs in Language::cDeclaration().
|
|
||||||
*/
|
*/
|
||||||
Setattr(n, "type", return_type);
|
typemap_copy_pname_to_lname(l);
|
||||||
tm = Swig_typemap_lookup_new("directorout", n, "result", w);
|
|
||||||
Setattr(n, "type", type);
|
Swig_typemap_attach_parms("in", l, 0);
|
||||||
if (tm == 0) {
|
Swig_typemap_attach_parms("directorin", l, 0);
|
||||||
String *name = NewString("result");
|
Swig_typemap_attach_parms("directorargout", l, w);
|
||||||
tm = Swig_typemap_search("directorout", return_type, name, NULL);
|
|
||||||
Delete(name);
|
int num_arguments = emit_num_arguments(l);
|
||||||
}
|
int i;
|
||||||
if (tm != 0) {
|
char source[256];
|
||||||
if (outputs > 1) {
|
|
||||||
Printf(w->code, "output = rb_ary_entry(result, %d);\n", idx++);
|
int outputs = 0;
|
||||||
Replaceall(tm, "$input", "output");
|
if (!is_void) outputs++;
|
||||||
} else {
|
|
||||||
Replaceall(tm, "$input", "result");
|
|
||||||
}
|
|
||||||
/* TODO check this */
|
|
||||||
if (Getattr(n,"wrap:disown")) {
|
|
||||||
Replaceall(tm,"$disown","SWIG_POINTER_DISOWN");
|
|
||||||
} else {
|
|
||||||
Replaceall(tm,"$disown","0");
|
|
||||||
}
|
|
||||||
Replaceall(tm, "$result", "c_result");
|
|
||||||
Printv(w->code, tm, "\n", NIL);
|
|
||||||
} else {
|
|
||||||
Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
|
|
||||||
"Unable to use return type %s in director method %s::%s (skipping method).\n", SwigType_str(return_type, 0), classname, name);
|
|
||||||
status = SWIG_ERROR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Marshal outputs */
|
/* build argument list and type conversion string */
|
||||||
for (p = l; p; ) {
|
for (i=0, idx=0, p = l; i < num_arguments; i++) {
|
||||||
if ((tm = Getattr(p, "tmap:directorargout")) != 0) {
|
|
||||||
if (outputs > 1) {
|
while (Getattr(p, "tmap:ignore")) {
|
||||||
Printf(w->code, "output = rb_ary_entry(result, %d);\n", idx++);
|
p = Getattr(p, "tmap:ignore:next");
|
||||||
Replaceall(tm, "$input", "output");
|
}
|
||||||
} else {
|
|
||||||
Replaceall(tm, "$input", "result");
|
if (Getattr(p, "tmap:directorargout") != 0) outputs++;
|
||||||
|
|
||||||
|
String* parameterName = Getattr(p, "name");
|
||||||
|
String* parameterType = Getattr(p, "type");
|
||||||
|
|
||||||
|
Putc(',',arglist);
|
||||||
|
if ((tm = Getattr(p, "tmap:directorin")) != 0) {
|
||||||
|
sprintf(source, "obj%d", idx++);
|
||||||
|
Replaceall(tm, "$input", source);
|
||||||
|
Replaceall(tm, "$owner", "0");
|
||||||
|
Printv(wrap_args, tm, "\n", NIL);
|
||||||
|
Wrapper_add_localv(w, source, "VALUE", source, "= Qnil", NIL);
|
||||||
|
Printv(arglist, source, NIL);
|
||||||
|
p = Getattr(p, "tmap:directorin:next");
|
||||||
|
continue;
|
||||||
|
} else if (Cmp(parameterType, "void")) {
|
||||||
|
/**
|
||||||
|
* Special handling for pointers to other C++ director classes.
|
||||||
|
* Ideally this would be left to a typemap, but there is currently no
|
||||||
|
* way to selectively apply the dynamic_cast<> to classes that have
|
||||||
|
* directors. In other words, the type "SwigDirector_$1_lname" only exists
|
||||||
|
* for classes with directors. We avoid the problem here by checking
|
||||||
|
* module.wrap::directormap, but it's not clear how to get a typemap to
|
||||||
|
* do something similar. Perhaps a new default typemap (in addition
|
||||||
|
* to SWIGTYPE) called DIRECTORTYPE?
|
||||||
|
*/
|
||||||
|
if (SwigType_ispointer(parameterType) || SwigType_isreference(parameterType)) {
|
||||||
|
Node *modname = Getattr(parent, "module");
|
||||||
|
Node *target = Swig_directormap(modname, parameterType);
|
||||||
|
sprintf(source, "obj%d", idx++);
|
||||||
|
String *nonconst = 0;
|
||||||
|
/* strip pointer/reference --- should move to Swig/stype.c */
|
||||||
|
String *nptype = NewString(Char(parameterType)+2);
|
||||||
|
/* name as pointer */
|
||||||
|
String *ppname = Copy(parameterName);
|
||||||
|
if (SwigType_isreference(parameterType)) {
|
||||||
|
Insert(ppname,0,"&");
|
||||||
|
}
|
||||||
|
/* if necessary, cast away const since Ruby doesn't support it! */
|
||||||
|
if (SwigType_isconst(nptype)) {
|
||||||
|
nonconst = NewStringf("nc_tmp_%s", parameterName);
|
||||||
|
String *nonconst_i = NewStringf("= const_cast<%s>(%s)", SwigType_lstr(parameterType, 0), ppname);
|
||||||
|
Wrapper_add_localv(w, nonconst, SwigType_lstr(parameterType, 0), nonconst, nonconst_i, NIL);
|
||||||
|
Delete(nonconst_i);
|
||||||
|
Swig_warning(WARN_LANG_DISCARD_CONST, input_file, line_number,
|
||||||
|
"Target language argument '%s' discards const in director method %s::%s.\n", SwigType_str(parameterType, parameterName), classname, name);
|
||||||
|
} else {
|
||||||
|
nonconst = Copy(ppname);
|
||||||
|
}
|
||||||
|
Delete(nptype);
|
||||||
|
Delete(ppname);
|
||||||
|
String *mangle = SwigType_manglestr(parameterType);
|
||||||
|
if (target) {
|
||||||
|
String *director = NewStringf("director_%s", mangle);
|
||||||
|
Wrapper_add_localv(w, director, "Swig::Director *", director, "= 0", NIL);
|
||||||
|
Wrapper_add_localv(w, source, "VALUE", source, "= Qnil", NIL);
|
||||||
|
Printf(wrap_args, "%s = dynamic_cast<Swig::Director *>(%s);\n", director, nonconst);
|
||||||
|
Printf(wrap_args, "if (!%s) {\n", director);
|
||||||
|
Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
|
||||||
|
Printf(wrap_args, "} else {\n");
|
||||||
|
Printf(wrap_args, "%s = %s->swig_get_self();\n", source, director);
|
||||||
|
Printf(wrap_args, "}\n");
|
||||||
|
Delete(director);
|
||||||
|
Printv(arglist, source, NIL);
|
||||||
|
} else {
|
||||||
|
Wrapper_add_localv(w, source, "VALUE", source, "= Qnil", NIL);
|
||||||
|
Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n",
|
||||||
|
source, nonconst, mangle);
|
||||||
|
//Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE_p_%s, 0);\n",
|
||||||
|
// source, nonconst, base);
|
||||||
|
Printv(arglist, source, NIL);
|
||||||
|
}
|
||||||
|
Delete(mangle);
|
||||||
|
Delete(nonconst);
|
||||||
|
} else {
|
||||||
|
Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file, line_number,
|
||||||
|
"Unable to use type %s as a function argument in director method %s::%s (skipping method).\n", SwigType_str(parameterType, 0), classname, name);
|
||||||
|
status = SWIG_NOWRAP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Replaceall(tm, "$result", Getattr(p, "name"));
|
|
||||||
Printv(w->code, tm, "\n", NIL);
|
|
||||||
p = Getattr(p, "tmap:directorargout:next");
|
|
||||||
} else {
|
|
||||||
p = nextSibling(p);
|
p = nextSibling(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* declare Ruby return value */
|
||||||
|
Wrapper_add_local(w, "result", "VALUE result");
|
||||||
|
|
||||||
|
/* wrap complex arguments to VALUEs */
|
||||||
|
Printv(w->code, wrap_args, NIL);
|
||||||
|
|
||||||
|
/* pass the method call on to the Ruby object */
|
||||||
|
exceptionSafeMethodCall(classname, n, w, idx, arglist);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ruby method may return a simple object, or an Array of objects.
|
||||||
|
* For in/out arguments, we have to extract the appropriate VALUEs from the Array,
|
||||||
|
* then marshal everything back to C/C++ (return value and output arguments).
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Marshal return value and other outputs (if any) from VALUE to C/C++ type */
|
||||||
|
|
||||||
|
String* cleanup = NewString("");
|
||||||
|
String* outarg = NewString("");
|
||||||
|
|
||||||
|
if (outputs > 1) {
|
||||||
|
Wrapper_add_local(w, "output", "VALUE output");
|
||||||
|
Printf(w->code, "if (TYPE(result) != T_ARRAY) {\n");
|
||||||
|
Printf(w->code, "throw Swig::DirectorTypeMismatchException(\"Ruby method failed to return an array.\");\n");
|
||||||
|
Printf(w->code, "}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
idx = 0;
|
||||||
|
|
||||||
|
/* Marshal return value */
|
||||||
|
if (!is_void) {
|
||||||
|
/* This seems really silly. The node's type excludes qualifier/pointer/reference markers,
|
||||||
|
* which have to be retrieved from the decl field to construct return_type. But the typemap
|
||||||
|
* lookup routine uses the node's type, so we have to swap in and out the correct type.
|
||||||
|
* It's not just me, similar silliness also occurs in Language::cDeclaration().
|
||||||
|
*/
|
||||||
|
Setattr(n, "type", return_type);
|
||||||
|
tm = Swig_typemap_lookup_new("directorout", n, "result", w);
|
||||||
|
Setattr(n, "type", type);
|
||||||
|
if (tm == 0) {
|
||||||
|
String *name = NewString("result");
|
||||||
|
tm = Swig_typemap_search("directorout", return_type, name, NULL);
|
||||||
|
Delete(name);
|
||||||
|
}
|
||||||
|
if (tm != 0) {
|
||||||
|
if (outputs > 1) {
|
||||||
|
Printf(w->code, "output = rb_ary_entry(result, %d);\n", idx++);
|
||||||
|
Replaceall(tm, "$input", "output");
|
||||||
|
} else {
|
||||||
|
Replaceall(tm, "$input", "result");
|
||||||
|
}
|
||||||
|
/* TODO check this */
|
||||||
|
if (Getattr(n,"wrap:disown")) {
|
||||||
|
Replaceall(tm,"$disown","SWIG_POINTER_DISOWN");
|
||||||
|
} else {
|
||||||
|
Replaceall(tm,"$disown","0");
|
||||||
|
}
|
||||||
|
Replaceall(tm, "$result", "c_result");
|
||||||
|
Printv(w->code, tm, "\n", NIL);
|
||||||
|
} else {
|
||||||
|
Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
|
||||||
|
"Unable to use return type %s in director method %s::%s (skipping method).\n", SwigType_str(return_type, 0), classname, name);
|
||||||
|
status = SWIG_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Marshal outputs */
|
||||||
|
for (p = l; p; ) {
|
||||||
|
if ((tm = Getattr(p, "tmap:directorargout")) != 0) {
|
||||||
|
if (outputs > 1) {
|
||||||
|
Printf(w->code, "output = rb_ary_entry(result, %d);\n", idx++);
|
||||||
|
Replaceall(tm, "$input", "output");
|
||||||
|
} else {
|
||||||
|
Replaceall(tm, "$input", "result");
|
||||||
|
}
|
||||||
|
Replaceall(tm, "$result", Getattr(p, "name"));
|
||||||
|
Printv(w->code, tm, "\n", NIL);
|
||||||
|
p = Getattr(p, "tmap:directorargout:next");
|
||||||
|
} else {
|
||||||
|
p = nextSibling(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Delete(arglist);
|
||||||
|
Delete(cleanup);
|
||||||
|
Delete(outarg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* any existing helper functions to handle this? */
|
/* any existing helper functions to handle this? */
|
||||||
if (!is_void) {
|
if (!is_void) {
|
||||||
String* rettype = SwigType_str(return_type, 0);
|
if (!(ignored_method && !pure_virtual)) {
|
||||||
if (!SwigType_isreference(return_type)) {
|
String* rettype = SwigType_str(return_type, 0);
|
||||||
Printf(w->code, "return (%s) c_result;\n", rettype);
|
if (!SwigType_isreference(return_type)) {
|
||||||
} else {
|
Printf(w->code, "return (%s) c_result;\n", rettype);
|
||||||
Printf(w->code, "return (%s) *c_result;\n", rettype);
|
} else {
|
||||||
|
Printf(w->code, "return (%s) *c_result;\n", rettype);
|
||||||
|
}
|
||||||
|
Delete(rettype);
|
||||||
}
|
}
|
||||||
Delete(rettype);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Printf(w->code, "}\n");
|
Printf(w->code, "}\n");
|
||||||
|
|
||||||
// We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method
|
// We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method
|
||||||
|
|
@ -2617,12 +2637,9 @@ public:
|
||||||
|
|
||||||
/* clean up */
|
/* clean up */
|
||||||
Delete(wrap_args);
|
Delete(wrap_args);
|
||||||
Delete(arglist);
|
|
||||||
Delete(rtype);
|
Delete(rtype);
|
||||||
Delete(return_type);
|
Delete(return_type);
|
||||||
Delete(pclassname);
|
Delete(pclassname);
|
||||||
Delete(cleanup);
|
|
||||||
Delete(outarg);
|
|
||||||
DelWrapper(w);
|
DelWrapper(w);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue