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
This commit is contained in:
William S Fulton 2011-12-20 20:50:36 +00:00
commit 468ca084fc
18 changed files with 249 additions and 96 deletions

View file

@ -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).

View file

@ -159,6 +159,7 @@ CPP_TEST_CASES += \
director_abstract \
director_alternating \
director_basic \
director_binary_string \
director_classes \
director_classic \
director_constructor \

View file

@ -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 <stdlib.h>
#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;
}
}
};
%}

View file

@ -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);
}
}

View file

@ -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 */

View file

@ -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);
}

View file

@ -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;

View file

@ -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)

View file

@ -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)

View file

@ -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);
}
}

View file

@ -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);

View file

@ -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);

View file

@ -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 {

View file

@ -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 {

View file

@ -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 {

View file

@ -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 {

View file

@ -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");

View file

@ -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" {