Author: Armin Rigo <[email protected]>
Branch: wchar_t
Changeset: r601:dac0ad93c7e5
Date: 2012-07-08 21:29 +0200
http://bitbucket.org/cffi/cffi/changeset/dac0ad93c7e5/
Log: Going for the simplest solution: no encoding/decoding issues,
require exactly strings for 'char' and unicodes for 'wchar_t'.
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -658,18 +658,34 @@
return -1;
}
-static int _convert_to_char(PyObject *init)
+static int _convert_to_char(PyObject *init, Py_ssize_t size)
{
- if (PyString_Check(init) && PyString_GET_SIZE(init) == 1) {
- return (unsigned char)(PyString_AS_STRING(init)[0]);
+ const char *msg;
+ if (size == sizeof(char)) {
+ if (PyString_Check(init) && PyString_GET_SIZE(init) == 1) {
+ return (unsigned char)(PyString_AS_STRING(init)[0]);
+ }
+ }
+ else { /* size == sizeof(wchar_t) */
+ if (PyUnicode_Check(init) && PyUnicode_GET_SIZE(init) == 1) {
+ return (wchar_t)(PyUnicode_AS_UNICODE(init)[0]);
+ }
}
if (CData_Check(init) &&
- (((CDataObject *)init)->c_type->ct_flags & CT_PRIMITIVE_CHAR)) {
- return (unsigned char)(((CDataObject *)init)->c_data[0]);
+ (((CDataObject *)init)->c_type->ct_flags & CT_PRIMITIVE_CHAR) &&
+ (((CDataObject *)init)->c_type->ct_size == size)) {
+ if (size == sizeof(char))
+ return (unsigned char)(((CDataObject *)init)->c_data[0]);
+ else
+ return *(wchar_t *)((CDataObject *)init)->c_data;
}
- PyErr_Format(PyExc_TypeError,
- "initializer for ctype 'char' must be a string of length 1, "
- "not %.200s", Py_TYPE(init)->tp_name);
+ if (size == sizeof(char))
+ msg = ("initializer for ctype 'char' must be a string of length 1, "
+ "not %.200s");
+ else
+ msg = ("initializer for ctype 'wchar_t' must be a unicode string "
+ "of length 1, not %.200s");
+ PyErr_Format(PyExc_TypeError, msg, Py_TYPE(init)->tp_name);
return -1;
}
@@ -829,7 +845,7 @@
return 0;
}
if (ct->ct_flags & CT_PRIMITIVE_CHAR) {
- int res = _convert_to_char(init);
+ int res = _convert_to_char(init, ct->ct_size);
if (res < 0)
return -1;
data[0] = res;
@@ -2237,8 +2253,6 @@
{ "ptrdiff_t", sizeof(ptrdiff_t) },
{ "size_t", sizeof(size_t) | UNSIGNED },
{ "ssize_t", sizeof(ssize_t) },
- { "wchar_t", sizeof(wchar_t) |
- (sizeof(wchar_t) < 4 ? UNSIGNED : 0) },
{ NULL }
};
#undef UNSIGNED
@@ -2281,7 +2295,8 @@
EPTYPE(ul, unsigned long, CT_PRIMITIVE_UNSIGNED ) \
EPTYPE(ull, unsigned long long, CT_PRIMITIVE_UNSIGNED ) \
EPTYPE(f, float, CT_PRIMITIVE_FLOAT ) \
- EPTYPE(d, double, CT_PRIMITIVE_FLOAT )
+ EPTYPE(d, double, CT_PRIMITIVE_FLOAT ) \
+ EPTYPE(wc, wchar_t, CT_PRIMITIVE_CHAR )
#define EPTYPE(code, typename, flags) \
struct aligncheck_##code { char x; typename y; };
@@ -2590,6 +2605,8 @@
if (!(ftype->ct_flags & (CT_PRIMITIVE_SIGNED |
CT_PRIMITIVE_UNSIGNED |
CT_PRIMITIVE_CHAR)) ||
+ ((ftype->ct_flags & CT_PRIMITIVE_CHAR)
+ && ftype->ct_size > 1) ||
fbitsize == 0 ||
fbitsize > 8 * ftype->ct_size) {
PyErr_Format(PyExc_TypeError, "invalid bit field '%s'",
@@ -3719,7 +3736,7 @@
static char _cffi_to_c_char(PyObject *obj)
{
- return (char)_convert_to_char(obj);
+ return (char)_convert_to_char(obj, sizeof(char));
}
static PyObject *_cffi_from_c_pointer(char *ptr, CTypeDescrObject *ct)
diff --git a/c/test_c.py b/c/test_c.py
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -1285,9 +1285,10 @@
complete_struct_or_union(BStruct, [('a1', BWChar, -1),
('a2', BWCharP, -1)])
s = newp(BStructPtr)
- s.a1 = '\x00'
+ s.a1 = u'\x00'
assert s.a1 == u'\x00'
- py.test.raises(UnicodeDecodeError, "s.a1 = '\xFF'")
+ py.test.raises(TypeError, "s.a1 = 'a'")
+ py.test.raises(TypeError, "s.a1 = '\xFF'")
s.a1 = u'\u1234'
assert s.a1 == u'\u1234'
if pyuni4:
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit