From 468ca084fc464f7eec1d0780e8a92bf451e5ea61 Mon Sep 17 00:00:00 2001 From: William S Fulton Date: Tue, 20 Dec 2011 20:50:36 +0000 Subject: [PATCH] Correct special variables in 'directorargout' typemap. This change will break any 'directorargout' typemaps you may have written. Please change: to and to \n Also fix the named 'directorargout' DIRECTOROUT typemaps for these languages which didn't previously compile and add in , etc expansion.\n [C#, Go, Java, D] Add support for the 'directorargout' typemap.\n [Java] Add (char *STRING, size_t LENGTH) director typemaps. git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@12877 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 17 +++++++ Examples/test-suite/common.mk | 1 + Examples/test-suite/director_binary_string.i | 50 +++++++++++++++++++ .../java/director_binary_string_runme.java | 42 ++++++++++++++++ Lib/java/java.swg | 7 +++ Lib/typemaps/ptrtypes.swg | 6 +-- Lib/typemaps/valtypes.swg | 7 ++- Source/Modules/csharp.cxx | 29 ++++++----- Source/Modules/d.cxx | 29 ++++++----- Source/Modules/directors.cxx | 26 ++++++++++ Source/Modules/go.cxx | 28 +++++++---- Source/Modules/java.cxx | 29 ++++++----- Source/Modules/ocaml.cxx | 5 +- Source/Modules/octave.cxx | 8 ++- Source/Modules/php.cxx | 8 ++- Source/Modules/python.cxx | 10 ++-- Source/Modules/ruby.cxx | 42 +++++----------- Source/Modules/swigmod.h | 1 + 18 files changed, 249 insertions(+), 96 deletions(-) create mode 100644 Examples/test-suite/director_binary_string.i create mode 100644 Examples/test-suite/java/director_binary_string_runme.java diff --git a/CHANGES.current b/CHANGES.current index 2165d84f1..936a8bc46 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,23 @@ See the RELEASENOTES file for a summary of changes in each release. Version 2.0.5 (in progress) =========================== +2011-12-20: wsfulton + [Java] Add (char *STRING, size_t LENGTH) director typemaps. + +2011-12-20: wsfulton + [C#, Go, Java, D] Add support for the 'directorargout' typemap. + +2011-12-20: wsfulton + [Ocaml, Octave, PHP, Python, Ruby] Correct special variables in 'directorargout' typemap. + This change will break any 'directorargout' typemaps you may have written. Please change: + $result to $1 + $input to $result + + Also fix the named 'directorargout' DIRECTOROUT typemaps for these languages which didn't + previously compile and add in $1, $2 etc expansion. + + *** POTENTIAL INCOMPATIBILITY *** + 2011-12-10: talby [perl5] SWIG_error() now gets decorated with perl source file/line number. [perl5] error handling now conforms to public XS api (fixes perl v5.14 issue). diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk index b02afb463..85cd50244 100644 --- a/Examples/test-suite/common.mk +++ b/Examples/test-suite/common.mk @@ -159,6 +159,7 @@ CPP_TEST_CASES += \ director_abstract \ director_alternating \ director_basic \ + director_binary_string \ director_classes \ director_classic \ director_constructor \ diff --git a/Examples/test-suite/director_binary_string.i b/Examples/test-suite/director_binary_string.i new file mode 100644 index 000000000..ec64bc4b4 --- /dev/null +++ b/Examples/test-suite/director_binary_string.i @@ -0,0 +1,50 @@ +%module(directors="1") director_binary_string; + +%feature("director") Callback; + +%apply (char *STRING, size_t LENGTH) { (char *dataBufferAA, int sizeAA) }; +%apply (char *STRING, size_t LENGTH) { (char *dataBufferBB, int sizeBB) }; + +%inline %{ +#include + +#define BUFFER_SIZE_AA 8 +#define BUFFER_SIZE_BB 5 + +class Callback { +public: + virtual ~Callback() {} + virtual void run(char* dataBufferAA, int sizeAA, char* dataBufferBB, int sizeBB) { + memset(dataBufferAA, -1, sizeAA); + memset(dataBufferBB, -1, sizeBB); + } +}; + +class Caller { +private: + Callback *_callback; +public: + Caller(): _callback(0) {} + ~Caller() { delCallback(); } + void delCallback() { delete _callback; _callback = 0; } + void setCallback(Callback *cb) { delCallback(); _callback = cb; } + int call() { + if (_callback) { + char* aa = (char*)malloc(BUFFER_SIZE_AA); + memset(aa, 9, BUFFER_SIZE_AA); + char* bb = (char*)malloc(BUFFER_SIZE_BB); + memset(bb, 13, BUFFER_SIZE_BB); + int sum = 0; + _callback->run(aa, BUFFER_SIZE_AA, bb, BUFFER_SIZE_BB); + for (int i = 0; i < BUFFER_SIZE_AA; i++) + sum += aa[i]; + for (int i = 0; i < BUFFER_SIZE_BB; i++) + sum += bb[i]; + free(aa); + free(bb); + return sum; + } + } +}; + +%} diff --git a/Examples/test-suite/java/director_binary_string_runme.java b/Examples/test-suite/java/director_binary_string_runme.java new file mode 100644 index 000000000..e2bf4da40 --- /dev/null +++ b/Examples/test-suite/java/director_binary_string_runme.java @@ -0,0 +1,42 @@ + +import director_binary_string.*; + +public class director_binary_string_runme { + + static { + try { + System.loadLibrary("director_binary_string"); + } catch (UnsatisfiedLinkError e) { + System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e); + System.exit(1); + } + } + + public static void main(String argv[]) { + Caller caller = new Caller(); + Callback callback = new DirectorBinaryStringCallback(); + caller.setCallback(callback); + int sum = caller.call(); + caller.delCallback(); + + if (sum != 9*2*8 + 13*3*5) + throw new RuntimeException("Unexpected sum: " + sum); + } +} + +class DirectorBinaryStringCallback extends Callback { + public DirectorBinaryStringCallback() { + super(); + } + + @Override + public void run(byte[] dataBufferAA, byte[] dataBufferBB) + { + for (int i = 0; i < dataBufferAA.length; i++) + dataBufferAA[i] = (byte)(dataBufferAA[i] * 2); + + for (int i = 0; i < dataBufferBB.length; i++) + dataBufferBB[i] = (byte)(dataBufferBB[i] * 3); + } +} + diff --git a/Lib/java/java.swg b/Lib/java/java.swg index c727d9611..81b7c5d07 100644 --- a/Lib/java/java.swg +++ b/Lib/java/java.swg @@ -1307,6 +1307,13 @@ SWIG_PROXY_CONSTRUCTOR(true, true, SWIGTYPE) %typemap(argout) (char *STRING, size_t LENGTH) { JCALL3(ReleaseByteArrayElements, jenv, $input, (jbyte *)$1, 0); } +%typemap(directorin, descriptor="[B") (char *STRING, size_t LENGTH) { + jbyteArray jb = (jenv)->NewByteArray($2); + (jenv)->SetByteArrayRegion(jb, 0, $2, (jbyte *)$1); + $input = jb; +} +%typemap(directorargout) (char *STRING, size_t LENGTH) +%{(jenv)->GetByteArrayRegion($input, 0, $2, (jbyte *)$1); %} %apply (char *STRING, size_t LENGTH) { (char *STRING, int LENGTH) } /* java keywords */ diff --git a/Lib/typemaps/ptrtypes.swg b/Lib/typemaps/ptrtypes.swg index e1bc476ed..e8439e6dc 100644 --- a/Lib/typemaps/ptrtypes.swg +++ b/Lib/typemaps/ptrtypes.swg @@ -66,14 +66,14 @@ /* directorout */ %define %ptr_directorout_typemap(asptr_meth,frag,Type...) - %typemap(directorargout,noblock=1,fragment=frag) Type *DIRECTOROUT ($*ltype temp) { + %typemap(directorargout,noblock=1,fragment=frag) Type *DIRECTOROUT ($*ltype temp, int swig_ores) { Type *swig_optr = 0; - int swig_ores = $input ? asptr_meth($input, &swig_optr) : 0; + swig_ores = $result ? asptr_meth($result, &swig_optr) : 0; if (!SWIG_IsOK(swig_ores) || !swig_optr) { %dirout_fail((swig_optr ? swig_ores : SWIG_TypeError),"$type"); } temp = *swig_optr; - $result = &temp; + $1 = &temp; if (SWIG_IsNewObj(swig_ores)) %delete(swig_optr); } diff --git a/Lib/typemaps/valtypes.swg b/Lib/typemaps/valtypes.swg index cd1143073..a72e719cd 100644 --- a/Lib/typemaps/valtypes.swg +++ b/Lib/typemaps/valtypes.swg @@ -107,13 +107,12 @@ /* directorout */ %define %value_directorout_typemap(asval_meth,frag,Type...) - %typemap(directorargout,noblock=1,fragment=frag) Type *DIRECTOROUT { - Type swig_val; - int swig_res = asval_meth($input, &swig_val); + %typemap(directorargout,noblock=1,fragment=frag) Type *DIRECTOROUT(Type swig_val, int swig_res) { + swig_res = asval_meth($result, &swig_val); if (!SWIG_IsOK(swig_res)) { %dirout_fail(swig_res, "$type"); } - *$result = %static_cast(swig_val, $type); + *$1 = swig_val; } %typemap(directorout,noblock=1,fragment=frag) Type { Type swig_val; diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx index bcf5c2b22..fe28e0ae9 100644 --- a/Source/Modules/csharp.cxx +++ b/Source/Modules/csharp.cxx @@ -3576,19 +3576,7 @@ public: Delete(retpm); } - /* Go through argument list, attach lnames for arguments */ - for (i = 0, p = l; p; p = nextSibling(p), ++i) { - String *arg = Getattr(p, "name"); - String *lname = NewString(""); - - if (!arg && Cmp(Getattr(p, "type"), "void")) { - lname = NewStringf("arg%d", i); - Setattr(p, "name", lname); - } else - lname = arg; - - Setattr(p, "lname", lname); - } + Swig_director_parms_fixup(l); /* Attach the standard typemaps */ Swig_typemap_attach_parms("out", l, 0); @@ -3597,6 +3585,7 @@ public: Swig_typemap_attach_parms("cstype", l, 0); Swig_typemap_attach_parms("directorin", l, 0); Swig_typemap_attach_parms("csdirectorin", l, 0); + Swig_typemap_attach_parms("directorargout", l, w); /* Preamble code */ if (!ignored_method) @@ -3653,6 +3642,7 @@ public: /* Add input marshalling code */ if ((tm = Getattr(p, "tmap:directorin"))) { + Setattr(p, "emit:directorinput", arg); Replaceall(tm, "$input", arg); Replaceall(tm, "$owner", "0"); @@ -3830,6 +3820,19 @@ public: Delete(result_str); } + /* Marshal outputs */ + for (p = l; p;) { + if ((tm = Getattr(p, "tmap:directorargout"))) { + canThrow(n, "directorargout", p); + Replaceall(tm, "$result", "jresult"); + Replaceall(tm, "$input", Getattr(p, "emit:directorinput")); + Printv(w->code, tm, "\n", NIL); + p = Getattr(p, "tmap:directorargout:next"); + } else { + p = nextSibling(p); + } + } + /* Terminate wrapper code */ Printf(w->code, "}\n"); if (!is_void) diff --git a/Source/Modules/d.cxx b/Source/Modules/d.cxx index 3e5375af7..8e13799bd 100644 --- a/Source/Modules/d.cxx +++ b/Source/Modules/d.cxx @@ -2057,19 +2057,7 @@ public: Delete(retpm); } - /* Go through argument list, attach lnames for arguments */ - for (i = 0, p = l; p; p = nextSibling(p), ++i) { - String *arg = Getattr(p, "name"); - String *lname = NewString(""); - - if (!arg && Cmp(Getattr(p, "type"), "void")) { - lname = NewStringf("arg%d", i); - Setattr(p, "name", lname); - } else - lname = arg; - - Setattr(p, "lname", lname); - } + Swig_director_parms_fixup(l); // Attach the standard typemaps. Swig_typemap_attach_parms("out", l, 0); @@ -2078,6 +2066,7 @@ public: Swig_typemap_attach_parms("dtype", l, 0); Swig_typemap_attach_parms("directorin", l, 0); Swig_typemap_attach_parms("ddirectorin", l, 0); + Swig_typemap_attach_parms("directorargout", l, w); // Preamble code. if (!ignored_method) @@ -2135,6 +2124,7 @@ public: /* Add input marshalling code */ if ((tm = Getattr(p, "tmap:directorin"))) { + Setattr(p, "emit:directorinput", arg); Replaceall(tm, "$input", arg); Replaceall(tm, "$owner", "0"); @@ -2318,6 +2308,19 @@ public: Delete(result_str); } + /* Marshal outputs */ + for (p = l; p;) { + if ((tm = Getattr(p, "tmap:directorargout"))) { + canThrow(n, "directorargout", p); + Replaceall(tm, "$result", "jresult"); + Replaceall(tm, "$input", Getattr(p, "emit:directorinput")); + Printv(w->code, tm, "\n", NIL); + p = Getattr(p, "tmap:directorargout:next"); + } else { + p = nextSibling(p); + } + } + /* Terminate wrapper code */ Printf(w->code, "}\n"); if (!is_void) diff --git a/Source/Modules/directors.cxx b/Source/Modules/directors.cxx index 6064e1758..af1798b8b 100644 --- a/Source/Modules/directors.cxx +++ b/Source/Modules/directors.cxx @@ -290,3 +290,29 @@ void Swig_director_emit_dynamic_cast(Node *n, Wrapper *f) { } } +/* ------------------------------------------------------------ + * Swig_director_parms_fixup() + * + * For each parameter in 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 "directorin" typemaps. + * ------------------------------------------------------------ */ + +void Swig_director_parms_fixup(ParmList *parms) { + Parm *p; + int i; + for (i = 0, p = parms; p; p = nextSibling(p), ++i) { + String *arg = Getattr(p, "name"); + String *lname = 0; + + if (!arg && !Equal(Getattr(p, "type"), "void")) { + lname = NewStringf("arg%d", i); + Setattr(p, "name", lname); + } else + lname = Copy(arg); + + Setattr(p, "lname", lname); + Delete(lname); + } +} + diff --git a/Source/Modules/go.cxx b/Source/Modules/go.cxx index 8fb2bb25e..4e5f6d5ca 100644 --- a/Source/Modules/go.cxx +++ b/Source/Modules/go.cxx @@ -2941,21 +2941,13 @@ private: Append(go_with_over_name, overname); } + Parm *p = 0; Wrapper *f = NewWrapper(); - Parm *p = parms; - for (int i = 0; i < parm_count; ++i) { - p = getParm(p); - Swig_cparm_name(p, i); - if (!Getattr(p, "name")) { - String *pn = NewString(""); - Printf(pn, "arg%d", i); - Setattr(p, "name", pn); - } - p = nextParm(p); - } + Swig_director_parms_fixup(parms); Swig_typemap_attach_parms("directorin", parms, f); + Swig_typemap_attach_parms("directorargout", parms, f); if (!is_ignored) { // We use an interface to see if this method is defined in Go. @@ -3422,6 +3414,7 @@ private: String *ln = Getattr(p, "lname"); String *input = NewString(""); Printv(input, "swig_a.", ln, NULL); + Setattr(p, "emit:directorinput", input); Replaceall(tm, "$input", input); Replaceall(tm, "$owner", "0"); Delete(input); @@ -3527,6 +3520,19 @@ private: Delete(rname); } } + + /* Marshal outputs */ + for (p = parms; p;) { + String *tm; + if ((tm = Getattr(p, "tmap:directorargout"))) { + Replaceall(tm, "$result", "jresult"); + Replaceall(tm, "$input", Getattr(p, "emit:directorinput")); + Printv(f->code, tm, "\n", NIL); + p = Getattr(p, "tmap:directorargout:next"); + } else { + p = nextSibling(p); + } + } } else { assert(is_pure_virtual); Printv(f->code, " _swig_gopanic(\"call to pure virtual function ", Getattr(parent, "sym:name"), name, "\");\n", NULL); diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx index 12b8102e4..3439dacb1 100644 --- a/Source/Modules/java.cxx +++ b/Source/Modules/java.cxx @@ -3682,19 +3682,7 @@ public: Delete(retpm); } - /* Go through argument list, attach lnames for arguments */ - for (i = 0, p = l; p; p = nextSibling(p), ++i) { - String *arg = Getattr(p, "name"); - String *lname = NewString(""); - - if (!arg && Cmp(Getattr(p, "type"), "void")) { - lname = NewStringf("arg%d", i); - Setattr(p, "name", lname); - } else - lname = arg; - - Setattr(p, "lname", lname); - } + Swig_director_parms_fixup(l); /* Attach the standard typemaps */ Swig_typemap_attach_parms("out", l, 0); @@ -3702,6 +3690,7 @@ public: Swig_typemap_attach_parms("jtype", l, 0); Swig_typemap_attach_parms("directorin", l, 0); Swig_typemap_attach_parms("javadirectorin", l, 0); + Swig_typemap_attach_parms("directorargout", l, w); if (!ignored_method) { /* Add Java environment pointer to wrapper */ @@ -3811,6 +3800,7 @@ public: Append(jnidesc, jni_canon); Delete(jni_canon); + Setattr(p, "emit:directorinput", arg); Replaceall(tm, "$input", arg); Replaceall(tm, "$owner", "0"); @@ -4014,6 +4004,19 @@ public: Delete(result_str); } + /* Marshal outputs */ + for (p = l; p;) { + if ((tm = Getattr(p, "tmap:directorargout"))) { + addThrows(n, "tmap:directorargout", p); + Replaceall(tm, "$result", "jresult"); + Replaceall(tm, "$input", Getattr(p, "emit:directorinput")); + Printv(w->code, tm, "\n", NIL); + p = Getattr(p, "tmap:directorargout:next"); + } else { + p = nextSibling(p); + } + } + Delete(imclass_desc); Delete(class_desc); diff --git a/Source/Modules/ocaml.cxx b/Source/Modules/ocaml.cxx index 0e42bd866..2184440c1 100644 --- a/Source/Modules/ocaml.cxx +++ b/Source/Modules/ocaml.cxx @@ -1499,6 +1499,7 @@ public: Putc(',', arglist); if ((tm = Getattr(p, "tmap:directorin")) != 0) { + Setattr(p, "emit:directorinput", pname); Replaceall(tm, "$input", pname); Replaceall(tm, "$owner", "0"); if (Len(tm) == 0) @@ -1638,8 +1639,8 @@ public: /* marshal outputs */ for (p = l; p;) { if ((tm = Getattr(p, "tmap:directorargout")) != 0) { - Replaceall(tm, "$input", "swig_result"); - Replaceall(tm, "$result", Getattr(p, "name")); + Replaceall(tm, "$result", "swig_result"); + Replaceall(tm, "$input", Getattr(p, "emit:directorinput")); Printv(w->code, tm, "\n", NIL); p = Getattr(p, "tmap:directorargout:next"); } else { diff --git a/Source/Modules/octave.cxx b/Source/Modules/octave.cxx index 4d54084da..7bf33169b 100644 --- a/Source/Modules/octave.cxx +++ b/Source/Modules/octave.cxx @@ -1325,6 +1325,8 @@ public: // attach typemaps to arguments (C/C++ -> Python) String *parse_args = NewString(""); + Swig_director_parms_fixup(l); + Swig_typemap_attach_parms("in", l, 0); Swig_typemap_attach_parms("directorin", l, 0); Swig_typemap_attach_parms("directorargout", l, w); @@ -1354,6 +1356,7 @@ public: if ((tm = Getattr(p, "tmap:directorin")) != 0) { String *parse = Getattr(p, "tmap:directorin:parse"); if (!parse) { + Setattr(p, "emit:directorinput", "tmpv"); Replaceall(tm, "$input", "tmpv"); Replaceall(tm, "$owner", "0"); Printv(wrap_args, tm, "\n", NIL); @@ -1361,6 +1364,7 @@ public: Putc('O', parse_args); } else { Append(parse_args, parse); + Setattr(p, "emit:directorinput", pname); Replaceall(tm, "$input", pname); Replaceall(tm, "$owner", "0"); if (Len(tm) == 0) @@ -1430,8 +1434,8 @@ public: if ((tm = Getattr(p, "tmap:directorargout")) != 0) { char temp[24]; sprintf(temp, "out(%d)", idx); - Replaceall(tm, "$input", temp); - Replaceall(tm, "$result", Getattr(p, "name")); + Replaceall(tm, "$result", temp); + Replaceall(tm, "$input", Getattr(p, "emit:directorinput")); Printv(w->code, tm, "\n", NIL); p = Getattr(p, "tmap:directorargout:next"); } else { diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx index 3e8df76b9..6bcb2d457 100644 --- a/Source/Modules/php.cxx +++ b/Source/Modules/php.cxx @@ -2535,6 +2535,8 @@ done: /* attach typemaps to arguments (C/C++ -> PHP) */ String *parse_args = NewStringEmpty(); + Swig_director_parms_fixup(l); + /* remove the wrapper 'w' since it was producing spurious temps */ Swig_typemap_attach_parms("in", l, 0); Swig_typemap_attach_parms("directorin", l, 0); @@ -2567,6 +2569,7 @@ done: if (!parse) { sprintf(source, "obj%d", idx++); String *input = NewStringf("&%s", source); + Setattr(p, "emit:directorinput", input); Replaceall(tm, "$input", input); Delete(input); Replaceall(tm, "$owner", "0"); @@ -2577,6 +2580,7 @@ done: Putc('O', parse_args); } else { Append(parse_args, parse); + Setattr(p, "emit:directorinput", pname); Replaceall(tm, "$input", pname); Replaceall(tm, "$owner", "0"); if (Len(tm) == 0) @@ -2680,8 +2684,8 @@ done: /* marshal outputs */ for (p = l; p;) { if ((tm = Getattr(p, "tmap:directorargout")) != 0) { - Replaceall(tm, "$input", Swig_cresult_name()); - Replaceall(tm, "$result", Getattr(p, "name")); + Replaceall(tm, "$result", Swig_cresult_name()); + Replaceall(tm, "$input", Getattr(p, "emit:directorinput")); Printv(w->code, tm, "\n", NIL); p = Getattr(p, "tmap:directorargout:next"); } else { diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx index f94d54106..296a920b7 100644 --- a/Source/Modules/python.cxx +++ b/Source/Modules/python.cxx @@ -4656,6 +4656,8 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) { String *arglist = NewString(""); String *parse_args = NewString(""); + Swig_director_parms_fixup(l); + /* remove the wrapper 'w' since it was producing spurious temps */ Swig_typemap_attach_parms("in", l, 0); Swig_typemap_attach_parms("directorin", l, 0); @@ -4698,6 +4700,7 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) { if (!parse) { sprintf(source, "obj%d", idx++); String *input = NewString(source); + Setattr(p, "emit:directorinput", input); Replaceall(tm, "$input", input); Delete(input); Replaceall(tm, "$owner", "0"); @@ -4710,6 +4713,7 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) { } else { use_parse = 1; Append(parse_args, parse); + Setattr(p, "emit:directorinput", pname); Replaceall(tm, "$input", pname); Replaceall(tm, "$owner", "0"); if (Len(tm) == 0) @@ -4940,11 +4944,11 @@ int PYTHON::classDirectorMethod(Node *n, Node *parent, String *super) { if ((tm = Getattr(p, "tmap:directorargout")) != 0) { if (outputs > 1) { Printf(w->code, "output = PyTuple_GetItem(%s, %d);\n", Swig_cresult_name(), idx++); - Replaceall(tm, "$input", "output"); + Replaceall(tm, "$result", "output"); } else { - Replaceall(tm, "$input", Swig_cresult_name()); + Replaceall(tm, "$result", Swig_cresult_name()); } - Replaceall(tm, "$result", Getattr(p, "name")); + Replaceall(tm, "$input", Getattr(p, "emit:directorinput")); Printv(w->code, tm, "\n", NIL); p = Getattr(p, "tmap:directorargout:next"); } else { diff --git a/Source/Modules/ruby.cxx b/Source/Modules/ruby.cxx index 6aaa8d398..f9582b8f4 100644 --- a/Source/Modules/ruby.cxx +++ b/Source/Modules/ruby.cxx @@ -3152,13 +3152,7 @@ public: /* 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_director_parms_fixup(l); Swig_typemap_attach_parms("in", l, 0); Swig_typemap_attach_parms("directorin", l, 0); @@ -3182,11 +3176,10 @@ public: if (Getattr(p, "tmap:directorargout") != 0) outputs++; - if ( checkAttribute( p, "tmap:in:numinputs", "0") ) - { - p = Getattr(p, "tmap:in:next"); - continue; - } + if ( checkAttribute( p, "tmap:in:numinputs", "0") ) { + p = Getattr(p, "tmap:in:next"); + continue; + } String *parameterName = Getattr(p, "name"); String *parameterType = Getattr(p, "type"); @@ -3194,8 +3187,11 @@ public: Putc(',', arglist); if ((tm = Getattr(p, "tmap:directorin")) != 0) { sprintf(source, "obj%d", idx++); - Replaceall(tm, "$input", source); + String *input = NewString(source); + Setattr(p, "emit:directorinput", input); + Replaceall(tm, "$input", input); Replaceall(tm, "$owner", "0"); + Delete(input); Printv(wrap_args, tm, "\n", NIL); Wrapper_add_localv(w, source, "VALUE", source, "= Qnil", NIL); Printv(arglist, source, NIL); @@ -3340,11 +3336,11 @@ public: if ((tm = Getattr(p, "tmap:directorargout")) != 0) { if (outputs > 1) { Printf(w->code, "output = rb_ary_entry(%s, %d);\n", Swig_cresult_name(), idx++); - Replaceall(tm, "$input", "output"); + Replaceall(tm, "$result", "output"); } else { - Replaceall(tm, "$input", Swig_cresult_name()); + Replaceall(tm, "$result", Swig_cresult_name()); } - Replaceall(tm, "$result", Getattr(p, "name")); + Replaceall(tm, "$input", Getattr(p, "emit:directorinput")); Printv(w->code, tm, "\n", NIL); p = Getattr(p, "tmap:directorargout:next"); } else { @@ -3417,20 +3413,6 @@ public: return Language::classDirectorDisown(n); } - void typemap_copy_pname_to_lname(ParmList *parms) { - Parm *p; - String *pname; - String *lname; - - p = parms; - while (p) { - pname = Getattr(p, "name"); - lname = Copy(pname); - Setattr(p, "lname", lname); - p = nextSibling(p); - } - } - String *runtimeCode() { String *s = NewString(""); String *shead = Swig_include_sys("rubyhead.swg"); diff --git a/Source/Modules/swigmod.h b/Source/Modules/swigmod.h index 208a7b026..7733391fc 100644 --- a/Source/Modules/swigmod.h +++ b/Source/Modules/swigmod.h @@ -355,6 +355,7 @@ String *Swig_method_call(const_String_or_char_ptr name, ParmList *parms); String *Swig_method_decl(SwigType *rtype, SwigType *decl, const_String_or_char_ptr id, List *args, int strip, int values); String *Swig_director_declaration(Node *n); void Swig_director_emit_dynamic_cast(Node *n, Wrapper *f); +void Swig_director_parms_fixup(ParmList *parms); /* directors.cxx end */ extern "C" {