Author: Armin Rigo <[email protected]>
Branch:
Changeset: r97:23788a07cebd
Date: 2014-11-27 17:12 +0100
http://bitbucket.org/cffi/creflect/changeset/23788a07cebd/
Log: Add a test and fix for an empty struct declaration
diff --git a/creflect/cparser.py b/creflect/cparser.py
--- a/creflect/cparser.py
+++ b/creflect/cparser.py
@@ -28,6 +28,7 @@
r_comment1 = re.compile(r"//.*")
r_comment2 = re.compile(r"/[*]")
r_comment3 = re.compile(r"[*]/")
+r_empty_braces = re.compile(r"{.*}") # after comments have been removed
def remove_comments(csource):
csource = r_comment1.sub('', csource) # remove the '//' comments
@@ -48,6 +49,9 @@
parts.append(' ' + '\n' * csource.count('\n', start, pos))
return ''.join(parts)
+def expand_empty_braces(csource):
+ return r_empty_braces.sub('{ char __crx_empty__; }', csource)
+
class CSource(object):
@@ -58,8 +62,10 @@
def to_ast(self):
cparser = pycparser.CParser()
+ csource = remove_comments(self.cdefblock)
+ csource = expand_empty_braces(csource)
try:
- ast = cparser.parse(remove_comments(self.cdefblock))
+ ast = cparser.parse(csource)
except pycparser.c_parser.ParseError as e:
msg, lineno = self.convert_pycparser_error_line(e)
raise CDefError(msg, self, lineno)
@@ -270,14 +276,9 @@
fldnames = []
fldtypes = []
fldbitsize = []
+ if len(fields) == 1 and fields[0].name == '__crx_empty__':
+ fields = []
for decl in fields:
- if (isinstance(decl.type, pycparser.c_ast.IdentifierType) and
- ''.join(decl.type.names) == '__dotdotdot__'):
- # XXX pycparser is inconsistent: 'names' should be a list
- # of strings, but is sometimes just one string. Use
- # str.join() as a way to cope with both.
- self._make_partial(tp, nested)
- continue
if decl.bitsize is None:
bitsize = -1
else:
diff --git a/creflect/model.py b/creflect/model.py
--- a/creflect/model.py
+++ b/creflect/model.py
@@ -606,7 +606,10 @@
" - (char *)0" % (realtp,)) # alignment
else:
text_offset = '0'
- d1 = funcblock.write_crx_field_var(len(self.fldnames))
+ if self.fldnames:
+ d1 = funcblock.write_crx_field_var(len(self.fldnames))
+ else:
+ d1 = 'NULL'
t1 = self.type.get_type_var(funcblock)
#
for i, (fldname, fldtype) in enumerate(
diff --git a/test/codegen/struct-006.c b/test/codegen/struct-006.c
new file mode 100644
--- /dev/null
+++ b/test/codegen/struct-006.c
@@ -0,0 +1,17 @@
+typedef struct { } foo_t;
+
+# ____________________________________________________________
+
+void teststruct_006(crx_builder_t *cb)
+{
+ crx_type_t *t1;
+ t1 = cb->get_struct_type(cb, "$foo_t");
+ cb->complete(cb, t1, sizeof(foo_t),
+ ((char *)&((struct{char a; foo_t b;} *)0)->b) - (char *)0,
+ NULL, 0);
+#expect STRUCT $foo_t:
+ {
+ cb->define_type(cb, "foo_t", t1);
+#expect TYPEDEF foo_t = STRUCT $foo_t
+ }
+}
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit