PageRenderTime 9ms CodeModel.GetById 4ms app.highlight 2ms RepoModel.GetById 1ms app.codeStats 0ms

/trunk/Examples/python/libffi/example.i

#
Swig | 176 lines | 138 code | 27 blank | 11 comment | 0 complexity | a92c30056f9c0114667aaba3b3d74ec9 MD5 | raw file
  1/* File : example.i */
  2%module example
  3
  4%{
  5#include <unistd.h>
  6#include <ffi.h>
  7%}
  8
  9/* A wrapper for execlp() using libffi to handle an arbitrary
 10   number of arguments */
 11
 12%typemap(in) (...) {
 13   char **argv;
 14   int    argc;
 15   int    i;
 16
 17   argc = PyTuple_Size(varargs);
 18   argv = (char **) malloc(sizeof(char *)*(argc+1));
 19   for (i = 0; i < argc; i++) {
 20      PyObject *o = PyTuple_GetItem(varargs,i);
 21      if (!PyString_Check(o)) {
 22          PyErr_SetString(PyExc_ValueError,"Expected a string");
 23          return NULL;
 24      }
 25      argv[i] = PyString_AsString(o);
 26   }
 27   argv[i] = NULL;
 28   $1 = (void *) argv;
 29}
 30
 31/* Rewrite the function call, using libffi */    
 32%feature("action") execlp {
 33  int       i, vc;
 34  ffi_cif   cif;
 35  ffi_type  **types;
 36  void      **values;
 37  char      **args;
 38
 39  vc = PyTuple_Size(varargs);
 40  types  = (ffi_type **) malloc((vc+3)*sizeof(ffi_type *));
 41  values = (void **) malloc((vc+3)*sizeof(void *));
 42  args   = (char **) arg3;
 43
 44  /* Set up path parameter */
 45  types[0] = &ffi_type_pointer;
 46  values[0] = &arg1;
 47  
 48  /* Set up first argument */
 49  types[1] = &ffi_type_pointer;
 50  values[1] = &arg2;
 51
 52  /* Set up rest of parameters */
 53  for (i = 0; i <= vc; i++) {
 54    types[2+i] = &ffi_type_pointer;
 55    values[2+i] = &args[i];
 56  }
 57  if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, vc+3,
 58                   &ffi_type_uint, types) == FFI_OK) {
 59    ffi_call(&cif, (void (*)()) execlp, &result, values);
 60  } else {
 61    PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
 62    free(types);
 63    free(values);
 64    free(arg3);
 65    return NULL;
 66  }
 67  free(types);
 68  free(values);
 69  free(arg3);
 70}
 71
 72int execlp(const char *path, const char *arg1, ...);
 73
 74
 75/* A wrapper for printf() using libffi */
 76
 77%{
 78  typedef struct {
 79    int type;
 80    union {
 81      int    ivalue;
 82      double dvalue;
 83      void   *pvalue;
 84    } val;
 85  } vtype;
 86  enum { VT_INT, VT_DOUBLE, VT_POINTER };
 87  %}
 88
 89%typemap(in) (const char *fmt, ...) {
 90  vtype *argv;
 91  int    argc;
 92  int    i;
 93
 94  $1 = PyString_AsString($input);
 95
 96  argc = PyTuple_Size(varargs);
 97  argv = (vtype *) malloc(argc*sizeof(vtype));
 98  for (i = 0; i < argc; i++) {
 99    PyObject *o = PyTuple_GetItem(varargs,i);
100    if (PyInt_Check(o)) {
101      argv[i].type = VT_INT;
102      argv[i].val.ivalue = PyInt_AsLong(o);
103    } else if (PyFloat_Check(o)) {
104      argv[i].type = VT_DOUBLE;
105      argv[i].val.dvalue = PyFloat_AsDouble(o);
106    } else if (PyString_Check(o)) {
107      argv[i].type = VT_POINTER;
108      argv[i].val.pvalue = (void *) PyString_AsString(o);
109    } else {
110      PyErr_SetString(PyExc_ValueError,"Unsupported argument type");
111      free(argv);
112      return NULL;
113    }
114  }
115
116  $2 = (void *) argv;
117}
118
119/* Rewrite the function call, using libffi */    
120%feature("action") printf {
121  int       i, vc;
122  ffi_cif   cif;
123  ffi_type  **types;
124  void      **values;
125  vtype     *args;
126
127  vc = PyTuple_Size(varargs);
128  types  = (ffi_type **) malloc((vc+1)*sizeof(ffi_type *));
129  values = (void **) malloc((vc+1)*sizeof(void *));
130  args   = (vtype *) arg2;
131
132  /* Set up fmt parameter */
133  types[0] = &ffi_type_pointer;
134  values[0] = &arg1;
135
136  /* Set up rest of parameters */
137  for (i = 0; i < vc; i++) {
138    switch(args[i].type) {
139    case VT_INT:
140      types[1+i] = &ffi_type_uint;
141      values[1+i] = &args[i].val.ivalue;
142      break;
143    case VT_DOUBLE:
144      types[1+i] = &ffi_type_double;
145      values[1+i] = &args[i].val.dvalue;
146      break;
147    case VT_POINTER:
148      types[1+i] = &ffi_type_pointer;
149      values[1+i] = &args[i].val.pvalue;
150      break;
151    default:
152      abort();    /* Whoa! We're seriously hosed */
153      break;   
154    }
155  }
156  if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, vc+1,
157                   &ffi_type_uint, types) == FFI_OK) {
158    ffi_call(&cif, (void (*)()) printf, &result, values);
159  } else {
160    PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
161    free(types);
162    free(values);
163    free(args);
164    return NULL;
165  }
166  free(types);
167  free(values);
168  free(args);
169}
170
171int printf(const char *fmt, ...);
172
173
174  
175
176