summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorWilliam S Fulton <wsf@fultondesigns.co.uk>2015-10-11 22:11:09 +0100
committerWilliam S Fulton <wsf@fultondesigns.co.uk>2015-10-11 22:11:09 +0100
commit3d681571e1e9726510c35cbbd2e0342d010ec09a (patch)
tree167b35a5d83020c44e9910f3a67474bb8573635f /Source
parent593c452c37e56ff2c96096711d88fb809bfb28ad (diff)
parent8275f8158a04351c225a3cdad3787646391fe72a (diff)
downloadswig-3d681571e1e9726510c35cbbd2e0342d010ec09a.tar.gz
Merge pull request #498 from lyze/extend-cffi-typemap-machinery
Implement argout, freearg, and check for CFFI.
Diffstat (limited to 'Source')
-rw-r--r--Source/Modules/cffi.cxx91
1 files changed, 89 insertions, 2 deletions
diff --git a/Source/Modules/cffi.cxx b/Source/Modules/cffi.cxx
index 39a1ac763..174bc123c 100644
--- a/Source/Modules/cffi.cxx
+++ b/Source/Modules/cffi.cxx
@@ -61,6 +61,11 @@ public:
virtual int classHandler(Node *n);
private:
+ static void checkConstraints(ParmList *parms, Wrapper *f);
+ static void argout(ParmList *parms, Wrapper *f);
+ static String *freearg(ParmList *parms);
+ static void cleanupFunction(Node *n, Wrapper *f, ParmList *parms);
+
void emit_defun(Node *n, String *name);
void emit_defmethod(Node *n);
void emit_initialize_instance(Node *n);
@@ -364,6 +369,77 @@ int CFFI::membervariableHandler(Node *n) {
return Language::membervariableHandler(n);
}
+
+void CFFI::checkConstraints(ParmList *parms, Wrapper *f) {
+ Parm *p = parms;
+ while (p) {
+ String *tm = Getattr(p, "tmap:check");
+ if (!tm) {
+ p = nextSibling(p);
+ } else {
+ tm = Copy(tm);
+ Replaceall(tm, "$input", Getattr(p, "emit:input"));
+ Printv(f->code, tm, "\n\n", NULL);
+ Delete(tm);
+ p = Getattr(p, "tmap:check:next");
+ }
+ }
+}
+
+void CFFI::argout(ParmList *parms, Wrapper *f) {
+ Parm *p = parms;
+ while (p) {
+ String *tm = Getattr(p, "tmap:argout");
+ if (!tm) {
+ p = nextSibling(p);
+ } else {
+ tm = Copy(tm);
+ Replaceall(tm, "$result", Swig_cresult_name());
+ Replaceall(tm, "$input", Getattr(p, "emit:input"));
+ Printv(f->code, tm, "\n", NULL);
+ Delete(tm);
+ p = Getattr(p, "tmap:argout:next");
+ }
+ }
+}
+
+String *CFFI::freearg(ParmList *parms) {
+ String *ret = NewString("");
+ Parm *p = parms;
+ while (p) {
+ String *tm = Getattr(p, "tmap:freearg");
+ if (!tm) {
+ p = nextSibling(p);
+ } else {
+ tm = Copy(tm);
+ Replaceall(tm, "$input", Getattr(p, "emit:input"));
+ Printv(ret, tm, "\n", NULL);
+ Delete(tm);
+ p = Getattr(p, "tmap:freearg:next");
+ }
+ }
+ return ret;
+}
+
+void CFFI::cleanupFunction(Node *n, Wrapper *f, ParmList *parms) {
+ String *cleanup = freearg(parms);
+ Printv(f->code, cleanup, NULL);
+
+ if (GetFlag(n, "feature:new")) {
+ String *tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0);
+ if (tm) {
+ Replaceall(tm, "$source", Swig_cresult_name());
+ Printv(f->code, tm, "\n", NULL);
+ Delete(tm);
+ }
+ }
+
+ Replaceall(f->code, "$cleanup", cleanup);
+ Delete(cleanup);
+
+ Replaceall(f->code, "$symname", Getattr(n, "sym:name"));
+}
+
int CFFI::functionWrapper(Node *n) {
ParmList *parms = Getattr(n, "parms");
@@ -451,6 +527,9 @@ int CFFI::functionWrapper(Node *n) {
// Emit the function definition
String *signature = SwigType_str(return_type, name_and_parms);
Printf(f->def, "EXPORT %s {", signature);
+
+ checkConstraints(parms, f);
+
Printf(f->code, " try {\n");
String *actioncode = emit_action(n);
@@ -459,9 +538,17 @@ int CFFI::functionWrapper(Node *n) {
if (result_convert) {
Replaceall(result_convert, "$result", "lresult");
Printf(f->code, "%s\n", result_convert);
- if(!is_void_return) Printf(f->code, " return lresult;\n");
- Delete(result_convert);
}
+ Delete(result_convert);
+
+ argout(parms, f);
+
+ cleanupFunction(n, f, parms);
+
+ if (!is_void_return) {
+ Printf(f->code, " return lresult;\n");
+ }
+
emit_return_variable(n, Getattr(n, "type"), f);
Printf(f->code, " } catch (...) {\n");