Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import sys
- import os
- from cffi import ffiplatform, recompiler, VerificationError
- class CaptureStdOutStdErr:
- def __init__(self, dumpfilename):
- self.dumpfilename = dumpfilename
- def __enter__(self):
- fd = os.open(self.dumpfilename, os.O_WRONLY | os.O_CREAT | os.O_TRUNC)
- self.fd1 = os.dup(1)
- self.fd2 = os.dup(2)
- os.dup2(fd, 1)
- os.dup2(fd, 2)
- os.close(fd)
- def __exit__(self, *args):
- os.dup2(self.fd1, 1)
- os.dup2(self.fd2, 2)
- os.close(self.fd1)
- os.close(self.fd2)
- class PreprocessorFailure(Exception):
- pass
- class Check:
- source_extension = '.c'
- _count = 0
- _dumperrorsrc = None
- def __init__(self, tmpdir='.'):
- self._tmpdir = tmpdir
- self.options = {}
- self.verbose = '-v' in sys.argv
- def _check_compile(self, source, stmts=''):
- module_name = '_cffi__check%d' % (self._count,)
- self._count += 1
- tmpdir = self._tmpdir
- c_file, parts = recompiler._modname_to_file(tmpdir, module_name,
- self.source_extension)
- ext_c_file = os.path.join(*parts)
- with open(ext_c_file, 'w') as f:
- f.write(source)
- f.write('''
- void init%s(void)
- {
- ''' % module_name)
- f.write(stmts)
- f.write('''
- }
- ''')
- ext = ffiplatform.get_extension(ext_c_file, module_name, **self.options)
- self._dumpfilename = os.path.join(tmpdir, module_name + '.log')
- self._dumperrorsrc = ext_c_file
- cwd = os.getcwd()
- try:
- os.chdir(tmpdir)
- try:
- with CaptureStdOutStdErr(self._dumpfilename):
- outputfilename = ffiplatform.compile('.', ext)
- self._dumperrorsrc = None
- return True
- except VerificationError:
- return False
- finally:
- os.chdir(cwd)
- def _ppcheck(self, msg, source, if_condition):
- self._pre_msg(msg)
- result = self._check_compile(source,
- '#if %s\n#else\n#error\n#endif' % (if_condition,))
- if result is False: # either not defined, or an unrelated error
- result = self._check_compile(source,
- '#if %s\n#error\n#endif' % (if_condition,))
- if result is False:
- self._post_msg('ERROR', verbose=True)
- raise PreprocessorFailure(if_condition)
- result = False
- self._post_msg(result)
- return result
- def _pre_msg(self, msg):
- sys.stdout.write('checking %s... ' % (msg,))
- sys.stdout.flush()
- def _post_msg(self, result, verbose=False):
- if result is True:
- result = 'yes'
- elif result is False:
- result = 'no'
- if self._dumperrorsrc is not None:
- verbose |= self.verbose
- if not verbose:
- result += ' (-v for details)'
- sys.stdout.write('%s\n' % (result,))
- if verbose:
- self._report_error()
- else:
- sys.stdout.write('%s\n' % (result,))
- def _report_error(self):
- sys.stderr.write('-' * 70 + '\n')
- sys.stderr.write('failed to compile %r in directory %r:\n' % (
- self._dumperrorsrc, self._tmpdir))
- try:
- with open(self._dumpfilename, 'r') as f:
- sys.stderr.write(f.read())
- except IOError:
- pass
- sys.stderr.write('-' * 70 + '\n')
- def compiles(self, text_message, source, stmts=''):
- self._pre_msg(text_message)
- result = self._check_compile(source, stmts)
- self._post_msg(result)
- return result
- def symbol_exists(self, symbol, source):
- return self.compiles('for symbol %r' % (symbol,), source,
- 'static void *p = &(%s);' % (symbol,))
- def defined(self, macro, source):
- return self._ppcheck('if %r is defined' % (macro,), source,
- 'defined(%s)' % (macro,))
- def pp_eval(self, pp_expr, source):
- return self._ppcheck('if %r' % (pp_expr,), source, pp_expr)
- # ___________________________________________________
- check = Check()
- check.compiles("foobar library", """
- int foobar(int);
- """)
- check.symbol_exists("foobar", """
- int foobar(int);
- """)
- check.defined("ADFLKDJAFSDKLA", """
- #include <stdio.h>
- #define ADFLKDJAFSDKLA
- """)
- check.pp_eval("X > 5", """
- #define X 13
- """
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement