Commits

Armin Rigo committed 31f46a2 Merge

hg merge default

  • Participants
  • Parent commits 34052d6, dd5af0e
  • Branches verifier2

Comments (0)

Files changed (9)

         self._function_caches.append(function_cache)
         return lib
 
-    def typeof(self, cdecl, consider_function_as_funcptr=False):
+    def _typeof(self, cdecl, consider_function_as_funcptr=False):
+        # string -> ctype object
+        try:
+            btype, cfaf = self._parsed_types[cdecl]
+            if consider_function_as_funcptr and not cfaf:
+                raise KeyError
+        except KeyError:
+            cfaf = consider_function_as_funcptr
+            type = self._parser.parse_type(cdecl,
+                       consider_function_as_funcptr=cfaf)
+            btype = self._get_cached_btype(type)
+            self._parsed_types[cdecl] = btype, cfaf
+        return btype
+
+    def typeof(self, cdecl):
         """Parse the C type given as a string and return the
         corresponding Python type: <class 'ffi.CData<...>'>.
         It can also be used on 'cdata' instance to get its C type.
         """
         if isinstance(cdecl, basestring):
-            try:
-                btype, cfaf = self._parsed_types[cdecl]
-                if consider_function_as_funcptr and not cfaf:
-                    raise KeyError
-            except KeyError:
-                cfaf = consider_function_as_funcptr
-                type = self._parser.parse_type(cdecl,
-                           consider_function_as_funcptr=cfaf)
-                btype = self._get_cached_btype(type)
-                self._parsed_types[cdecl] = btype, cfaf
-            return btype
+            return self._typeof(cdecl)
         else:
             return self._backend.typeof(cdecl)
 
         string naming a C type, or a 'cdata' instance.
         """
         if isinstance(cdecl, basestring):
-            BType = self.typeof(cdecl)
+            BType = self._typeof(cdecl)
             return self._backend.sizeof(BType)
         else:
             return self._backend.sizeof(cdecl)
         given as a string.
         """
         if isinstance(cdecl, basestring):
-            cdecl = self.typeof(cdecl)
+            cdecl = self._typeof(cdecl)
         return self._backend.alignof(cdecl)
 
     def offsetof(self, cdecl, fieldname):
         structure, which must be given as a C type name.
         """
         if isinstance(cdecl, basestring):
-            cdecl = self.typeof(cdecl)
+            cdecl = self._typeof(cdecl)
         return self._backend.offsetof(cdecl, fieldname)
 
     def new(self, cdecl, init=None):
         about that when copying the pointer to the memory somewhere
         else, e.g. into another structure.
         """
-        BType = self.typeof(cdecl)
-        return self._backend.newp(BType, init)
+        if isinstance(cdecl, basestring):
+            cdecl = self._typeof(cdecl)
+        return self._backend.newp(cdecl, init)
 
     def cast(self, cdecl, source):
         """Similar to a C cast: returns an instance of the named C
         type initialized with the given 'source'.  The source is
         casted between integers or pointers of any type.
         """
-        BType = self.typeof(cdecl)
-        return self._backend.cast(BType, source)
+        if isinstance(cdecl, basestring):
+            cdecl = self._typeof(cdecl)
+        return self._backend.cast(cdecl, source)
 
     def buffer(self, cdata, size=-1):
         """Return a read-write buffer object that references the raw C data
         """
         if not callable(python_callable):
             raise TypeError("the 'python_callable' argument is not callable")
-        BFunc = self.typeof(cdecl, consider_function_as_funcptr=True)
-        return self._backend.callback(BFunc, python_callable, error)
+        if isinstance(cdecl, basestring):
+            cdecl = self._typeof(cdecl, consider_function_as_funcptr=True)
+        return self._backend.callback(cdecl, python_callable, error)
 
     def getctype(self, cdecl, replace_with=''):
         """Return a string giving the C type 'cdecl', which may be itself
         a variable name, or '*' to get actually the C type 'pointer-to-cdecl'.
         """
         if isinstance(cdecl, basestring):
-            cdecl = self.typeof(cdecl)
+            cdecl = self._typeof(cdecl)
         replace_with = replace_with.strip()
         if (replace_with.startswith('*')
                 and '&[' in self._backend.getcname(cdecl, '&')):

File cffi/backend_ctypes.py

         return BType._offsetof(fieldname)
 
     def newp(self, BType, source):
+        if not issubclass(BType, CTypesData):
+            raise TypeError
         return BType._newp(source)
 
     def cast(self, BType, source):

File demo/_curses.py

     if fd < 0:
         import sys
         fd = sys.stdout.fileno()
-    err = ffi.new("int")
+    err = ffi.new("int *")
     if lib.setupterm(term, fd, err) == ERR:
         if err[0] == 0:
             s = "setupterm: could not find terminal"

File demo/btrfs-snap.py

 target = os.open(opts.target, os.O_DIRECTORY)
 
 
-args = ffi.new('struct btrfs_ioctl_vol_args_v2')
+args = ffi.new('struct btrfs_ioctl_vol_args_v2 *')
 args.name = opts.newname
 args.fd = source
 args_buffer = ffi.buffer(args)

File demo/cffi-cocoa.py

 NSTitledWindowMask = ffi.cast('NSUInteger', 1)
 NSBackingStoreBuffered = ffi.cast('NSBackingStoreType', 2)
 
-NSMakePoint = lambda x, y: ffi.new('NSPoint', (x, y))[0]
-NSMakeRect = lambda x, y, w, h: ffi.new('NSRect', ((x, y), (w, h)))[0]
+NSMakePoint = lambda x, y: ffi.new('NSPoint *', (x, y))[0]
+NSMakeRect = lambda x, y, w, h: ffi.new('NSRect *', ((x, y), (w, h)))[0]
 
 get, send, sel = objc.objc_getClass, objc.objc_msgSend, objc.sel_registerName
 at = lambda s: send(

File demo/readdir.py

         # error in openat()
         return
     dir = ffi.C.fdopendir(dirfd)
-    dirent = ffi.new("struct dirent")
-    result = ffi.new("struct dirent *")
+    dirent = ffi.new("struct dirent *")
+    result = ffi.new("struct dirent **")
     while True:
         if ffi.C.readdir_r(dir, dirent, result):
             # error in readdir_r()

File demo/readdir2.py

         # error in openat()
         return
     dir = ffi.C.fdopendir(dirfd)
-    dirent = ffi.new("struct dirent")
-    result = ffi.new("struct dirent *")
+    dirent = ffi.new("struct dirent *")
+    result = ffi.new("struct dirent **")
     while True:
         if ffi.C.readdir_r(dir, dirent, result):
             # error in readdir_r()

File demo/xclient.py

 ffi.cdef("""
 
 typedef ... Display;
-typedef ... Window;
+typedef struct { ...; } Window;
 
 typedef struct { int type; ...; } XEvent;
 
     w = XCreateSimpleWindow(display, DefaultRootWindow(display),
                             10, 10, 500, 350, 0, 0, 0)
     XMapRaised(display, w)
-    event = ffi.new("XEvent")
+    event = ffi.new("XEvent *")
     XNextEvent(display, event)
 
 if __name__ == '__main__':

File testing/backend_tests.py

         assert ffi.getctype("e*") == 'enum $1 *'
         assert ffi.getctype("pe") == 'enum $1 *'
         assert ffi.getctype("e1*") == 'enum $2 *'
+
+    def test_new_ctype(self):
+        ffi = FFI(backend=self.Backend())
+        p = ffi.new("int *")
+        py.test.raises(TypeError, ffi.new, p)
+        p = ffi.new(ffi.typeof("int *"), 42)
+        assert p[0] == 42
+
+    def test_enum_with_non_injective_mapping(self):
+        ffi = FFI(backend=self.Backend())
+        ffi.cdef("enum e { AA=0, BB=0, CC=0, DD=0 };")
+        e = ffi.cast("enum e", 'CC')
+        assert str(e) == "AA"     # pick the first one arbitrarily