Author: Armin Rigo <[email protected]>
Branch: cffi-1.0
Changeset: r1804:fff6ae4c61b2
Date: 2015-04-24 16:00 +0200
http://bitbucket.org/cffi/cffi/changeset/fff6ae4c61b2/
Log: Enums, first complete passing tests
diff --git a/_cffi1/_cffi_include.h b/_cffi1/_cffi_include.h
--- a/_cffi1/_cffi_include.h
+++ b/_cffi1/_cffi_include.h
@@ -161,6 +161,13 @@
#define _cffi_array_len(array) (sizeof(array) / sizeof((array)[0]))
+#define _cffi_prim_int(size, sign) \
+ ((size) == 1 ? ((sign) ? _CFFI_PRIM_INT8 : _CFFI_PRIM_UINT8) : \
+ (size) == 2 ? ((sign) ? _CFFI_PRIM_INT16 : _CFFI_PRIM_UINT16) : \
+ (size) == 4 ? ((sign) ? _CFFI_PRIM_INT32 : _CFFI_PRIM_UINT32) : \
+ (size) == 8 ? ((sign) ? _CFFI_PRIM_INT64 : _CFFI_PRIM_UINT64) : \
+ 0)
+
static int _cffi_init(void)
{
diff --git a/_cffi1/parse_c_type.h b/_cffi1/parse_c_type.h
--- a/_cffi1/parse_c_type.h
+++ b/_cffi1/parse_c_type.h
@@ -90,7 +90,7 @@
struct _cffi_enum_s {
const char *name;
- int size_and_sign;
+ int type_prim; /* _CFFI_PRIM_xxx */
};
struct _cffi_typename_s {
diff --git a/_cffi1/realize_c_type.c b/_cffi1/realize_c_type.c
--- a/_cffi1/realize_c_type.c
+++ b/_cffi1/realize_c_type.c
@@ -360,6 +360,18 @@
break;
}
+ case _CFFI_OP_ENUM:
+ {
+ const struct _cffi_enum_s *e;
+
+ e = &builder->ctx.enums[_CFFI_GETARG(op)];
+ x = all_primitives[e->type_prim];
+ if (x == NULL)
+ x = build_primitive_type(e->type_prim);
+ Py_XINCREF(x);
+ break;
+ }
+
case _CFFI_OP_FUNCTION:
{
PyObject *fargs;
diff --git a/_cffi1/recompiler.py b/_cffi1/recompiler.py
--- a/_cffi1/recompiler.py
+++ b/_cffi1/recompiler.py
@@ -550,13 +550,13 @@
def _generate_cpy_anonymous_decl(self, tp, name):
if isinstance(tp, model.EnumType):
- self._generate_cpy_enum_decl(tp, name, '')
+ self._generate_cpy_enum_decl(tp)
else:
self._struct_decl(tp, name, 'typedef_' + name)
def _generate_cpy_anonymous_ctx(self, tp, name):
if isinstance(tp, model.EnumType):
- self._generate_cpy_enum_ctx(tp, name, '')
+ self._enum_ctx(tp, name)
else:
self._struct_ctx(tp, name, 'typedef_' + name)
@@ -589,15 +589,19 @@
is_int = isinstance(tp, model.PrimitiveType) and tp.is_integer_type()
self._generate_cpy_const(is_int, name, tp)
+ def _generate_const_int_ctx(self, name):
+ self._lsts["global"].append(
+ ' { "%s", _cffi_const_%s, _CFFI_OP(_CFFI_OP_CONSTANT_INT, 0) },' %
+ (name, name))
+
def _generate_cpy_constant_ctx(self, tp, name):
- is_int = isinstance(tp, model.PrimitiveType) and tp.is_integer_type()
- if not is_int:
+ if isinstance(tp, model.PrimitiveType) and tp.is_integer_type():
+ self._generate_const_int_ctx(name)
+ else:
type_index = self._typesdict[tp]
type_op = '_CFFI_OP(_CFFI_OP_CONSTANT, %d)' % type_index
- else:
- type_op = '_CFFI_OP(_CFFI_OP_CONSTANT_INT, 0)'
- self._lsts["global"].append(
- ' { "%s", _cffi_const_%s, %s },' % (name, name, type_op))
+ self._lsts["global"].append(
+ ' { "%s", _cffi_const_%s, %s },' % (name, name, type_op))
# ----------
# enums
@@ -605,6 +609,29 @@
def _generate_cpy_enum_collecttype(self, tp, name):
self._do_collect_type(tp)
+ def _generate_cpy_enum_decl(self, tp, name=None):
+ for enumerator in tp.enumerators:
+ self._generate_cpy_const(True, enumerator)
+
+ def _enum_ctx(self, tp, cname):
+ for enumerator in tp.enumerators:
+ self._generate_const_int_ctx(enumerator)
+ if cname is not None:
+ size = "sizeof(%s)" % cname
+ signed = "((%s)-1) <= 0" % cname
+ prim = "_cffi_prim_int(%s, %s)" % (size, signed)
+ else:
+ size = xxxx
+ self._lsts["enum"].append(
+ ' { "%s", %s },' % (tp.name, prim))
+
+ def _generate_cpy_enum_ctx(self, tp, name):
+ if tp.has_c_name():
+ cname = tp.get_c_name('')
+ else:
+ cname = None
+ self._enum_ctx(tp, cname)
+
# ----------
# macros: for now only for integers
diff --git a/_cffi1/test_recompiler.py b/_cffi1/test_recompiler.py
--- a/_cffi1/test_recompiler.py
+++ b/_cffi1/test_recompiler.py
@@ -264,16 +264,20 @@
ffi2.typeof("void(*)(struct foo_s*)"))
def test_verify_enum():
- py.test.skip("in-progress")
ffi = FFI()
- ffi.cdef("""enum e1 { B1, A1, ... };""")
+ ffi.cdef("""enum e1 { B1, A1, ... }; enum e2 { B2, A2, ... };""")
lib = verify(ffi, 'test_verify_enum',
- "enum e1 { A1, B1, C1=%d };" % sys.maxint)
+ "enum e1 { A1, B1, C1=%d };" % sys.maxint +
+ "enum e2 { A2, B2, C2 };")
ffi.typeof("enum e1")
+ ffi.typeof("enum e2")
assert lib.A1 == 0
- assert lib.B1 == 0
+ assert lib.B1 == 1
+ assert lib.A2 == 0
+ assert lib.B2 == 1
assert ffi.sizeof("enum e1") == ffi.sizeof("long")
-
+ assert ffi.sizeof("enum e2") == ffi.sizeof("int")
+
def test_dotdotdot_length_of_array_field():
ffi = FFI()
ffi.cdef("struct foo_s { int a[...]; int b[...]; };")
@@ -341,3 +345,18 @@
"typedef struct { int a; long b; } *foo_t;")
p = ffi.new("foo_t", {'b': 42})
assert p.b == 42
+
+def test_verify_anonymous_enum_with_typedef():
+ ffi = FFI()
+ ffi.cdef("typedef enum { AA, ... } e1;")
+ lib = verify(ffi, 'test_verify_anonymous_enum_with_typedef1',
+ "typedef enum { BB, CC, AA } e1;")
+ assert lib.AA == 2
+ assert ffi.sizeof("e1") == ffi.sizeof("int")
+ #
+ ffi = FFI()
+ ffi.cdef("typedef enum { AA=%d } e1;" % sys.maxint)
+ lib = verify(ffi, 'test_verify_anonymous_enum_with_typedef2',
+ "typedef enum { AA=%d } e1;" % sys.maxint)
+ assert lib.AA == sys.maxint
+ assert ffi.sizeof("e1") == ffi.sizeof("long")
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit