From: Dag Sverre Seljebotn Date: Thu, 4 Sep 2008 11:47:08 +0000 (+0200) Subject: Buffers: Format string parsing change (ticket 66) X-Git-Tag: 0.9.9.2.beta~63^2~10 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=111f3d42c2c07050fde23d4e58115a2b29e4cf95;p=cython.git Buffers: Format string parsing change (ticket 66) --- diff --git a/Cython/Compiler/Buffer.py b/Cython/Compiler/Buffer.py index 41b5ee11..985351ed 100644 --- a/Cython/Compiler/Buffer.py +++ b/Cython/Compiler/Buffer.py @@ -534,12 +534,11 @@ def get_getbuffer_code(dtype, code): } ts = buf->format; ts = __Pyx_ConsumeWhitespace(ts); - ts = __Pyx_BufferTypestringCheckEndian(ts); if (!ts) goto fail; - ts = __Pyx_ConsumeWhitespace(ts); ts = %(itemchecker)s(ts); if (!ts) goto fail; ts = __Pyx_ConsumeWhitespace(ts); + if (!ts) goto fail; if (*ts != 0) { PyErr_Format(PyExc_ValueError, "Expected non-struct buffer data type (expected end, got '%%s')", ts); @@ -667,7 +666,6 @@ acquire_utility_code = ["""\ static INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info); static INLINE void __Pyx_ZeroBuffer(Py_buffer* buf); /*proto*/ static INLINE const char* __Pyx_ConsumeWhitespace(const char* ts); /*proto*/ -static INLINE const char* __Pyx_BufferTypestringCheckEndian(const char* ts); /*proto*/ static void __Pyx_BufferNdimError(Py_buffer* buffer, int expected_ndim); /*proto*/ """, """ static INLINE void __Pyx_SafeReleaseBuffer(Py_buffer* info) { @@ -687,41 +685,24 @@ static INLINE void __Pyx_ZeroBuffer(Py_buffer* buf) { static INLINE const char* __Pyx_ConsumeWhitespace(const char* ts) { while (1) { switch (*ts) { + case '@': case 10: case 13: case ' ': ++ts; + break; + case '=': + case '<': + case '>': + case '!': + PyErr_SetString(PyExc_ValueError, "Buffer acquisition error: Only native byte order, size and alignment supported."); + return NULL; default: return ts; } } } -static INLINE const char* __Pyx_BufferTypestringCheckEndian(const char* ts) { - int num = 1; - int little_endian = ((char*)&num)[0]; - int ok = 1; - switch (*ts) { - case '@': - case '=': - ++ts; break; - case '<': - if (little_endian) ++ts; - else ok = 0; - break; - case '>': - case '!': - if (!little_endian) ++ts; - else ok = 0; - break; - } - if (!ok) { - PyErr_Format(PyExc_ValueError, "Buffer has wrong endianness (rejecting on '%s')", ts); - return NULL; - } - return ts; -} - static void __Pyx_BufferNdimError(Py_buffer* buffer, int expected_ndim) { PyErr_Format(PyExc_ValueError, "Buffer has wrong number of dimensions (expected %d, got %d)", diff --git a/tests/run/bufaccess.pyx b/tests/run/bufaccess.pyx index dff49290..3a571297 100644 --- a/tests/run/bufaccess.pyx +++ b/tests/run/bufaccess.pyx @@ -329,6 +329,35 @@ def explicitly_release_buffer(): x = None print "After release" +# +# Format strings +# +@testcase +def alignment_string(object[int] buf): + """ + >>> alignment_string(IntMockBuffer(None, [1,2], format="@i")) + 2 + >>> alignment_string(IntMockBuffer(None, [1,2], format="@i@@")) + 2 + >>> alignment_string(IntMockBuffer(None, [1,2], format=">i")) + Traceback (most recent call last): + ... + ValueError: Buffer acquisition error: Only native byte order, size and alignment supported. + >>> alignment_string(IntMockBuffer(None, [1,2], format=">> alignment_string(IntMockBuffer(None, [1,2], format="=i")) + Traceback (most recent call last): + ... + ValueError: Buffer acquisition error: Only native byte order, size and alignment supported. + >>> alignment_string(IntMockBuffer(None, [1,2], format="!i")) + Traceback (most recent call last): + ... + ValueError: Buffer acquisition error: Only native byte order, size and alignment supported. + """ + print buf[1] + # # Getting items and index bounds checking # @@ -997,7 +1026,7 @@ cdef class IntMockBuffer(MockBuffer): (buf)[0] = value return 0 cdef get_itemsize(self): return sizeof(int) - cdef get_default_format(self): return b"=i" + cdef get_default_format(self): return b"@i" cdef class ShortMockBuffer(MockBuffer): cdef int write(self, char* buf, object value) except -1: @@ -1011,7 +1040,7 @@ cdef class UnsignedShortMockBuffer(MockBuffer): (buf)[0] = value return 0 cdef get_itemsize(self): return sizeof(unsigned short) - cdef get_default_format(self): return b"=1H" # Try with repeat count + cdef get_default_format(self): return b"@1H" # Try with repeat count cdef class FloatMockBuffer(MockBuffer): cdef int write(self, char* buf, object value) except -1: @@ -1037,7 +1066,7 @@ cdef class ObjectMockBuffer(MockBuffer): return 0 cdef get_itemsize(self): return sizeof(void*) - cdef get_default_format(self): return b"=O" + cdef get_default_format(self): return b"@O" cdef class IntStridedMockBuffer(IntMockBuffer):