Author: Armin Rigo <[email protected]>
Branch:
Changeset: r139:c04b2a53ae95
Date: 2014-12-01 22:14 +0100
http://bitbucket.org/cffi/creflect/changeset/c04b2a53ae95/
Log: in-progress: parsing types given in ffi.xyz()
diff --git a/zeffir/builder.c b/zeffir/builder.c
--- a/zeffir/builder.c
+++ b/zeffir/builder.c
@@ -268,3 +268,46 @@
return PyErr_Occurred() ? -1 : 0;
}
+
+static CTypeDescrObject *parse_c_decl(ZefFFIObject *ffi, const char *str)
+{
+ zeffir_builder_t builder = {
+ {
+ zef_get_void_type,
+ zef_get_char_type,
+ zef_get_bool_type,
+ zef_get_signed_type,
+ zef_get_unsigned_type,
+ zef_get_float_type,
+ zef_get_function_type,
+ zef_get_ellipsis_function_type,
+ zef_get_pointer_type,
+ zef_get_array_type,
+ zef_get_incomplete_array_type,
+ zef_get_struct_type,
+ zef_get_union_type,
+ zef_get_enum_type,
+ zef_get_user_type,
+ zef_get_unknown_type,
+ 0, /* complete */
+ 0, /* complete_enum */
+ 0, /* define_type */
+ 0, /* define_var */
+ 0, /* define_func */
+ 0, /* define_num_const */
+ zef_error,
+ },
+ NULL, /* lib */
+ NULL, /* l_dict */
+ ffi, /* ffi */
+ ffi->types_dict, /* types_dict */
+ };
+
+ _crx_qual_type result;
+ const char *err = creflect_decl_parser(&builder.cb, str, &result);
+ if (err != NULL)
+ abort();
+
+ Py_INCREF(result.type);
+ return result.type;
+}
diff --git a/zeffir/ctype.c b/zeffir/ctype.c
--- a/zeffir/ctype.c
+++ b/zeffir/ctype.c
@@ -81,6 +81,11 @@
return ct;
}
+static PyObject *ctypedescr_repr(CTypeDescrObject *ct)
+{
+ return PyString_FromFormat("<ctype '%s'>", ct->ct_name);
+}
+
static void ctypedescr_dealloc(CTypeDescrObject *ct)
{
PyObject_GC_UnTrack(ct);
@@ -109,7 +114,7 @@
static PyTypeObject CTypeDescr_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
- "_cffi_backend.CTypeDescr",
+ "zeffir.CType",
offsetof(CTypeDescrObject, ct_name),
sizeof(char),
(destructor)ctypedescr_dealloc, /* tp_dealloc */
@@ -117,7 +122,7 @@
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_compare */
- 0,//(reprfunc)ctypedescr_repr, /* tp_repr */
+ (reprfunc)ctypedescr_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
diff --git a/zeffir/ffi_obj.c b/zeffir/ffi_obj.c
--- a/zeffir/ffi_obj.c
+++ b/zeffir/ffi_obj.c
@@ -108,10 +108,30 @@
return Py_None;
}
+static PyObject *ffi_typeof(ZefFFIObject *self, PyObject *arg)
+{
+ if (!PyString_Check(arg)) {
+ PyErr_SetString(PyExc_TypeError, "XXX");
+ return NULL;
+ }
+
+ PyObject *x = PyDict_GetItem(self->types_dict, arg);
+ if (x != NULL) {
+ Py_INCREF(x);
+ return x;
+ }
+
+ x = (PyObject *)parse_c_decl(self, PyString_AS_STRING(arg));
+ if (x != NULL)
+ PyDict_SetItem(self->types_dict, arg, x);
+ return x;
+}
+
static PyMethodDef ffi_methods[] = {
- {"load_library", (PyCFunction)ffi_load_library,
- METH_VARARGS | METH_KEYWORDS},
- {"close_library", ffi_close_library, METH_VARARGS | METH_STATIC},
+ {"close_library", ffi_close_library, METH_VARARGS | METH_STATIC},
+ {"load_library", (PyCFunction)ffi_load_library,
+ METH_VARARGS | METH_KEYWORDS},
+ {"typeof", (PyCFunction)ffi_typeof, METH_O},
{NULL}
};
diff --git a/zeffir/lib_obj.c b/zeffir/lib_obj.c
--- a/zeffir/lib_obj.c
+++ b/zeffir/lib_obj.c
@@ -28,8 +28,7 @@
static PyObject *lib_getattr(ZefLibObject *lib, PyObject *name)
{
if (lib->l_dict == NULL) {
- PyErr_Format(PyExc_ValueError, "lib '%.200s' was closed",
- lib->l_libname);
+ PyErr_Format(ZefError, "lib '%.200s' was closed", lib->l_libname);
return NULL;
}
diff --git a/zeffir/test/test_ctype.py b/zeffir/test/test_ctype.py
new file mode 100644
--- /dev/null
+++ b/zeffir/test/test_ctype.py
@@ -0,0 +1,8 @@
+import support
+
+
+def test_typeof():
+ ffi = support.new_ffi()
+ assert repr(ffi.typeof("int")) == "<ctype 'int'>"
+ assert repr(ffi.typeof("long int")) == "<ctype 'long'>"
+ #assert repr(ffi.typeof("int*")) == "<ctype 'int *'>"
diff --git a/zeffir/zeffir.c b/zeffir/zeffir.c
--- a/zeffir/zeffir.c
+++ b/zeffir/zeffir.c
@@ -16,6 +16,7 @@
#include "ffi_obj.c"
#include "cfunc.c"
#include "builder.c"
+#include "../creflect/creflect_cdecl.c"
/************************************************************/
@@ -43,4 +44,13 @@
if (PyModule_AddObject(m, "FFI", (PyObject *)&ZefFFI_Type) < 0)
return;
+ if (PyModule_AddObject(m, "CType", (PyObject *)&CTypeDescr_Type) < 0)
+ return;
+
+ ZefError = PyErr_NewException("zeffir.error", NULL, NULL);
+ if (ZefError == NULL)
+ return;
+ Py_INCREF(ZefError);
+ if (PyModule_AddObject(m, "error", ZefError) < 0)
+ return;
}
diff --git a/zeffir/zeffir.h b/zeffir/zeffir.h
--- a/zeffir/zeffir.h
+++ b/zeffir/zeffir.h
@@ -5,5 +5,8 @@
static PyTypeObject ZefFFI_Type;
+static PyObject *ZefError;
+
static int lib_close(ZefLibObject *);
static int load_creflect_main(ZefFFIObject *, ZefLibObject *);
+static CTypeDescrObject *parse_c_decl(ZefFFIObject *ffi, const char *str);
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit