Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r172:233cdddde8f1
Date: 2014-12-05 18:27 +0100
http://bitbucket.org/cffi/creflect/changeset/233cdddde8f1/

Log:    ffi.offsetof

diff --git a/zeffir/ffi_obj.c b/zeffir/ffi_obj.c
--- a/zeffir/ffi_obj.c
+++ b/zeffir/ffi_obj.c
@@ -255,7 +255,7 @@
     return (PyObject *)cd;
 }
 
-static PyObject *ffi_string(PyObject *self, PyObject *args)
+static PyObject *ffi_string(ZefFFIObject *self, PyObject *args)
 {
     CDataObject *cd;
     Py_ssize_t maxlen = -1;
@@ -317,10 +317,49 @@
     return NULL;
 }
 
+static PyObject *ffi_offsetof(ZefFFIObject *self, PyObject *args)
+{
+    PyObject *arg;
+    char *fieldname;
+    CTypeDescrObject *ct;
+    CFieldObject *cf;
+
+    if (!PyArg_ParseTuple(args, "Os:offsetof", &arg, &fieldname))
+        return NULL;
+
+    ct = _ffi_type(self, arg, ACCEPT_STRING|ACCEPT_CTYPE);
+    if (ct == NULL)
+        return NULL;
+
+    if (!(ct->ct_flags & (CT_STRUCT|CT_UNION))) {
+        PyErr_Format(PyExc_TypeError,
+                     "expected a struct or union ctype, got '%s'",
+                     ct->ct_name);
+        return NULL;
+    }
+    if (ct->ct_stuff == NULL) {
+        PyErr_Format(PyExc_TypeError, "'%s' is incomplete", ct->ct_name);
+        return NULL;
+    }
+
+    cf = (CFieldObject *)PyDict_GetItemString(ct->ct_stuff, fieldname);
+    if (cf == NULL) {
+        PyErr_Format(PyExc_KeyError, "'%s' has got no field '%s'",
+                     ct->ct_name, fieldname);
+        return NULL;
+    }
+    if (cf->cf_bitshift >= 0) {
+        PyErr_SetString(PyExc_TypeError, "not supported for bitfields");
+        return NULL;
+    }
+    return PyInt_FromSsize_t(cf->cf_offset);
+}
+
 static PyMethodDef ffi_methods[] = {
     {"close_library", ffi_close_library,         METH_VARARGS | METH_STATIC},
     {"load_library",  (PyCFunction)ffi_load_library,
                                                  METH_VARARGS | METH_KEYWORDS},
+    {"offsetof",      (PyCFunction)ffi_offsetof, METH_VARARGS},
     {"new",           (PyCFunction)ffi_new,      METH_VARARGS},
     {"sizeof",        (PyCFunction)ffi_sizeof,   METH_O},
     {"string",        (PyCFunction)ffi_string,   METH_VARARGS},
diff --git a/zeffir/test/test_struct.py b/zeffir/test/test_struct.py
--- a/zeffir/test/test_struct.py
+++ b/zeffir/test/test_struct.py
@@ -10,8 +10,7 @@
     p.b += 1
     assert p.b == 0x600112234
 
-def test_addressof():
-    py.test.skip("in-progress")
+def test_offsetof():
     ffi, lib = support.compile_and_open('struct')
-    p = ffi.new('mystruct_t *')
-    ffi.addressof(p[0], 'a')
+    assert ffi.offsetof("mystruct_t", "a") == 0
+    assert ffi.offsetof("mystruct_t", "b") == ffi.sizeof("long")
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to