Author: Armin Rigo <[email protected]>
Branch: cpy-extension
Changeset: r293:4f6d840ef0e4
Date: 2012-06-12 17:28 +0200
http://bitbucket.org/cffi/cffi/changeset/4f6d840ef0e4/
Log: Char arguments.
diff --git a/c/_ffi_backend.c b/c/_ffi_backend.c
--- a/c/_ffi_backend.c
+++ b/c/_ffi_backend.c
@@ -593,6 +593,21 @@
return -1;
}
+static int _convert_to_char(PyObject *init)
+{
+ if (PyString_Check(init) && PyString_GET_SIZE(init) == 1) {
+ return (unsigned char)(PyString_AS_STRING(init)[0]);
+ }
+ if (CData_Check(init) &&
+ (((CDataObject *)init)->c_type->ct_flags & CT_PRIMITIVE_CHAR)) {
+ return (unsigned char)(((CDataObject *)init)->c_data[0]);
+ }
+ PyErr_Format(PyExc_TypeError,
+ "initializer for ctype 'char' must be a string of length 1, "
+ "not %.200s", Py_TYPE(init)->tp_name);
+ return -1;
+}
+
static int
convert_from_object(char *data, CTypeDescrObject *ct, PyObject *init)
{
@@ -708,17 +723,11 @@
return 0;
}
if (ct->ct_flags & CT_PRIMITIVE_CHAR) {
- if (PyString_Check(init) && PyString_GET_SIZE(init) == 1) {
- data[0] = PyString_AS_STRING(init)[0];
- return 0;
- }
- if (CData_Check(init) &&
- (((CDataObject *)init)->c_type->ct_flags & CT_PRIMITIVE_CHAR)) {
- data[0] = ((CDataObject *)init)->c_data[0];
- return 0;
- }
- expected = "string of length 1";
- goto cannot_convert;
+ int res = _convert_to_char(init);
+ if (res < 0)
+ return -1;
+ data[0] = res;
+ return 0;
}
if (ct->ct_flags & CT_STRUCT) {
@@ -3293,6 +3302,11 @@
return _my_PyLong_AsUnsignedLongLong(obj, 1);
}
+static char _cffi_to_c_char(PyObject *obj)
+{
+ return (char)_convert_to_char(obj);
+}
+
static void *cffi_exports[] = {
_cffi_to_c_char_p,
_cffi_to_c_signed_char,
@@ -3308,6 +3322,7 @@
#endif
_cffi_to_c_unsigned_long,
_cffi_to_c_unsigned_long_long,
+ _cffi_to_c_char,
};
/************************************************************/
diff --git a/cffi/verifier.py b/cffi/verifier.py
--- a/cffi/verifier.py
+++ b/cffi/verifier.py
@@ -76,9 +76,11 @@
if tp.name in ('float', 'double'):
# float types
converter = 'PyFloat_AsDouble'
+ #
elif tp.name == 'char':
# char
- xxx
+ converter = '_cffi_to_c_char'
+ #
else:
unsigned = tp.name.startswith('unsigned ')
size = self.ffi.sizeof(bt)
@@ -225,6 +227,10 @@
# define _cffi_from_c_long_long PyInt_FromLong
#endif
+static PyObject *_cffi_from_c_char(char x) {
+ return PyString_FromStringAndSize(&x, 1);
+}
+
#define _cffi_to_c_short PyInt_AsLong
#define _cffi_to_c_int PyInt_AsLong
#define _cffi_to_c_long PyInt_AsLong
@@ -250,6 +256,8 @@
((unsigned long(*)(PyObject *))_cffi_exports[7])
#define _cffi_to_c_unsigned_long_long \
((unsigned long long(*)(PyObject *))_cffi_exports[8])
+#define _cffi_to_c_char \
+ ((char(*)(PyObject *))_cffi_exports[9])
static void **_cffi_exports;
diff --git a/testing/test_verify.py b/testing/test_verify.py
--- a/testing/test_verify.py
+++ b/testing/test_verify.py
@@ -59,6 +59,13 @@
assert lib.foo(ffi.cast(typename, 46)) == 47
py.test.raises(TypeError, lib.foo, None)
+def test_char_type():
+ ffi = FFI()
+ ffi.cdef("char foo(char);")
+ lib = ffi.verify("char foo(char x) { return x+1; }")
+ assert lib.foo("A") == "B"
+ py.test.raises(TypeError, lib.foo, "bar")
+
def test_verify_typedefs():
py.test.skip("XXX?")
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit