Author: sebor
Date: Thu Jan 12 16:30:12 2006
New Revision: 368527
URL: http://svn.apache.org/viewcvs?rev=368527&view=rev
Log:
2006-01-12 Martin Sebor <[EMAIL PROTECTED]>
STDCXX-108
* TIMEZONE.cpp: New test to determine whether the POSIX timezone
variable is declared in <time.h>.
* time_put.cpp (__rw_get_zone): Changed to return 0 instead of void
on success (and non-zero on error) and handled _RWSTD_NO_TIMEZONE.
(__rw_get_time_put_data): Handled __rw_get_zone failure.
Added:
incubator/stdcxx/trunk/etc/config/src/TIMEZONE.cpp (with props)
Modified:
incubator/stdcxx/trunk/src/time_put.cpp
Added: incubator/stdcxx/trunk/etc/config/src/TIMEZONE.cpp
URL:
http://svn.apache.org/viewcvs/incubator/stdcxx/trunk/etc/config/src/TIMEZONE.cpp?rev=368527&view=auto
==============================================================================
--- incubator/stdcxx/trunk/etc/config/src/TIMEZONE.cpp (added)
+++ incubator/stdcxx/trunk/etc/config/src/TIMEZONE.cpp Thu Jan 12 16:30:12 2006
@@ -0,0 +1,17 @@
+// checking for int timezone in <time.h>
+
+#include <time.h>
+
+int get_timezone_value ()
+{
+ // POSIX requires a timezone variable:
+ // http://www.opengroup.org/onlinepubs/009695399/functions/timezone.html
+
+ // BSD-based systems such as Darwin define a char* timezone(int, int)
+ // function that has nothing to do with the variable:
+ // http://developer.apple.com/documentation/Darwin/Reference/ManPages/ \
+ // man3/timezone.3.html
+
+ // check to see if a timezone variable exists and is convertible to int
+ return timezone / 2;
+}
Propchange: incubator/stdcxx/trunk/etc/config/src/TIMEZONE.cpp
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: incubator/stdcxx/trunk/etc/config/src/TIMEZONE.cpp
------------------------------------------------------------------------------
svn:keywords = Id
Modified: incubator/stdcxx/trunk/src/time_put.cpp
URL:
http://svn.apache.org/viewcvs/incubator/stdcxx/trunk/src/time_put.cpp?rev=368527&r1=368526&r2=368527&view=diff
==============================================================================
--- incubator/stdcxx/trunk/src/time_put.cpp (original)
+++ incubator/stdcxx/trunk/src/time_put.cpp Thu Jan 12 16:30:12 2006
@@ -1923,9 +1923,11 @@
};
-static void
+static int
__rw_get_zone (__rw_time_put_data &tpd, const char *var, int isdst)
{
+ _RWSTD_ASSERT (0 != var);
+
// TZ format:
// :characters
// or
@@ -1999,20 +2001,65 @@
else
goto use_tzset;
- return;
+ return 0; // success
use_tzset:
+ // the lock cannot prevent another thread from calling tzset()
+ // directly (or one of the other functions in the #else block)
+ // for "stronger" thread-safety it might be better to take the
+ // #else branch below and use gmtime_r() there (that would
+ // only be safe if mktime() were thread-safe)
_RWSTD_MT_STATIC_GUARD (__rw_time_put_data);
+#ifndef _RWSTD_NO_TIMEZONE
+
// set the POSIX `timezone' and `daylight' extern variables
tzset ();
+ // tzet() sets timezone to the difference, in seconds, between
+ // Coordinated Universal Time (UTC) and local standard time
tpd.val = timezone / 60;
+
+#else // if defined (_RWSTD_NO_TIMEZONE)
+
+ tpd.val = 0;
+
+ // calculate the difference the hard way
+ static const time_t tgm = 0;
+
+ const tm* const tmp = gmtime (&tgm);
+
+ if (tmp) {
+ tm tmgm = *tmp;
+
+ const time_t tlocal = mktime (&tmgm);
+
+ if (time_t (-1) != tlocal) {
+
+ const double diff = difftime (tlocal, tgm);
+
+ tpd.val = int (diff / 60);
+ }
+ else {
+ // FIXME: indicate the nature of the error to the caller somehow
+ return -1;
+ }
+ }
+ else {
+ // FIXME: indicate the nature of the error to the caller somehow
+ return -1;
+ }
+
+#endif // _RWSTD_NO_TIMEZONE
+
+ // set the value to the difference in the HH:MM "format"
tpd.val = 100 * (tpd.val / 60) + tpd.val % 60;
if (daylight && isdst)
tpd.val += (tpd.val < 0 ? -100 : 100) * isdst;
+
+ return 0; // success
}
@@ -2037,6 +2084,12 @@
_RWSTD_ASSERT ( 0 != tmb
|| 'c' == fmt || 'r' == fmt || 'x' == fmt || 'X' == fmt);
+ static const union {
+#ifndef _RWSTD_NO_WCHAR_T
+ wchar_t wide_data [1];
+#endif // _RWSTD_NO_WCHAR_T
+ char data [4];
+ } null_fmt = { 0 };
const __rw_time_t *ptime =
_RWSTD_STATIC_CAST (const __rw_time_t*, facet->_C_data ());
@@ -2500,7 +2553,7 @@
if (tmb->tm_isdst < 0) {
// force no output
tpd.val = _RWSTD_INT_MIN;
- tpd.fmt = L"";
+ tpd.fmt = null_fmt.data;
break;
}
@@ -2547,16 +2600,22 @@
const char* const var = getenv ("TZ");
- if (!var || !*var)
+ if (!var || !*var || __rw_get_zone (tpd, var, tmb->tm_isdst)) {
+ // force no output on error
+ tpd.val = _RWSTD_INT_MIN;
+ tpd.fmt = null_fmt.data;
break;
-
- __rw_get_zone (tpd, var, tmb->tm_isdst);
+ }
}
else {
const char* const var = getenv ("TZ");
- if (!var || !*var)
+ if (!var || !*var) {
+ // force no output
+ tpd.val = _RWSTD_INT_MIN;
+ tpd.fmt = null_fmt.data;
break;
+ }
__rw_get_zone_name (tpd, var, tmb->tm_isdst);
}