[pypy-commit] cffi default: Add some more context in the error messages "cannot generate 'struct $1'
arigo
noreply at buildbot.pypy.org
Thu Aug 23 15:15:47 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r878:889d00534a6b
Date: 2012-08-23 15:15 +0200
http://bitbucket.org/cffi/cffi/changeset/889d00534a6b/
Log: Add some more context in the error messages "cannot generate 'struct
$1' in C file".
diff --git a/cffi/model.py b/cffi/model.py
--- a/cffi/model.py
+++ b/cffi/model.py
@@ -2,13 +2,13 @@
class BaseType(object):
- def get_c_name(self, replace_with=''):
+ def get_c_name(self, replace_with='', context='a C file'):
result = self._get_c_name(replace_with)
if '$' in result:
from .ffiplatform import VerificationError
raise VerificationError(
- "cannot generate '%s' in a C file: unknown type name"
- % (result,))
+ "cannot generate '%s' in %s: unknown type name"
+ % (self._get_c_name(''), context))
return result
def has_c_name(self):
diff --git a/cffi/vengine_cpy.py b/cffi/vengine_cpy.py
--- a/cffi/vengine_cpy.py
+++ b/cffi/vengine_cpy.py
@@ -272,11 +272,13 @@
prnt('_cffi_f_%s(PyObject *self, PyObject *%s)' % (name, argname))
prnt('{')
#
+ context = 'argument of %s' % name
for i, type in enumerate(tp.args):
- prnt(' %s;' % type.get_c_name(' x%d' % i))
+ prnt(' %s;' % type.get_c_name(' x%d' % i, context))
if not isinstance(tp.result, model.VoidType):
result_code = 'result = '
- prnt(' %s;' % tp.result.get_c_name(' result'))
+ context = 'result of %s' % name
+ prnt(' %s;' % tp.result.get_c_name(' result', context))
else:
result_code = ''
#
@@ -372,8 +374,11 @@
# only accept exactly the type declared. Note the parentheses
# around the '*tmp' below. In most cases they are not needed
# but don't hurt --- except test_struct_array_field.
- prnt(' { %s = &p->%s; (void)tmp; }' % (
- ftype.get_c_name('(*tmp)'), fname))
+ try:
+ prnt(' { %s = &p->%s; (void)tmp; }' % (
+ ftype.get_c_name('(*tmp)', 'field %r'%fname), fname))
+ except ffiplatform.VerificationError, e:
+ prnt(' /* %s */' % str(e)) # cannot verify it, ignore
prnt('}')
prnt('static PyObject *')
prnt('%s(PyObject *self, PyObject *noarg)' % (layoutfuncname,))
@@ -492,7 +497,7 @@
prnt(' PyObject *o;')
prnt(' int res;')
if not is_int:
- prnt(' %s;' % (vartp or tp).get_c_name(' i'))
+ prnt(' %s;' % (vartp or tp).get_c_name(' i', name))
else:
assert category == 'const'
#
diff --git a/cffi/vengine_gen.py b/cffi/vengine_gen.py
--- a/cffi/vengine_gen.py
+++ b/cffi/vengine_gen.py
@@ -108,13 +108,15 @@
if isinstance(type, model.StructOrUnion):
indirection = '*'
argnames.append('%sx%d' % (indirection, i))
- arglist = [type.get_c_name(' %s' % arg)
+ context = 'argument of %s' % name
+ arglist = [type.get_c_name(' %s' % arg, context)
for type, arg in zip(tp.args, argnames)]
arglist = ', '.join(arglist) or 'void'
wrappername = '_cffi_f_%s' % name
self.export_symbols.append(wrappername)
funcdecl = ' %s(%s)' % (wrappername, arglist)
- prnt(tp.result.get_c_name(funcdecl))
+ context = 'result of %s' % name
+ prnt(tp.result.get_c_name(funcdecl, context))
prnt('{')
#
if not isinstance(tp.result, model.VoidType):
@@ -192,8 +194,11 @@
# only accept exactly the type declared. Note the parentheses
# around the '*tmp' below. In most cases they are not needed
# but don't hurt --- except test_struct_array_field.
- prnt(' { %s = &p->%s; (void)tmp; }' % (
- ftype.get_c_name('(*tmp)'), fname))
+ try:
+ prnt(' { %s = &p->%s; (void)tmp; }' % (
+ ftype.get_c_name('(*tmp)', 'field %r'%fname), fname))
+ except ffiplatform.VerificationError, e:
+ prnt(' /* %s */' % str(e)) # cannot verify it, ignore
prnt('}')
self.export_symbols.append(layoutfuncname)
prnt('ssize_t %s(ssize_t i)' % (layoutfuncname,))
@@ -309,7 +314,7 @@
prnt('}')
else:
assert tp is not None
- prnt(tp.get_c_name(' %s(void)' % funcname),)
+ prnt(tp.get_c_name(' %s(void)' % funcname, name),)
prnt('{')
if category == 'var':
ampersand = '&'
@@ -336,7 +341,7 @@
if value < 0 and not negative:
value += (1 << (8*self.ffi.sizeof("long long")))
else:
- BFunc = self.ffi.typeof(tp.get_c_name('(*)(void)'))
+ BFunc = self.ffi.typeof(tp.get_c_name('(*)(void)', name))
function = module.load_function(BFunc, funcname)
value = function()
return value
@@ -436,7 +441,7 @@
# remove ptr=<cdata 'int *'> from the library instance, and replace
# it by a property on the class, which reads/writes into ptr[0].
funcname = '_cffi_var_%s' % name
- BFunc = self.ffi.typeof(tp.get_c_name('*(*)(void)'))
+ BFunc = self.ffi.typeof(tp.get_c_name('*(*)(void)', name))
function = module.load_function(BFunc, funcname)
ptr = function()
def getter(library):
diff --git a/testing/test_verify.py b/testing/test_verify.py
--- a/testing/test_verify.py
+++ b/testing/test_verify.py
@@ -882,3 +882,16 @@
""")
h = lib.foo()
assert ffi.sizeof(h) == ffi.sizeof("short")
+
+def test_cannot_name_struct_type():
+ ffi = FFI()
+ ffi.cdef("typedef struct { int x; } *sp; void foo(sp);")
+ e = py.test.raises(VerificationError, ffi.verify,
+ "typedef struct { int x; } *sp; void foo(sp);")
+ assert 'in argument of foo: unknown type name' in str(e.value)
+
+def test_dont_check_unnamable_fields():
+ ffi = FFI()
+ ffi.cdef("struct foo_s { struct { int x; } someone; };")
+ ffi.verify("struct foo_s { struct { int x; } someone; };")
+ # assert did not crash
More information about the pypy-commit
mailing list