Commits

Armin Rigo committed a6249df

In-progress

  • Participants
  • Parent commits 67ebe0b

Comments (0)

Files changed (3)

             return self._get_cached_btype('new_array_type', bitem, length)
         else:
             # assume a primitive type
-            ident = ' '.join(typenode.type.names)
+            names = typenode.type.names
+            if len(names) > 1 and names[-1] == 'int':
+                names = names[:-1]
+            ident = ' '.join(names)
             return self._get_cached_btype('new_primitive_type', ident)
 
     def _get_cached_btype(self, methname, *args):

File ffi/backend_ctypes.py

 import ctypes, ctypes.util
 
 
+class CTypesData(object):
+
+    @staticmethod
+    def _import(value):
+        x
+
+    @staticmethod
+    def _export(ctypes_value):
+        raise NotImplementedError
+
+
 class CTypesBackend(object):
 
     PRIMITIVE_TYPES = {
         'short': ctypes.c_short,
         'int': ctypes.c_int,
         'long': ctypes.c_long,
-        'long int': ctypes.c_long,
         'long long': ctypes.c_longlong,
-        'long long int': ctypes.c_longlong,
         'signed char': ctypes.c_byte,
         'signed short': ctypes.c_short,
-        'signed int': ctypes.c_int,
+        'signed': ctypes.c_int,
         'signed long': ctypes.c_long,
-        'signed long int': ctypes.c_long,
         'signed long long': ctypes.c_longlong,
-        'signed long long int': ctypes.c_longlong,
         'unsigned char': ctypes.c_ubyte,
         'unsigned short': ctypes.c_ushort,
-        'unsigned int': ctypes.c_uint,
+        'unsigned': ctypes.c_uint,
         'unsigned long': ctypes.c_ulong,
-        'unsigned long int': ctypes.c_ulong,
         'unsigned long long': ctypes.c_ulonglong,
-        'unsigned long long int': ctypes.c_ulonglong,
         'double': ctypes.c_double,
     }
 
     def new_primitive_type(self, name):
         # XXX integer types only
         ctype = self.PRIMITIVE_TYPES[name]
+        is_signed = (ctype(-1).value == -1)
         #
-        class CTypesInt(object):
+        class CTypesInt(CTypesData):
             _ctype = ctype
+
             def __init__(self, value=0):
                 if ctype(value).value != value:
                     raise OverflowError("%r out of range: %d" %
                                         (name, value))
                 self._value = value
+
             def __int__(self):
                 return self._value
+
+            @staticmethod
+            def _import(x):
+                if not isinstance(x, (int, long)):
+                    if isinstance(x, CTypesData):
+                        x = int(x)
+                    else:
+                        raise TypeError("integer expected, got %s" %
+                                        type(x).__name__)
+                if ctype(x).value != x:
+                    if not is_signed and x < 0:
+                        raise OverflowError("%s: negative integer" % name)
+                    else:
+                        raise OverflowError("%s: integer out of bounds" % name)
+                return x
+            _export = staticmethod(_identity)
         #
         return CTypesInt
 
     def new_array_type(self, bitem, length):
-        # XXX array of integers only
         #
-        class CTypesArray(object):
+        class CTypesArray(CTypesData):
+            if length is not None:
+                _ctype = bitem._ctype * length
 
             def __init__(self, init):
                 if length is not None:
             def __getitem__(self, index):
                 if not (0 <= index < len(self._blob)):
                     raise IndexError
-                return self._blob[index]
+                return bitem._export(self._blob[index])
 
             def __setitem__(self, index, value):
                 if not (0 <= index < len(self._blob)):
                     raise IndexError
-                self._blob[index] = value
+                self._blob[index] = bitem._import(value)
+
+            @staticmethod
+            def _export(xx):
+                xxx
         #
         return CTypesArray
 
         func.argtypes = args
         func.restype = result
         return func
+
+
+def _identity(x):
+    return x

File testing/backend_tests.py

         ffi = FFI(backend=self.Backend())
         for (c_type, size) in [('char', 1),
                                ('short', 2),
+                               ('short int', 2),
+                               ('', 4),
                                ('int', 4),
                                ('long', SIZE_OF_LONG),
                                ('long int', SIZE_OF_LONG),
                 c_decl = {None: '',
                           False: 'signed ',
                           True: 'unsigned '}[unsigned] + c_type
-                if c_decl == 'char':
+                if c_decl == 'char' or c_decl == '':
                     continue
                 if unsigned:
                     min = 0
         assert p[1] == 0     # follow C convention rather than LuaJIT's
         assert p[2] == 0
         assert p[3] == 0
+        p = ffi.new("int[4]", [ffi.new("int", -5)])
+        assert p[0] == -5
 
     def test_new_array_varsize(self):
         ffi = FFI(backend=self.Backend())
         assert p[0] == -6
         assert p[1] == -7
         py.test.raises(IndexError, "p[2]")
+
+    def test_new_array_of_array(self):
+        py.test.skip("in-progress")
+        ffi = FFI(backend=self.Backend())
+        p = ffi.new("int[3][4]")
+        p[0][0] = 10
+        p[2][3] = 33
+        assert p[0][0] == 10
+        assert p[2][3] == 33
+        py.test.raises(IndexError, "p[1][-1]")