From edffe66631b626951a665d12bfc4c2970edb41d3 Mon Sep 17 00:00:00 2001 From: Dag Sverre Seljebotn Date: Fri, 15 Aug 2008 16:29:27 +0200 Subject: [PATCH] Buffers: Support for typedefs floats. --- Cython/Compiler/Buffer.py | 28 +++++++----- tests/run/bufaccess.h | 4 +- tests/run/bufaccess.pyx | 92 +++++++++++++++++++++++++++------------ 3 files changed, 84 insertions(+), 40 deletions(-) diff --git a/Cython/Compiler/Buffer.py b/Cython/Compiler/Buffer.py index e53c5a4a..477f80ac 100644 --- a/Cython/Compiler/Buffer.py +++ b/Cython/Compiler/Buffer.py @@ -474,20 +474,26 @@ def get_ts_check_item(dtype, writer): ('b', 'char'), ('h', 'short'), ('i', 'int'), ('l', 'long'), ('q', 'long long') ] - if dtype.signed == 0: - code += "".join(["\n case '%s': ok = (sizeof(%s) == sizeof(%s) && (%s)-1 > 0); break;" % + elif dtype.is_float: + types = [('f', 'float'), ('d', 'double'), ('g', 'long double')] + else: + assert False + if dtype.signed == 0: + code += "".join(["\n case '%s': ok = (sizeof(%s) == sizeof(%s) && (%s)-1 > 0); break;" % (char.upper(), ctype, against, ctype) for char, against in types]) - else: - code += "".join(["\n case '%s': ok = (sizeof(%s) == sizeof(%s) && (%s)-1 < 0); break;" % + else: + code += "".join(["\n case '%s': ok = (sizeof(%s) == sizeof(%s) && (%s)-1 < 0); break;" % (char, ctype, against, ctype) for char, against in types]) - code += dedent("""\ - default: ok = 0; - } - if (!ok) { - PyErr_Format(PyExc_ValueError, "Buffer datatype mismatch (rejecting on '%s')", ts); - return NULL; - } else return ts + 1; + code += dedent("""\ + default: ok = 0; + } + if (!ok) { + PyErr_Format(PyExc_ValueError, "Buffer datatype mismatch (rejecting on '%s')", ts); + return NULL; + } else return ts + 1; """, 2) + + writer.globalstate.use_utility_code([dedent("""\ static const char* %s(const char* ts); /*proto*/ """) % name, dedent(""" diff --git a/tests/run/bufaccess.h b/tests/run/bufaccess.h index 5da79d29..48715bbe 100644 --- a/tests/run/bufaccess.h +++ b/tests/run/bufaccess.h @@ -1,3 +1,5 @@ /* See bufaccess.pyx */ -typedef short htypedef_short; +typedef short td_h_short; +typedef double td_h_double; +typedef unsigned short td_h_ushort; diff --git a/tests/run/bufaccess.pyx b/tests/run/bufaccess.pyx index 9cd830a9..a4ad192c 100644 --- a/tests/run/bufaccess.pyx +++ b/tests/run/bufaccess.pyx @@ -657,19 +657,22 @@ def printbuf_float(o, shape): # # Typedefs # -ctypedef int cytypedef_int +# Test three layers of typedefs going through a h file for plain int, and +# simply a header file typedef for floats and unsigned. + +ctypedef int td_cy_int cdef extern from "bufaccess.h": - ctypedef cytypedef_int htypedef_short # Defined as short, but Cython doesn't know this! -ctypedef htypedef_short cytypedef2 + ctypedef td_cy_int td_h_short # Defined as short, but Cython doesn't know this! + ctypedef float td_h_double # Defined as double + ctypedef unsigned int td_h_ushort # Defined as unsigned short +ctypedef td_h_short td_h_cy_short @testcase -def printbuf_cytypedef_int(object[cytypedef_int] buf, shape): +def printbuf_td_cy_int(object[td_cy_int] buf, shape): """ - >>> printbuf_cytypedef_int(IntMockBuffer("A", range(3)), (3,)) - acquired A + >>> printbuf_td_cy_int(IntMockBuffer(None, range(3)), (3,)) 0 1 2 END - released A - >>> printbuf_cytypedef_int(ShortMockBuffer("B", range(3)), (3,)) + >>> printbuf_td_cy_int(ShortMockBuffer(None, range(3)), (3,)) Traceback (most recent call last): ... ValueError: Buffer datatype mismatch (rejecting on 'h') @@ -681,41 +684,66 @@ def printbuf_cytypedef_int(object[cytypedef_int] buf, shape): print 'END' @testcase -def printbuf_htypedef_short(object[htypedef_short] buf, shape): +def printbuf_td_h_short(object[td_h_short] buf, shape): """ - >>> printbuf_htypedef_short(ShortMockBuffer("A", range(3)), (3,)) - acquired A + >>> printbuf_td_h_short(ShortMockBuffer(None, range(3)), (3,)) 0 1 2 END - released A - >>> printbuf_htypedef_short(IntMockBuffer("B", range(3)), (3,)) + >>> printbuf_td_h_short(IntMockBuffer(None, range(3)), (3,)) Traceback (most recent call last): ... ValueError: Buffer datatype mismatch (rejecting on 'i') - """ - + """ cdef int i for i in range(shape[0]): print buf[i], print 'END' @testcase -def printbuf_cytypedef2(object[cytypedef2] buf, shape): +def printbuf_td_h_cy_short(object[td_h_cy_short] buf, shape): """ - >>> printbuf_cytypedef2(ShortMockBuffer("A", range(3)), (3,)) - acquired A + >>> printbuf_td_h_cy_short(ShortMockBuffer(None, range(3)), (3,)) 0 1 2 END - released A - >>> printbuf_cytypedef2(IntMockBuffer("B", range(3)), (3,)) + >>> printbuf_td_h_cy_short(IntMockBuffer(None, range(3)), (3,)) Traceback (most recent call last): ... ValueError: Buffer datatype mismatch (rejecting on 'i') """ - cdef int i for i in range(shape[0]): print buf[i], print 'END' +@testcase +def printbuf_td_h_ushort(object[td_h_ushort] buf, shape): + """ + >>> printbuf_td_h_ushort(UnsignedShortMockBuffer(None, range(3)), (3,)) + 0 1 2 END + >>> printbuf_td_h_ushort(ShortMockBuffer(None, range(3)), (3,)) + Traceback (most recent call last): + ... + ValueError: Buffer datatype mismatch (rejecting on 'h') + """ + cdef int i + for i in range(shape[0]): + print buf[i], + print 'END' + +@testcase +def printbuf_td_h_double(object[td_h_double] buf, shape): + """ + >>> printbuf_td_h_double(DoubleMockBuffer(None, [0.25, 1, 3.125]), (3,)) + 0.25 1.0 3.125 END + >>> printbuf_td_h_double(FloatMockBuffer(None, [0.25, 1, 3.125]), (3,)) + Traceback (most recent call last): + ... + ValueError: Buffer datatype mismatch (rejecting on 'f') + """ + cdef int i + for i in range(shape[0]): + print buf[i], + print 'END' + + # # Object access # @@ -932,13 +960,6 @@ cdef class MockBuffer: cdef get_default_format(self): print "ERROR, not subclassed", self.__class__ -cdef class FloatMockBuffer(MockBuffer): - cdef int write(self, char* buf, object value) except -1: - (buf)[0] = value - return 0 - cdef get_itemsize(self): return sizeof(float) - cdef get_default_format(self): return b"=f" - cdef class IntMockBuffer(MockBuffer): cdef int write(self, char* buf, object value) except -1: (buf)[0] = value @@ -960,6 +981,21 @@ cdef class UnsignedShortMockBuffer(MockBuffer): cdef get_itemsize(self): return sizeof(unsigned short) 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: + (buf)[0] = value + return 0 + cdef get_itemsize(self): return sizeof(float) + cdef get_default_format(self): return b"f" + +cdef class DoubleMockBuffer(MockBuffer): + cdef int write(self, char* buf, object value) except -1: + (buf)[0] = value + return 0 + cdef get_itemsize(self): return sizeof(double) + cdef get_default_format(self): return b"d" + + cdef extern from *: void* addr_of_pyobject "(void*)"(object) -- 2.26.2