Commits

Maciej Fijalkowski committed d4ec042

tmpfile support

  • Participants
  • Parent commits 404ed50
  • Branches file-support-in-rpython

Comments (0)

Files changed (3)

File rpython/rlib/rfile.py

     def specialize_call(self, hop):
         return hop.r_result.rtype_constructor(hop)
 
-    #def ll_os_tmpfile():
-    #pass
+class OSTempfileEntry(ExtRegistryEntry):
+    _about_ = os.tmpfile
 
-    #register_external(os.tmpfile, [], SomeFile(), llimpl=ll_os_tmpfile)
+    def compute_result_annotation(self):
+        return SomeFile()
+
+    def specialize_call(self, hop):
+        return hop.r_result.rtype_tempfile(hop)
+

File rpython/rlib/test/test_rfile.py

 
+import os
 from rpython.rtyper.test.tool import BaseRtypingTest
 from rpython.tool.udir import udir
 from rpython.rlib import rfile
 
         f()
         self.interpret(f, [])
+
+    def test_tempfile(self):
+        def f():
+            f = os.tmpfile()
+            f.write("xxx")
+            f.seek(0)
+            assert f.read() == "xxx"
+            f.close()
+
+        f()
+        self.interpret(f, [])

File rpython/rtyper/lltypesystem/rfile.py

 
 eci = ExternalCompilationInfo(includes=['stdio.h'])
 
-c_open = rffi.llexternal('fopen', [rffi.CCHARP, rffi.CCHARP],
-                          lltype.Ptr(FILE), compilation_info=eci)
-c_close = rffi.llexternal('fclose', [lltype.Ptr(FILE)], rffi.INT,
-                          compilation_info=eci)
-c_write = rffi.llexternal('fwrite', [rffi.CCHARP, rffi.SIZE_T, rffi.SIZE_T,
+def llexternal(*args):
+    return rffi.llexternal(*args, compilation_info=eci)
+
+c_open = llexternal('fopen', [rffi.CCHARP, rffi.CCHARP], lltype.Ptr(FILE))
+c_close = llexternal('fclose', [lltype.Ptr(FILE)], rffi.INT)
+c_write = llexternal('fwrite', [rffi.CCHARP, rffi.SIZE_T, rffi.SIZE_T,
                                      lltype.Ptr(FILE)], rffi.SIZE_T)
-c_read = rffi.llexternal('fread', [rffi.CCHARP, rffi.SIZE_T, rffi.SIZE_T,
+c_read = llexternal('fread', [rffi.CCHARP, rffi.SIZE_T, rffi.SIZE_T,
                                    lltype.Ptr(FILE)], rffi.SIZE_T)
-c_feof = rffi.llexternal('feof', [lltype.Ptr(FILE)], rffi.INT)
-c_ferror = rffi.llexternal('ferror', [lltype.Ptr(FILE)], rffi.INT)
-c_clearerror = rffi.llexternal('clearerr', [lltype.Ptr(FILE)], lltype.Void)
-c_fseek = rffi.llexternal('fseek', [lltype.Ptr(FILE), rffi.LONG, rffi.INT],
+c_feof = llexternal('feof', [lltype.Ptr(FILE)], rffi.INT)
+c_ferror = llexternal('ferror', [lltype.Ptr(FILE)], rffi.INT)
+c_clearerror = llexternal('clearerr', [lltype.Ptr(FILE)], lltype.Void)
+c_fseek = llexternal('fseek', [lltype.Ptr(FILE), rffi.LONG, rffi.INT],
                           rffi.INT)
+c_tmpfile = llexternal('tmpfile', [], lltype.Ptr(FILE))
 
 def ll_open(name, mode):
     file_wrapper = lltype.malloc(FILE_WRAPPER)
         lltype.free(ll_mode, flavor='raw')
     return file_wrapper
 
+def ll_tmpfile():
+    file_wrapper = lltype.malloc(FILE_WRAPPER)
+    res = c_tmpfile()
+    if not res:
+        errno = rposix.get_errno()
+        raise OSError(errno, os.strerror(errno))
+    file_wrapper.file = res
+    return file_wrapper
+
 def ll_write(file_wrapper, value):
     ll_file = file_wrapper.file
     if not ll_file:
     res = c_fseek(ll_file, pos, whence)
     if res == -1:
         errno = rposix.get_errno()
-        raise OSError(errno, os.strerror(errno))        
+        raise OSError(errno, os.strerror(errno))
 
 def ll_close(file_wrapper):
     if file_wrapper.file:
         return hop.genop('direct_call', [v_open, arg_0, arg_1],
                          resulttype=self)
 
+    def rtype_tempfile(self, hop):
+        tmpfile = hop.rtyper.getannmixlevel().delayedfunction(
+            ll_tmpfile, [], annmodel.SomePtr(self.lowleveltype))
+        v_tmpfile = hop.inputconst(lltype.typeOf(tmpfile), tmpfile)
+        hop.exception_is_here()
+        return hop.genop('direct_call', [v_tmpfile], resulttype=self)
+
+
     def rtype_method_write(self, hop):
         args_v = hop.inputargs(self, string_repr)
         hop.exception_is_here()
             arg_2 = hop.inputarg(lltype.Signed, 2)
         hop.exception_is_here()
         return hop.gendirectcall(ll_seek, r_self, arg_1, arg_2)
+