[pypy-commit] cffi wchar_t: hg merge default
arigo
noreply at buildbot.pypy.org
Sat Jun 23 09:59:37 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch: wchar_t
Changeset: r488:702a14644ece
Date: 2012-06-23 08:16 +0200
http://bitbucket.org/cffi/cffi/changeset/702a14644ece/
Log: hg merge default
diff --git a/c/_ffi_backend.c b/c/_ffi_backend.c
--- a/c/_ffi_backend.c
+++ b/c/_ffi_backend.c
@@ -1148,34 +1148,52 @@
static PyObject *cdata_richcompare(PyObject *v, PyObject *w, int op)
{
- CDataObject *obv, *obw;
- int equal;
- PyObject *res;
-
- if (op != Py_EQ && op != Py_NE)
- goto Unimplemented;
+ int res, full_order;
+ PyObject *pyres;
+ char *v_cdata, *w_cdata;
+
+ full_order = (op != Py_EQ && op != Py_NE);
assert(CData_Check(v));
- obv = (CDataObject *)v;
+ v_cdata = ((CDataObject *)v)->c_data;
+ if (full_order &&
+ (((CDataObject *)v)->c_type->ct_flags & CT_PRIMITIVE_ANY))
+ goto Error;
if (w == Py_None) {
- equal = (obv->c_data == NULL);
+ w_cdata = NULL;
}
else if (CData_Check(w)) {
- obw = (CDataObject *)w;
- equal = (obv->c_type == obw->c_type) && (obv->c_data == obw->c_data);
+ w_cdata = ((CDataObject *)w)->c_data;
+ if (full_order &&
+ (((CDataObject *)w)->c_type->ct_flags & CT_PRIMITIVE_ANY))
+ goto Error;
}
else
goto Unimplemented;
- res = (equal ^ (op == Py_NE)) ? Py_True : Py_False;
+ switch (op) {
+ case Py_EQ: res = (v_cdata == w_cdata); break;
+ case Py_NE: res = (v_cdata != w_cdata); break;
+ case Py_LT: res = (v_cdata < w_cdata); break;
+ case Py_LE: res = (v_cdata <= w_cdata); break;
+ case Py_GT: res = (v_cdata > w_cdata); break;
+ case Py_GE: res = (v_cdata >= w_cdata); break;
+ default: res = -1;
+ }
+ pyres = res ? Py_True : Py_False;
done:
- Py_INCREF(res);
- return res;
+ Py_INCREF(pyres);
+ return pyres;
Unimplemented:
- res = Py_NotImplemented;
+ pyres = Py_NotImplemented;
goto done;
+
+ Error:
+ PyErr_SetString(PyExc_TypeError,
+ "cannot do comparison on a primitive cdata");
+ return NULL;
}
static long cdata_hash(CDataObject *cd)
@@ -1197,12 +1215,9 @@
return -1;
}
-static PyObject *
-cdata_subscript(CDataObject *cd, PyObject *key)
+static char *
+_cdata_get_indexed_ptr(CDataObject *cd, PyObject *key)
{
- CTypeDescrObject *ctitem = cd->c_type->ct_itemdescr;
- /* use 'mp_subscript' instead of 'sq_item' because we don't want
- negative indexes to be corrected automatically */
Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
if (i == -1 && PyErr_Occurred())
return NULL;
@@ -1234,48 +1249,31 @@
cd->c_type->ct_name);
return NULL;
}
- return convert_to_object(cd->c_data + i * ctitem->ct_size, ctitem);
+ return cd->c_data + i * cd->c_type->ct_itemdescr->ct_size;
+}
+
+static PyObject *
+cdata_subscript(CDataObject *cd, PyObject *key)
+{
+ char *c = _cdata_get_indexed_ptr(cd, key);
+ CTypeDescrObject *ctitem = cd->c_type->ct_itemdescr;
+ /* use 'mp_subscript' instead of 'sq_item' because we don't want
+ negative indexes to be corrected automatically */
+ if (c == NULL)
+ return NULL;
+ return convert_to_object(c, ctitem);
}
static int
cdata_ass_sub(CDataObject *cd, PyObject *key, PyObject *v)
{
+ char *c = _cdata_get_indexed_ptr(cd, key);
CTypeDescrObject *ctitem = cd->c_type->ct_itemdescr;
/* use 'mp_ass_subscript' instead of 'sq_ass_item' because we don't want
negative indexes to be corrected automatically */
- Py_ssize_t i = PyNumber_AsSsize_t(key, PyExc_IndexError);
- if (i == -1 && PyErr_Occurred())
+ if (c == NULL)
return -1;
-
- if (cd->c_type->ct_flags & CT_POINTER) {
- if (CDataOwn_Check(cd) && i != 0) {
- PyErr_Format(PyExc_IndexError,
- "cdata '%s' can only be indexed by 0",
- cd->c_type->ct_name);
- return -1;
- }
- }
- else if (cd->c_type->ct_flags & CT_ARRAY) {
- if (i < 0) {
- PyErr_SetString(PyExc_IndexError,
- "negative index not supported");
- return -1;
- }
- if (i >= get_array_length(cd)) {
- PyErr_Format(PyExc_IndexError,
- "index too large for cdata '%s' (expected %zd < %zd)",
- cd->c_type->ct_name,
- i, get_array_length(cd));
- return -1;
- }
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "cdata of type '%s' does not support index assignment",
- cd->c_type->ct_name);
- return -1;
- }
- return convert_from_object(cd->c_data + i * ctitem->ct_size, ctitem, v);
+ return convert_from_object(c, ctitem, v);
}
static PyObject *
@@ -1984,8 +1982,11 @@
write_raw_float_data(cd->c_data, value, ct->ct_size);
return (PyObject *)cd;
}
- else
- goto cannot_cast;
+ else {
+ PyErr_Format(PyExc_TypeError, "cannot cast to ctype '%s'",
+ ct->ct_name);
+ return NULL;
+ }
cannot_cast:
if (CData_Check(ob))
@@ -2363,11 +2364,7 @@
PyErr_SetString(PyExc_ValueError, "negative array length");
return NULL;
}
-#ifdef MS_WIN32
- sprintf(extra_text, "[%ld]", (long)length); /* XXX not large enough */
-#else
- sprintf(extra_text, "[%zd]", length);
-#endif
+ sprintf(extra_text, "[%llu]", (unsigned PY_LONG_LONG)length);
arraysize = length * ctitem->ct_size;
if (length > 0 && (arraysize / length) != ctitem->ct_size) {
PyErr_SetString(PyExc_OverflowError,
diff --git a/c/test_c.py b/c/test_c.py
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -8,6 +8,7 @@
from _ffi_backend import *
from _ffi_backend import _getfields, _testfunc
+# ____________________________________________________________
def size_of_int():
BInt = new_primitive_type("int")
diff --git a/cffi/backend_ctypes.py b/cffi/backend_ctypes.py
--- a/cffi/backend_ctypes.py
+++ b/cffi/backend_ctypes.py
@@ -1,4 +1,4 @@
-import ctypes, ctypes.util
+import ctypes, ctypes.util, operator
from . import model
class CTypesData(object):
@@ -76,10 +76,42 @@
raise TypeError("cdata %r does not support iteration" % (
self._get_c_name()),)
+ def _make_cmp(name):
+ cmpfunc = getattr(operator, name)
+ def cmp(self, other):
+ if isinstance(other, CTypesData):
+ return cmpfunc(self._convert_to_address(None),
+ other._convert_to_address(None))
+ elif other is None:
+ return cmpfunc(self._convert_to_address(None), 0)
+ else:
+ return NotImplemented
+ cmp.func_name = name
+ return cmp
+
+ __eq__ = _make_cmp('__eq__')
+ __ne__ = _make_cmp('__ne__')
+ __lt__ = _make_cmp('__lt__')
+ __le__ = _make_cmp('__le__')
+ __gt__ = _make_cmp('__gt__')
+ __ge__ = _make_cmp('__ge__')
+
+ def __hash__(self):
+ return hash(type(self)) ^ hash(self._convert_to_address(None))
+
class CTypesGenericPrimitive(CTypesData):
__slots__ = []
+ def __eq__(self, other):
+ return self is other
+
+ def __ne__(self, other):
+ return self is not other
+
+ def __hash__(self):
+ return object.__hash__(self)
+
class CTypesGenericArray(CTypesData):
__slots__ = []
@@ -119,18 +151,6 @@
def __nonzero__(self):
return bool(self._address)
- def __eq__(self, other):
- if other is None:
- return not bool(self._address)
- return (type(self) is type(other) and
- self._address == other._address)
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
- def __hash__(self):
- return hash(type(self)) ^ hash(self._address)
-
@classmethod
def _to_ctypes(cls, value):
if value is None:
diff --git a/demo/winclipboard.py b/demo/winclipboard.py
--- a/demo/winclipboard.py
+++ b/demo/winclipboard.py
@@ -24,6 +24,9 @@
BOOL EmptyClipboard(void);
HANDLE SetClipboardData(UINT uFormat, HANDLE hMem);
+ #define CF_TEXT ...
+ #define GMEM_MOVEABLE ...
+
void * memcpy(void * s1, void * s2, int n);
''')
@@ -37,9 +40,6 @@
'''
use win32 api to copy `string` to the clipboard
'''
- CF_TEXT = 1
- GMEM_MOVEABLE = 0x0002
-
hWnd = GetConsoleWindow()
if OpenClipboard(hWnd):
diff --git a/testing/backend_tests.py b/testing/backend_tests.py
--- a/testing/backend_tests.py
+++ b/testing/backend_tests.py
@@ -67,6 +67,7 @@
q = ffi.cast(c_decl, long(min - 1))
assert ffi.typeof(q) is ffi.typeof(p) and int(q) == max
assert q != p
+ assert int(q) == int(p)
assert hash(q) != hash(p) # unlikely
py.test.raises(OverflowError, ffi.new, c_decl, min - 1)
py.test.raises(OverflowError, ffi.new, c_decl, max + 1)
@@ -911,6 +912,67 @@
assert p == s+0
assert p+1 == s+1
+ def test_pointer_comparison(self):
+ ffi = FFI(backend=self.Backend())
+ s = ffi.new("short[]", range(100))
+ p = ffi.cast("short *", s)
+ assert (p < s) is False
+ assert (p <= s) is True
+ assert (p == s) is True
+ assert (p != s) is False
+ assert (p > s) is False
+ assert (p >= s) is True
+ assert (s < p) is False
+ assert (s <= p) is True
+ assert (s == p) is True
+ assert (s != p) is False
+ assert (s > p) is False
+ assert (s >= p) is True
+ q = p + 1
+ assert (q < s) is False
+ assert (q <= s) is False
+ assert (q == s) is False
+ assert (q != s) is True
+ assert (q > s) is True
+ assert (q >= s) is True
+ assert (s < q) is True
+ assert (s <= q) is True
+ assert (s == q) is False
+ assert (s != q) is True
+ assert (s > q) is False
+ assert (s >= q) is False
+ assert (q < p) is False
+ assert (q <= p) is False
+ assert (q == p) is False
+ assert (q != p) is True
+ assert (q > p) is True
+ assert (q >= p) is True
+ assert (p < q) is True
+ assert (p <= q) is True
+ assert (p == q) is False
+ assert (p != q) is True
+ assert (p > q) is False
+ assert (p >= q) is False
+ #
+ assert (None == s) is False
+ assert (None != s) is True
+ assert (s == None) is False
+ assert (s != None) is True
+ assert (None == q) is False
+ assert (None != q) is True
+ assert (q == None) is False
+ assert (q != None) is True
+
+ def test_no_integer_comparison(self):
+ ffi = FFI(backend=self.Backend())
+ x = ffi.cast("int", 123)
+ y = ffi.cast("int", 456)
+ py.test.raises(TypeError, "x < y")
+ #
+ z = ffi.cast("double", 78.9)
+ py.test.raises(TypeError, "x < z")
+ py.test.raises(TypeError, "z < y")
+
def test_ffi_buffer_ptr(self):
ffi = FFI(backend=self.Backend())
a = ffi.new("short", 100)
More information about the pypy-commit
mailing list