[pypy-svn] pypy jitypes2: support for chars

antocuni commits-noreply at bitbucket.org
Wed Jan 12 17:52:09 CET 2011


Author: Antonio Cuni <anto.cuni at gmail.com>
Branch: jitypes2
Changeset: r40631:3b80209b0841
Date: 2011-01-12 17:50 +0100
http://bitbucket.org/pypy/pypy/changeset/3b80209b0841/

Log:	support for chars

diff --git a/pypy/module/_ffi/test/test__ffi.py b/pypy/module/_ffi/test/test__ffi.py
--- a/pypy/module/_ffi/test/test__ffi.py
+++ b/pypy/module/_ffi/test/test__ffi.py
@@ -215,6 +215,19 @@
         assert sum_xy(10, 20) == 30
         assert sum_xy(100, 28) == -128
 
+    def test_char_args(self):
+        """
+            DLLEXPORT char my_toupper(char x)
+            {
+                return x - ('a'-'A');
+            }
+        """
+        from _ffi import CDLL, types
+        libfoo = CDLL(self.libfoo_name)
+        my_toupper = libfoo.getfunc('my_toupper', [types.char],
+                                    types.char)
+        assert my_toupper('c') == 'C'
+
     def test_single_float_args(self):
         """
             DLLEXPORT float sum_xy_float(float x, float y)

diff --git a/pypy/module/_ffi/interp_ffi.py b/pypy/module/_ffi/interp_ffi.py
--- a/pypy/module/_ffi/interp_ffi.py
+++ b/pypy/module/_ffi/interp_ffi.py
@@ -43,6 +43,9 @@
                 shape == 'B' or
                 shape == 'P' or
                 shape == 'Q')
+
+    def is_char(self):
+        return self.shape == 'c'
     
     def is_longlong(self):
         shape = self.shape
@@ -72,6 +75,10 @@
 def build_ffi_types():
     from pypy.rlib.clibffi import FFI_TYPE_P
     types = [
+        # note: most of the type name directly come from the C equivalent,
+        # with the exception of bytes: in C, ubyte and char are equivalent,
+        # but for _ffi the first expects a number while the second a 1-length
+        # string
         W_FFIType('slong',     'l', libffi.types.slong),
         W_FFIType('sint',      'i', libffi.types.sint),
         W_FFIType('sshort',    'h', libffi.types.sshort),
@@ -84,15 +91,15 @@
         W_FFIType('ubyte',     'B', libffi.types.uchar),
         W_FFIType('ulonglong', 'Q', libffi.types.ulonglong),
         #
+        W_FFIType('char',     'c', libffi.types.uchar),
+    
+       
         W_FFIType('double',    'd', libffi.types.double),
         W_FFIType('float',     'f', libffi.types.float),
         W_FFIType('void',      '0', libffi.types.void),
         W_FFIType('pointer',   'P', libffi.types.pointer),
         #
         # missing types:
-        ## 'c' : ffi_type_uchar,
-        ## 'b' : ffi_type_schar,
-        ## 'B' : ffi_type_uchar,
         ## 'u' : cast_type_to_ffitype(lltype.UniChar),
         ## 's' : ffi_type_pointer,
         ## 'z' : ffi_type_pointer,
@@ -152,6 +159,9 @@
                 argchain.arg(space.int_w(w_arg))
             elif w_argtype.is_unsigned():
                 argchain.arg(intmask(space.uint_w(w_arg)))
+            elif w_argtype.is_char():
+                w_arg = space.ord(w_arg)
+                argchain.arg(space.int_w(w_arg))
             elif w_argtype.is_double():
                 argchain.arg(space.float_w(w_arg))
             elif w_argtype.is_singlefloat():
@@ -195,6 +205,9 @@
             return self._call_int(space, argchain)
         elif w_restype.is_unsigned():
             return self._call_uint(space, argchain)
+        elif w_restype.is_char():
+            intres = self.func.call(argchain, rffi.UCHAR)
+            return space.wrap(chr(intres))
         elif w_restype.is_double():
             floatres = self.func.call(argchain, rffi.DOUBLE)
             return space.wrap(floatres)


More information about the Pypy-commit mailing list