[pypy-svn] r68237 - in pypy/trunk/pypy: rlib rpython/module

afa at codespeak.net afa at codespeak.net
Wed Oct 7 17:58:58 CEST 2009


Author: afa
Date: Wed Oct  7 17:58:55 2009
New Revision: 68237

Modified:
   pypy/trunk/pypy/rlib/rwin32.py
   pypy/trunk/pypy/rpython/module/ll_os.py
Log:
Fix --backend=cli translation on Windows, by providing a dumb message for WindowsError exceptions.
Also fix a memory leak.

There ought to be a better way for backends to override functions.


Modified: pypy/trunk/pypy/rlib/rwin32.py
==============================================================================
--- pypy/trunk/pypy/rlib/rwin32.py	(original)
+++ pypy/trunk/pypy/rlib/rwin32.py	Wed Oct  7 17:58:55 2009
@@ -5,7 +5,8 @@
 from pypy.rpython.tool import rffi_platform
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
 from pypy.rpython.lltypesystem import lltype, rffi
-import os
+from pypy.rlib.rarithmetic import intmask
+import os, sys
 
 # This module can be imported on any platform,
 # but most symbols are not usable...
@@ -95,24 +96,38 @@
 
     # A bit like strerror...
     def FormatError(code):
+        return llimpl_FormatError(code)
+
+    def llimpl_FormatError(code):
         "Return a message corresponding to the given Windows error code."
         buf = lltype.malloc(rffi.VOIDPP.TO, 1, flavor='raw')
 
-        msglen = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
-                               FORMAT_MESSAGE_FROM_SYSTEM,
-                               None,
-                               code,
-                               DEFAULT_LANGUAGE,
-                               rffi.cast(rffi.VOIDP, buf),
-                               0, None)
-
-        # FormatMessage always appends a \n.
-        msglen -= 1
-        
-        result = ''.join([buf[0][i] for i in range(msglen)])
-        LocalFree(buf[0])
+        try:
+            msglen = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+                                   FORMAT_MESSAGE_FROM_SYSTEM,
+                                   None,
+                                   code,
+                                   DEFAULT_LANGUAGE,
+                                   rffi.cast(rffi.VOIDP, buf),
+                                   0, None)
+
+            if msglen <= 2 or msglen > sys.maxint:
+                return fake_FormatError(code)
+
+            # FormatMessage always appends \r\n.
+            buflen = intmask(msglen - 2)
+            assert buflen > 0
+
+            result = rffi.charpsize2str(buf[0], buflen)
+            LocalFree(buf[0])
+        finally:
+            lltype.free(buf, flavor='raw')
+
         return result
 
+    def fake_FormatError(code):
+        return 'Windows Error %d' % (code,)
+
     def lastWindowsError(context="Windows Error"):
         code = GetLastError()
         return WindowsError(code, context)

Modified: pypy/trunk/pypy/rpython/module/ll_os.py
==============================================================================
--- pypy/trunk/pypy/rpython/module/ll_os.py	(original)
+++ pypy/trunk/pypy/rpython/module/ll_os.py	Wed Oct  7 17:58:55 2009
@@ -1507,3 +1507,20 @@
     def getcontroller(self):
         from pypy.rpython.module.ll_os_environ import OsEnvironController
         return OsEnvironController()
+
+# ____________________________________________________________
+# Support for the WindowsError exception
+
+if sys.platform == 'win32':
+    from pypy.rlib import rwin32
+
+    class RegisterFormatError(BaseLazyRegistering):
+        def __init__(self):
+            pass
+
+        @registering(rwin32.FormatError)
+        def register_rwin32_FormatError(self):
+            return extdef([int], str,
+                          "rwin32_FormatError",
+                          llimpl=rwin32.llimpl_FormatError,
+                          ooimpl=rwin32.fake_FormatError)



More information about the Pypy-commit mailing list