[pypy-commit] cffi cffi-1.0: enum
arigo
noreply at buildbot.pypy.org
Tue May 12 17:02:31 CEST 2015
Author: Armin Rigo <arigo at tunes.org>
Branch: cffi-1.0
Changeset: r1998:e72977e45c75
Date: 2015-05-12 17:03 +0200
http://bitbucket.org/cffi/cffi/changeset/e72977e45c75/
Log: enum
diff --git a/cffi/recompiler.py b/cffi/recompiler.py
--- a/cffi/recompiler.py
+++ b/cffi/recompiler.py
@@ -2,6 +2,11 @@
from cffi import ffiplatform, model
from .cffi_opcode import *
+try:
+ int_type = (int, long)
+except NameError: # Python 3
+ int_type = int
+
class GlobalExpr:
def __init__(self, name, address, type_op, size=0, check_value=None):
@@ -16,7 +21,7 @@
self.name, self.address, self.type_op.as_c_expr(), self.size)
def as_python_expr(self):
- if self.check_value is None:
+ if not isinstance(self.check_value, int_type):
raise ffiplatform.VerificationError(
"ffi.dlopen() will not be able to figure out the value of "
"constant %r (only integer constants are supported, and only "
@@ -35,6 +40,30 @@
def as_python_expr(self):
return "b'%s%s'" % (format_four_bytes(self.type_index), self.name)
+class EnumExpr:
+ def __init__(self, name, type_index, size, signed, allenums):
+ self.name = name
+ self.type_index = type_index
+ self.size = size
+ self.signed = signed
+ self.allenums = allenums
+
+ def as_c_expr(self):
+ return (' { "%s", %d, _cffi_prim_int(%s, %s),\n'
+ ' "%s" },' % (self.name, self.type_index,
+ self.size, self.signed, self.allenums))
+
+ def as_python_expr(self):
+ prim_index = {
+ (1, 0): PRIM_UINT8, (1, 1): PRIM_INT8,
+ (2, 0): PRIM_UINT16, (2, 1): PRIM_INT16,
+ (4, 0): PRIM_UINT32, (4, 1): PRIM_INT32,
+ (8, 0): PRIM_UINT64, (8, 1): PRIM_INT64,
+ }[self.size, self.signed]
+ return "b'%s%s%s\\x00%s'" % (format_four_bytes(self.type_index),
+ format_four_bytes(prim_index),
+ self.name, self.allenums)
+
class Recompiler:
@@ -167,7 +196,7 @@
lst = self._lsts["enum"]
for tp, i in self._enums.items():
assert i < len(lst)
- assert lst[i].startswith(' { "%s"' % tp.name)
+ assert lst[i].name == tp.name
assert len(lst) == len(self._enums)
# ----------
@@ -855,11 +884,12 @@
def _enum_ctx(self, tp, cname):
type_index = self._typesdict[tp]
type_op = CffiOp(OP_ENUM, -1)
- for enumerator in tp.enumerators:
+ for enumerator, enumvalue in zip(tp.enumerators, tp.enumvalues):
self._lsts["global"].append(
- GlobalExpr(enumerator, '_cffi_const_%s' % enumerator, type_op))
+ GlobalExpr(enumerator, '_cffi_const_%s' % enumerator, type_op,
+ check_value=enumvalue))
#
- if cname is not None and '$' not in cname:
+ if cname is not None and '$' not in cname and not self.target_is_python:
size = "sizeof(%s)" % cname
signed = "((%s)-1) <= 0" % cname
else:
@@ -868,8 +898,7 @@
signed = int(int(self.ffi.cast(basetp, -1)) < 0)
allenums = ",".join(tp.enumerators)
self._lsts["enum"].append(
- ' { "%s", %d, _cffi_prim_int(%s, %s),\n'
- ' "%s" },' % (tp.name, type_index, size, signed, allenums))
+ EnumExpr(tp.name, type_index, size, signed, allenums))
def _generate_cpy_enum_ctx(self, tp, name):
self._enum_ctx(tp, tp._get_c_name())
diff --git a/testing/cffi1/test_dlopen.py b/testing/cffi1/test_dlopen.py
--- a/testing/cffi1/test_dlopen.py
+++ b/testing/cffi1/test_dlopen.py
@@ -53,3 +53,18 @@
_typenames = (b'\x00\x00\x00\x00foobar_t',),
)
"""
+
+def test_enum():
+ ffi = FFI()
+ ffi.cdef("enum myenum_e { AA, BB, CC=-42 };")
+ target = udir.join('test_enum.py')
+ assert make_py_source(ffi, 'test_enum', str(target))
+ assert target.read() == r"""# auto-generated file
+import _cffi_backend
+
+ffi = _cffi_backend.FFI(b'test_enum',
+ _types = b'\x00\x00\x00\x0B',
+ _globals = (b'\xFF\xFF\xFF\x0BAA',0,b'\xFF\xFF\xFF\x0BBB',1,b'\xFF\xFF\xFF\x0BCC',-42),
+ _enums = (b'\x00\x00\x00\x00\x00\x00\x00\x15myenum_e\x00AA,BB,CC',),
+)
+"""
More information about the pypy-commit
mailing list