Author: Armin Rigo <[email protected]>
Branch: cffi-1.0
Changeset: r1843:fd13bd62a49a
Date: 2015-04-26 11:52 +0200
http://bitbucket.org/cffi/cffi/changeset/fd13bd62a49a/
Log: small refactoring ending up with support for SF_PACKED structures
diff --git a/_cffi1/cffi_opcode.py b/_cffi1/cffi_opcode.py
--- a/_cffi1/cffi_opcode.py
+++ b/_cffi1/cffi_opcode.py
@@ -97,6 +97,10 @@
'ssize_t': PRIM_SSIZE,
}
+F_UNION = 0x01
+F_CHECK_FIELDS = 0x02
+F_PACKED = 0x04
+
CLASS_NAME = {}
for _name, _value in globals().items():
if _name.startswith('OP_') and isinstance(_value, int):
diff --git a/_cffi1/ffi_obj.c b/_cffi1/ffi_obj.c
--- a/_cffi1/ffi_obj.c
+++ b/_cffi1/ffi_obj.c
@@ -692,7 +692,8 @@
if (!CTypeDescr_Check(x))
goto bad_usage;
types[i] = x;
- struct_unions[i].flags = ((CTypeDescrObject *)x)->ct_flags & CT_UNION;
+ struct_unions[i].flags = ((CTypeDescrObject *)x)->ct_flags & CT_UNION ?
+ _CFFI_F_UNION : 0;
struct_unions[i].size = (size_t)-2;
struct_unions[i].alignment = -2;
}
diff --git a/_cffi1/parse_c_type.c b/_cffi1/parse_c_type.c
--- a/_cffi1/parse_c_type.c
+++ b/_cffi1/parse_c_type.c
@@ -628,7 +628,7 @@
int n = search_in_struct_unions(tok->info->ctx, tok->p, tok->size);
if (n < 0)
return parse_error(tok, "undefined struct/union name");
- if (((tok->info->ctx->struct_unions[n].flags & CT_UNION) != 0)
+ if (((tok->info->ctx->struct_unions[n].flags & _CFFI_F_UNION) != 0)
^ (kind == TOK_UNION))
return parse_error(tok, "wrong kind of tag: struct vs union");
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
@@ -69,18 +69,16 @@
struct _cffi_struct_union_s {
const char *name;
int type_index; // -> _cffi_types, on a OP_STRUCT_UNION
- int flags; // CT_UNION? CT_CUSTOM_FIELD_POS?
+ int flags; // _CFFI_F_* flags below
size_t size;
int alignment;
int first_field_index; // -> _cffi_fields array
int num_fields;
};
-#ifdef _CFFI_INTERNAL
-#define CT_UNION 128
-#define CT_CUSTOM_FIELD_POS 32768
-/* ^^^ if not CUSTOM_FIELD_POS, complain if fields are not in the
- "standard layout" and/or if some are missing */
-#endif
+#define _CFFI_F_UNION 0x01 // is a union, not a struct
+#define _CFFI_F_CHECK_FIELDS 0x02 // complain if fields are not in the
+ // "standard layout" or if some are
missing
+#define _CFFI_F_PACKED 0x04 // for CHECK_FIELDS, assume a packed
struct
struct _cffi_field_s {
const char *name;
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
@@ -404,10 +404,10 @@
Py_INCREF(x);
}
else {
- int flags = (s->flags & CT_UNION) ? CT_UNION : CT_STRUCT;
+ int flags = (s->flags & _CFFI_F_UNION) ? CT_UNION : CT_STRUCT;
char *name = alloca(8 + strlen(s->name));
_realize_name(name,
- (s->flags & CT_UNION) ? "union " : "struct ",
+ (s->flags & _CFFI_F_UNION) ? "union " : "struct ",
s->name);
x = new_struct_or_union_type(name, flags);
@@ -683,7 +683,11 @@
PyList_SET_ITEM(fields, i, f);
}
- int sflags = (s->flags & CT_CUSTOM_FIELD_POS) ? 0 : SF_STD_FIELD_POS;
+ int sflags = 0;
+ if (s->flags & _CFFI_F_CHECK_FIELDS)
+ sflags |= SF_STD_FIELD_POS;
+ if (s->flags & _CFFI_F_PACKED)
+ sflags |= SF_PACKED;
PyObject *args = Py_BuildValue("(OOOnni)", ct, fields,
Py_None,
@@ -696,7 +700,6 @@
ct->ct_extra = NULL;
ct->ct_flags |= CT_IS_OPAQUE;
- ct->ct_flags &= ~CT_CUSTOM_FIELD_POS;
PyObject *res = b_complete_struct_or_union(NULL, args);
ct->ct_flags &= ~CT_IS_OPAQUE;
Py_DECREF(args);
diff --git a/_cffi1/recompiler.py b/_cffi1/recompiler.py
--- a/_cffi1/recompiler.py
+++ b/_cffi1/recompiler.py
@@ -456,11 +456,16 @@
def _struct_ctx(self, tp, cname, approxname):
type_index = self._typesdict[tp]
- flags = 0
+ flags = []
+ if isinstance(tp, model.UnionType):
+ flags.append("_CFFI_F_UNION")
if tp.partial or tp.has_anonymous_struct_fields():
- flags |= 32768 # CT_CUSTOM_FIELD_POS
- if isinstance(tp, model.UnionType):
- flags |= 128 # CT_UNION
+ pass # the field layout is obtained silently from the C compiler
+ else:
+ flags.append("_CFFI_F_CHECK_FIELDS")
+ if tp.packed:
+ flags.append("_CFFI_F_PACKED")
+ flags = '|'.join(flags) or '0'
if tp.fldtypes is not None:
c_field = [approxname]
enumfields = list(tp.enumfields())
@@ -502,7 +507,7 @@
else:
size_align = ' (size_t)-1, -1, -1, 0 /* opaque */ },'
self._lsts["struct_union"].append(
- ' { "%s", %d, 0x%x,' % (tp.name, type_index, flags) + size_align)
+ ' { "%s", %d, %s,' % (tp.name, type_index, flags) + size_align)
self._seen_struct_unions.add(tp)
def _add_missing_struct_unions(self):
diff --git a/_cffi1/test_new_ffi_1.py b/_cffi1/test_new_ffi_1.py
--- a/_cffi1/test_new_ffi_1.py
+++ b/_cffi1/test_new_ffi_1.py
@@ -75,9 +75,9 @@
ffi1.cdef(DEFS)
ffi1.cdef(DEFS_PACKED, packed=True)
- outputfilename = recompile(ffi1, "test_old_ffi1", CCODE,
+ outputfilename = recompile(ffi1, "test_new_ffi_1", CCODE,
tmpdir=str(udir))
- module = imp.load_dynamic("test_old_ffi1", outputfilename)
+ module = imp.load_dynamic("test_new_ffi_1", outputfilename)
ffi = module.ffi
diff --git a/_cffi1/test_parse_c_type.py b/_cffi1/test_parse_c_type.py
--- a/_cffi1/test_parse_c_type.py
+++ b/_cffi1/test_parse_c_type.py
@@ -36,7 +36,7 @@
ctx_structs = ffi.new("struct _cffi_struct_union_s[]", len(struct_names))
for _i in range(len(struct_names)):
ctx_structs[_i].name = c_struct_names[_i]
-ctx_structs[3].flags = lib.CT_UNION
+ctx_structs[3].flags = lib._CFFI_F_UNION
ctx.struct_unions = ctx_structs
ctx.num_struct_unions = len(struct_names)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit