Advertisement
Guest User

cffi "configure"

a guest
Oct 2nd, 2018
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.55 KB | None | 0 0
  1. import sys
  2. import os
  3. from cffi import ffiplatform, recompiler, VerificationError
  4.  
  5.  
  6. class CaptureStdOutStdErr:
  7.     def __init__(self, dumpfilename):
  8.         self.dumpfilename = dumpfilename
  9.     def __enter__(self):
  10.         fd = os.open(self.dumpfilename, os.O_WRONLY | os.O_CREAT | os.O_TRUNC)
  11.         self.fd1 = os.dup(1)
  12.         self.fd2 = os.dup(2)
  13.         os.dup2(fd, 1)
  14.         os.dup2(fd, 2)
  15.         os.close(fd)
  16.     def __exit__(self, *args):
  17.         os.dup2(self.fd1, 1)
  18.         os.dup2(self.fd2, 2)
  19.         os.close(self.fd1)
  20.         os.close(self.fd2)
  21.  
  22. class PreprocessorFailure(Exception):
  23.     pass
  24.  
  25.  
  26. class Check:
  27.     source_extension = '.c'
  28.     _count = 0
  29.     _dumperrorsrc = None
  30.  
  31.     def __init__(self, tmpdir='.'):
  32.         self._tmpdir = tmpdir
  33.         self.options = {}
  34.         self.verbose = '-v' in sys.argv
  35.  
  36.     def _check_compile(self, source, stmts=''):
  37.         module_name = '_cffi__check%d' % (self._count,)
  38.         self._count += 1
  39.         tmpdir = self._tmpdir
  40.         c_file, parts = recompiler._modname_to_file(tmpdir, module_name,
  41.                                                     self.source_extension)
  42.         ext_c_file = os.path.join(*parts)
  43.  
  44.         with open(ext_c_file, 'w') as f:
  45.             f.write(source)
  46.             f.write('''
  47.  
  48. void init%s(void)
  49. {
  50. ''' % module_name)
  51.             f.write(stmts)
  52.             f.write('''
  53. }
  54. ''')
  55.         ext = ffiplatform.get_extension(ext_c_file, module_name, **self.options)
  56.  
  57.         self._dumpfilename = os.path.join(tmpdir, module_name + '.log')
  58.         self._dumperrorsrc = ext_c_file
  59.         cwd = os.getcwd()
  60.         try:
  61.             os.chdir(tmpdir)
  62.             try:
  63.                 with CaptureStdOutStdErr(self._dumpfilename):
  64.                     outputfilename = ffiplatform.compile('.', ext)
  65.                 self._dumperrorsrc = None
  66.                 return True
  67.             except VerificationError:
  68.                 return False
  69.         finally:
  70.             os.chdir(cwd)
  71.  
  72.     def _ppcheck(self, msg, source, if_condition):
  73.         self._pre_msg(msg)
  74.         result = self._check_compile(source,
  75.                 '#if %s\n#else\n#error\n#endif' % (if_condition,))
  76.         if result is False:   # either not defined, or an unrelated error
  77.             result = self._check_compile(source,
  78.                 '#if %s\n#error\n#endif' % (if_condition,))
  79.             if result is False:
  80.                 self._post_msg('ERROR', verbose=True)
  81.                 raise PreprocessorFailure(if_condition)
  82.             result = False
  83.         self._post_msg(result)
  84.         return result
  85.  
  86.     def _pre_msg(self, msg):
  87.         sys.stdout.write('checking %s... ' % (msg,))
  88.         sys.stdout.flush()
  89.  
  90.     def _post_msg(self, result, verbose=False):
  91.         if result is True:
  92.             result = 'yes'
  93.         elif result is False:
  94.             result = 'no'
  95.         if self._dumperrorsrc is not None:
  96.             verbose |= self.verbose
  97.             if not verbose:
  98.                 result += '  (-v for details)'
  99.             sys.stdout.write('%s\n' % (result,))
  100.             if verbose:
  101.                 self._report_error()
  102.         else:
  103.             sys.stdout.write('%s\n' % (result,))
  104.  
  105.     def _report_error(self):
  106.         sys.stderr.write('-' * 70 + '\n')
  107.         sys.stderr.write('failed to compile %r in directory %r:\n' % (
  108.             self._dumperrorsrc, self._tmpdir))
  109.         try:
  110.             with open(self._dumpfilename, 'r') as f:
  111.                 sys.stderr.write(f.read())
  112.         except IOError:
  113.             pass
  114.         sys.stderr.write('-' * 70 + '\n')
  115.  
  116.     def compiles(self, text_message, source, stmts=''):
  117.         self._pre_msg(text_message)
  118.         result = self._check_compile(source, stmts)
  119.         self._post_msg(result)
  120.         return result
  121.  
  122.     def symbol_exists(self, symbol, source):
  123.         return self.compiles('for symbol %r' % (symbol,), source,
  124.                 'static void *p = &(%s);' % (symbol,))
  125.  
  126.     def defined(self, macro, source):
  127.         return self._ppcheck('if %r is defined' % (macro,), source,
  128.                 'defined(%s)' % (macro,))
  129.  
  130.     def pp_eval(self, pp_expr, source):
  131.         return self._ppcheck('if %r' % (pp_expr,), source, pp_expr)
  132.  
  133.  
  134. # ___________________________________________________
  135.  
  136.  
  137. check = Check()
  138. check.compiles("foobar library", """
  139.        int foobar(int);
  140. """)
  141. check.symbol_exists("foobar", """
  142.        int foobar(int);
  143. """)
  144. check.defined("ADFLKDJAFSDKLA", """
  145.        #include <stdio.h>
  146.        #define ADFLKDJAFSDKLA
  147. """)
  148. check.pp_eval("X > 5", """
  149.        #define X 13
  150. """
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement