[pypy-commit] creflect default: tweak tweak tweak
arigo
noreply at buildbot.pypy.org
Sat Nov 29 22:32:49 CET 2014
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r126:80866ed7c824
Date: 2014-11-29 22:33 +0100
http://bitbucket.org/cffi/creflect/changeset/80866ed7c824/
Log: tweak tweak tweak
diff --git a/zeffir/test/test_basic.py b/zeffir/test/test_basic.py
--- a/zeffir/test/test_basic.py
+++ b/zeffir/test/test_basic.py
@@ -2,6 +2,7 @@
from udir import udir, include_dir
def setup_module(mod):
+ global zeffir, zeffir_lib_path
zeffir_dir = os.path.join(os.path.dirname(__file__), '..')
zeffir_lib_path = str(udir.join('zeffir.so'))
err = os.system("cd '%s' && "
@@ -10,7 +11,6 @@
assert not err
#
sys.path.insert(0, str(udir))
- global zeffir
import zeffir
#
basic_c_path = str(udir.join('basic.c'))
@@ -20,15 +20,16 @@
"gcc -g -I../../creflect -fPIC -shared '%s' -o '%s'" %
(zeffir_dir, basic_c_path, basic_c_path, basic_lib_path))
assert not err
- #
- global ffi, lib
- ffi, lib = zeffir.open('basic', relative_to=zeffir_lib_path)
def test_ffi_type():
+ ffi, lib = zeffir.open('basic', relative_to=zeffir_lib_path)
assert type(ffi).__module__ == 'zeffir'
assert type(ffi).__name__ == 'FFI'
+ assert repr(ffi) == "<zeffir.FFI object for '%s/libbasic.so'>" % (
+ os.path.dirname(zeffir_lib_path),)
def test_forty_two():
+ ffi, lib = zeffir.open('basic', relative_to=zeffir_lib_path)
assert lib.forty_two == 42
assert type(lib.forty_two) is int
diff --git a/zeffir/zeffir.c b/zeffir/zeffir.c
--- a/zeffir/zeffir.c
+++ b/zeffir/zeffir.c
@@ -1,4 +1,5 @@
#include <Python.h>
+#include <dlfcn.h>
#include "../creflect/creflect.h"
#include "../creflect/creflect_cdecl.h"
@@ -7,15 +8,23 @@
typedef struct {
PyObject_HEAD
+ void *dl_lib;
char *libname;
} PyFFIObject;
static void ffi_dealloc(PyFFIObject *ffi)
{
+ if (ffi->dl_lib != NULL)
+ dlclose(ffi->dl_lib);
free(ffi->libname);
PyObject_Del(ffi);
}
+static PyObject *ffi_repr(PyFFIObject *ffi)
+{
+ return PyString_FromFormat("<zeffir.FFI object for '%s'>", ffi->libname);
+}
+
static PyTypeObject FFI_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"zeffir.FFI",
@@ -26,7 +35,7 @@
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
- 0, /* tp_repr */
+ (reprfunc)ffi_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
@@ -54,19 +63,51 @@
{
char *keywords[] = {"libname", "relative_to", NULL};
char *libname, *relative_to;
+ char *path;
if (!PyArg_ParseTupleAndKeywords(args, kwds, "ss", keywords,
&libname, &relative_to))
return NULL;
+ char *last_slash = strrchr(relative_to, '/');
+ if (last_slash == NULL) {
+ relative_to = "./";
+ last_slash = relative_to + 1;
+ }
+ size_t n = last_slash + 1 - relative_to;
+ path = malloc(n + strlen(libname) + 16);
+ if (path == NULL)
+ return PyErr_NoMemory();
+ memcpy(path, relative_to, n);
+ strcpy(path + n, "lib");
+ strcat(path + n, libname);
+ strcat(path + n, ".so");
+
+ dlerror(); /* clear errors */
+ void *dl_lib = dlopen(path, RTLD_LAZY);
+ if (dl_lib == NULL) {
+ char *error = dlerror();
+ if (error == NULL)
+ error = "failed to open";
+ PyErr_Format(PyExc_OSError, "%s: %s", path, error);
+ goto error;
+ }
+
PyFFIObject *ffi = PyObject_New(PyFFIObject, &FFI_Type);
if (ffi == NULL)
- return NULL;
- ffi->libname = strdup(libname);
+ goto error;
+ ffi->dl_lib = dl_lib;
+ ffi->libname = path;
PyObject *result = Py_BuildValue("OO", ffi, Py_None);
Py_DECREF(ffi);
return result;
+
+ error:
+ if (dl_lib != NULL)
+ dlclose(dl_lib);
+ free(path);
+ return NULL;
}
More information about the pypy-commit
mailing list