PageRenderTime 43ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

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

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