[pypy-svn] r54796 - pypy/dist/pypy/rlib

afa at codespeak.net afa at codespeak.net
Fri May 16 19:34:07 CEST 2008


Author: afa
Date: Fri May 16 19:34:06 2008
New Revision: 54796

Added:
   pypy/dist/pypy/rlib/rwin32.py
Modified:
   pypy/dist/pypy/rlib/libffi.py
Log:
Start a new rlib\rwin32 module, to hold common types and functions from the win32 API,
and use it in libffi.

The module should be importable from all platforms, the WIN32 symbol
will always be available:

    from pypy.rlib import rwin32
    if rwin32.WIN32:
        ...

Tests will follow.


Modified: pypy/dist/pypy/rlib/libffi.py
==============================================================================
--- pypy/dist/pypy/rlib/libffi.py	(original)
+++ pypy/dist/pypy/rlib/libffi.py	Fri May 16 19:34:06 2008
@@ -14,6 +14,9 @@
 
 _MS_WINDOWS = os.name == "nt"
 
+if _MS_WINDOWS:
+    from pypy.rlib import rwin32
+
 if not _MS_WINDOWS:
     includes = ['dlfcn.h', 'ffi.h']
     include_dirs = []
@@ -75,10 +78,6 @@
 
     ffi_closure = rffi_platform.Struct('ffi_closure', [])
 
-    if _MS_WINDOWS:
-        DWORD = rffi_platform.SimpleType("DWORD", rffi.UINT)
-        BOOL = rffi_platform.SimpleType("BOOL", rffi.LONG)
-
 def add_simple_type(type_name):
     for name in ['size', 'alignment', 'type']:
         setattr(CConfig, type_name + '_' + name,
@@ -198,32 +197,30 @@
         return res
 
 if _MS_WINDOWS:
-    LoadLibrary = winexternal('LoadLibraryA', [rffi.CCHARP], rffi.VOIDP)
-    GetProcAddress = winexternal('GetProcAddress', [rffi.VOIDP, rffi.CCHARP], rffi.VOIDP)
-    FreeLibrary = winexternal('FreeLibrary', [rffi.VOIDP], cConfig.BOOL)
-    GetLastError = winexternal('GetLastError', [], cConfig.DWORD)
-    
     def dlopen(name):
-        res = LoadLibrary(name)
+        res = rwin32.LoadLibrary(name)
         if not res:
             # XXX format error message
-            raise WindowsError(2, GetLastError())
+            raise WindowsError(2, rwin32.GetLastError())
         return res
 
     def dlclose(handle):
-        res = FreeLibrary(handle)
+        res = rwin32.FreeLibrary(handle)
         if res:
             return -1
         else:
             return 0
 
     def dlsym(handle, name):
-        res = GetProcAddress(handle, name)
+        res = rwin32.GetProcAddress(handle, name)
         if not res:
             raise KeyError(name)
         # XXX rffi.cast here...
         return res
 
+    FormatError = rwin32.FormatError
+    LoadLibrary = rwin32.LoadLibrary
+
 FFI_OK = cConfig.FFI_OK
 FFI_BAD_TYPEDEF = cConfig.FFI_BAD_TYPEDEF
 FFI_DEFAULT_ABI = rffi.cast(rffi.USHORT, cConfig.FFI_DEFAULT_ABI)
@@ -323,8 +320,9 @@
 
 closureHeap = ClosureHeap()
 
-FUNCFLAG_STDCALL = 0
-FUNCFLAG_CDECL =   1  # for WINAPI calls
+FUNCFLAG_STDCALL   = 0
+FUNCFLAG_CDECL     = 1  # for WINAPI calls
+FUNCFLAG_PYTHONAPI = 4
 
 class AbstractFuncPtr(object):
     ll_cif = lltype.nullptr(FFI_CIFP.TO)

Added: pypy/dist/pypy/rlib/rwin32.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rlib/rwin32.py	Fri May 16 19:34:06 2008
@@ -0,0 +1,81 @@
+""" External functions accessing the win32 api.
+Common types, functions from core win32 libraries, such as kernel32
+"""
+
+from pypy.rpython.tool import rffi_platform
+from pypy.translator.tool.cbuild import ExternalCompilationInfo
+from pypy.rpython.lltypesystem import lltype, rffi
+import os
+
+# This module can be imported on any platform,
+# but most symbols are not usable...
+WIN32 = os.name == "nt"
+
+if WIN32:
+    eci = ExternalCompilationInfo(
+        includes = ['windows.h'],
+        libraries = ['kernel32'],
+        )
+else:
+    eci = ExternalCompilationInfo()
+
+class CConfig:
+    _compilation_info_ = eci
+
+    if WIN32:
+        DWORD = rffi_platform.SimpleType("DWORD", rffi.UINT)
+        BOOL = rffi_platform.SimpleType("BOOL", rffi.LONG)
+
+        HANDLE = rffi_platform.SimpleType("HANDLE", rffi.VOIDP)
+        HLOCAL = rffi_platform.SimpleType("HLOCAL", rffi.VOIDP)
+
+        DEFAULT_LANGUAGE = rffi_platform.ConstantInteger(
+            "MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT)")
+
+        for name in """FORMAT_MESSAGE_ALLOCATE_BUFFER FORMAT_MESSAGE_FROM_SYSTEM
+              """.split():
+            locals()[name] = rffi_platform.ConstantInteger(name)
+        
+
+for k, v in rffi_platform.configure(CConfig).items():
+    globals()[k] = v
+
+def winexternal(name, args, result):
+    return rffi.llexternal(name, args, result, compilation_info=eci, calling_conv='win')
+
+if WIN32:
+    GetLastError = winexternal('GetLastError', [], DWORD)
+
+    LoadLibrary = winexternal('LoadLibraryA', [rffi.CCHARP], rffi.VOIDP)
+    GetProcAddress = winexternal('GetProcAddress',
+                                 [rffi.VOIDP, rffi.CCHARP],
+                                 rffi.VOIDP)
+    FreeLibrary = winexternal('FreeLibrary', [rffi.VOIDP], BOOL)
+
+    LocalFree = winexternal('LocalFree', [HLOCAL], DWORD)
+
+    FormatMessage = winexternal(
+        'FormatMessageA',
+        [DWORD, rffi.VOIDP, DWORD, DWORD, rffi.CCHARP, DWORD, rffi.VOIDP],
+        DWORD)
+
+
+    # A bit like strerror...
+    def 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])
+        return result



More information about the Pypy-commit mailing list