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