Add the optimal attribute to the out typemap for more optimal code generation when returning objects by value

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@10450 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
William S Fulton 2008-05-14 22:12:31 +00:00
commit 336b50b43d
39 changed files with 726 additions and 833 deletions

View file

@ -2517,7 +2517,7 @@ int ALLEGROCL::emit_defun(Node *n, File *f_cl) {
int ALLEGROCL::functionWrapper(Node *n) {
ParmList *parms = CopyParmList(Getattr(n, "parms"));
Wrapper *wrap = NewWrapper();
Wrapper *f = NewWrapper();
String *raw_return_type = Swig_typemap_lookup_new("ctype", n, "", 0);
SwigType *return_type = Swig_cparse_type(raw_return_type);
@ -2528,18 +2528,18 @@ int ALLEGROCL::functionWrapper(Node *n) {
if (!is_void_return) {
String *lresult_init = NewStringf("= (%s)0", raw_return_type);
Wrapper_add_localv(wrap, "lresult",
Wrapper_add_localv(f, "lresult",
SwigType_lstr(SwigType_ltype(return_type), "lresult"),
lresult_init, NIL);
Delete(lresult_init);
}
// Emit all of the local variables for holding arguments.
emit_args(Getattr(n, "type"), parms, wrap);
emit_parameter_variables(parms, f);
// Attach the standard typemaps
Swig_typemap_attach_parms("ctype", parms, wrap);
Swig_typemap_attach_parms("lin", parms, wrap);
emit_attach_parmmaps(parms, wrap);
Swig_typemap_attach_parms("ctype", parms, f);
Swig_typemap_attach_parms("lin", parms, f);
emit_attach_parmmaps(parms, f);
String *mangled = mangle_name(n);
Node *overloaded = Getattr(n, "sym:overloaded");
@ -2562,7 +2562,7 @@ int ALLEGROCL::functionWrapper(Node *n) {
emit_buffered_defuns(n);
emit_dispatch_defun(n);
}
DelWrapper(wrap);
DelWrapper(f);
return SWIG_OK;
}
}
@ -2609,7 +2609,7 @@ int ALLEGROCL::functionWrapper(Node *n) {
// canThrow(n, "in", p);
Replaceall(parm_code, "$input", arg);
Setattr(p, "emit:input", arg);
Printf(wrap->code, "%s\n", parm_code);
Printf(f->code, "%s\n", parm_code);
p = Getattr(p, "tmap:in:next");
}
@ -2619,28 +2619,30 @@ int ALLEGROCL::functionWrapper(Node *n) {
// Emit the function definition
String *signature = SwigType_str(return_type, name_and_parms);
Printf(wrap->def, "EXPORT %s {", signature);
Printf(f->def, "EXPORT %s {", signature);
if (CPlusPlus)
Printf(wrap->code, " try {\n");
emit_action(n, wrap);
if (!is_void_return) {
String *result_convert = Swig_typemap_lookup_new("out", n, "result", 0);
Replaceall(result_convert, "$result", "lresult");
Printf(wrap->code, "%s\n", result_convert);
Printf(wrap->code, " return lresult;\n");
Delete(result_convert);
}
Printf(f->code, " try {\n");
String *actioncode = emit_action(n);
String *result_convert = Swig_typemap_lookup_out("out", n, "result", f, actioncode);
Replaceall(result_convert, "$result", "lresult");
Printf(f->code, "%s\n", result_convert);
Printf(f->code, " return lresult;\n");
Delete(result_convert);
emit_return_variable(n, Getattr(n, "type"), f);
if (CPlusPlus) {
Printf(wrap->code, " } catch (...) {\n");
Printf(f->code, " } catch (...) {\n");
if (!is_void_return)
Printf(wrap->code, " return (%s)0;\n", raw_return_type);
Printf(wrap->code, " }\n");
Printf(f->code, " return (%s)0;\n", raw_return_type);
Printf(f->code, " }\n");
}
Printf(wrap->code, "}\n");
Printf(f->code, "}\n");
/* print this when in C mode? make this a command-line arg? */
if (Generate_Wrapper)
Wrapper_print(wrap, f_cxx);
Wrapper_print(f, f_cxx);
String *f_buffer = NewString("");
@ -2656,7 +2658,7 @@ int ALLEGROCL::functionWrapper(Node *n) {
}
}
DelWrapper(wrap);
DelWrapper(f);
return SWIG_OK;
}

View file

@ -354,7 +354,7 @@ int CFFI::functionWrapper(Node *n) {
ParmList *parms = Getattr(n, "parms");
String *iname = Getattr(n, "sym:name");
Wrapper *wrap = NewWrapper();
Wrapper *f = NewWrapper();
String *raw_return_type = Swig_typemap_lookup_new("ctype", n, "", 0);
SwigType *return_type = Swig_cparse_type(raw_return_type);
@ -364,7 +364,7 @@ int CFFI::functionWrapper(Node *n) {
if (!is_void_return) {
String *lresult_init = NewStringf("lresult = (%s)0", raw_return_type);
Wrapper_add_localv(wrap, "lresult", raw_return_type, lresult_init, NIL);
Wrapper_add_localv(f, "lresult", raw_return_type, lresult_init, NIL);
Delete(lresult_init);
}
@ -373,7 +373,7 @@ int CFFI::functionWrapper(Node *n) {
overname = Getattr(n, "sym:overname");
} else {
if (!addSymbol(iname, n)) {
DelWrapper(wrap);
DelWrapper(f);
return SWIG_ERROR;
}
}
@ -385,11 +385,11 @@ int CFFI::functionWrapper(Node *n) {
Setattr(n, "wrap:name", wname);
// Emit all of the local variables for holding arguments.
emit_args(Getattr(n, "type"), parms, wrap);
emit_parameter_variables(parms, f);
// Attach the standard typemaps
Swig_typemap_attach_parms("ctype", parms, wrap);
emit_attach_parmmaps(parms, wrap);
Swig_typemap_attach_parms("ctype", parms, f);
emit_attach_parmmaps(parms, f);
int num_arguments = emit_num_arguments(parms);
String *name_and_parms = NewStringf("%s (", wname);
@ -426,7 +426,7 @@ int CFFI::functionWrapper(Node *n) {
{
Replaceall(parm_code, "$input", arg);
Setattr(p, "emit:input", arg);
Printf(wrap->code, "%s\n", parm_code);
Printf(f->code, "%s\n", parm_code);
p = Getattr(p, "tmap:in:next");
}
@ -436,25 +436,26 @@ int CFFI::functionWrapper(Node *n) {
// Emit the function definition
String *signature = SwigType_str(return_type, name_and_parms);
Printf(wrap->def, "EXPORT %s {", signature);
Printf(wrap->code, " try {\n");
emit_action(n, wrap);
if (!is_void_return) {
String *result_convert = Swig_typemap_lookup_new("out", n, "result", 0);
Replaceall(result_convert, "$result", "lresult");
Printf(wrap->code, "%s\n", result_convert);
Printf(wrap->code, " return lresult;\n");
Delete(result_convert);
}
Printf(f->def, "EXPORT %s {", signature);
Printf(f->code, " try {\n");
Printf(wrap->code, " } catch (...) {\n");
String *actioncode = emit_action(n);
String *result_convert = Swig_typemap_lookup_out("out", n, "result", f, actioncode);
Replaceall(result_convert, "$result", "lresult");
Printf(f->code, "%s\n", result_convert);
Printf(f->code, " return lresult;\n");
Delete(result_convert);
emit_return_variable(n, Getattr(n, "type"), f);
Printf(f->code, " } catch (...) {\n");
if (!is_void_return)
Printf(wrap->code, " return (%s)0;\n", raw_return_type);
Printf(wrap->code, " }\n");
Printf(wrap->code, "}\n");
Printf(f->code, " return (%s)0;\n", raw_return_type);
Printf(f->code, " }\n");
Printf(f->code, "}\n");
if (CPlusPlus)
Wrapper_print(wrap, f_cxx);
Wrapper_print(f, f_cxx);
if (CPlusPlus) {
emit_defun(n, wname);
@ -482,7 +483,7 @@ int CFFI::functionWrapper(Node *n) {
// }
Delete(wname);
DelWrapper(wrap);
DelWrapper(f);
return SWIG_OK;
}

View file

@ -368,7 +368,7 @@ int CHICKEN::functionWrapper(Node *n) {
Wrapper_add_local(f, "resultobj", "C_word resultobj");
/* Write code to extract function parameters. */
emit_args(d, l, f);
emit_parameter_variables(l, f);
/* Attach the standard typemaps */
emit_attach_parmmaps(l, f);
@ -501,11 +501,6 @@ int CHICKEN::functionWrapper(Node *n) {
}
}
Setattr(n, "wrap:name", wname);
/* Emit the function call */
emit_action(n, f);
/* Insert argument output code */
have_argout = 0;
for (p = l; p;) {
@ -514,7 +509,7 @@ int CHICKEN::functionWrapper(Node *n) {
if (!have_argout) {
have_argout = 1;
// Print initial argument output code
Printf(f->code, "SWIG_Chicken_SetupArgout\n");
Printf(argout, "SWIG_Chicken_SetupArgout\n");
}
Replaceall(tm, "$source", Getattr(p, "lname"));
@ -528,8 +523,13 @@ int CHICKEN::functionWrapper(Node *n) {
}
}
Setattr(n, "wrap:name", wname);
/* Emit the function call */
String *actioncode = emit_action(n);
/* Return the function value */
if ((tm = Swig_typemap_lookup_new("out", n, "result", 0))) {
if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
Replaceall(tm, "$source", "result");
Replaceall(tm, "$target", "resultobj");
Replaceall(tm, "$result", "resultobj");
@ -547,6 +547,7 @@ int CHICKEN::functionWrapper(Node *n) {
} else {
Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), name);
}
emit_return_variable(n, d, f);
/* Insert the argumetn output code */
Printv(f->code, argout, NIL);
@ -731,7 +732,7 @@ int CHICKEN::variableWrapper(Node *n) {
Replaceall(tm, "$target", name);
Replaceall(tm, "$input", "value");
/* Printv(f->code, tm, "\n",NIL); */
emit_action_code(n, f, tm);
emit_action_code(n, f->code, tm);
} else {
Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0));
}
@ -753,7 +754,7 @@ int CHICKEN::variableWrapper(Node *n) {
Replaceall(tm, "$target", "resultobj");
Replaceall(tm, "$result", "resultobj");
/* Printf(f->code, "%s\n", tm); */
emit_action_code(n, f, tm);
emit_action_code(n, f->code, tm);
} else {
Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0));
}
@ -926,7 +927,7 @@ int CHICKEN::constantWrapper(Node *n) {
Replaceall(tm, "$target", "resultobj");
Replaceall(tm, "$result", "resultobj");
/* Printf(f->code, "%s\n", tm); */
emit_action_code(n, f, tm);
emit_action_code(n, f->code, tm);
} else {
Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0));
}

View file

@ -757,7 +757,7 @@ public:
Printv(f->def, " SWIGEXPORT ", c_return_type, " SWIGSTDCALL ", wname, "(", NIL);
// Emit all of the local variables for holding arguments.
emit_args(t, l, f);
emit_parameter_variables(l, f);
/* Attach the standard typemaps */
emit_attach_parmmaps(l, f);
@ -901,25 +901,26 @@ public:
}
}
if (Cmp(nodeType(n), "constant") == 0) {
// Wrapping a constant hack
Swig_save("functionWrapper", n, "wrap:action", NIL);
// below based on Swig_VargetToFunction()
SwigType *ty = Swig_wrapped_var_type(Getattr(n, "type"), use_naturalvar_mode(n));
Setattr(n, "wrap:action", NewStringf("result = (%s) %s;", SwigType_lstr(ty, 0), Getattr(n, "value")));
}
// Now write code to make the function call
if (!native_function_flag)
emit_action(n, f);
if (Cmp(nodeType(n), "constant") == 0)
Swig_restore(n);
/* Return value if necessary */
String *null_attribute = 0;
// Now write code to make the function call
if (!native_function_flag) {
if ((tm = Swig_typemap_lookup_new("out", n, "result", 0))) {
if (Cmp(nodeType(n), "constant") == 0) {
// Wrapping a constant hack
Swig_save("functionWrapper", n, "wrap:action", NIL);
// below based on Swig_VargetToFunction()
SwigType *ty = Swig_wrapped_var_type(Getattr(n, "type"), use_naturalvar_mode(n));
Setattr(n, "wrap:action", NewStringf("result = (%s) %s;", SwigType_lstr(ty, 0), Getattr(n, "value")));
}
Swig_director_emit_dynamic_cast(n, f);
String *actioncode = emit_action(n);
if (Cmp(nodeType(n), "constant") == 0)
Swig_restore(n);
/* Return value if necessary */
if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
canThrow(n, "out", n);
Replaceall(tm, "$source", "result"); /* deprecated */
Replaceall(tm, "$target", "jresult"); /* deprecated */
@ -937,6 +938,7 @@ public:
} else {
Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(t, 0), Getattr(n, "name"));
}
emit_return_variable(n, t, f);
}
/* Output argument output code */
@ -3463,9 +3465,6 @@ public:
// Get any Java exception classes in the throws typemap
ParmList *throw_parm_list = NULL;
if ((tm = Swig_typemap_lookup_new("out", n, "", 0)))
addThrows(n, "tmap:out", n);
if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
int gencomma = 0;
@ -3507,8 +3506,7 @@ public:
if (!is_void) {
Parm *tp = NewParmFromNode(returntype, empty_str, n);
tm = Swig_typemap_lookup_new("csdirectorout", tp, "", 0);
if (tm) {
if ((tm = Swig_typemap_lookup_new("csdirectorout", tp, "", 0))) {
substituteClassname(returntype, tm);
Replaceall(tm, "$cscall", upcall);

View file

@ -261,3 +261,28 @@ String *Swig_method_decl(SwigType *returntype, SwigType *decl, const String_or_c
return result;
}
/* -----------------------------------------------------------------------------
* Swig_director_emit_dynamic_cast()
*
* In order to call protected virtual director methods from the target language, we need
* to add an extra dynamic_cast to call the public C++ wrapper in the director class.
* Also for non-static protected members when the allprotected option is on.
* ----------------------------------------------------------------------------- */
void Swig_director_emit_dynamic_cast(Node *n, Wrapper *f) {
// TODO: why is the storage element removed in staticmemberfunctionHandler ??
if ((!is_public(n) && (is_member_director(n) || GetFlag(n, "explicitcall"))) ||
(is_non_virtual_protected_access(n) && !(checkAttribute(n, "staticmemberfunctionHandler:storage", "static") ||
checkAttribute(n, "storage", "static"))
&& !Equal(nodeType(n), "constructor"))) {
Node *parent = Getattr(n, "parentNode");
String *symname = Getattr(parent, "sym:name");
String *dirname = NewStringf("SwigDirector_%s", symname);
String *dirdecl = NewStringf("%s *darg = 0", dirname);
Wrapper_add_local(f, "darg", dirdecl);
Printf(f->code, "darg = dynamic_cast<%s *>(arg1);\n", dirname);
Delete(dirname);
Delete(dirdecl);
}
}

View file

@ -12,16 +12,47 @@ char cvsroot_emit_cxx[] = "$Id$";
#include "swigmod.h"
/* -----------------------------------------------------------------------------
* emit_args()
* emit_return_variable()
*
* Creates a list of variable declarations for both the return value
* and function parameters.
*
* The return value is always called result and arguments arg0, arg1, arg2, etc...
* Returns the number of parameters associated with a function.
* Emits a variable declaration for a function return value.
* The variable name is always called result.
* n => Node of the method being wrapped
* rt => the return type
* f => the wrapper to generate code into
* ----------------------------------------------------------------------------- */
void emit_args(SwigType *rt, ParmList *l, Wrapper *f) {
void emit_return_variable(Node *n, SwigType *rt, Wrapper *f) {
if (!GetFlag(n, "tmap:out:optimal")) {
if (rt && (SwigType_type(rt) != T_VOID)) {
SwigType *vt = cplus_value_type(rt);
SwigType *tt = vt ? vt : rt;
SwigType *lt = SwigType_ltype(tt);
String *lstr = SwigType_str(lt, "result");
if (SwigType_ispointer(lt)) {
Wrapper_add_localv(f, "result", lstr, "= 0", NULL);
} else {
Wrapper_add_local(f, "result", lstr);
}
if (vt) {
Delete(vt);
}
Delete(lt);
Delete(lstr);
}
}
}
/* -----------------------------------------------------------------------------
* emit_parameter_variables()
*
* Emits a list of variable declarations for function parameters.
* The variable names are always called arg1, arg2, etc...
* l => the parameter list
* f => the wrapper to generate code into
* ----------------------------------------------------------------------------- */
void emit_parameter_variables(ParmList *l, Wrapper *f) {
Parm *p;
String *tm;
@ -29,24 +60,6 @@ void emit_args(SwigType *rt, ParmList *l, Wrapper *f) {
/* Emit function arguments */
Swig_cargs(f, l);
/* Handle return type */
if (rt && (SwigType_type(rt) != T_VOID)) {
SwigType *vt = cplus_value_type(rt);
SwigType *tt = vt ? vt : rt;
SwigType *lt = SwigType_ltype(tt);
String *lstr = SwigType_str(lt, "result");
if (SwigType_ispointer(lt)) {
Wrapper_add_localv(f, "result", lstr, "= 0", NULL);
} else {
Wrapper_add_local(f, "result", lstr);
}
if (vt) {
Delete(vt);
}
Delete(lt);
Delete(lstr);
}
/* Attach typemaps to parameters */
/* Swig_typemap_attach_parms("ignore",l,f); */
@ -78,7 +91,6 @@ void emit_args(SwigType *rt, ParmList *l, Wrapper *f) {
p = nextSibling(p);
}
}
return;
}
/* -----------------------------------------------------------------------------
@ -332,11 +344,13 @@ static void replace_contract_args(Parm *cp, Parm *rp, String *s) {
#endif
/* -----------------------------------------------------------------------------
* int emit_action()
* int emit_action_code()
*
* Emits action code for a wrapper. Adds in exception handling code (%exception).
* eaction -> the action code to emit
* wrappercode -> the emitted code (output)
* ----------------------------------------------------------------------------- */
int emit_action_code(Node *n, Wrapper *f, String *eaction) {
int emit_action_code(Node *n, String *wrappercode, String *eaction) {
assert(Getattr(n, "wrap:name"));
/* Look for except feature (%exception) */
@ -364,16 +378,23 @@ int emit_action_code(Node *n, Wrapper *f, String *eaction) {
Delete(fulldecl);
}
}
Printv(f->code, tm, "\n", NIL);
Printv(wrappercode, tm, "\n", NIL);
Delete(tm);
return 1;
} else {
Printv(f->code, eaction, "\n", NIL);
Printv(wrappercode, eaction, "\n", NIL);
return 0;
}
}
void emit_action(Node *n, Wrapper *f) {
/* -----------------------------------------------------------------------------
* int emit_action()
*
* Emits the call to the wrapped function.
* Adds in exception specification exception handling and %exception code.
* ----------------------------------------------------------------------------- */
String *emit_action(Node *n) {
String *actioncode = NewStringEmpty();
String *tm;
String *action;
String *wrap;
@ -382,11 +403,10 @@ void emit_action(Node *n, Wrapper *f) {
/* Look for fragments */
{
String *f;
f = Getattr(n, "feature:fragment");
if (f) {
String *fragment = Getattr(n, "feature:fragment");
if (fragment) {
char *c, *tok;
String *t = Copy(f);
String *t = Copy(fragment);
c = Char(t);
tok = strtok(c, ",");
while (tok) {
@ -416,27 +436,7 @@ void emit_action(Node *n, Wrapper *f) {
action = Getattr(n, "wrap:action");
assert(action != 0);
/* In order to call protected virtual director methods from the target language, we need
* to add an extra dynamic_cast to call the public C++ wrapper in the director class.
* Also for non-static protected members when the allprotected option is on. */
// TODO: why is the storage element removed in staticmemberfunctionHandler ??
if ((!is_public(n) && (is_member_director(n) || GetFlag(n, "explicitcall"))) ||
(is_non_virtual_protected_access(n) && !(checkAttribute(n, "staticmemberfunctionHandler:storage", "static") ||
checkAttribute(n, "storage", "static"))
&& !Equal(nodeType(n), "constructor"))) {
Node *parent = Getattr(n, "parentNode");
String *symname = Getattr(parent, "sym:name");
String *dirname = NewStringf("SwigDirector_%s", symname);
String *dirdecl = NewStringf("%s *darg = 0", dirname);
Wrapper_add_local(f, "darg", dirdecl);
Printf(f->code, "darg = dynamic_cast<%s *>(arg1);\n", dirname);
Delete(dirname);
Delete(dirdecl);
}
/* Get the return type */
rt = Getattr(n, "type");
/* Emit contract code (if any) */
@ -444,7 +444,7 @@ void emit_action(Node *n, Wrapper *f) {
/* Preassertion */
tm = Getattr(n, "contract:preassert");
if (Len(tm)) {
Printv(f->code, tm, "\n", NIL);
Printv(actioncode, tm, "\n", NIL);
}
}
/* Exception handling code */
@ -495,7 +495,7 @@ void emit_action(Node *n, Wrapper *f) {
}
/* emit the except feature code */
emit_action_code(n, f, eaction);
emit_action_code(n, actioncode, eaction);
Delete(eaction);
@ -504,8 +504,9 @@ void emit_action(Node *n, Wrapper *f) {
/* Postassertion */
tm = Getattr(n, "contract:postassert");
if (Len(tm)) {
Printv(f->code, tm, "\n", NIL);
Printv(actioncode, tm, "\n", NIL);
}
}
return actioncode;
}

View file

@ -687,7 +687,7 @@ public:
Replaceall(proc_name, "_", "-");
/* Emit locals etc. into f->code; figure out which args to ignore */
emit_args(d, l, f);
emit_parameter_variables(l, f);
/* Attach the standard typemaps */
emit_attach_parmmaps(l, f);
@ -702,25 +702,6 @@ public:
Wrapper_add_local(f, "gswig_result", "SCM gswig_result");
Wrapper_add_local(f, "gswig_list_p", "SWIGUNUSED int gswig_list_p = 0");
/* Get the output typemap so we can start generating documentation. Don't
worry, the returned string is saved as 'tmap:out' */
Swig_typemap_lookup_new("out", n, "result", 0);
if ((tm = Getattr(n, "tmap:out:doc"))) {
Printv(returns, tm, NIL);
if (Len(tm) > 0)
num_results = 1;
else
num_results = 0;
} else {
String *s = SwigType_str(d, 0);
Chop(s);
Printf(returns, "<%s>", s);
Delete(s);
num_results = 1;
}
/* Open prototype and signature */
Printv(f->def, "static SCM\n", wname, " (", NIL);
@ -830,6 +811,7 @@ public:
/* Pass output arguments back to the caller. */
/* Insert argument output code */
String *returns_argout = NewString("");
for (p = l; p;) {
if ((tm = Getattr(p, "tmap:argout"))) {
Replaceall(tm, "$source", Getattr(p, "lname"));
@ -838,7 +820,7 @@ public:
Replaceall(tm, "$input", Getattr(p, "emit:input"));
Printv(outarg, tm, "\n", NIL);
if (procdoc) {
if (handle_documentation_typemap(returns, ", ", p, "tmap:argout:doc", "$NAME (of type $type)")) {
if (handle_documentation_typemap(returns_argout, ", ", p, "tmap:argout:doc", "$NAME (of type $type)")) {
/* A documentation typemap that is not the empty string
indicates that a value is returned to Scheme. */
num_results++;
@ -881,13 +863,14 @@ public:
// Now write code to make the function call
if (!use_scm_interface)
Printv(f->code, tab4, "gh_defer_ints();\n", NIL);
emit_action(n, f);
String *actioncode = emit_action(n);
if (!use_scm_interface)
Printv(f->code, tab4, "gh_allow_ints();\n", NIL);
Printv(actioncode, tab4, "gh_allow_ints();\n", NIL);
// Now have return value, figure out what to do with it.
if ((tm = Getattr(n, "tmap:out"))) {
if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
Replaceall(tm, "$result", "gswig_result");
Replaceall(tm, "$target", "gswig_result");
Replaceall(tm, "$source", "result");
@ -899,6 +882,24 @@ public:
} else {
throw_unhandled_guile_type_error(d);
}
emit_return_variable(n, d, f);
// Documentation
if ((tm = Getattr(n, "tmap:out:doc"))) {
Printv(returns, tm, NIL);
if (Len(tm) > 0)
num_results = 1;
else
num_results = 0;
} else {
String *s = SwigType_str(d, 0);
Chop(s);
Printf(returns, "<%s>", s);
Delete(s);
num_results = 1;
}
Append(returns, returns_argout);
// Dump the argument output code
Printv(f->code, outarg, NIL);
@ -1123,6 +1124,7 @@ public:
Delete(method_signature);
Delete(primitive_args);
Delete(doc_body);
Delete(returns_argout);
Delete(returns);
Delete(tmp);
Delete(scheme_arg_names);
@ -1182,7 +1184,7 @@ public:
Replaceall(tm, "$input", "s_0");
Replaceall(tm, "$target", name);
/* Printv(f->code,tm,"\n",NIL); */
emit_action_code(n, f, tm);
emit_action_code(n, f->code, tm);
} else {
throw_unhandled_guile_type_error(t);
}
@ -1196,7 +1198,7 @@ public:
Replaceall(tm, "$target", "gswig_result");
Replaceall(tm, "$result", "gswig_result");
/* Printv(f->code,tm,"\n",NIL); */
emit_action_code(n, f, tm);
emit_action_code(n, f->code, tm);
} else {
throw_unhandled_guile_type_error(t);
}

View file

@ -829,7 +829,7 @@ public:
Printv(f->code, " (void)jcls;\n", NIL);
// Emit all of the local variables for holding arguments.
emit_args(t, l, f);
emit_parameter_variables(l, f);
/* Attach the standard typemaps */
emit_attach_parmmaps(l, f);
@ -980,27 +980,28 @@ public:
}
}
if (Cmp(nodeType(n), "constant") == 0) {
// Wrapping a constant hack
Swig_save("functionWrapper", n, "wrap:action", NIL);
// below based on Swig_VargetToFunction()
SwigType *ty = Swig_wrapped_var_type(Getattr(n, "type"), use_naturalvar_mode(n));
Setattr(n, "wrap:action", NewStringf("result = (%s) %s;", SwigType_lstr(ty, 0), Getattr(n, "value")));
}
// Now write code to make the function call
if (!native_function_flag) {
emit_action(n, f);
if (Cmp(nodeType(n), "constant") == 0) {
// Wrapping a constant hack
Swig_save("functionWrapper", n, "wrap:action", NIL);
// below based on Swig_VargetToFunction()
SwigType *ty = Swig_wrapped_var_type(Getattr(n, "type"), use_naturalvar_mode(n));
Setattr(n, "wrap:action", NewStringf("result = (%s) %s;", SwigType_lstr(ty, 0), Getattr(n, "value")));
}
// Now write code to make the function call
Swig_director_emit_dynamic_cast(n, f);
String *actioncode = emit_action(n);
// Handle exception classes specified in the "except" feature's "throws" attribute
addThrows(n, "feature:except", n);
}
if (Cmp(nodeType(n), "constant") == 0)
Swig_restore(n);
if (Cmp(nodeType(n), "constant") == 0)
Swig_restore(n);
/* Return value if necessary */
if (!native_function_flag) {
if ((tm = Swig_typemap_lookup_new("out", n, "result", 0))) {
/* Return value if necessary */
if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
addThrows(n, "tmap:out", n);
Replaceall(tm, "$source", "result"); /* deprecated */
Replaceall(tm, "$target", "jresult"); /* deprecated */
@ -1017,6 +1018,7 @@ public:
} else {
Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(t, 0), Getattr(n, "name"));
}
emit_return_variable(n, t, f);
}
/* Output argument output code */
@ -3550,6 +3552,7 @@ public:
* intermediate's upcall code */
if ((tm = Getattr(p, "tmap:jtype"))) {
String *din = Copy(Getattr(p, "tmap:javadirectorin"));
addThrows(n, "tmap:javadirectorin", p);
if (din) {
Replaceall(din, "$module", module_class_name);
@ -3629,9 +3632,6 @@ public:
// Get any Java exception classes in the throws typemap
ParmList *throw_parm_list = NULL;
if ((tm = Swig_typemap_lookup_new("out", n, "", 0)))
addThrows(n, "tmap:out", n);
if ((throw_parm_list = Getattr(n, "throws")) || Getattr(n, "throw")) {
int gencomma = 0;
@ -3661,12 +3661,6 @@ public:
Append(w->def, " {");
Append(declaration, ";\n");
/* Finish off the inherited upcall's definition */
Putc(')', callback_def);
generateThrowsClause(n, callback_def);
Printf(callback_def, " {\n");
/* Emit the intermediate class's upcall to the actual class */
String *upcall = NewStringf("self.%s(%s)", symname, imcall_args);
@ -3674,14 +3668,17 @@ public:
if (!is_void) {
Parm *tp = NewParmFromNode(returntype, empty_str, n);
tm = Swig_typemap_lookup_new("javadirectorout", tp, "", 0);
if (tm) {
if ((tm = Swig_typemap_lookup_new("javadirectorout", tp, "", 0))) {
addThrows(n, "tmap:javadirectorout", tp);
substituteClassname(returntype, tm);
Replaceall(tm, "$javacall", upcall);
Printf(callback_code, " return %s;\n", tm);
}
if ((tm = Swig_typemap_lookup_new("out", tp, "", 0)))
addThrows(n, "tmap:out", tp);
Delete(tm);
Delete(tp);
} else
@ -3690,6 +3687,11 @@ public:
Printf(callback_code, " }\n");
Delete(upcall);
/* Finish off the inherited upcall's definition */
Putc(')', callback_def);
generateThrowsClause(n, callback_def);
Printf(callback_def, " {\n");
if (!ignored_method) {
/* Emit the actual upcall through */
String *imclass_desc = NewStringf("(%s)%s", jnidesc, jniret_desc);

View file

@ -362,7 +362,7 @@ public:
we need to add a couple of local variables
NEW LANGUAGE NOTE:END ************************************************/
Wrapper *f = NewWrapper();
Wrapper_add_local(f, "SWIG_arg", "int SWIG_arg = -1");
Wrapper_add_local(f, "SWIG_arg", "int SWIG_arg = 0");
String *wname = Swig_name_wrapper(iname);
@ -383,10 +383,9 @@ public:
it will print
int arg1;
int arg2;
int result;
NEW LANGUAGE NOTE:END ************************************************/
/* Write code to extract function parameters. */
emit_args(d, l, f);
emit_parameter_variables(l, f);
/* Attach the standard typemaps */
emit_attach_parmmaps(l, f);
@ -554,16 +553,15 @@ public:
Setattr(n, "wrap:name", wname);
/* Emit the function call */
emit_action(n, f);
String *actioncode = emit_action(n);
/* NEW LANGUAGE NOTE:***********************************************
FIXME:
returns 1 if there is a void return type
this is because there is a typemap for void
NEW LANGUAGE NOTE:END ************************************************/
Printv(f->code, "SWIG_arg=0;\n", NIL);
// Return value if necessary
if ((tm = Swig_typemap_lookup_new("out", n, "result", 0))) {
if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
// managing the number of returning variables
// if (numoutputs=Getattr(tm,"numoutputs")){
// int i=GetInt(tm,"numoutputs");
@ -582,6 +580,7 @@ public:
} else {
Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), name);
}
emit_return_variable(n, d, f);
/* Output argument output code */
Printv(f->code, outarg, NIL);

View file

@ -1304,7 +1304,7 @@ MODULA3():
Printv(f->def, " SWIGEXPORT ", c_return_type, " ", wname, "(", NIL);
// Emit all of the local variables for holding arguments.
emit_args(t, l, f);
emit_parameter_variables(l, f);
/* Attach the standard typemaps */
emit_attach_parmmaps(l, f);
@ -1420,17 +1420,15 @@ MODULA3():
// Now write code to make the function call
if (!native_function_flag) {
emit_action(n, f);
}
String *actioncode = emit_action(n);
if (Cmp(nodeType(n), "constant") == 0) {
Swig_restore(n);
}
if (Cmp(nodeType(n), "constant") == 0) {
Swig_restore(n);
}
/* Return value if necessary */
if (!native_function_flag) {
String *tm = getMappedTypeNew(n, "out", "result");
if (tm != NIL) {
/* Return value if necessary */
String *tm;
if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
addThrows(throws_hash, "out", n);
Replaceall(tm, "$source", "result"); /* deprecated */
Replaceall(tm, "$target", "cresult"); /* deprecated */
@ -1441,6 +1439,7 @@ MODULA3():
} else {
Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(t, 0), rawname);
}
emit_return_variable(n, t, f);
}
/* Output argument output code */

View file

@ -271,12 +271,8 @@ public:
macros. */
Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL);
// Declare return variable and arguments
// number of parameters
// they are called arg0, arg1, ...
// the return value is called result
emit_args(d, l, f);
// Emit all of the local variables for holding arguments.
emit_parameter_variables(l, f);
/* Attach the standard typemaps */
emit_attach_parmmaps(l, f);
@ -394,11 +390,10 @@ public:
// Now write code to make the function call
emit_action(n, f);
String *actioncode = emit_action(n);
// Now have return value, figure out what to do with it.
if ((tm = Swig_typemap_lookup_new("out", n, "result", 0))) {
if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
Replaceall(tm, "$source", "result");
Replaceall(tm, "$target", "values[0]");
Replaceall(tm, "$result", "values[0]");
@ -410,6 +405,7 @@ public:
} else {
throw_unhandled_mzscheme_type_error(d);
}
emit_return_variable(n, d, f);
// Dump the argument output code
Printv(f->code, Char(outarg), NIL);
@ -539,7 +535,7 @@ public:
Replaceall(tm, "$target", name);
Replaceall(tm, "$input", "argv[0]");
/* Printv(f->code, tm, "\n",NIL); */
emit_action_code(n, f, tm);
emit_action_code(n, f->code, tm);
} else {
throw_unhandled_mzscheme_type_error(t);
}
@ -553,7 +549,7 @@ public:
Replaceall(tm, "$target", "swig_result");
Replaceall(tm, "$result", "swig_result");
/* Printf (f->code, "%s\n", tm); */
emit_action_code(n, f, tm);
emit_action_code(n, f->code, tm);
} else {
throw_unhandled_mzscheme_type_error(t);
}

View file

@ -518,13 +518,8 @@ public:
"argv = (CAML_VALUE *)malloc( argc * sizeof( CAML_VALUE ) );\n"
"for( i = 0; i < argc; i++ ) {\n" " argv[i] = caml_list_nth(args,i);\n" "}\n", NIL);
}
// Declare return variable and arguments
// number of parameters
// they are called arg0, arg1, ...
// the return value is called result
d = SwigType_typedef_qualified(d);
emit_args(d, l, f);
emit_parameter_variables(l, f);
/* Attach the standard typemaps */
emit_attach_parmmaps(l, f);
@ -645,13 +640,12 @@ public:
Wrapper_add_local(f, "upcall", "bool upcall = false");
Append(f->code, "upcall = (director);\n");
}
// Now write code to make the function call
Swig_director_emit_dynamic_cast(n, f);
String *actioncode = emit_action(n);
emit_action(n, f);
// Now have return value, figure out what to do with it.
if ((tm = Swig_typemap_lookup_new("out", n, "result", 0))) {
if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
Replaceall(tm, "$source", "swig_result");
Replaceall(tm, "$target", "rv");
Replaceall(tm, "$result", "rv");
@ -660,6 +654,7 @@ public:
} else {
throw_unhandled_ocaml_type_error(d, "out");
}
emit_return_variable(n, d, f);
// Dump the argument output code
Printv(f->code, Char(outarg), NIL);
@ -810,7 +805,7 @@ public:
Replaceall(tm, "$target", name);
Replaceall(tm, "$input", "args");
/* Printv(f->code, tm, "\n",NIL); */
emit_action_code(n, f, tm);
emit_action_code(n, f->code, tm);
} else if ((tm = Swig_typemap_lookup_new("in", n, name, 0))) {
Replaceall(tm, "$source", "args");
Replaceall(tm, "$target", name);
@ -828,14 +823,12 @@ public:
Replaceall(tm, "$source", name);
Replaceall(tm, "$target", "swig_result");
Replaceall(tm, "$result", "swig_result");
/* Printf (f->code, "%s\n", tm); */
emit_action_code(n, f, tm);
emit_action_code(n, f->code, tm);
} else if ((tm = Swig_typemap_lookup_new("out", n, name, 0))) {
Replaceall(tm, "$source", name);
Replaceall(tm, "$target", "swig_result");
Replaceall(tm, "$result", "swig_result");
Printf(f->code, "%s\n", tm);
} else {
throw_unhandled_ocaml_type_error(t, "varout/out");
}

View file

@ -426,7 +426,7 @@ public:
Printv(f->def, "static octave_value_list ", overname, " (const octave_value_list& args, int nargout) {", NIL);
emit_args(d, l, f);
emit_parameter_variables(l, f);
emit_attach_parmmaps(l, f);
Setattr(n, "wrap:parms", l);
@ -569,14 +569,15 @@ public:
Setattr(n, "wrap:name", overname);
emit_action(n, f);
Swig_director_emit_dynamic_cast(n, f);
String *actioncode = emit_action(n);
Wrapper_add_local(f, "_out", "octave_value_list _out");
Wrapper_add_local(f, "_outp", "octave_value_list *_outp=&_out");
Wrapper_add_local(f, "_outv", "octave_value _outv");
// Return the function value
if ((tm = Swig_typemap_lookup_new("out", n, "result", 0))) {
if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
Replaceall(tm, "$source", "result");
Replaceall(tm, "$target", "_outv");
Replaceall(tm, "$result", "_outv");
@ -592,6 +593,7 @@ public:
} else {
Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), iname);
}
emit_return_variable(n, d, f);
Printv(f->code, outarg, NIL);
Printv(f->code, cleanup, NIL);
@ -690,7 +692,7 @@ public:
if (Getattr(n, "tmap:varin:implicitconv")) {
Replaceall(tm, "$implicitconv", get_implicitconv_flag(n));
}
emit_action_code(n, setf, tm);
emit_action_code(n, setf->code, tm);
Delete(tm);
} else {
Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0));
@ -711,7 +713,7 @@ public:
Replaceall(tm, "$source", name);
Replaceall(tm, "$target", "obj");
Replaceall(tm, "$result", "obj");
addfail = emit_action_code(n, getf, tm);
addfail = emit_action_code(n, getf->code, tm);
Delete(tm);
} else {
Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0));

View file

@ -589,7 +589,7 @@ public:
Printv(f->def, "XS(", wname, ") {\n", "{\n", /* scope to destroy C++ objects before croaking */
NIL);
emit_args(d, l, f);
emit_parameter_variables(l, f);
emit_attach_parmmaps(l, f);
Setattr(n, "wrap:parms", l);
@ -722,9 +722,10 @@ public:
/* Now write code to make the function call */
emit_action(n, f);
Swig_director_emit_dynamic_cast(n, f);
String *actioncode = emit_action(n);
if ((tm = Swig_typemap_lookup_new("out", n, "result", 0))) {
if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
SwigType *t = Getattr(n, "type");
Replaceall(tm, "$source", "result");
Replaceall(tm, "$target", "ST(argvi)");
@ -743,6 +744,7 @@ public:
} else {
Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), name);
}
emit_return_variable(n, d, f);
/* If there were any output args, take care of them. */
@ -860,7 +862,7 @@ public:
Replaceall(tm, "$target", name);
Replaceall(tm, "$input", "sv");
/* Printf(setf->code,"%s\n", tm); */
emit_action_code(n, setf, tm);
emit_action_code(n, setf->code, tm);
} else {
Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0));
return SWIG_NOWRAP;
@ -887,7 +889,7 @@ public:
Replaceall(tm, "$shadow", "0");
}
/* Printf(getf->code,"%s\n", tm); */
addfail = emit_action_code(n, getf, tm);
addfail = emit_action_code(n, getf->code, tm);
} else {
Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0));
DelWrapper(setf);

View file

@ -1007,7 +1007,7 @@ public:
Printv(f->def, "ZEND_NAMED_FUNCTION(", wname, ") {\n", NIL);
}
emit_args(d, l, f);
emit_parameter_variables(l, f);
/* Attach standard typemaps */
emit_attach_parmmaps(l, f);
@ -1175,9 +1175,9 @@ public:
Setattr(n, "wrap:name", wname);
/* emit function call */
emit_action(n, f);
String *actioncode = emit_action(n);
if ((tm = Swig_typemap_lookup_new("out", n, "result", 0))) {
if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
Replaceall(tm, "$input", "result");
Replaceall(tm, "$source", "result");
Replaceall(tm, "$target", "return_value");
@ -1205,6 +1205,7 @@ public:
} else {
Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), name);
}
emit_return_variable(n, d, f);
if (outarg) {
Printv(f->code, outarg, NIL);
@ -2679,24 +2680,23 @@ public:
int CreateZendListDestructor(Node *n) {
String *name = GetChar(Swig_methodclass(n), "name");
String *iname = GetChar(n, "sym:name");
SwigType *d = Getattr(n, "type");
ParmList *l = Getattr(n, "parms");
String *destructorname = NewStringEmpty();
Printf(destructorname, "_%s", Swig_name_wrapper(iname));
Setattr(classnode, "destructor", destructorname);
Wrapper *df = NewWrapper();
Printf(df->def, "/* This function is designed to be called by the zend list destructors */\n");
Printf(df->def, "/* to typecast and do the actual destruction */\n");
Printf(df->def, "static void %s(zend_rsrc_list_entry *rsrc, const char *type_name TSRMLS_DC) {\n", destructorname);
Wrapper *f = NewWrapper();
Printf(f->def, "/* This function is designed to be called by the zend list destructors */\n");
Printf(f->def, "/* to typecast and do the actual destruction */\n");
Printf(f->def, "static void %s(zend_rsrc_list_entry *rsrc, const char *type_name TSRMLS_DC) {\n", destructorname);
Wrapper_add_localv(df, "value", "swig_object_wrapper *value=(swig_object_wrapper *) rsrc->ptr", NIL);
Wrapper_add_localv(df, "ptr", "void *ptr=value->ptr", NIL);
Wrapper_add_localv(df, "newobject", "int newobject=value->newobject", NIL);
Wrapper_add_localv(f, "value", "swig_object_wrapper *value=(swig_object_wrapper *) rsrc->ptr", NIL);
Wrapper_add_localv(f, "ptr", "void *ptr=value->ptr", NIL);
Wrapper_add_localv(f, "newobject", "int newobject=value->newobject", NIL);
emit_args(d, l, df);
emit_attach_parmmaps(l, df);
emit_parameter_variables(l, f);
emit_attach_parmmaps(l, f);
// Get type of first arg, thing to be destructed
// Skip ignored arguments
@ -2707,18 +2707,20 @@ public:
}
SwigType *pt = Getattr(p, "type");
Printf(df->code, " efree(value);\n");
Printf(df->code, " if (! newobject) return; /* can't delete it! */\n");
Printf(df->code, " arg1 = (%s)SWIG_ZTS_ConvertResourceData(ptr,type_name,SWIGTYPE%s TSRMLS_CC);\n", SwigType_lstr(pt, 0), SwigType_manglestr(pt));
Printf(df->code, " if (! arg1) zend_error(E_ERROR, \"%s resource already free'd\");\n", Char(name));
Printf(f->code, " efree(value);\n");
Printf(f->code, " if (! newobject) return; /* can't delete it! */\n");
Printf(f->code, " arg1 = (%s)SWIG_ZTS_ConvertResourceData(ptr,type_name,SWIGTYPE%s TSRMLS_CC);\n", SwigType_lstr(pt, 0), SwigType_manglestr(pt));
Printf(f->code, " if (! arg1) zend_error(E_ERROR, \"%s resource already free'd\");\n", Char(name));
Setattr(n, "wrap:name", destructorname);
emit_action(n, df);
String *actioncode = emit_action(n);
Append(f->code, actioncode);
Delete(actioncode);
Printf(df->code, "}\n");
Printf(f->code, "}\n");
Wrapper_print(df, s_wrappers);
Wrapper_print(f, s_wrappers);
return SWIG_OK;

View file

@ -288,8 +288,8 @@ public:
Wrapper *f = NewWrapper();
/* Write code to extract function parameters. */
emit_args(d, l, f);
// Emit all of the local variables for holding arguments.
emit_parameter_variables(l, f);
/* Attach the standard typemaps */
emit_attach_parmmaps(l, f);
@ -400,21 +400,21 @@ public:
}
/* Emit the function call */
emit_action(n, f);
String *actioncode = emit_action(n);
/* Clear the return stack */
Printf(f->code, "pop_n_elems(args);\n");
Printf(actioncode, "pop_n_elems(args);\n");
/* Return the function value */
if (current == CONSTRUCTOR) {
Printv(f->code, "THIS = (void *) result;\n", NIL);
Printv(actioncode, "THIS = (void *) result;\n", NIL);
Printv(description, ", tVoid", NIL);
} else if (current == DESTRUCTOR) {
Printv(description, ", tVoid", NIL);
} else {
// Wrapper_add_local(f, "resultobj", "struct object *resultobj");
Printv(description, ", ", NIL);
if ((tm = Swig_typemap_lookup_new("out", n, "result", 0))) {
if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
actioncode = 0;
Replaceall(tm, "$source", "result");
Replaceall(tm, "$target", "resultobj");
Replaceall(tm, "$result", "resultobj");
@ -432,6 +432,11 @@ public:
Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), name);
}
}
if (actioncode) {
Append(f->code, actioncode);
Delete(actioncode);
}
emit_return_variable(n, d, f);
/* Output argument output code */
Printv(f->code, outarg, NIL);

View file

@ -1611,8 +1611,8 @@ public:
Wrapper_add_local(f, "resultobj", "PyObject *resultobj = 0");
/* Write code to extract function parameters. */
emit_args(d, l, f);
// Emit all of the local variables for holding arguments.
emit_parameter_variables(l, f);
/* Attach the standard typemaps */
emit_attach_parmmaps(l, f);
@ -1916,17 +1916,6 @@ public:
}
}
/* for constructor, determine if Python class has been subclassed.
* if so, create a director instance. otherwise, just create a normal instance.
*/
/* MOVED TO Swig_ConstructorToFunction() */
/*
if (constructor && (Getattr(n, "wrap:self") != 0)) {
Wrapper_add_local(f, "subclassed", "int subclassed = 0");
Append(f->code, "subclassed = (arg1 != Py_None);\n");
}
*/
/* Emit the function call */
if (director_method) {
Append(f->code, "try {\n");
@ -1939,23 +1928,24 @@ public:
Setattr(n, "wrap:name", wname);
emit_action(n, f);
Swig_director_emit_dynamic_cast(n, f);
String *actioncode = emit_action(n);
if (director_method) {
Append(f->code, "} catch (Swig::DirectorException&) {\n");
Append(f->code, " SWIG_fail;\n");
Append(f->code, "}\n");
Append(actioncode, "} catch (Swig::DirectorException&) {\n");
Append(actioncode, " SWIG_fail;\n");
Append(actioncode, "}\n");
} else {
if (allow_thread) {
thread_end_allow(n, f->code);
Append(f->code, "}\n");
thread_end_allow(n, actioncode);
Append(actioncode, "}\n");
}
}
/* This part below still needs cleanup */
/* Return the function value */
if ((tm = Swig_typemap_lookup_new("out", n, "result", 0))) {
if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
if (funpack) {
Replaceall(tm, "$self", "swig_obj[0]");
} else {
@ -2013,6 +2003,7 @@ public:
} else {
Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), name);
}
emit_return_variable(n, d, f);
/* Output argument output code */
Printv(f->code, outarg, NIL);
@ -2187,7 +2178,7 @@ public:
if (Getattr(n, "tmap:varin:implicitconv")) {
Replaceall(tm, "$implicitconv", get_implicitconv_flag(n));
}
emit_action_code(n, setf, tm);
emit_action_code(n, setf->code, tm);
Delete(tm);
} else {
Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0));
@ -2217,7 +2208,7 @@ public:
Replaceall(tm, "$source", name);
Replaceall(tm, "$target", "pyobj");
Replaceall(tm, "$result", "pyobj");
addfail = emit_action_code(n, getf, tm);
addfail = emit_action_code(n, getf->code, tm);
Delete(tm);
} else {
Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0));

View file

@ -354,7 +354,6 @@ protected:
int outputRegistrationRoutines(File *out);
int outputCommandLineArguments(File *out);
int generateCopyRoutinesObsolete(Node *n);
int generateCopyRoutines(Node *n);
int DumpCode(Node *n);
@ -619,7 +618,8 @@ String * R::createFunctionPointerHandler(SwigType *t, Node *n, int *numArgs) {
Printf(f->def, "%s %s(", rtype, funName);
emit_args(rettype, parms, f);
emit_parameter_variables(parms, f);
emit_return_variable(n, rettype, f);
// emit_attach_parmmaps(parms,f);
/* Using weird name and struct to avoid potential conflicts. */
@ -630,7 +630,7 @@ String * R::createFunctionPointerHandler(SwigType *t, Node *n, int *numArgs) {
Wrapper_add_local(f, "r_nprotect", "int r_nprotect = 0"); // for use in converting arguments to R objects for call.
Wrapper_add_local(f, "r_vmax", "char * r_vmax= 0"); // for use in converting arguments to R objects for call.
// Add local for error code in return value. This is not in emit_args because that assumes an out typemap
// Add local for error code in return value. This is not in emit_return_variable because that assumes an out typemap
// whereas the type makes are reverse
Wrapper_add_local(f, "ecode", "int ecode = 0");
@ -1700,7 +1700,6 @@ int R::functionWrapper(Node *n) {
ParmList *l = Getattr(n, "parms");
Parm *p;
String *returnTM = NULL;
String *tm;
p = l;
@ -1775,11 +1774,11 @@ int R::functionWrapper(Node *n) {
Wrapper *f = NewWrapper();
Wrapper *sfun = NewWrapper();
int isVoidReturnType = 0;
returnTM = Swig_typemap_lookup_new("out", n, "result",0);
if(returnTM)
isVoidReturnType = (Strcmp(type, "void") == 0);
int isVoidReturnType = (Strcmp(type, "void") == 0);
// Need to use the unresolved return type since
// typedef resolution removes the const which causes a
// mismatch with the function action
emit_return_variable(n, unresolved_return_type, f);
SwigType *rtype = Getattr(n, "type");
int addCopyParam = 0;
@ -1808,10 +1807,7 @@ int R::functionWrapper(Node *n) {
Swig_typemap_attach_parms("scoerceout", l, f);
Swig_typemap_attach_parms("scheck", l, f);
// Need to use the unresolved return type since
// typedef resolution removes the const which causes a
// mismatch with the function action
emit_args(unresolved_return_type, l, f);
emit_parameter_variables(l, f);
emit_attach_parmmaps(l,f);
Setattr(n,"wrap:parms",l);
@ -1989,16 +1985,9 @@ int R::functionWrapper(Node *n) {
}
}
emit_action(n, f);
String *outargs = NewString("");
int numOutArgs = isVoidReturnType ? -1 : 0;
for(p = l, i = 0; p; i++) {
String *tm;
if((tm = Getattr(p, "tmap:argout"))) {
// String *lname = Getattr(p, "lname");
numOutArgs++;
@ -2017,9 +2006,10 @@ int R::functionWrapper(Node *n) {
p = nextSibling(p);
}
String *actioncode = emit_action(n);
/* Deal with the explicit return value. */
if (returnTM) {
String *tm = returnTM;
if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
SwigType *retType = Getattr(n, "type");
//Printf(stderr, "Return Value for %s, array? %s\n", retType, SwigType_isarray(retType) ? "yes" : "no");
/* if(SwigType_isarray(retType)) {
@ -2168,185 +2158,6 @@ int R::functionWrapper(Node *n) {
return SWIG_OK;
}
int R::defineArrayAccessors(SwigType *type) {
SwigType *base = SwigType_base(type);
String *rclass = NewStringf("%sArray", base);
char *prclassName = Char(rclass);
if(strncmp(prclassName, "struct ", 7) == 0)
prclassName += 7;
Node *n = NewHash();
Setattr(n, "type", base);
String *tm;
String *rclassName = getRClassName(base);
String *rclassBase = getRClassName(base, 0);
String *cGetName = NewStringf("R_SWIG_%s_get_item_", prclassName);
String *cSetName = NewStringf("R_SWIG_%s_set_item_", prclassName);
Wrapper *cGetItem = NewWrapper();
String *getItem = NewString(""),
*setItem = NewString("");
Printf(getItem, "function(x, i, j, ..., drop = TRUE) {\n");
Printf(getItem, "%sif(i < 1 || i > x@dims[1])\n%sstop('index must be between 1 and ', x@dims[1])\n", tab4, tab8);
Printf(getItem, "%s.Call('%s', x@ref, as.integer(i-1), PACKAGE = '%s')\n", tab4, cGetName, Rpackage);
Printf(getItem, "}\n");
Printf(setItem, "function(x, i, j, ..., value) {\n");
Printf(setItem, "%sif(i < 1 || i > x@dims[1])\n%sstop('index must be between 1 and ', x@dims[1])\n", tab4, tab8);
/* Do the SCOERCEIN and the SCHECK here */
tm = Swig_typemap_lookup_new("scoercein", n, "value", 0);
if(tm) {
Replaceall(tm, "$input", "s_value");
Replaceall(tm, "$R_class", rclassName);
Replaceall(tm, "$*R_class", rclassBase);
Printf(setItem, "%s%s\n", tab4, tm);
}
tm = Swig_typemap_lookup_new("scheck", n, "value", 0);
if(tm) {
Replaceall(tm, "$input", "s_value");
Replaceall(tm, "$R_class", rclassName);
Replaceall(tm, "$*R_class", rclassBase);
Printf(setItem, "%s%s\n", tab4, tm);
}
Printf(setItem, "%s.Call('%s', x@ref, as.integer(i-1), value, PACKAGE = '%s')\n", tab4, cSetName, Rpackage);
Printf(setItem, "%sx\n}\n", tab4);
Printf(cGetItem->def, "SEXP\n%s(SEXP s_x, SEXP s_i)\n{\n", cGetName);
String *tmp = NewStringf("%s *ptr", SwigType_lstr(base, 0));
String *tmp1 = NewStringf("%s result", SwigType_lstr(base, 0));
Wrapper_add_localv(cGetItem, "r_vmax", "VMAXTYPE", "r_vmax = vmaxget()", NIL);
Wrapper_add_local(cGetItem, "ptr", tmp);
Wrapper_add_local(cGetItem, "r_ans", "SEXP r_ans");
Wrapper_add_local(cGetItem, "result", tmp1);
Wrapper_add_local(cGetItem, "r_nprotect", "int r_nprotect = 0");
Printf(cGetItem->code, "ptr = (%s *) R_SWIG_resolveExternalRef(s_x, \"\", \"s_x\", 0);\n", SwigType_lstr(base, 0));
Printf(cGetItem->code, "result = ptr[INTEGER(s_i)[0]];\n");
tm = Swig_typemap_lookup_new("out", n, "result", 0);
if(tm) {
Replaceall(tm, "$result", "r_ans");
Replaceall(tm,"$owner", "R_SWIG_EXTERNAL");
Printf(cGetItem->code, "%s\n", tm);
}
Delete(tmp); Delete(tmp1);
Printf(cGetItem->code, "%s\nreturn r_ans;\n}\n\n", UnProtectWrapupCode);
/******************************/
/*
R_SWIG_..._set_item(SEXP x, SEXP s_i, SEXP s_value) {
char *r_vmax = vmaxget();
int r_nprotect = 0;
type *ptr, *el, value;
ptr = (type *) R_SWIG_resolveExternalRef(s_x, "", "s_x", 0);
ptr[INTEGER(s_i)[0]] = *el;
cleanup
return
}
*/
Wrapper *cSetItem = NewWrapper();
{
Printf(cSetItem->def, "SEXP\n%s(SEXP s_x, SEXP s_i, SEXP s_value)\n{\n", cSetName);
tmp = NewStringf("%s *ptr", SwigType_lstr(base, 0));
tmp1 = NewStringf("%s value", SwigType_lstr(base, 0));
Wrapper_add_localv(cSetItem, "r_vmax", "VMAXTYPE", "r_vmax = vmaxget()", NIL);
Wrapper_add_local(cSetItem, "r_nprotect", "int r_nprotect = 0");
Wrapper_add_local(cSetItem, "ptr", tmp);
Wrapper_add_local(cSetItem, "value", tmp1);
Replaceall(tmp, "*ptr", "*el = &value");
Wrapper_add_local(cSetItem, "el", tmp);
Printf(cSetItem->code,
"ptr = (%s *) R_SWIG_resolveExternalRef(s_x, \"\", \"s_x\", 0);\n",
SwigType_lstr(base, 0));
String *tm = Swig_typemap_lookup_new("in", n, "value", 0);
if(tm) {
String *rclassName = getRClassName(base);
String *rclassBase = getRClassName(base, 0);
Replaceall(tm, "$input", "s_value");
Replaceall(tm, "$*1", "value");
//XXX think about what we really mean here.
Replaceall(tm, "$1", "el");
Replaceall(tm, "$R_class", rclassName);
Replaceall(tm, "$*R_class", rclassBase);
Printf(cSetItem->code, "%s\n", tm);
Delete(rclassName); Delete(rclassBase);
}
Printf(cSetItem->code, "ptr[INTEGER(s_i)[0]] = *el;\n");
}
Printf(cSetItem->code, "%s\nreturn R_NilValue;\n}\n\n", UnProtectWrapupCode);
/*************************/
Wrapper_print(cGetItem, f_wrapper);
Wrapper_print(cSetItem, f_wrapper);
String *elClass = NewStringf("_p%s", SwigType_manglestr(base));
if(!Getattr(SClassDefs, elClass)) {
if (debugMode)
Printf(stderr, "<defineArrayAccessors> Defining class %s\n", elClass);
Printf(s_classes, "setClass('%s', contains = 'ExternalReference')\n", elClass);
//Add to namespace
Setattr(SClassDefs, elClass, elClass);
}
Delete(elClass);
if(!Getattr(SClassDefs, rclassName)) {
Setattr(SClassDefs, rclassName, rclassName);
Printf(s_classes, "setClass('%s', contains = 'SWIGArray')\n", rclassName);
}
Printf(s_classes, "setMethod('[', '%s',\n%s)\n", rclassName, getItem);
Printf(s_classes, "setMethod('[<-', '%s',\n%s)\n", rclassName, setItem);
Delete(n);
DelWrapper(cGetItem);
DelWrapper(cSetItem);
Delete(rclass);
Delete(cGetName);
return SWIG_OK;
}
/*****************************************************
Add the specified routine name to the collection of
generated routines that are called from R functions.
@ -2583,219 +2394,6 @@ int R::classDeclaration(Node *n) {
in all cases.
*/
// This procedure is for reference
int R::generateCopyRoutinesObsolete(Node *n) {
Wrapper *toC = NewWrapper();
Wrapper *toCRef = NewWrapper();
Wrapper *toR = NewWrapper();
Wrapper *copyToR = NewWrapper();
Wrapper *copyToC = NewWrapper();
String *name = Getattr(n, "name");
String *tdname = Getattr(n, "tdname");
String *kind = Getattr(n, "kind");
String *type;
if(Len(tdname)) {
type = Copy(tdname);
} else {
type = NewStringf("%s %s", kind, name);
}
#ifdef R_SWIG_VERBOSE
if (debugMode)
Printf(stderr, "generateCopyRoutines: name = %s, %s\n", name, type);
#endif
String *rclassNameRef = getRClassName(type, 1);
String *copyRefRefName = NewStringf("R_swig_copy_%sRef_%sRef", rclassNameRef, rclassNameRef);
String *toCName = NewStringf("R_swig_copy_%sRef_to_C", name);
String *toRName = NewStringf("R_swig_copy_%sRef_to_R", name);
addRegistrationRoutine(copyRefRefName, 2);
addRegistrationRoutine(toCName, 2);
addRegistrationRoutine(toRName, 1);
Printf(toC->def, "int\n%s(SEXP sobj, %s *value)", toCName, type);
Printf(toR->def, "SEXP\n%s(%s *value)", toRName, type);
Printf(toCRef->def, "SEXP\n%s(SEXP s_src, SEXP s_dest) {", copyRefRefName);
Delete(toCName);
Delete(toRName);
String *tmp = NewStringf("%s *src", type);
Wrapper_add_local(toCRef, "src", tmp);
Delete(tmp);
tmp = NewStringf("%s *dest", type);
Wrapper_add_local(toCRef, "dest", tmp);
Delete(tmp);
Printf(toCRef->code, "src = (%s *) R_SWIG_resolveExternalRef(s_src, \"%sRef\", \"s_src\", (Rboolean) FALSE);\n",
type, rclassNameRef);
Printf(toCRef->code, "dest = (%s *) R_SWIG_resolveExternalRef(s_dest, \"%sRef\", \"s_dest\", (Rboolean) FALSE);\n",
type, rclassNameRef);
Printf(toCRef->code, "memcpy(dest, src, sizeof(*src));\nreturn R_NilValue;\n}\n\n");
Wrapper_add_localv(toR, "r_obj", "SEXP", "r_obj", NIL);
Wrapper_add_localv(toR, "r_vmax", "VMAXTYPE", "r_vmax = vmaxget()", NIL);
Wrapper_add_localv(toR, "_tmp_sexp", "SEXP", "_tmp_sexp", NIL);
Wrapper_add_local(toR, "r_nprotect", "int r_nprotect = 0");
Wrapper_add_local(toC, "ecode", "int ecode = 0");
Printf(copyToR->def, "%sCopyToR = function(value, obj = new(\"%s\"))\n{\n", name, name);
Printf(copyToC->def, "%sCopyToC = function(value, obj)\n{\n", name);
Printf(toR->code, "Rf_protect(r_obj = NEW_OBJECT(MAKE_CLASS(\"%s\")));\nr_nprotect++;\n\n", name);
Wrapper_add_localv(toC, "_tmp_sexp", "SEXP", "_tmp_sexp", NIL);
Node *c = firstChild(n);
// Swig_typemap_attach_parms("in", c, toR);
// Swig_typemap_attach_parms("out", c, toR);
for(; c; c = nextSibling(c)) {
String *elName = Getattr(c, "name");
if (!Len(elName)) {
continue;
}
String *tp = Swig_typemap_lookup_new("rtype", c, "", 0);
if(!tp) {
continue;
}
/* The S functions to get and set the member value. */
String *symname = Getattr(c, "sym:name");
String *ClassPrefix = Getattr(n, "sym:name");
String *get = Swig_name_get(Swig_name_member(Char(ClassPrefix), symname));
String *set = Swig_name_set(Swig_name_member(Char(ClassPrefix), symname));
#if 0
This is already done now in getRType().
If that for some reason no longer gets called, this had better go back.
SwigType *elTT = Getattr(c, "type");
SwigType *decl = Getattr(c, "decl");
SwigType_push(elTT, decl);
#endif
String *elNameT = replaceInitialDash(elName);
Printf(copyToR->code, "obj@%s = %s(value)\n", elNameT, get);
Printf(copyToC->code, "%s(obj, value@%s)\n", set, elNameT);
String *field = NewStringf("value->%s", elNameT);
Delete(elNameT);
SwigType *elType = Getattr(c, "type");
String *tm = Swig_typemap_lookup_new("out", c, field, 0);
if(tm) {
#ifdef R_SWIG_VERBOSE
if (debugMode)
Printf(stderr, "Got conversion to R for '%s': '%s' '%s' -> '%s'\n", elName, elType, elTT, tm);
#endif
//XXX Get the field in as the rhs.
// What about looking in the "memberin"/"memberout" typemaps.
Replaceall(tm, "$1", Char(field));
Replaceall(tm, "$result", "_tmp_sexp");
Replaceall(tm,"$owner", "R_SWIG_EXTERNAL");
replaceRClass(tm,elType);
Printf(toR->code, "%s\nRf_protect(_tmp_sexp);\nr_nprotect++;\n", tm);
Printf(toR->code, "Rf_protect(r_obj = R_do_slot_assign(r_obj, Rf_mkString(\"%s\"), _tmp_sexp));\nr_nprotect++;\n\n", elName);
} else {
Printf(stderr, "*** Can't convert field %s in \n", elName);
}
char *field_p = Char(field);
tm = Swig_typemap_lookup_new("in", c, field_p, 0);
if(tm && !GetFlag(c, "feature:immutable")) {
replaceRClass(tm,elType);
if (debugMode)
Printf(stderr, "typemap (in) for %s => %s\n",
SwigType_str(elType, 0), tm);
String *tmp1 =
NewStringf("%s val", SwigType_lstr(elType, 0));
Wrapper_add_local(toC, "val", tmp1);
Replaceall(tm, "$input", "_tmp_sexp");
if (debugMode)
Printf(stderr, "Got conversion to C for %s: %s. %s\n",
elName, tm, field);
#ifdef R_SWIG_VERBOSE
#endif
Printf(toC->code, "_tmp_sexp = GET_SLOT(sobj, Rf_mkString(\"%s\"));\n%s\n\n", elName, tm);
Delete(field);
}
/*
Replaceall(conversion, "$1", field);
Printf(toC->code, "value->%s = ;\n", name);
*/
}
Printv(toR->code, UnProtectWrapupCode,
"\nreturn(r_obj);\n}\n", NIL);
Printf(toC->code, "\nreturn(1);\n}\n");
Printf(f_wrapper, "%s;\n", toR->def);
Printf(f_wrapper, "%s;\n", toC->def);
Printf(toR->def, "\n{\n");
Printf(toC->def, "\n{\n");
String *rclassName = getRClassName(type, 0); // without the Ref.
Printf(copyToR->code, "obj\n}\n\n");
Printf(sfile, "# Start definition of copy functions & methods for %s\n", rclassName);
Wrapper_print(copyToR, sfile);
Printf(copyToC->code, "obj\n}\n\n");
Wrapper_print(copyToC, sfile);
Printf(sfile, "# Start definition of copy methods for %s\n", rclassName);
Printf(sfile, "setMethod('copyToR', '%sRef', %sCopyToR)\n", rclassName, name);
Printf(sfile, "setMethod('copyToC', '%s', %sCopyToC)\n\n", rclassName, name);
Printv(sfile, "setMethod('copyToC', c('", rclassName, "Ref', '", rclassName, "Ref'),",
" function(value, obj) {\n",
tab4, ".Call(\"", copyRefRefName, "\", value, obj, PACKAGE = \"",
Rpackage, "\")\n})\n\n", NIL);
Printf(sfile, "# End definition of copy methods for %s\n", rclassName);
Printf(sfile, "# End definition of copy functions & methods for %s\n", rclassName);
String *m = NewStringf("%sCopyToR", name);
addNamespaceMethod(m);
char *tt = Char(m); tt[Len(m)-1] = 'C';
addNamespaceMethod(m);
Delete(m);
Delete(rclassName);
DelWrapper(copyToR);
DelWrapper(copyToC);
Wrapper_print(toR, f_wrapper);
Wrapper_print(toC, f_wrapper);
Wrapper_print(toCRef, f_wrapper);
DelWrapper(toR);
DelWrapper(toC);
DelWrapper(toCRef);
return SWIG_OK;
}
int R::generateCopyRoutines(Node *n) {
Wrapper *copyToR = NewWrapper();
Wrapper *copyToC = NewWrapper();

View file

@ -1649,7 +1649,7 @@ public:
/* Emit arguments */
if (current != CONSTRUCTOR_ALLOCATE) {
emit_args(t, l, f);
emit_parameter_variables(l, f);
}
/* Attach standard typemaps */
@ -1773,72 +1773,79 @@ public:
Setattr(n, "wrap:name", wname);
emit_action(n, f);
Swig_director_emit_dynamic_cast(n, f);
String *actioncode = emit_action(n);
if (director_method) {
Printf(f->code, "} catch (Swig::DirectorException& e) {\n");
Printf(f->code, " rb_exc_raise(e.getError());\n");
Printf(f->code, " SWIG_fail;\n");
Printf(f->code, "}\n");
Printf(actioncode, "} catch (Swig::DirectorException& e) {\n");
Printf(actioncode, " rb_exc_raise(e.getError());\n");
Printf(actioncode, " SWIG_fail;\n");
Printf(actioncode, "}\n");
}
}
/* Return value if necessary */
if (SwigType_type(t) != T_VOID && current != CONSTRUCTOR_ALLOCATE && current != CONSTRUCTOR_INITIALIZE) {
need_result = 1;
if (GetFlag(n, "feature:predicate")) {
Printv(f->code, tab4, "vresult = (result ? Qtrue : Qfalse);\n", NIL);
} else {
tm = Swig_typemap_lookup_new("out", n, "result", 0);
if (tm) {
Replaceall(tm, "$result", "vresult");
Replaceall(tm, "$source", "result");
Replaceall(tm, "$target", "vresult");
/* Return value if necessary */
if (SwigType_type(t) != T_VOID && current != CONSTRUCTOR_INITIALIZE) {
need_result = 1;
if (GetFlag(n, "feature:predicate")) {
Printv(actioncode, tab4, "vresult = (result ? Qtrue : Qfalse);\n", NIL);
} else {
tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode);
actioncode = 0;
if (tm) {
Replaceall(tm, "$result", "vresult");
Replaceall(tm, "$source", "result");
Replaceall(tm, "$target", "vresult");
if (GetFlag(n, "feature:new"))
Replaceall(tm, "$owner", "SWIG_POINTER_OWN");
else
Replaceall(tm, "$owner", "0");
if (GetFlag(n, "feature:new"))
Replaceall(tm, "$owner", "SWIG_POINTER_OWN");
else
Replaceall(tm, "$owner", "0");
#if 1
// FIXME: this will not try to unwrap directors returned as non-director
// base class pointers!
// FIXME: this will not try to unwrap directors returned as non-director
// base class pointers!
/* New addition to unwrap director return values so that the original
* Ruby object is returned instead.
*/
bool unwrap = false;
String *decl = Getattr(n, "decl");
int is_pointer = SwigType_ispointer_return(decl);
int is_reference = SwigType_isreference_return(decl);
if (is_pointer || is_reference) {
String *type = Getattr(n, "type");
Node *parent = Swig_methodclass(n);
Node *modname = Getattr(parent, "module");
Node *target = Swig_directormap(modname, type);
if (target)
unwrap = true;
}
if (unwrap) {
Wrapper_add_local(f, "director", "Swig::Director *director = 0");
Printf(f->code, "director = dynamic_cast<Swig::Director *>(result);\n");
Printf(f->code, "if (director) {\n");
Printf(f->code, " vresult = director->swig_get_self();\n");
Printf(f->code, "} else {\n");
Printf(f->code, "%s\n", tm);
Printf(f->code, "}\n");
director_method = 0;
} else {
Printf(f->code, "%s\n", tm);
}
/* New addition to unwrap director return values so that the original
* Ruby object is returned instead.
*/
bool unwrap = false;
String *decl = Getattr(n, "decl");
int is_pointer = SwigType_ispointer_return(decl);
int is_reference = SwigType_isreference_return(decl);
if (is_pointer || is_reference) {
String *type = Getattr(n, "type");
Node *parent = Swig_methodclass(n);
Node *modname = Getattr(parent, "module");
Node *target = Swig_directormap(modname, type);
if (target)
unwrap = true;
}
if (unwrap) {
Wrapper_add_local(f, "director", "Swig::Director *director = 0");
Printf(f->code, "director = dynamic_cast<Swig::Director *>(result);\n");
Printf(f->code, "if (director) {\n");
Printf(f->code, " vresult = director->swig_get_self();\n");
Printf(f->code, "} else {\n");
Printf(f->code, "%s\n", tm);
Printf(f->code, "}\n");
director_method = 0;
} else {
Printf(f->code, "%s\n", tm);
}
#else
Printf(f->code, "%s\n", tm);
Printf(f->code, "%s\n", tm);
#endif
Delete(tm);
} else {
Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s.\n", SwigType_str(t, 0));
}
Delete(tm);
} else {
Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s.\n", SwigType_str(t, 0));
}
}
}
if (actioncode) {
Append(f->code, actioncode);
Delete(actioncode);
}
emit_return_variable(n, t, f);
}
/* Extra code needed for new and initialize methods */
@ -2108,7 +2115,7 @@ public:
Replaceall(tm, "$target", "_val");
Replaceall(tm, "$source", name);
/* Printv(getf->code,tm, NIL); */
addfail = emit_action_code(n, getf, tm);
addfail = emit_action_code(n, getf->code, tm);
} else {
Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0));
}
@ -2140,7 +2147,7 @@ public:
Replaceall(tm, "$source", "_val");
Replaceall(tm, "$target", name);
/* Printv(setf->code,tm,"\n",NIL); */
emit_action_code(n, setf, tm);
emit_action_code(n, setf->code, tm);
} else {
Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s\n", SwigType_str(t, 0));
}

View file

@ -310,7 +310,8 @@ private:
};
int SWIG_main(int, char **, Language *);
void emit_args(SwigType *, ParmList *, Wrapper *f);
void emit_parameter_variables(ParmList *l, Wrapper *f);
void emit_return_variable(Node *n, SwigType *rt, Wrapper *f);
void SWIG_exit(int); /* use EXIT_{SUCCESS,FAILURE} */
void SWIG_config_file(const String_or_char *);
const String *SWIG_output_directory();
@ -322,8 +323,8 @@ int emit_num_required(ParmList *);
int emit_isvarargs(ParmList *);
void emit_attach_parmmaps(ParmList *, Wrapper *f);
void emit_mark_varargs(ParmList *l);
void emit_action(Node *n, Wrapper *f);
int emit_action_code(Node *n, Wrapper *f, String *action);
String *emit_action(Node *n);
int emit_action_code(Node *n, String *wrappercode, String *action);
void Swig_overload_check(Node *n);
String *Swig_overload_dispatch(Node *n, const String_or_char *fmt, int *);
String *Swig_overload_dispatch_cast(Node *n, const String_or_char *fmt, int *);
@ -337,6 +338,7 @@ String *Swig_class_name(Node *n);
String *Swig_method_call(String_or_char *name, ParmList *parms);
String *Swig_method_decl(SwigType *rtype, SwigType *decl, const String_or_char *id, List *args, int strip, int values);
String *Swig_director_declaration(Node *n);
void Swig_director_emit_dynamic_cast(Node *n, Wrapper *f);
/* directors.cxx end */
extern "C" {

View file

@ -303,8 +303,8 @@ public:
Printv(f->def, "SWIGINTERN int\n ", wname, "(ClientData clientData SWIGUNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {", NIL);
/* Print out variables for storing arguments. */
emit_args(type, parms, f);
// Emit all of the local variables for holding arguments.
emit_parameter_variables(parms, f);
/* Attach standard typemaps */
emit_attach_parmmaps(parms, f);
@ -443,12 +443,12 @@ public:
}
/* Now write code to make the function call */
emit_action(n, f);
String *actioncode = emit_action(n);
/* Need to redo all of this code (eventually) */
/* Return value if necessary */
if ((tm = Swig_typemap_lookup_new("out", n, "result", 0))) {
if ((tm = Swig_typemap_lookup_out("out", n, "result", f, actioncode))) {
Replaceall(tm, "$source", "result");
#ifdef SWIG_USE_RESULTOBJ
Replaceall(tm, "$target", "resultobj");
@ -466,6 +466,7 @@ public:
} 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), name);
}
emit_return_variable(n, type, f);
/* Dump output argument code */
Printv(f->code, outarg, NIL);
@ -570,7 +571,7 @@ public:
Replaceall(tm, "$target", "value");
Replaceall(tm, "$result", "value");
/* Printf(getf->code, "%s\n",tm); */
addfail = emit_action_code(n, getf, tm);
addfail = emit_action_code(n, getf->code, tm);
Printf(getf->code, "if (value) {\n");
Printf(getf->code, "Tcl_SetVar2(interp,name1,name2,Tcl_GetStringFromObj(value,NULL), flags);\n");
Printf(getf->code, "Tcl_DecrRefCount(value);\n");
@ -610,7 +611,7 @@ public:
Printf(setf->code, "Tcl_DecrRefCount(name1o);\n");
Printf(setf->code, "if (!value) SWIG_fail;\n");
/* Printf(setf->code,"%s\n", tm); */
emit_action_code(n, setf, tm);
emit_action_code(n, setf->code, tm);
Printf(setf->code, "return NULL;\n");
Printf(setf->code, "fail:\n");
Printf(setf->code, "return \"%s\";\n", iname);