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