OSDN Git Service

2010-04-06 Matthias Klose <doko@ubuntu.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / sysdep.c
index 8a227b4..5af4299 100644 (file)
@@ -6,7 +6,7 @@
  *                                                                          *
  *                          C Implementation File                           *
  *                                                                          *
- *            Copyright (C) 1992-2009 Free Software Foundation, Inc.        *
+ *         Copyright (C) 1992-2009, Free Software Foundation, Inc.          *
  *                                                                          *
  * GNAT is free software;  you can  redistribute it  and/or modify it under *
  * terms of the  GNU General Public License as published  by the Free Soft- *
 
 #ifdef __vxworks
 #include "ioLib.h"
+#if ! defined (__VXWORKSMILS__)
 #include "dosFsLib.h"
-#ifndef __RTP__
+#endif
+#if ! defined (__RTP__) && (! defined (VTHREADS) || defined (__VXWORKSMILS__))
 # include "nfsLib.h"
 #endif
 #include "selectLib.h"
@@ -764,6 +766,22 @@ __gnat_localtime_tzoff (const time_t *timer, long *off)
 
   (*Lock_Task) ();
 
+#ifdef RTX
+
+  tzi_status = GetTimeZoneInformation (&tzi);
+  *off = tzi.Bias;
+  if (tzi_status == TIME_ZONE_ID_STANDARD)
+     /* The system is operating in the range covered by the StandardDate
+        member. */
+     *off = *off + tzi.StandardBias;
+  else if (tzi_status == TIME_ZONE_ID_DAYLIGHT)
+     /* The system is operating in the range covered by the DaylightDate
+        member. */
+     *off = *off + tzi.DaylightBias;
+  *off = *off * -60;
+
+#else
+
   /* First convert unix time_t structure to windows FILETIME format.  */
   utc_time.ull_time = ((unsigned long long) *timer + w32_epoch_offset)
                       * 10000000ULL;
@@ -787,13 +805,21 @@ __gnat_localtime_tzoff (const time_t *timer, long *off)
      /* An error occurs so return invalid_tzoff.  */
      *off = __gnat_invalid_tzoff;
   else
-     *off = (long) ((local_time.ull_time - utc_time.ull_time) / 10000000ULL);
+     if (local_time.ull_time > utc_time.ull_time)
+        *off = (long) ((local_time.ull_time - utc_time.ull_time) / 10000000ULL);
+     else
+        *off = - (long) ((utc_time.ull_time - local_time.ull_time) / 10000000ULL);
+
+#endif
 
   (*Unlock_Task) ();
 }
 
 #else
-#if defined (__Lynx__) && defined (___THREADS_POSIX4ad4__)
+
+/* On Lynx, all time values are treated in GMT */
+
+#if defined (__Lynx__)
 
 /* As of LynxOS 3.1.0a patch level 040, LynuxWorks changes the
    prototype to the C library function localtime_r from the POSIX.4
@@ -807,18 +833,24 @@ __gnat_localtime_tzoff (const time_t *, long *);
 void
 __gnat_localtime_tzoff (const time_t *timer, long *off)
 {
-  /* Treat all time values in GMT */
   *off = 0;
 }
 
 #else
+
+/* VMS does not need __gnat_locatime_tzoff */
+
 #if defined (VMS)
 
-/* __gnat_localtime_tzoff is not needed on VMS */
+/* Other targets except Lynx, VMS and Windows provide a standard locatime_r */
 
 #else
 
-/* All other targets provide a standard localtime_r */
+#define Lock_Task system__soft_links__lock_task
+extern void (*Lock_Task) (void);
+
+#define Unlock_Task system__soft_links__unlock_task
+extern void (*Unlock_Task) (void);
 
 extern void
 __gnat_localtime_tzoff (const time_t *, long *);
@@ -826,25 +858,35 @@ __gnat_localtime_tzoff (const time_t *, long *);
 void
 __gnat_localtime_tzoff (const time_t *timer, long *off)
 {
-   struct tm tp;
-   localtime_r (timer, &tp);
+  struct tm tp;
 
 /* 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;
+{
+  (*Lock_Task) ();
 
-/* Lynx - Treat all time values in GMT */
-#elif defined (__Lynx__)
-  *off = 0;
+  localtime_r (timer, &tp);
+  *off = (long) -timezone;
+
+  (*Unlock_Task) ();
+
+  /* Correct the offset if Daylight Saving Time is in effect */
+
+  if (tp.tm_isdst > 0)
+    *off = *off + 3600;
+}
 
 /* VxWorks */
 #elif defined (__vxworks)
 #include <stdlib.h>
 {
+  (*Lock_Task) ();
+
+  localtime_r (timer, &tp);
+
   /* 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");
 
   if ((tz_str == NULL) || (*tz_str == '\0'))
@@ -859,24 +901,41 @@ __gnat_localtime_tzoff (const time_t *timer, long *off)
        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;
+    /* The Ada layer expects an offset in seconds. Note that we must reverse
+       the sign of the result since west is positive and east is negative on
+       VxWorks targets. */
+
+    *off = -atol (tz_start) * 60;
+
+    /* Correct the offset if Daylight Saving Time is in effect */
+
+    if (tp.tm_isdst > 0)
+      *off = *off + 3600;
   }
+
+  (*Unlock_Task) ();
 }
 
 /* Darwin, Free BSD, Linux, Tru64, where component tm_gmtoff is present in
    struct tm */
+
 #elif defined (__APPLE__) || defined (__FreeBSD__) || defined (linux) ||\
      (defined (__alpha__) && defined (__osf__)) || defined (__GLIBC__)
+{
+  localtime_r (timer, &tp);
   *off = tp.tm_gmtoff;
+}
+
+/* Default: treat all time values in GMT */
 
-/* All other platforms: Treat all time values in GMT */
 #else
   *off = 0;
+
 #endif
 }
 
@@ -892,7 +951,8 @@ __gnat_localtime_tzoff (const time_t *timer, long *off)
    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. */
+   because it is almost always required. On processors with the SPE
+   category, VX_SPE_TASK is needed to enable the SPE. */
 extern int __gnat_get_task_options (void);
 
 int
@@ -905,6 +965,9 @@ __gnat_get_task_options (void)
 
   /* Force VX_FP_TASK because it is almost always required */
   options |= VX_FP_TASK;
+#if defined (__SPE__)
+  options |= VX_SPE_TASK;
+#endif
 
   /* Mask those bits that are not under user control */
 #ifdef VX_USR_TASK_OPTIONS
@@ -924,8 +987,10 @@ __gnat_is_file_not_found_error (int errno_val) {
       /* In the case of VxWorks, we also have to take into account various
        * filesystem-specific variants of this error.
        */
+#if ! defined (__VXWORKSMILS__)
       case S_dosFsLib_FILE_NOT_FOUND:
-#ifndef __RTP__
+#endif
+#if ! defined (__RTP__) && (! defined (VTHREADS) || defined (__VXWORKSMILS__))
       case S_nfsLib_NFSERR_NOENT:
 #endif
 #endif