summaryrefslogtreecommitdiff
path: root/Examples/python/libffi/example.i
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2009-08-18 20:56:02 +0000
committerLorry <lorry@roadtrain.codethink.co.uk>2012-09-25 16:59:08 +0000
commit9f8a09ed743cedd9547bf0661d518647966ab114 (patch)
tree9c7803d3b27a8ec22e91792ac7f7932efa128b20 /Examples/python/libffi/example.i
downloadswig-tarball-master.tar.gz
Imported from /srv/lorry/lorry-area/swig-tarball/swig-1.3.40.tar.gz.HEADswig-1.3.40master
Diffstat (limited to 'Examples/python/libffi/example.i')
-rw-r--r--Examples/python/libffi/example.i176
1 files changed, 176 insertions, 0 deletions
diff --git a/Examples/python/libffi/example.i b/Examples/python/libffi/example.i
new file mode 100644
index 0000000..9a29ec0
--- /dev/null
+++ b/Examples/python/libffi/example.i
@@ -0,0 +1,176 @@
+/* File : example.i */
+%module example
+
+%{
+#include <unistd.h>
+#include <ffi.h>
+%}
+
+/* A wrapper for execlp() using libffi to handle an arbitrary
+ number of arguments */
+
+%typemap(in) (...) {
+ char **argv;
+ int argc;
+ int i;
+
+ argc = PyTuple_Size(varargs);
+ argv = (char **) malloc(sizeof(char *)*(argc+1));
+ for (i = 0; i < argc; i++) {
+ PyObject *o = PyTuple_GetItem(varargs,i);
+ if (!PyString_Check(o)) {
+ PyErr_SetString(PyExc_ValueError,"Expected a string");
+ return NULL;
+ }
+ argv[i] = PyString_AsString(o);
+ }
+ argv[i] = NULL;
+ $1 = (void *) argv;
+}
+
+/* Rewrite the function call, using libffi */
+%feature("action") execlp {
+ int i, vc;
+ ffi_cif cif;
+ ffi_type **types;
+ void **values;
+ char **args;
+
+ vc = PyTuple_Size(varargs);
+ types = (ffi_type **) malloc((vc+3)*sizeof(ffi_type *));
+ values = (void **) malloc((vc+3)*sizeof(void *));
+ args = (char **) arg3;
+
+ /* Set up path parameter */
+ types[0] = &ffi_type_pointer;
+ values[0] = &arg1;
+
+ /* Set up first argument */
+ types[1] = &ffi_type_pointer;
+ values[1] = &arg2;
+
+ /* Set up rest of parameters */
+ for (i = 0; i <= vc; i++) {
+ types[2+i] = &ffi_type_pointer;
+ values[2+i] = &args[i];
+ }
+ if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, vc+3,
+ &ffi_type_uint, types) == FFI_OK) {
+ ffi_call(&cif, (void (*)()) execlp, &result, values);
+ } else {
+ PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
+ free(types);
+ free(values);
+ free(arg3);
+ return NULL;
+ }
+ free(types);
+ free(values);
+ free(arg3);
+}
+
+int execlp(const char *path, const char *arg1, ...);
+
+
+/* A wrapper for printf() using libffi */
+
+%{
+ typedef struct {
+ int type;
+ union {
+ int ivalue;
+ double dvalue;
+ void *pvalue;
+ } val;
+ } vtype;
+ enum { VT_INT, VT_DOUBLE, VT_POINTER };
+ %}
+
+%typemap(in) (const char *fmt, ...) {
+ vtype *argv;
+ int argc;
+ int i;
+
+ $1 = PyString_AsString($input);
+
+ argc = PyTuple_Size(varargs);
+ argv = (vtype *) malloc(argc*sizeof(vtype));
+ for (i = 0; i < argc; i++) {
+ PyObject *o = PyTuple_GetItem(varargs,i);
+ if (PyInt_Check(o)) {
+ argv[i].type = VT_INT;
+ argv[i].val.ivalue = PyInt_AsLong(o);
+ } else if (PyFloat_Check(o)) {
+ argv[i].type = VT_DOUBLE;
+ argv[i].val.dvalue = PyFloat_AsDouble(o);
+ } else if (PyString_Check(o)) {
+ argv[i].type = VT_POINTER;
+ argv[i].val.pvalue = (void *) PyString_AsString(o);
+ } else {
+ PyErr_SetString(PyExc_ValueError,"Unsupported argument type");
+ free(argv);
+ return NULL;
+ }
+ }
+
+ $2 = (void *) argv;
+}
+
+/* Rewrite the function call, using libffi */
+%feature("action") printf {
+ int i, vc;
+ ffi_cif cif;
+ ffi_type **types;
+ void **values;
+ vtype *args;
+
+ vc = PyTuple_Size(varargs);
+ types = (ffi_type **) malloc((vc+1)*sizeof(ffi_type *));
+ values = (void **) malloc((vc+1)*sizeof(void *));
+ args = (vtype *) arg2;
+
+ /* Set up fmt parameter */
+ types[0] = &ffi_type_pointer;
+ values[0] = &arg1;
+
+ /* Set up rest of parameters */
+ for (i = 0; i < vc; i++) {
+ switch(args[i].type) {
+ case VT_INT:
+ types[1+i] = &ffi_type_uint;
+ values[1+i] = &args[i].val.ivalue;
+ break;
+ case VT_DOUBLE:
+ types[1+i] = &ffi_type_double;
+ values[1+i] = &args[i].val.dvalue;
+ break;
+ case VT_POINTER:
+ types[1+i] = &ffi_type_pointer;
+ values[1+i] = &args[i].val.pvalue;
+ break;
+ default:
+ abort(); /* Whoa! We're seriously hosed */
+ break;
+ }
+ }
+ if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, vc+1,
+ &ffi_type_uint, types) == FFI_OK) {
+ ffi_call(&cif, (void (*)()) printf, &result, values);
+ } else {
+ PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
+ free(types);
+ free(values);
+ free(args);
+ return NULL;
+ }
+ free(types);
+ free(values);
+ free(args);
+}
+
+int printf(const char *fmt, ...);
+
+
+
+
+