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

Reply via email to