Add a new compiler object method: has_members (#723)

* Add a new compiler object method: has_members

Identical to 'cc.has_member', except that this takes multiple members
and all of them must exist else it returns false.

This is useful when you want to verify that a structure has all of
a given set of fields. Individually checking each member is horrifying.

* Fix typo in exceptions for has_member(s)
pull/727/head
Nirbheek Chauhan 9 years ago committed by Jussi Pakkanen
parent b7392bb290
commit 7830cb61c3
  1. 19
      mesonbuild/compilers.py
  2. 25
      mesonbuild/interpreter.py
  3. 12
      test cases/common/44 has member/meson.build

@ -902,16 +902,21 @@ int main(int argc, char **argv) {
# directly try to link via main().
return self.links('int main() {{ {0}; }}'.format('__builtin_' + funcname), env, args)
def has_member(self, typename, membername, prefix, env, extra_args=None):
def has_members(self, typename, membernames, prefix, env, extra_args=None):
if extra_args is None:
extra_args = []
templ = '''%s
void bar() {
%s foo;
foo.%s;
};
templ = '''{0}
void bar() {{
{1} {2};
{3}
}};
'''
return self.compiles(templ % (prefix, typename, membername), env, extra_args)
# Create code that accesses all members
members = ''
for m in membernames:
members += 'foo.{};\n'.format(m)
code = templ.format(prefix, typename, 'foo', members)
return self.compiles(code, env, extra_args)
def has_type(self, typename, prefix, env, extra_args):
templ = '''%s

@ -590,6 +590,7 @@ class CompilerHolder(InterpreterObject):
'run' : self.run_method,
'has_function' : self.has_function_method,
'has_member' : self.has_member_method,
'has_members' : self.has_members_method,
'has_type' : self.has_type_method,
'alignment' : self.alignment_method,
'version' : self.version_method,
@ -665,9 +666,10 @@ class CompilerHolder(InterpreterObject):
membername = args[1]
prefix = kwargs.get('prefix', '')
if not isinstance(prefix, str):
raise InterpreterException('Prefix argument of has_function must be a string.')
raise InterpreterException('Prefix argument of has_member must be a string.')
extra_args = self.determine_args(kwargs)
had = self.compiler.has_member(typename, membername, prefix, self.environment, extra_args)
had = self.compiler.has_members(typename, [membername], prefix,
self.environment, extra_args)
if had:
hadtxt = mlog.green('YES')
else:
@ -676,6 +678,25 @@ class CompilerHolder(InterpreterObject):
'" has member "', mlog.bold(membername), '": ', hadtxt, sep='')
return had
def has_members_method(self, args, kwargs):
check_stringlist(args)
typename = args[0]
membernames = args[1:]
prefix = kwargs.get('prefix', '')
if not isinstance(prefix, str):
raise InterpreterException('Prefix argument of has_members must be a string.')
extra_args = self.determine_args(kwargs)
had = self.compiler.has_members(typename, membernames, prefix,
self.environment, extra_args)
if had:
hadtxt = mlog.green('YES')
else:
hadtxt = mlog.red('NO')
members = mlog.bold(', '.join(['"{}"'.format(m) for m in membernames]))
mlog.log('Checking whether type "', mlog.bold(typename),
'" has members ', members, ': ', hadtxt, sep='')
return had
def has_function_method(self, args, kwargs):
if len(args) != 1:
raise InterpreterException('Has_function takes exactly one argument.')

@ -3,9 +3,17 @@ project('has member', 'c')
cc = meson.get_compiler('c')
if not cc.has_member('struct tm', 'tm_sec', prefix : '#include<time.h>')
error('Did not detect member that exists.')
error('Did not detect member of "struct tm" that exists: "tm_sec"')
endif
if cc.has_member('struct tm', 'tm_nonexistent', prefix : '#include<time.h>')
error('Not existing member found.')
error('Not existing member "tm_nonexistent" found.')
endif
if not cc.has_members('struct tm', 'tm_sec', 'tm_min', prefix : '#include<time.h>')
error('Did not detect members of "struct tm" that exist: "tm_sec" "tm_min"')
endif
if cc.has_members('struct tm', 'tm_sec', 'tm_nonexistent2', prefix : '#include<time.h>')
error('Not existing member "tm_nonexistent2" found.')
endif

Loading…
Cancel
Save