[pypy-svn] r55426 - in pypy/branch/build-external/pypy: module/rctime module/rctime/test rpython/lltypesystem rpython/module rpython/module/test

afa at codespeak.net afa at codespeak.net
Fri May 30 17:36:45 CEST 2008


Author: afa
Date: Fri May 30 17:36:42 2008
New Revision: 55426

Modified:
   pypy/branch/build-external/pypy/module/rctime/__init__.py
   pypy/branch/build-external/pypy/module/rctime/interp_time.py
   pypy/branch/build-external/pypy/module/rctime/test/test_rctime.py
   pypy/branch/build-external/pypy/rpython/lltypesystem/rffi.py
   pypy/branch/build-external/pypy/rpython/module/ll_os.py
   pypy/branch/build-external/pypy/rpython/module/ll_time.py
   pypy/branch/build-external/pypy/rpython/module/test/test_ll_os.py
Log:
Adapt time functions to win32 and Visual 2005 (vs 8.0):
time_t is a 64bit type,
and functions are exported with modified names: _time64, _localtime64.

Also port the timezone variables from ctypes to rffi.


Modified: pypy/branch/build-external/pypy/module/rctime/__init__.py
==============================================================================
--- pypy/branch/build-external/pypy/module/rctime/__init__.py	(original)
+++ pypy/branch/build-external/pypy/module/rctime/__init__.py	Fri May 30 17:36:42 2008
@@ -19,15 +19,13 @@
         'mktime': 'interp_time.mktime',
         'strftime': 'interp_time.strftime',
         'sleep' : 'interp_time.sleep',
+        'tzset' : 'interp_time.tzset',
     }
 
     def buildloaders(cls):
         from pypy.module.rctime import interp_time
         import os
         
-        if os.name == "posix":
-            Module.interpleveldefs['tzset'] = 'interp_time.tzset'
-
         # this machinery is needed to expose constants
         # that have to be initialized one time only
         

Modified: pypy/branch/build-external/pypy/module/rctime/interp_time.py
==============================================================================
--- pypy/branch/build-external/pypy/module/rctime/interp_time.py	(original)
+++ pypy/branch/build-external/pypy/module/rctime/interp_time.py	Fri May 30 17:36:42 2008
@@ -27,7 +27,7 @@
     time_t = platform.SimpleType("time_t", rffi.LONG)
     size_t = platform.SimpleType("size_t", rffi.LONG)
     has_gettimeofday = platform.Has('gettimeofday')
-    
+
 if _POSIX:
     calling_conv = 'c'
     CConfig.timeval = platform.Struct("struct timeval",
@@ -61,6 +61,18 @@
 if _POSIX:
     cConfig.timeval.__name__ = "_timeval"
     timeval = cConfig.timeval
+    
+if _WIN:
+    def getter(typ, name):
+        func, _ = rffi.CExternVariable(
+            typ, name,
+            CConfig._compilation_info_,
+            readonly=True)
+        return func
+    
+    get_timezone = getter(rffi.LONG, "_timezone")
+    get_daylight = getter(rffi.LONG, "_daylight")
+    get_tzname = getter(rffi.CCHARPP, "tzname")
 
 CLOCKS_PER_SEC = cConfig.CLOCKS_PER_SEC
 clock_t = cConfig.clock_t
@@ -73,15 +85,27 @@
     c_gettimeofday = external('gettimeofday', [rffi.VOIDP, rffi.VOIDP], rffi.INT)
 TIME_TP = rffi.CArrayPtr(time_t)
 TM_P = lltype.Ptr(tm)
+
+def m(name):
+    """Name mangling, for VS8.0 which exports 32bit and 64bit versions
+    under different names
+    """
+    if _WIN and rffi.sizeof(time_t) == 8:
+        return '_' + name + '64'
+    else:
+        return name
+    
 c_clock = external('clock', [TIME_TP], clock_t)
-c_time = external('time', [TIME_TP], time_t)
-c_ctime = external('ctime', [TIME_TP], rffi.CCHARP)
-c_gmtime = external('gmtime', [TIME_TP], TM_P)
-c_mktime = external('mktime', [TM_P], time_t)
+c_time = external(m('time'), [TIME_TP], time_t)
+c_ctime = external(m('ctime'), [TIME_TP], rffi.CCHARP)
+c_gmtime = external(m('gmtime'), [TIME_TP], TM_P)
+c_mktime = external(m('mktime'), [TM_P], time_t)
 c_asctime = external('asctime', [TM_P], rffi.CCHARP)
-c_localtime = external('localtime', [TIME_TP], TM_P)
+c_localtime = external(m('localtime'), [TIME_TP], TM_P)
 if _POSIX:
     c_tzset = external('tzset', [], lltype.Void)
+if _WIN:
+    c_tzset = external('_tzset', [], lltype.Void)
 c_strftime = external('strftime', [rffi.CCHARP, size_t, rffi.CCHARP, TM_P],
                       size_t)
 
@@ -92,20 +116,12 @@
     timezone = daylight = altzone = 0
     tzname = ["", ""]
     
-    # pypy cant' use in_dll to access global exported variables
-    # so we can't compute these attributes
-
-    # if _WIN:
-    #     cdll.msvcrt._tzset()
-    # 
-    #     timezone = c_long.in_dll(cdll.msvcrt, "_timezone").value
-    #     if hasattr(cdll.msvcrt, "altzone"):
-    #         altzone = c_long.in_dll(cdll.msvcrt, "altzone").value
-    #     else:
-    #         altzone = timezone - 3600
-    #     daylight = c_long.in_dll(cdll.msvcrt, "_daylight").value
-    #     tzname = _tzname_t.in_dll(cdll.msvcrt, "_tzname")
-    #     tzname = (tzname.tzname_0, tzname.tzname_1)
+    if _WIN:
+        timezone = get_timezone()
+        altzone = timezone - 3600
+        daylight = get_daylight()
+        tznames = get_tzname()
+        tzname = [rffi.charp2str(tznames[0]), rffi.charp2str(tznames[1])]
     if _POSIX:
         YEAR = (365 * 24 + 6) * 3600
 
@@ -143,9 +159,13 @@
     errno = rposix.get_errno()
     return os.strerror(errno)
 
-def sleep(secs):
-    pytime.sleep(secs)
-sleep.unwrap_spec = [float]
+def sleep(space, secs):
+    try:
+        pytime.sleep(secs)
+    except OverflowError:
+        raise OperationError(space.w_OverflowError,
+                             space.wrap("sleep length is too large"))
+sleep.unwrap_spec = [ObjSpace, float]
 
 def _get_module_object(space, obj_name):
     w_module = space.getbuiltinmodule('time')
@@ -164,10 +184,11 @@
     else:
         seconds = space.float_w(w_seconds)
     try:
-        return ovfcheck_float_to_int(seconds)
+        ovfcheck_float_to_int(seconds)
     except OverflowError:
         raise OperationError(space.w_ValueError,
                              space.wrap("time argument too large"))
+    return rffi.r_time_t(seconds)
 
 def _tm_to_tuple(space, t):
     time_tuple = []
@@ -189,7 +210,7 @@
 def _gettmarg(space, w_tup, allowNone=True):
     if allowNone and space.is_w(w_tup, space.w_None):
         # default to the current local time
-        tt = int(pytime.time())
+        tt = rffi.r_time_t(pytime.time())
         t_ref = lltype.malloc(TIME_TP.TO, 1, flavor='raw')
         t_ref[0] = tt
         pbuf = c_localtime(t_ref)
@@ -364,30 +385,29 @@
     return space.wrap(float(tt))
 mktime.unwrap_spec = [ObjSpace, W_Root]
 
-if _POSIX:
-    def tzset(space):
-        """tzset()
-
-        Initialize, or reinitialize, the local timezone to the value stored in
-        os.environ['TZ']. The TZ environment variable should be specified in
-        standard Unix timezone format as documented in the tzset man page
-        (eg. 'US/Eastern', 'Europe/Amsterdam'). Unknown timezones will silently
-        fall back to UTC. If the TZ environment variable is not set, the local
-        timezone is set to the systems best guess of wallclock time.
-        Changing the TZ environment variable without calling tzset *may* change
-        the local timezone used by methods such as localtime, but this behaviour
-        should not be relied on"""
+def tzset(space):
+    """tzset()
 
-        c_tzset()
-        
-        # reset timezone, altzone, daylight and tzname
-        timezone, daylight, tzname, altzone = _init_timezone()
-        _set_module_object(space, "timezone", space.wrap(timezone))
-        _set_module_object(space, 'daylight', space.wrap(daylight))
-        tzname_w = [space.wrap(tzname[0]), space.wrap(tzname[1])] 
-        _set_module_object(space, 'tzname', space.newtuple(tzname_w))
-        _set_module_object(space, 'altzone', space.wrap(altzone))
-    tzset.unwrap_spec = [ObjSpace]
+    Initialize, or reinitialize, the local timezone to the value stored in
+    os.environ['TZ']. The TZ environment variable should be specified in
+    standard Unix timezone format as documented in the tzset man page
+    (eg. 'US/Eastern', 'Europe/Amsterdam'). Unknown timezones will silently
+    fall back to UTC. If the TZ environment variable is not set, the local
+    timezone is set to the systems best guess of wallclock time.
+    Changing the TZ environment variable without calling tzset *may* change
+    the local timezone used by methods such as localtime, but this behaviour
+    should not be relied on"""
+
+    c_tzset()
+
+    # reset timezone, altzone, daylight and tzname
+    timezone, daylight, tzname, altzone = _init_timezone()
+    _set_module_object(space, "timezone", space.wrap(timezone))
+    _set_module_object(space, 'daylight', space.wrap(daylight))
+    tzname_w = [space.wrap(tzname[0]), space.wrap(tzname[1])] 
+    _set_module_object(space, 'tzname', space.newtuple(tzname_w))
+    _set_module_object(space, 'altzone', space.wrap(altzone))
+tzset.unwrap_spec = [ObjSpace]
 
 def strftime(space, format, w_tup=None):
     """strftime(format[, tuple]) -> string

Modified: pypy/branch/build-external/pypy/module/rctime/test/test_rctime.py
==============================================================================
--- pypy/branch/build-external/pypy/module/rctime/test/test_rctime.py	(original)
+++ pypy/branch/build-external/pypy/module/rctime/test/test_rctime.py	Fri May 30 17:36:42 2008
@@ -76,6 +76,7 @@
     
     def test_mktime(self):
         import time as rctime
+        import os
         raises(TypeError, rctime.mktime, "foo")
         raises(TypeError, rctime.mktime, None)
         raises(TypeError, rctime.mktime, (1, 2))
@@ -93,7 +94,8 @@
         ltime = list(ltime)
         ltime[0] = 67
         ltime = tuple(ltime)
-        raises(OverflowError, rctime.mktime, ltime)
+        if os.name != "nt":   # time_t may be 64bit
+            raises(OverflowError, rctime.mktime, ltime)
     
         ltime = list(ltime)
         ltime[0] = 100

Modified: pypy/branch/build-external/pypy/rpython/lltypesystem/rffi.py
==============================================================================
--- pypy/branch/build-external/pypy/rpython/lltypesystem/rffi.py	(original)
+++ pypy/branch/build-external/pypy/rpython/lltypesystem/rffi.py	Fri May 30 17:36:42 2008
@@ -273,7 +273,8 @@
     for name in (_name, 'unsigned ' + _name):
         TYPES.append(name)
 TYPES += ['signed char', 'unsigned char',
-          'long long', 'unsigned long long', 'size_t']
+          'long long', 'unsigned long long',
+          'size_t', 'time_t']
 if os.name != 'nt':
     TYPES.append('mode_t')
     TYPES.append('pid_t')
@@ -378,7 +379,7 @@
     return lltype.Ptr(COpaque(*args, **kwds))
 
 def CExternVariable(TYPE, name, eci, _CConstantClass=CConstant,
-                    sandboxsafe=False):
+                    sandboxsafe=False, readonly=False):
     """Return a pair of functions - a getter and a setter - to access
     the given global C variable.
     """
@@ -408,12 +409,17 @@
     if sys.platform != 'win32':
         lines.append('extern %s %s;' % (c_type, name))
     lines.append(c_getter)
-    lines.append(c_setter)
+
+    symbols = [getter_name]
+    if not readonly:
+        lines.append(c_setter)
+        symbols.append(setter_name)
+
     sources = ('\n'.join(lines),)
     new_eci = eci.merge(ExternalCompilationInfo(
         separate_module_sources = sources,
         post_include_lines = [getter_prototype, setter_prototype],
-        export_symbols = [getter_name, setter_name],
+        export_symbols = symbols,
     ))
 
     getter = llexternal(getter_name, [], TYPE, compilation_info=new_eci,

Modified: pypy/branch/build-external/pypy/rpython/module/ll_os.py
==============================================================================
--- pypy/branch/build-external/pypy/rpython/module/ll_os.py	(original)
+++ pypy/branch/build-external/pypy/rpython/module/ll_os.py	Fri May 30 17:36:42 2008
@@ -262,8 +262,8 @@
             # we only have utime(), which does not allow sub-second resolution
             def os_utime_platform(path, actime, modtime):
                 l_utimbuf = lltype.malloc(UTIMBUFP.TO, flavor='raw')
-                l_utimbuf.c_actime  = int(actime)
-                l_utimbuf.c_modtime = int(modtime)
+                l_utimbuf.c_actime  = rffi.r_time_t(actime)
+                l_utimbuf.c_modtime = rffi.r_time_t(modtime)
                 error = os_utime(path, l_utimbuf)
                 lltype.free(l_utimbuf, flavor='raw')
                 return error

Modified: pypy/branch/build-external/pypy/rpython/module/ll_time.py
==============================================================================
--- pypy/branch/build-external/pypy/rpython/module/ll_time.py	(original)
+++ pypy/branch/build-external/pypy/rpython/module/ll_time.py	Fri May 30 17:36:42 2008
@@ -11,8 +11,8 @@
 from pypy.rlib import rposix
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
 
-if sys.platform.startswith('win'):
-    includes = ['time.h', 'windows.h']
+if sys.platform == 'win32':
+    includes = ['time.h', 'sys/timeb.h']
 else:
     includes = ['sys/time.h', 'time.h', 'errno.h', 'sys/select.h',
                 'sys/types.h', 'unistd.h', 'sys/timeb.h']
@@ -23,11 +23,13 @@
         includes=includes
     )
     CLOCK_T = platform.SimpleType('clock_t', rffi.INT)
-    TIMEVAL = platform.Struct('struct timeval', [('tv_sec', rffi.INT),
-                                                 ('tv_usec', rffi.INT)])
+    if sys.platform != 'win32':
+        TIMEVAL = platform.Struct('struct timeval', [('tv_sec', rffi.INT),
+                                                     ('tv_usec', rffi.INT)])
     TIME_T = platform.SimpleType('time_t', rffi.INT)
     HAVE_GETTIMEOFDAY = platform.Has('gettimeofday')
     HAVE_FTIME = platform.Has('ftime')
+    HAVE_FTIME64 = platform.Has('_ftime64') 
 
 class CConfigForFTime:
     _compilation_info_ = ExternalCompilationInfo(includes=['sys/timeb.h'])
@@ -49,7 +51,8 @@
                 self.CLOCKS_PER_SEC = 1000000
             else:
                 self.CLOCKS_PER_SEC = self.CLK_TCK
-        self.TIMEVALP = lltype.Ptr(self.TIMEVAL)
+        if sys.platform != 'win32':
+            self.TIMEVALP = lltype.Ptr(self.TIMEVAL)
 
     @registering(time.time)
     def register_time_time(self):
@@ -70,15 +73,26 @@
         else:
             c_gettimeofday = None
 
-        if self.HAVE_FTIME:
+        if self.HAVE_FTIME or self.HAVE_FTIME64:
             self.configure(CConfigForFTime)
-            c_ftime = self.llexternal('ftime', [lltype.Ptr(self.TIMEB)],
+            
+            if sys.platform == 'win32' and rffi.sizeof(self.TIME_T) == 8:
+                name = '_ftime64'
+            else:
+                name = 'ftime'
+
+            c_ftime = self.llexternal(name, [lltype.Ptr(self.TIMEB)],
                                       lltype.Void,
                                       _nowrapper=True, threadsafe=False)
         else:
             c_ftime = None    # to not confuse the flow space
 
-        c_time = self.llexternal('time', [rffi.VOIDP], self.TIME_T,
+        if sys.platform == 'win32' and rffi.sizeof(self.TIME_T) == 8:
+            name = '_time64'
+        else:
+            name = 'time'
+        
+        c_time = self.llexternal(name, [rffi.VOIDP], self.TIME_T,
                                  _nowrapper=True, threadsafe=False)
 
         def time_time_llimpl():

Modified: pypy/branch/build-external/pypy/rpython/module/test/test_ll_os.py
==============================================================================
--- pypy/branch/build-external/pypy/rpython/module/test/test_ll_os.py	(original)
+++ pypy/branch/build-external/pypy/rpython/module/test/test_ll_os.py	Fri May 30 17:36:42 2008
@@ -56,7 +56,7 @@
 
 def test_system():
     filename = str(udir.join('test_system.txt'))
-    arg = 'python -c "print 1+1" > %s' % filename
+    arg = '%s -c "print 1+1" > %s' % (sys.executable, filename)
     data = getllimpl(os.system)(arg)
     assert data == 0
     assert file(filename).read().strip() == '2'



More information about the Pypy-commit mailing list