[pypy-commit] pypy cffi-1.0: Enums

2015-05-08 Thread arigo
Author: Armin Rigo 
Branch: cffi-1.0
Changeset: r77212:59b2f83ef5fd
Date: 2015-05-08 16:16 +0200
http://bitbucket.org/pypy/pypy/changeset/59b2f83ef5fd/

Log:Enums

diff --git a/pypy/module/_cffi_backend/realize_c_type.py 
b/pypy/module/_cffi_backend/realize_c_type.py
--- a/pypy/module/_cffi_backend/realize_c_type.py
+++ b/pypy/module/_cffi_backend/realize_c_type.py
@@ -199,6 +199,50 @@
 raise
 return x
 
+def _realize_c_enum(ffi, eindex):
+e = ffi.ctxobj.ctx.c_enums[eindex]
+type_index = rffi.getintfield(e, 'c_type_index')
+if ffi.cached_types[type_index] is not None:
+return ffi.cached_types[type_index] #found already in the "primary" 
slot
+
+space = ffi.space
+w_basetd = get_primitive_type(space, rffi.getintfield(e, 'c_type_prim'))
+
+enumerators_w = []
+enumvalues_w = []
+p = e.c_enumerators
+if p[0] != '\x00':
+while True:
+j = 0
+while p[j] != ',' and p[j] != '\x00':
+j += 1
+enname = rffi.charpsize2str(p, j)
+enumerators_w.append(space.wrap(enname))
+
+gindex = parse_c_type.search_in_globals(ffi.ctxobj.ctx, enname)
+assert gindex >= 0
+g = ffi.ctxobj.ctx.c_globals[gindex]
+assert getop(g.c_type_op) == cffi_opcode.OP_ENUM
+assert getarg(g.c_type_op) == -1
+
+w_integer_value = realize_global_int(ffi, g)
+enumvalues_w.append(w_integer_value)
+
+p = rffi.ptradd(p, j)
+if p[0] == '\x00':
+break
+p = rffi.ptradd(p, 1)
+
+name = _realize_name("enum ", e.c_name)
+w_ctype = newtype.new_enum_type(space, name,
+space.newtuple(enumerators_w),
+space.newtuple(enumvalues_w),
+w_basetd)
+
+# Update the "primary" OP_ENUM slot
+ffi.cached_types[type_index] = w_ctype
+return w_ctype
+
 
 def realize_c_type_or_func(ffi, opcodes, index):
 op = opcodes[index]
@@ -231,6 +275,9 @@
 elif case == cffi_opcode.OP_STRUCT_UNION:
 x = _realize_c_struct_or_union(ffi, getarg(op))
 
+elif case == cffi_opcode.OP_ENUM:
+x = _realize_c_enum(ffi, getarg(op))
+
 elif case == cffi_opcode.OP_FUNCTION:
 y = realize_c_type(ffi, opcodes, getarg(op))
 base_index = index + 1
___
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit


[pypy-commit] pypy cffi-1.0: enums, structs

2015-05-02 Thread arigo
Author: Armin Rigo 
Branch: cffi-1.0
Changeset: r76978:0c05840fcfdc
Date: 2015-05-02 16:57 +0200
http://bitbucket.org/pypy/pypy/changeset/0c05840fcfdc/

Log:enums, structs

diff --git a/pypy/module/_cffi_backend/parse_c_type.py 
b/pypy/module/_cffi_backend/parse_c_type.py
--- a/pypy/module/_cffi_backend/parse_c_type.py
+++ b/pypy/module/_cffi_backend/parse_c_type.py
@@ -17,7 +17,36 @@
 return rffi.llexternal(name, args, result, compilation_info=eci, **kwds)
 
 
-PCTX = rffi.CStructPtr('struct _cffi_type_context_s')
+GLOBAL_S = rffi.CStruct('struct _cffi_global_s')
+STRUCT_UNION_S = rffi.CStruct('struct _cffi_struct_union_s',
+   ('name', rffi.CCHARP),
+   ('type_index', rffi.INT),
+   ('flags', rffi.INT),
+   ('size', rffi.SIZE_T),
+   ('alignment', rffi.INT),
+   ('first_field_index', rffi.INT),
+   ('num_fields', rffi.INT))
+FIELD_S = rffi.CStruct('struct _cffi_field_s')
+ENUM_S = rffi.CStruct('struct _cffi_enum_s',
+   ('name', rffi.CCHARP),
+   ('type_index', rffi.INT),
+   ('type_prim', rffi.INT),
+   ('enumerators', rffi.CCHARP))
+TYPENAME_S = rffi.CStruct('struct _cffi_typename_s')
+
+PCTX = rffi.CStructPtr('struct _cffi_type_context_s',
+   ('types', rffi.VOIDPP),
+   ('globals', rffi.CArrayPtr(GLOBAL_S)),
+   ('fields', rffi.CArrayPtr(FIELD_S)),
+   ('struct_unions', rffi.CArrayPtr(STRUCT_UNION_S)),
+   ('enums', rffi.CArrayPtr(ENUM_S)),
+   ('typenames', rffi.CArrayPtr(TYPENAME_S)),
+   ('num_globals', rffi.INT),
+   ('num_struct_unions', rffi.INT),
+   ('num_enums', rffi.INT),
+   ('num_typenames', rffi.INT),
+   ('includes', rffi.CCHARPP))
+
 PINFO = rffi.CStructPtr('struct _cffi_parse_info_s',
 ('ctx', PCTX),
 ('output', rffi.VOIDPP),
diff --git a/pypy/module/_cffi_backend/test/test_parse_c_type.py 
b/pypy/module/_cffi_backend/test/test_parse_c_type.py
--- a/pypy/module/_cffi_backend/test/test_parse_c_type.py
+++ b/pypy/module/_cffi_backend/test/test_parse_c_type.py
@@ -6,33 +6,39 @@
 class ParseError(Exception):
 pass
 
-## struct_names = ["bar_s", "foo", "foo_", "foo_s", "foo_s1", "foo_s12"]
-## assert struct_names == sorted(struct_names)
+struct_names = ["bar_s", "foo", "foo_", "foo_s", "foo_s1", "foo_s12"]
+assert struct_names == sorted(struct_names)
 
-## enum_names = ["ebar_s", "efoo", "efoo_", "efoo_s", "efoo_s1", "efoo_s12"]
-## assert enum_names == sorted(enum_names)
+enum_names = ["ebar_s", "efoo", "efoo_", "efoo_s", "efoo_s1", "efoo_s12"]
+assert enum_names == sorted(enum_names)
 
-## identifier_names = ["id", "id0", "id05", "id05b", "tail"]
-## assert identifier_names == sorted(identifier_names)
+identifier_names = ["id", "id0", "id05", "id05b", "tail"]
+assert identifier_names == sorted(identifier_names)
 
-## global_names = ["FIVE", "NEG", "ZERO"]
-## assert global_names == sorted(global_names)
+global_names = ["FIVE", "NEG", "ZERO"]
+assert global_names == sorted(global_names)
 
-## ctx = ffi.new("struct _cffi_type_context_s *")
-## c_struct_names = [ffi.new("char[]", _n.encode('ascii')) for _n in 
struct_names]
-## 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._CFFI_F_UNION
-## ctx.struct_unions = ctx_structs
-## ctx.num_struct_unions = len(struct_names)
+ctx = lltype.malloc(parse_c_type.PCTX.TO, flavor='raw', zero=True,
+track_allocation=False)
 
-## c_enum_names = [ffi.new("char[]", _n.encode('ascii')) for _n in enum_names]
-## ctx_enums = ffi.new("struct _cffi_enum_s[]", len(enum_names))
-## for _i in range(len(enum_names)):
-## ctx_enums[_i].name = c_enum_names[_i]
-## ctx.enums = ctx_enums
-## ctx.num_enums = len(enum_names)
+c_struct_names = [rffi.str2charp(_n.encode('ascii')) for _n in struct_names]
+ctx_structs = lltype.malloc(rffi.CArray(parse_c_type.STRUCT_UNION_S),
+len(struct_names), flavor='raw', zero=True,
+track_allocation=False)
+for _i in range(len(struct_names)):
+ctx_structs[_i].c_name = c_struct_names[_i]
+rffi.setintfield(ctx_structs[3], 'c_flags', cffi_opcode.F_UNION)
+ctx.c_struct_unions = ctx_structs
+rffi.setintfield(ctx, 'c_num_struct_unions', len(struct_names))
+
+c_enum_names = [rffi.str2charp(_n.encode('ascii')) for _n in enum_names]
+ctx_enums = lltype.malloc(rffi.CArray(parse_c_type.ENUM_S),
+len(enum_names), flavor='raw', zero=True,
+track_allocation=False)
+for _i in rang