Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r181:f1168b43ad59
Date: 2014-12-05 21:34 +0100
http://bitbucket.org/cffi/creflect/changeset/f1168b43ad59/

Log:    ffi.getctype()

diff --git a/zeffir/ffi_obj.c b/zeffir/ffi_obj.c
--- a/zeffir/ffi_obj.c
+++ b/zeffir/ffi_obj.c
@@ -643,10 +643,53 @@
     }
 }
 
+static PyObject *ffi_getctype(ZefFFIObject *self, PyObject *args)
+{
+    PyObject *cdecl, *res;
+    char *p, *replace_with = "";
+    int add_paren, add_space;
+    CTypeDescrObject *ct;
+    size_t replace_with_len;
+
+    if (!PyArg_ParseTuple(args, "O|s:getctype", &cdecl, &replace_with))
+        return NULL;
+
+    ct = _ffi_type(self, cdecl, ACCEPT_STRING|ACCEPT_CTYPE);
+    if (ct == NULL)
+        return NULL;
+
+    while (replace_with[0] != 0 && isspace(replace_with[0]))
+        replace_with++;
+    replace_with_len = strlen(replace_with);
+    while (replace_with_len > 0 && isspace(replace_with[replace_with_len - 1]))
+        replace_with_len--;
+
+    add_paren = (replace_with[0] == '*' &&
+                 ((ct->ct_flags & (CT_ARRAY | CT_FUNCTION)) != 0));
+    add_space = (!add_paren && replace_with_len > 0 &&
+                 replace_with[0] != '[' && replace_with[0] != '(');
+
+    res = combine_type_name_l(ct, replace_with_len + add_space + 2 * 
add_paren);
+    if (res == NULL)
+        return NULL;
+
+    p = PyString_AS_STRING(res) + ct->ct_name_position;
+    if (add_paren)
+        *p++ = '(';
+    if (add_space)
+        *p++ = ' ';
+    memcpy(p, replace_with, replace_with_len);
+    if (add_paren)
+        p[replace_with_len] = ')';
+    return res;
+}
+
+
 static PyMethodDef ffi_methods[] = {
     {"addressof",     (PyCFunction)ffi_addressof,METH_VARARGS},
     {"cast",          (PyCFunction)ffi_cast,     METH_VARARGS},
     {"close_library", ffi_close_library,         METH_VARARGS | METH_STATIC},
+    {"getctype",      (PyCFunction)ffi_getctype, METH_VARARGS},
     {"load_library",  (PyCFunction)ffi_load_library,
                                                  METH_VARARGS | METH_KEYWORDS},
     {"offsetof",      (PyCFunction)ffi_offsetof, METH_VARARGS},
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
@@ -54,3 +54,21 @@
     p = ffi.new("char[]", "----abcd")
     q = ffi.cast("int *", p)
     assert q[1] in [0x61626364, 0x64636261]
+
+def test_getctype():
+    ffi = support.new_ffi()
+    assert ffi.getctype("int") == "int"
+    assert ffi.getctype("int", 'x') == "int x"
+    assert ffi.getctype("int*") == "int *"
+    assert ffi.getctype("int*", '') == "int *"
+    assert ffi.getctype("int*", 'x') == "int * x"
+    assert ffi.getctype("int", '*') == "int *"
+    assert ffi.getctype("int", ' * x ') == "int * x"
+    assert ffi.getctype(ffi.typeof("int*"), '*') == "int * *"
+    assert ffi.getctype("int", '[5]') == "int[5]"
+    assert ffi.getctype("int[5]", '[6]') == "int[6][5]"
+    assert ffi.getctype("int[5]", '(*)') == "int(*)[5]"
+    # special-case for convenience: automatically put '()' around '*'
+    assert ffi.getctype("int[5]", '*') == "int(*)[5]"
+    assert ffi.getctype("int[5]", '*foo') == "int(*foo)[5]"
+    assert ffi.getctype("int[5]", ' ** foo ') == "int(** foo)[5]"
diff --git a/zeffir/zeffir.h b/zeffir/zeffir.h
--- a/zeffir/zeffir.h
+++ b/zeffir/zeffir.h
@@ -23,3 +23,5 @@
 static int fill_array_type(CTypeDescrObject *ctptr);
 static CTypeDescrObject *fetch_pointer_type(PyObject *types_dict,
                                             CTypeDescrObject *totype);
+static PyObject *combine_type_name_l(CTypeDescrObject *ct,
+                                     size_t extra_text_len);
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to