summaryrefslogtreecommitdiff
path: root/gcc/ada/sysdep.c
diff options
context:
space:
mode:
authorcharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2007-04-06 09:15:21 +0000
committercharlet <charlet@138bc75d-0d04-0410-961f-82ee72b054a4>2007-04-06 09:15:21 +0000
commiteaa006632546b894576a92e971294c7e9ac5231b (patch)
tree7a061f08c1577dcad5f77bb59e183a711e8af6e1 /gcc/ada/sysdep.c
parent232e4d04f0263022b1379a7886e28e7f082f7eb8 (diff)
downloadgcc-eaa006632546b894576a92e971294c7e9ac5231b.tar.gz
2007-04-06 Hristian Kirtchev <kirtchev@adacore.com>
Vincent Celier <celier@adacore.com> * a-calend-vms.ads, a-calend.ads, a-calend.adb, a-calend-vms.adb: New version of Ada.Calendar which supports the new upper bound of Ada time (2399-12-31 86_399.999999999). The following modifications have been made to the package: - New representation of time as count of nanoseconds since the start of Ada time (1901-1-1 0.0). - Target independent Split and Time_Of routines which service both Ada 95 and Ada 2005 code. - Target independent interface to the Ada 2005 children of Calendar. - Integrated leap seconds into Ada 95 and Ada 2005 mode. - Handling of non-leap centenial years. - Updated clock function. - Updated arithmetic and comparison operators. * a-caldel.adb (To_Duration): Add call to target independent routine in Ada.Calendar to handle the conversion of time to duration. * sysdep.c (__gnat_localtime_tzoff): Test timezone before setting off (UTC Offset). If timezone is obviously incorrect (outside of -14 hours .. 14 hours), set off to 0. (__gnat_localtime_tzoff for Lynx and VxWorks): Even though these targets do not have a natural time zone, GMT is used as a default. (__gnat_get_task_options): New. * a-direct.adb (Modification_Time): Add with and use clauses for Ada.Calendar and Ada. Calendar.Formatting. Remove with clause for Ada.Unchecked_Conversion since it is no longer needed. (Duration_To_Time): Removed. (OS_Time_To_Long_Integer): Removed. (Modification_Time): Rewritten to use Ada.Calendar and Ada.Calendar. Formatting Time_Of routines which automatically handle time zones, buffer periods and leap seconds. * a-calari.ads, a-calari.adb ("+", "-", Difference): Add calls to target independent routines in Ada.Calendar. * a-calfor.ads, a-calfor.adb: Code cleanup and addition of validity checks in various routines. (Day_Of_Week, Split, Time_Of): Add call to target independent routine in Ada.Calendar. * a-catizo.ads, a-catizo.adb (UTC_Time_Offset): Add call to target independent routine in Ada.Calendar. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@123543 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ada/sysdep.c')
-rw-r--r--gcc/ada/sysdep.c120
1 files changed, 110 insertions, 10 deletions
diff --git a/gcc/ada/sysdep.c b/gcc/ada/sysdep.c
index 0562766a9e5..595cc3d9edf 100644
--- a/gcc/ada/sysdep.c
+++ b/gcc/ada/sysdep.c
@@ -687,7 +687,7 @@ get_gmtoff (void)
/* This value is returned as the time zone offset when a valid value
cannot be determined. It is simply a bizarre value that will never
- occur. It is 3 days plus 73 seconds (offset is in seconds. */
+ occur. It is 3 days plus 73 seconds (offset is in seconds). */
long __gnat_invalid_tzoff = 259273;
@@ -755,8 +755,9 @@ __gnat_localtime_tzoff (const time_t *, struct tm *, long *);
struct tm *
__gnat_localtime_tzoff (const time_t *timer, struct tm *tp, long *off)
{
+ /* Treat all time values in GMT */
localtime_r (tp, timer);
- *off = __gnat_invalid_tzoff;
+ *off = 0;
return NULL;
}
@@ -779,17 +780,60 @@ __gnat_localtime_tzoff (const time_t *timer, struct tm *tp, long *off)
/* AIX, HPUX, SGI Irix, Sun Solaris */
#if defined (_AIX) || defined (__hpux__) || defined (sgi) || defined (sun)
- *off = (long) -timezone;
- if (tp->tm_isdst > 0)
- *off = *off + 3600;
+ /* The contents of external variable "timezone" may not always be
+ initialized. Instead of returning an incorrect offset, treat the local
+ time zone as 0 (UTC). The value of 28 hours is the maximum valid offset
+ allowed by Ada.Calendar.Time_Zones. */
+ if ((timezone < -28 * 3600) || (timezone > 28 * 3600))
+ *off = 0;
+ else
+ {
+ *off = (long) -timezone;
+ if (tp->tm_isdst > 0)
+ *off = *off + 3600;
+ }
+/* Lynx - Treat all time values in GMT */
+#elif defined (__Lynx__)
+ *off = 0;
+
+/* VxWorks */
+#elif defined (__vxworks)
+#include <stdlib.h>
+{
+ /* Try to read the environment variable TIMEZONE. The variable may not have
+ been initialize, in that case return an offset of zero (0) for UTC. */
+ char *tz_str = getenv ("TIMEZONE");
-/* Lynx, VXWorks */
-#elif defined (__Lynx__) || defined (__vxworks)
- *off = __gnat_invalid_tzoff;
+ if ((tz_str == NULL) || (*tz_str == '\0'))
+ *off = 0;
+ else
+ {
+ char *tz_start, *tz_end;
+
+ /* The format of the data contained in TIMEZONE is N::U:S:E where N is the
+ name of the time zone, U are the minutes difference from UTC, S is the
+ start of DST in mmddhh and E is the end of DST in mmddhh. Extracting
+ the value of U involves setting two pointers, one at the beginning and
+ one at the end of the value. The end pointer is then set to null in
+ order to delimit a string slice for atol to process. */
+ tz_start = index (tz_str, ':') + 2;
+ tz_end = index (tz_start, ':');
+ tz_end = '\0';
+
+ /* The Ada layer expects an offset in seconds */
+ *off = atol (tz_start) * 60;
+ }
+}
-/* Darwin, Free BSD, Linux, Tru64 */
-#else
+/* Darwin, Free BSD, Linux, Tru64, where there exists a component tm_gmtoff
+ in struct tm */
+#elif defined (__APPLE__) || defined (__FreeBSD__) || defined (linux) ||\
+ (defined (__alpha__) && defined (__osf__))
*off = tp->tm_gmtoff;
+
+/* All other platforms: Treat all time values in GMT */
+#else
+ *off = 0;
#endif
return NULL;
}
@@ -797,3 +841,59 @@ __gnat_localtime_tzoff (const time_t *timer, struct tm *tp, long *off)
#endif
#endif
#endif
+
+#ifdef __vxworks
+
+#include <taskLib.h>
+
+/* __gnat_get_task_options is used by s-taprop.adb only for VxWorks. This
+ function returns the options to be set when creating a new task. It fetches
+ the options assigned to the current task (parent), so offering some user
+ level control over the options for a task hierarchy. It forces VX_FP_TASK
+ because it is almost always required. */
+extern int __gnat_get_task_options (void);
+
+int
+__gnat_get_task_options (void)
+{
+ int options;
+
+ /* Get the options for the task creator */
+ taskOptionsGet (taskIdSelf (), &options);
+
+ /* Force VX_FP_TASK because it is almost always required */
+ options |= VX_FP_TASK;
+
+ /* Mask those bits that are not under user control */
+#ifdef VX_USR_TASK_OPTIONS
+ return options & VX_USR_TASK_OPTIONS;
+#else
+ return options;
+#endif
+}
+
+#endif
+
+#ifdef __Lynx__
+
+/*
+ The following code works around a problem in LynxOS version 4.2. As
+ of that version, the symbol pthread_mutex_lock has been removed
+ from libc and replaced with an inline C function in a system
+ header.
+
+ LynuxWorks has indicated that this is a bug and that they intend to
+ put that symbol back in libc in a future patch level, following
+ which this patch can be removed. However, for the time being we use
+ a wrapper which can be imported from the runtime.
+*/
+
+#include <pthread.h>
+
+int
+__gnat_pthread_mutex_lock (pthread_mutex_t *mutex)
+{
+ return pthread_mutex_lock (mutex);
+}
+
+#endif /* __Lynx__ */