Commit Graph

347 Commits

Author SHA1 Message Date
Victor Stinner 992c43fec9 Issue #22117: Fix rounding in _PyTime_FromSecondsObject()
* Rename _PyTime_FromObject() to _PyTime_FromSecondsObject()
* Add _PyTime_AsNanosecondsObject() and _testcapi.pytime_fromsecondsobject()
* Add unit tests
2015-03-27 17:12:45 +01:00
Victor Stinner cb29f0177c Issue #22117: Add a new Python timestamp format _PyTime_t to pytime.h
In practice, _PyTime_t is a number of nanoseconds. Its C type is a 64-bit
signed number. It's integer value is in the range [-2^63; 2^63-1]. In seconds,
the range is around [-292 years; +292 years]. In term of Epoch timestamp
(1970-01-01), it can store a date between 1677-09-21 and 2262-04-11.

The API has a resolution of 1 nanosecond and use integer number. With a
resolution on 1 nanosecond, 64-bit IEEE 754 floating point numbers loose
precision after 194 days. It's not the case with this API. The drawback is
overflow for values outside [-2^63; 2^63-1], but these values are unlikely for
most Python modules, except of the datetime module.

New functions:

- _PyTime_GetMonotonicClock()
- _PyTime_FromObject()
- _PyTime_AsMilliseconds()
- _PyTime_AsTimeval()

This change uses these new functions in time.sleep() to avoid rounding issues.

The new API will be extended step by step, and the old API will be removed step
by step. Currently, some code is duplicated just to be able to move
incrementally, instead of pushing a large change at once.
2015-03-27 13:31:18 +01:00
Victor Stinner 0eac13052c Issue #23646: Fix test_threading on Windows 2015-03-20 03:06:12 +01:00
Victor Stinner 9a8089b32a Issue #23646: Enhance precision of time.sleep() and socket timeout when
interrupted by a signal

Add a new _PyTime_AddDouble() function and remove _PyTime_ADD_SECONDS() macro.
The _PyTime_ADD_SECONDS only supported an integer number of seconds, the
_PyTime_AddDouble() has subsecond resolution.
2015-03-20 01:42:20 +01:00
Victor Stinner 79d68f929d Issue #23646: If time.sleep() is interrupted by a signal, the sleep is now
retried with the recomputed delay, except if the signal handler raises an
exception (PEP 475).

Modify also test_signal to use a monotonic clock instead of the system clock.
2015-03-19 21:54:09 +01:00
Victor Stinner 0c2fd89777 Revert changeset d927047b1d8eb87738676980a24930d053ba2150
Sorry, it was a mistake, the patch is still under review: issue #23646.
2015-03-17 10:49:17 +01:00
Victor Stinner 945c82eea3 test 2015-03-12 16:19:01 +01:00
Steve Dower 65e4cb10d9 Issue #22919: Windows build updated to support VC 14.0 (Visual Studio 2015), which will be used for the official 3.5 release. 2014-11-22 12:54:57 -08:00
Victor Stinner f427a14156 Issue #22592: Drop support of the Borland C compiler to build Python
The distutils module still supports it to build extensions.
2014-10-22 12:33:23 +02:00
Victor Stinner ae58649721 Issue #22043: time.monotonic() is now always available
threading.Lock.acquire(), threading.RLock.acquire() and socket operations now
use a monotonic clock, instead of the system clock, when a timeout is used.
2014-09-02 23:18:25 +02:00
Victor Stinner 67ca33dbf4 Issue #22043: Oops, fix perf_counter() on UNIX if no monotonic clock is
available (unlikely)
2014-08-29 17:00:17 +02:00
Victor Stinner 5488449ba4 Issue #22043: Simplify time.perf_counter() on Windows
QueryPerformanceFrequency() cannot fail on Windows XP and later according to
its documentation: raise an exception on error and drop the fallback to the
system clock.
2014-08-29 16:51:33 +02:00
Victor Stinner 0011124dc2 Issue #22043: _PyTime_Init() now checks if the system clock works.
Other changes:

* The whole _PyTime API is private (not defined if Py_LIMITED_API is set)
* _PyTime_gettimeofday_info() also returns -1 on error
* Simplify PyTime_gettimeofday(): only use clock_gettime(CLOCK_REALTIME) or
  gettimeofday() on UNIX. Don't fallback to ftime() or time() anymore.
2014-08-29 16:31:59 +02:00
Victor Stinner 7efb83393c Issue #22287: On UNIX, _PyTime_gettimeofday() now uses
clock_gettime(CLOCK_REALTIME) if available. As a side effect, Python now
depends on the librt library on Solaris and on Linux (only with glibc older
than 2.17).
2014-08-29 15:41:08 +02:00
Victor Stinner a734af3f39 timemodule.c: Replace PyExc_IOError with PyExc_OSError 2014-07-31 13:07:17 +02:00
Victor Stinner 1ac42614e3 Issue #19748: On AIX, time.mktime() now raises an OverflowError for year
outsize range [1902; 2037].
2014-02-21 09:27:17 +01:00
Victor Stinner 3c1b379ebd Issue #20320: select.select() and select.kqueue.control() now round the timeout
aways from zero, instead of rounding towards zero.

It should make test_asyncio more reliable, especially test_timeout_rounding() test.
2014-02-17 00:02:43 +01:00
Victor Stinner 93965f7a6b Issue #19634: time.strftime("%y") now raises a ValueError on Solaris when given
a year before 1900.
2013-11-23 14:59:33 +01:00
Victor Stinner 136f064b93 Issue #19634: Fix time_strftime() on AIX, format is a wchar_t* not a PyObject* 2013-11-18 02:43:29 +01:00
Victor Stinner 55329f8fbd Issue #19634: time.strftime("%y") now raises a ValueError on AIX when given a
year before 1900.
2013-11-17 23:39:21 +01:00
Tim Golden bbe268f583 Issue13674 Correct crash with strftime %y format under Windows 2013-11-12 12:48:20 +00:00
Tim Golden 6e51b8ff0f Issue13674 Correct crash with strftime %y format under Windows 2013-11-12 12:36:54 +00:00
Victor Stinner 1c8f059019 Issue #18520: Add a new PyStructSequence_InitType2() function, same than
PyStructSequence_InitType() except that it has a return value (0 on success,
-1 on error).

 * PyStructSequence_InitType2() now raises MemoryError on memory allocation failure
 * Fix also some calls to PyDict_SetItemString(): handle error
2013-07-22 22:24:54 +02:00
Victor Stinner 2ff51b83b8 Issue #18408: Fix time.tzset(), detect exception when calling PyInit_timezone() 2013-07-17 21:42:45 +02:00
Victor Stinner 93037498d1 Fix time.mktime() and datetime.datetime.timestamp() on AIX
On AIX, the C function mktime() alwaysd sets tm_wday, even on error. So tm_wday
cannot be used as a sentinel to detect an error, we can only check if the
result is (time_t)-1.
2013-06-25 22:54:35 +02:00
Victor Stinner d7a034bd75 (Merge 3.3) Fix time.strftime("%Y") on AIX: raise a ValueError for year > 9999
time.strtime("%Y") returned "2345" when formatting year 12345.
2013-06-25 02:34:13 +02:00
Victor Stinner 36b82d85a3 Fix time.strftime("%Y") on AIX: raise a ValueError for year > 9999
time.strtime("%Y") returned "2345" when formatting year 12345.
2013-06-25 02:33:53 +02:00
Richard Oudkerk 245bbee0d5 Merge. 2013-04-17 21:24:58 +01:00
Antoine Pitrou cf8a1e51ec - Issue #17782: Fix undefined behaviour on platforms where ``struct timespec``'s "tv_nsec" member is not a C long. 2013-04-17 22:06:44 +02:00
Martin v. Löwis b26a9b10ea Replace WaitForSingleObject with WaitForSingleObjectEx,
for better WinRT compatibility.
2013-01-25 14:25:48 +01:00
Jesus Cea 14c81aba50 #16135: Removal of OS/2 support (Modules/*) 2012-10-05 02:11:36 +02:00
Alexander Belopolsky cf77454908 Issue #9650: List commonly used format codes in time.strftime and time.strptime docsttings. 2012-10-02 18:39:16 -04:00
Alexander Belopolsky c142bba2a7 Issue #1667546: On platforms supporting tm_zone and tm_gmtoff fields
in struct tm, time.struct_time objects returned by time.gmtime(),
time.localtime() and time.strptime() functions now have tm_zone and
tm_gmtoff attributes.  Original patch by Paul Boddie.
2012-06-13 22:15:26 -04:00
Victor Stinner 2b89fdf7eb PEP 418: Rename adjusted attribute to adjustable in time.get_clock_info() result
Fix also its value on Windows and Linux according to its documentation:
"adjustable" indicates if the clock *can be* adjusted, not if it is or was
adjusted.

In most cases, it is not possible to indicate if a clock is or was adjusted.
2012-06-12 22:46:37 +02:00
Victor Stinner bda4b8802c time.get_clock_info() uses a namespace instead of structseq 2012-06-12 22:11:44 +02:00
Alexander Belopolsky d9738242f8 Fixed a typo in time_localtime() 2012-06-12 16:14:17 -04:00
Benjamin Peterson 49a69e4d48 strip is_ prefixes on clock_info fields 2012-05-01 09:38:34 -04:00
Victor Stinner ec89539ccc Issue #14428, #14397: Implement the PEP 418
* Rename time.steady() to time.monotonic()
 * On Windows, time.monotonic() uses GetTickCount/GetTickCount64() instead of
   QueryPerformanceCounter()
 * time.monotonic() uses CLOCK_HIGHRES if available
 * Add time.get_clock_info(), time.perf_counter() and time.process_time()
   functions
2012-04-29 02:41:27 +02:00
Victor Stinner b8d016955a Fix clock_gettime/getres/settime: PyArg_ParseTuple() expects an int
Only use a single #ifdef for the 3 functions.
2012-04-13 23:44:05 +02:00
Victor Stinner 30d79471bb Expose clock_settime() as time.clock_settime() 2012-04-03 00:45:07 +02:00
Victor Stinner 1470f35bc6 Add time.CLOCK_HIGHRES constant, needed on Solaris 2012-04-03 00:31:17 +02:00
Victor Stinner ad95c2d25c time.time() now uses clock_gettime(CLOCK_REALTIME) if available
clock_gettime(CLOCK_REALTIME) has a better resolution than gettimeofday().
time.time() falls back on gettimeofday() (and then on other functions) on
error.
2012-03-28 02:54:15 +02:00
Victor Stinner 74eb6c0e8b Document the fact that mach_timebase_info() cannot fail
And call mach_absolute_time() after mach_timebase_info().
2012-03-28 02:50:46 +02:00
Victor Stinner 8486076dd5 Fix time.steady(strict=True): don't use CLOCK_REALTIME 2012-03-26 22:53:14 +02:00
Victor Stinner 70b2e1e7d9 Issue #14368: _PyTime_gettimeofday() cannot fail
floattime() must not raise an error if the current time is 1970.1.1 at 00:00.
2012-03-26 22:08:02 +02:00
Victor Stinner 071eca3f5c Issue #10278: Add an optional strict argument to time.steady(), False by default 2012-03-15 01:17:09 +01:00
Victor Stinner ec919cc74d Issue #10278: Drop time.monotonic() function, rename time.wallclock() to time.steady()
* On Mac OS X, time.steady() now uses mach_absolute_time(), a monotonic clock
 * Optimistic change: bet that CLOCK_MONOTONIC and CLOCK_REALTIME are available
   when clock_gettime() is available
 * Rewrite time.steady() documentation
2012-03-15 00:58:32 +01:00
Victor Stinner 5d272cc6a2 Close #14180: Factorize code to convert a number of seconds to time_t, timeval or timespec
time.ctime(), gmtime(), time.localtime(), datetime.date.fromtimestamp(),
datetime.datetime.fromtimestamp() and datetime.datetime.utcfromtimestamp() now
raises an OverflowError, instead of a ValueError, if the timestamp does not fit
in time_t.

datetime.datetime.fromtimestamp() and datetime.datetime.utcfromtimestamp() now
round microseconds towards zero instead of rounding to nearest with ties going
away from zero.
2012-03-13 13:35:55 +01:00
Victor Stinner a8ec5ea923 Issue #14104: Implement time.monotonic() on Mac OS X,
patch written by Nicholas Riley.
2012-03-13 00:25:42 +01:00
Stefan Krah 4aea7d3811 Issue #14125: Fix refleak in timemodule.c on Windows. Thanks sbt for pointing
out the location of the problem. MS_WINDOWS currently implies !HAVE_WCSFTIME,
so the addition of !defined(HAVE_WCSFTIME) is for readability.
2012-02-27 16:30:26 +01:00
Victor Stinner 4195b5caea Backout f8409b3d6449: the PEP 410 is not accepted yet 2012-02-08 23:03:19 +01:00
Victor Stinner ccd5715a14 PEP 410 2012-02-08 14:31:50 +01:00
Victor Stinner 8b30201f7d Issue #13846: Add time.monotonic(), monotonic clock. 2012-02-07 23:29:46 +01:00
Victor Stinner 85fdfa85e1 Issue #13847: time.clock() now raises a RuntimeError if the processor time used
is not available or its value cannot be represented
2012-01-27 00:38:48 +01:00
Victor Stinner c1b5d34ede Issue #13847: time.localtime() and time.gmtime() now raise an OSError instead
of ValueError on failure. time.ctime() and time.asctime() now raises an
OSError if localtime() failed.
2012-01-27 00:08:48 +01:00
Antoine Pitrou e39ebe45c4 Merge 2012-01-18 02:05:38 +01:00
Victor Stinner 855889b4bf Issue #10278: fix a typo in the doc 2012-01-18 01:57:19 +01:00
Victor Stinner b94b266cfc Close #10278: Add time.wallclock() function, monotonic clock. 2012-01-18 01:50:21 +01:00
Antoine Pitrou 2c085604b7 Fix error handling in timemodule.c 2012-01-18 01:41:44 +01:00
Victor Stinner ab870218e3 Issue #10951: Fix compiler warnings in timemodule.c and unicodeobject.c
Thanks Jérémy Anger for the fix.
2011-12-17 22:39:43 +01:00
Victor Stinner 136ea49b39 Issue #10951: Fix a compiler warning in timemodule.c 2011-12-17 22:37:18 +01:00
Victor Stinner 1b57967b96 Issue #13560: Locale codec functions use the classic "errors" parameter,
instead of surrogateescape

So it would be possible to support more error handlers later.
2011-12-17 05:47:23 +01:00
Victor Stinner f2ea71fcc8 Issue #13560: Add PyUnicode_EncodeLocale()
* Use PyUnicode_EncodeLocale() in time.strftime() if wcsftime() is not
   available
 * Document my last changes in Misc/NEWS
2011-12-17 04:13:41 +01:00
Victor Stinner af02e1c85a Add PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale()
* PyUnicode_DecodeLocaleAndSize() and PyUnicode_DecodeLocale() decode a string
   from the current locale encoding
 * _Py_char2wchar() writes an "error code" in the size argument to indicate
   if the function failed because of memory allocation failure or because of a
   decoding error. The function doesn't write the error message directly to
   stderr.
 * Fix time.strftime() (if wcsftime() is missing): decode strftime() result
   from the current locale encoding, not from the filesystem encoding.
2011-12-16 23:56:01 +01:00
Antoine Pitrou ab0e9f7089 Issue #10350: Read and save errno before calling a function which might overwrite it.
Original patch by Hallvard B Furuseth.
2011-12-16 12:29:37 +01:00
Antoine Pitrou c345ce1a69 Issue #10350: Read and save errno before calling a function which might overwrite it.
Original patch by Hallvard B Furuseth.
2011-12-16 12:28:32 +01:00
Victor Stinner db6238964d (Merge 3.2) Issue #5905: time.strftime() is now using the locale encoding,
instead of UTF-8, if the wcsftime() function is not available.
2011-12-09 20:21:17 +01:00
Victor Stinner 720f34a3e8 Issue #5905: time.strftime() is now using the locale encoding, instead of
UTF-8, if the wcsftime() function is not available.
2011-12-09 20:19:24 +01:00
Antoine Pitrou 6dd381eb62 Issue #12328: Under Windows, refactor handling of Ctrl-C events and
make _multiprocessing.win32.WaitForMultipleObjects interruptible when
the wait_flag parameter is false.  Patch by sbt.
2011-11-21 21:26:56 +01:00
Victor Stinner e0be423297 Close #10278: Add clock_getres(), clock_gettime() and CLOCK_xxx constants to
the time module. time.clock_gettime(time.CLOCK_MONOTONIC) provides a monotonic
clock
2011-10-25 13:06:09 +02:00
Victor Stinner 5a3ff79fd6 Issue #10653: Fix time.strftime() on Windows, check for invalid format strings 2011-10-16 19:08:23 +02:00
Martin v. Löwis bd928fef42 Rename _Py_identifier to _Py_IDENTIFIER. 2011-10-14 10:20:37 +02:00
Victor Stinner 792b47f6ca (Merge 3.2) Issue #10653: On Windows, use strftime() instead of wcsftime()
because wcsftime() doesn't format time zone correctly.
2011-10-14 02:39:06 +02:00
Victor Stinner c1f32ca0ad Issue #10653: On Windows, use strftime() instead of wcsftime() because
wcsftime() doesn't format time zone correctly.
2011-10-14 02:36:13 +02:00
Martin v. Löwis afe55bba33 Add API for static strings, primarily good for identifiers.
Thanks to Konrad Schöbel and Jasper Schulz for helping with the mass-editing.
2011-10-09 10:38:36 +02:00
Victor Stinner 8d91d454d5 Issue #10653: Fix time.strftime() on Windows, check for invalid format strings 2011-10-16 23:45:39 +02:00
Victor Stinner 7f53a5027d Issue #12459: time.sleep() now raises a ValueError if the sleep length is
negative, instead of an infinite sleep on Windows or raising an IOError on
Linux for example, to have the same behaviour on all platforms.
2011-07-05 22:00:25 +02:00
Victor Stinner 99b9538636 Issue #9642: Uniformize the tests on the availability of the mbcs codec
Add a new HAVE_MBCS define.
2011-07-04 14:23:54 +02:00
Victor Stinner 9122fdd8fa Issue #9642: Fix the definition of time.clock() on Windows
Don't unset and set againt the HAVE_CLOCK define, reorder the #if tests
instead. Fix also the definition of the timezone encoding.
2011-07-04 13:55:40 +02:00
Victor Stinner 48b1ce5519 Issue #12462: time.sleep() now calls immediatly the (Python) signal handler if
it is interrupted by a signal, instead of having to wait until the next
instruction.

Patch reviewed by Antoine Pitrou.
2011-07-01 13:50:09 +02:00
Alexander Belopolsky 66746cb222 Removed unused variable 2011-05-02 13:44:20 -04:00
Alexander Belopolsky 03163ac185 Issue #11930: Remove deprecated time.accept2dyear. 2011-05-02 12:20:52 -04:00
Senthil Kumaran 736975a771 merge from 3.2 2011-04-06 14:16:08 +08:00
Senthil Kumaran ae664fb528 Merge from 3.1 2011-04-06 14:11:09 +08:00
Senthil Kumaran 8f377a3bbe Issue #10762: Guard against invalid/non-supported format string '%f' on Windows. Patch Santoso Wijaya. 2011-04-06 12:54:06 +08:00
Victor Stinner 499dfcf29d Issue #10833: Use PyUnicode_FromFormat() and PyErr_Format() instead of
PyOS_snprintf().
2011-03-21 13:26:24 +01:00
Victor Stinner 6f0e4f99ab time.strftime(): replace PyErr_Format() by PyErr_SetString()
The argument was not used in the format string.
2011-03-21 02:14:53 +01:00
Ezio Melotti 3b3499ba69 #11565: Merge with 3.1. 2011-03-16 11:35:38 +02:00
Ezio Melotti 13925008dc #11565: Fix several typos. Patch by Piotr Kasprzyk. 2011-03-16 11:05:33 +02:00
Alexander Belopolsky 4fb96f41f4 Merged revisions 87919 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k

........
  r87919 | alexander.belopolsky | 2011-01-10 20:21:25 -0500 (Mon, 10 Jan 2011) | 4 lines

  Issue #1726687: time.mktime() will now correctly compute value one
  second before epoch.  Original patch by Peter Wang, reported by Martin
  Blais.
........
2011-02-15 15:40:59 +00:00
R. David Murray 43b2f457a0 Merged revisions 87136,87221,87256,87337-87338,87571,87839,88164 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k


........
  r87136 | r.david.murray | 2010-12-08 17:53:00 -0500 (Wed, 08 Dec 2010) | 6 lines

  Have script_helper._assert_python strip refcount strings from stderr.

  This makes the output of the function and those that depend on it
  independent of whether or not they are being run under a debug
  build.
........
  r87221 | r.david.murray | 2010-12-13 19:55:46 -0500 (Mon, 13 Dec 2010) | 4 lines

  #10699: fix docstring for tzset: it does not take a parameter

  Thanks to Garrett Cooper for the fix.
........
  r87256 | r.david.murray | 2010-12-14 21:19:14 -0500 (Tue, 14 Dec 2010) | 2 lines

  #10705: document what the values of debuglevel are and mean.
........
  r87337 | r.david.murray | 2010-12-17 11:11:40 -0500 (Fri, 17 Dec 2010) | 2 lines

  #10559: provide instructions for accessing sys.argv when first mentioned.
........
  r87338 | r.david.murray | 2010-12-17 11:29:07 -0500 (Fri, 17 Dec 2010) | 2 lines

  #10454: clarify the compileall docs and help messages.
    [compileall.py changes not backported.]
........
  r87571 | r.david.murray | 2010-12-29 14:06:48 -0500 (Wed, 29 Dec 2010) | 2 lines

  Fix same typo in docs.
........
  r87839 | r.david.murray | 2011-01-07 16:57:25 -0500 (Fri, 07 Jan 2011) | 9 lines

  Fix formatting of values with embedded newlines when rfc2047 encoding

  Before this patch if a value being encoded had an embedded newline,
  the line following the newline would have no leading whitespace,
  and the whitespace it did have was encoded into the word.  Now
  the existing whitespace gets turned into a blank, the way it does
  in other header reformatting, and the _continuation_ws gets added
  at the beginning of the encoded line.
........
  r88164 | r.david.murray | 2011-01-24 14:34:58 -0500 (Mon, 24 Jan 2011) | 12 lines

  #10960: fix 'stat' links, link to lstat from stat, general tidy of stat doc.

  Original patch by Michal Nowikowski, with some additions and wording
  fixes by me.

  I changed the wording from 'Performs a stat system call' to 'Performs
  the equivalent of a stat system call', since on Windows there are no
  stat/lstat system calls involved.  I also extended Michal's breakout
  of the attributes into a list to the other paragraphs, and rearranged
  the order of the paragraphs in the 'stat' docs to make it flow
  better and put it in what I think is a more logical/useful order.
........
2011-02-11 03:13:19 +00:00
Alexander Belopolsky b7d40d1702 Issue #1726687: time.mktime() will now correctly compute value one
second before epoch.  Original patch by Peter Wang, reported by Martin
Blais.
2011-01-11 01:21:25 +00:00
Victor Stinner 06ec45e2f8 Issue #10864: limit year to [1; 9999] for strftime() on Solaris 2011-01-08 03:35:36 +00:00
Victor Stinner 301f1217ac Issue #1777412: Remove all limits on tm_year from time.strftime()
The buildbots will tell us which platform does support or not negative years.
2011-01-08 03:06:52 +00:00
Victor Stinner 73ea29cb03 Issue #1777412: strftime() accepts year >= 1 instead of year >= 1900
* With Visual Studio, year have to be in [1; 9999]
 * Add more tests on the year field
2011-01-08 01:56:31 +00:00
Alexander Belopolsky 0dd06f4082 Fixed error handling branches. Thanks
Victor Stinner for pointing this out.
2011-01-08 01:23:02 +00:00
Alexander Belopolsky b8bb4664fc Issue #1777412: extended year range of strftime down to 1000. 2011-01-08 00:13:34 +00:00
Alexander Belopolsky c64708ae48 Issue #10827: Changed the rules for 2-digit years. The time.asctime
function will now format any year when time.accept2dyear is false and
will accept years >= 1000 otherwise.  The year range accepted by
time.mktime and time.strftime is still system dependent, but
time.mktime will now accept full range supported by the OS. Conversion
of 2-digit years to 4-digit is deprecated.
2011-01-07 19:59:19 +00:00
Alexander Belopolsky 610e544bf7 Further simplify gettmarg() 2011-01-06 21:57:06 +00:00
Alexander Belopolsky ecbb8dc17a Use PyOS_snprintf for better portability. 2011-01-06 16:45:25 +00:00