1. Python CFFI
  2. Untitled project
  3. cffi

Commits

Armin Rigo  committed 33174f8

- One more step in the test.
- Add some more tests.

  • Participants
  • Parent commits c7e2c4e
  • Branches cpy-extension

Comments (0)

Files changed (3)

File cffi/cparser.py

View file
 import pycparser, weakref, re
 
 _r_partial_enum = re.compile(r"\.\.\.\s*\}")
+_r_enum_dotdotdot = re.compile(r"__dotdotdot\d+__$")
 _parser_cache = None
 
 def _get_parser():
         if key in self._declarations:
             return self._declarations[key]
         if decls is not None:
-            enumerators = tuple([enum.name for enum in decls.enumerators])
+            enumerators = [enum.name for enum in decls.enumerators]
+            partial = False
+            if enumerators and _r_enum_dotdotdot.match(enumerators[-1]):
+                enumerators.pop()
+                partial = True
+            enumerators = tuple(enumerators)
             enumvalues = []
             nextenumvalue = 0
-            for enum in decls.enumerators:
+            for enum in decls.enumerators[:len(enumerators)]:
                 if enum.value is not None:
                     nextenumvalue = self._parse_constant(enum.value)
                 enumvalues.append(nextenumvalue)
                 nextenumvalue += 1
             enumvalues = tuple(enumvalues) 
             tp = model.EnumType(name, enumerators, enumvalues)
+            tp.partial = partial
             self._declare(key, tp)
         else:   # opaque enum
             enumerators = ()

File cffi/model.py

View file
 
 class EnumType(BaseType):
     _attrs_ = ('name',)
+    partial = False
 
     def __init__(self, name, enumerators, enumvalues):
         self.name = name
     def get_c_name(self, replace_with=''):
         return 'enum %s%s' % (self.name, replace_with)
 
+    def check_not_partial(self):
+        if self.partial:
+            from . import ffiplatform
+            raise ffiplatform.VerificationMissing(self.get_c_name())
+
     def new_backend_type(self, ffi):
+        self.check_not_partial()
         return ffi._backend.new_enum_type(self.name, self.enumerators,
                                           self.enumvalues)

File testing/test_verify.py

View file
                 py.test.raises(VerificationError, ffi.verify,
                                "typedef %s foo_t;" % real)
 
+def test_missing_typedef():
+    py.test.skip("in-progress")
+    ffi = FFI()
+    ffi.cdef("typedef ... foo_t; int bar(foo_t *);")
+    py.test.raises(VerificationMissing, ffi.new, "foo_t")
+    lib = ffi.verify("typedef struct foo_s { int x; } foo_t;\n"
+                     "int bar(foo_t *f) { return 42; }\n")
+    f = ffi.new("foo_t")
+    assert lib.bar(f) == 42
+
 
 def test_ffi_full_struct():
     ffi = FFI()
 def test_nonfull_enum():
     ffi = FFI()
     ffi.cdef("enum ee { EE1, EE2, EE3, ... \n \t };")
+    py.test.raises(VerificationMissing, ffi.cast, 'enum ee', 'EE2')
     py.test.skip("in-progress")
-    py.test.raises(VerificationMissing, ffi.cast, 'enum ee', 'EE2')
+    ffi.verify("enum ee { EE1=10, EE2, EE3=-10, EE4 };")
+    assert int(ffi.cast('enum ee', 'EE2')) == 11
+    assert int(ffi.cast('enum ee', 'EE3')) == -10
+    py.test.raises(AttributeError, ffi.cast, 'enum ee', '__dotdotdot0__')
+
+def test_full_enum():
+    py.test.skip("in-progress")
+    ffi = FFI()
+    ffi.cdef("enum ee { EE1, EE2, EE3 };")
+    ffi.verify("enum ee { EE1, EE2, EE3 };")
+    for real in [
+        "enum ee { EE1, EE2 };"
+        "enum ee { EE1, EE3, EE2 };"
+        ]:
+        py.test.raises(VerificationError, ffi.verify, real)
+    # extra items cannot be seen and have no bad consequence anyway
+    ffi.verify("enum ee { EE1, EE2, EE3, EE4 };")