[pypy-svn] r46179 - in pypy/branch/pypy-more-rtti-inprogress/rpython/tool: . test

fijal at codespeak.net fijal at codespeak.net
Thu Aug 30 09:57:38 CEST 2007


Author: fijal
Date: Thu Aug 30 09:57:36 2007
New Revision: 46179

Modified:
   pypy/branch/pypy-more-rtti-inprogress/rpython/tool/rffi_platform.py
   pypy/branch/pypy-more-rtti-inprogress/rpython/tool/test/test_rffi_platform.py
Log:
Add the "has" function to rffi_platform, right now if we give up caching,
we can simply move to rffi_platform from rfficache


Modified: pypy/branch/pypy-more-rtti-inprogress/rpython/tool/rffi_platform.py
==============================================================================
--- pypy/branch/pypy-more-rtti-inprogress/rpython/tool/rffi_platform.py	(original)
+++ pypy/branch/pypy-more-rtti-inprogress/rpython/tool/rffi_platform.py	Thu Aug 30 09:57:36 2007
@@ -6,6 +6,7 @@
 from pypy.rpython.lltypesystem import llmemory
 from pypy.translator.tool.cbuild import build_executable
 from pypy.tool.udir import udir
+import distutils
 
 # ____________________________________________________________
 #
@@ -35,6 +36,12 @@
         DEFINED = Defined(macro)
     return configure(CConfig)['DEFINED']
 
+def has(name, c_header_source):
+    class CConfig:
+        _header_ = c_header_source
+        HAS = Has(name)
+    return configure(CConfig)['HAS']
+
 # ____________________________________________________________
 #
 # General interface
@@ -58,7 +65,56 @@
     def get_result(self):
         return dict([(name, self.result[entry])
                      for entry, name in self.entries.iteritems()])
-    
+
+class _CWriter(object):
+    """ A simple class which aggregates config parts
+    """
+    def __init__(self, CConfig):
+        self.path = uniquefilepath()
+        self.f = self.path.open("w")
+        self.config = CConfig
+
+    def write_header(self):
+        f = self.f
+        CConfig = self.config
+        print >> f, C_HEADER
+        print >> f
+        for path in getattr(CConfig, '_includes_', ()):   # optional
+            print >> f, '#include <%s>' % (path,)
+        print >> f, getattr(CConfig, '_header_', '')      # optional
+        print >> f
+
+    def write_entry(self, key, entry):
+        f = self.f
+        print >> f, 'void dump_section_%s(void) {' % (key,)
+        for line in entry.prepare_code():
+            if line and line[0] != '#':
+                line = '\t' + line
+            print >> f, line
+        print >> f, '}'
+        print >> f
+
+    def write_entry_main(self, key):
+        print >> self.f, '\tprintf("-+- %s\\n");' % (key,)
+        print >> self.f, '\tdump_section_%s();' % (key,)
+        print >> self.f, '\tprintf("---\\n");'
+
+    def start_main(self):
+        print >> self.f, 'int main(int argc, char *argv[]) {'
+
+    def close(self):
+        f = self.f
+        print >> f, '\treturn 0;'
+        print >> f, '}'
+        f.close()
+
+    def ask_gcc(self, question):
+        self.start_main()
+        self.f.write(question + "\n")
+        self.close()
+        include_dirs = getattr(self.config, '_include_dirs_', [])
+        build_executable([self.path], include_dirs=include_dirs)
+        
 def configure(CConfig):
     """Examine the local system by running the C compiler.
     The CConfig class contains CConfigEntry attribues that describe
@@ -69,36 +125,21 @@
     for key in dir(CConfig):
         value = getattr(CConfig, key)
         if isinstance(value, CConfigEntry):
-            entries.append((key, value))
+            entries.append((key, value))            
 
-    filepath = uniquefilepath()
-    f = filepath.open('w')
-    print >> f, C_HEADER
-    print >> f
-    for path in getattr(CConfig, '_includes_', ()):   # optional
-        print >> f, '#include <%s>' % (path,)
-    print >> f, getattr(CConfig, '_header_', '')      # optional
-    print >> f
+    writer = _CWriter(CConfig)
+    writer.write_header()
     for key, entry in entries:
-        print >> f, 'void dump_section_%s(void) {' % (key,)
-        for line in entry.prepare_code():
-            if line and line[0] != '#':
-                line = '\t' + line
-            print >> f, line
-        print >> f, '}'
-        print >> f
+        writer.write_entry(key, entry)
 
-    print >> f, 'int main(int argc, char *argv[]) {'
+    f = writer.f
+    writer.start_main()
     for key, entry in entries:
-        print >> f, '\tprintf("-+- %s\\n");' % (key,)
-        print >> f, '\tdump_section_%s();' % (key,)
-        print >> f, '\tprintf("---\\n");'
-    print >> f, '\treturn 0;'
-    print >> f, '}'
-    f.close()
+        writer.write_entry_main(key)
+    writer.close()
 
     include_dirs = getattr(CConfig, '_include_dirs_', [])
-    infolist = list(run_example_code(filepath, include_dirs))
+    infolist = list(run_example_code(writer.path, include_dirs))
     assert len(infolist) == len(entries)
 
     resultinfo = {}
@@ -110,6 +151,15 @@
     result = ConfigResult(CConfig, resultinfo, resultentries)
     for name, entry in entries:
         result.get_entry_result(entry)
+
+    for key in dir(CConfig):
+        value = getattr(CConfig, key)
+        if isinstance(value, CConfigSingleEntry):
+            writer = _CWriter(CConfig)
+            writer.write_header()
+            result.result[value] = value.question(writer.ask_gcc)
+            result.entries[value] = key
+    
     return result.get_result()
 
 # ____________________________________________________________
@@ -332,31 +382,22 @@
     def build_result(self, info, config_result):
         return bool(info['defined'])
 
-
-class Library(CConfigEntry):
-    """The loaded library object.
+class CConfigSingleEntry(object):
+    """ An abstract class of type which requires
+    gcc succeeding/failing instead of only asking
     """
+    pass
+
+class Has(CConfigSingleEntry):
     def __init__(self, name):
-        XXX # uh
         self.name = name
-
-    def prepare_code(self):
-        # XXX should check that we can link against the lib
-        return []
-
-    def build_result(self, info, config_result):
-        from pypy.rpython.rctypes.tool import util
-        path = util.find_library(self.name)
-        mylib = ctypes.cdll.LoadLibrary(path)
-
-        class _FuncPtr(ctypes._CFuncPtr):
-            _flags_ = ctypes._FUNCFLAG_CDECL
-            _restype_ = ctypes.c_int # default, can be overridden in instances
-            includes = tuple(config_result.CConfig._includes_)
-            libraries = (self.name,)
-        
-        mylib._FuncPtr = _FuncPtr
-        return mylib
+    
+    def question(self, ask_gcc):
+        try:
+            ask_gcc(self.name + ';')
+            return True
+        except distutils.errors.CompileError:
+            return False
 
 # ____________________________________________________________
 #

Modified: pypy/branch/pypy-more-rtti-inprogress/rpython/tool/test/test_rffi_platform.py
==============================================================================
--- pypy/branch/pypy-more-rtti-inprogress/rpython/tool/test/test_rffi_platform.py	(original)
+++ pypy/branch/pypy-more-rtti-inprogress/rpython/tool/test/test_rffi_platform.py	Thu Aug 30 09:57:36 2007
@@ -185,3 +185,7 @@
                                        """,
                                        [("d_name", lltype.FixedSizeArray(rffi.CHAR, 1))])
     assert dirent.c_d_name.length == 32
+
+def test_has():
+    assert rffi_platform.has("x", "int x = 3;")
+    assert not rffi_platform.has("x", "")



More information about the Pypy-commit mailing list