X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=gcc%2Fada%2Fsysdep.c;h=a8f24cd71e5570940f93d35bf6d61ce4687c361c;hp=9ec94ea819c368c262e7be0826ff1730b11075f9;hb=c2f0327042399b100d792f828204e32afe4b78a4;hpb=cbc72f1a66ac985773daa55b5516327bba1b00e8 diff --git a/gcc/ada/sysdep.c b/gcc/ada/sysdep.c index 9ec94ea819c..a8f24cd71e5 100644 --- a/gcc/ada/sysdep.c +++ b/gcc/ada/sysdep.c @@ -6,7 +6,7 @@ * * * C Implementation File * * * - * Copyright (C) 1992-2003 Free Software Foundation, Inc. * + * Copyright (C) 1992-2008, 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- * @@ -16,8 +16,8 @@ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * * for more details. You should have received a copy of the GNU General * * Public License distributed with GNAT; see file COPYING. If not, write * - * to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, * - * MA 02111-1307, USA. * + * to the Free Software Foundation, 51 Franklin Street, Fifth Floor, * + * Boston, MA 02110-1301, USA. * * * * As a special exception, if you link this file with other files to * * produce an executable, this file does not by itself cause the resulting * @@ -44,7 +44,6 @@ #include "tsystem.h" #include #include -#include #ifdef VMS #include #endif @@ -53,6 +52,14 @@ #include "system.h" #endif +#include + +#if defined (sun) && defined (__SVR4) && !defined (__vxworks) +/* The declaration is present in but conditionalized + on a couple of macros we don't define. */ +extern struct tm *localtime_r(const time_t *, struct tm *); +#endif + #include "adaint.h" /* @@ -187,7 +194,7 @@ __gnat_ttyname (int filedes) return NULL; } -/* This function is needed to fix a bug under Win95/98. Under these plateforms +/* This function is needed to fix a bug under Win95/98. Under these platforms doing : ch1 = getch(); ch2 = fgetc (stdin); @@ -206,12 +213,31 @@ __gnat_ttyname (int filedes) Calling FlushConsoleInputBuffer just after getch() fix the bug under 95/98. */ +#ifdef RTX + +static void winflush_nt (void); + +/* winflush_function will do nothing since we only have problems with Windows + 95/98 which are not supported by RTX. */ + +static void (*winflush_function) (void) = winflush_nt; + +static void +winflush_nt (void) +{ + /* Does nothing as there is no problem under NT. */ +} + +#else + static void winflush_init (void); static void winflush_95 (void); static void winflush_nt (void); +int __gnat_is_windows_xp (void); + /* winflusfunction is set first to the winflushinit function which will check the OS version 95/98 or NT/2000 */ @@ -234,15 +260,42 @@ winflush_init (void) } -static void winflush_95 (void) +static void +winflush_95 (void) { FlushConsoleInputBuffer (GetStdHandle (STD_INPUT_HANDLE)); } -static void winflush_nt (void) +static void +winflush_nt (void) { /* Does nothing as there is no problem under NT. */ } + +int +__gnat_is_windows_xp (void) +{ + static int is_win_xp=0, is_win_xp_checked=0; + + if (!is_win_xp_checked) + { + OSVERSIONINFO version; + + is_win_xp_checked = 1; + + memset (&version, 0, sizeof (version)); + version.dwOSVersionInfoSize = sizeof (version); + + is_win_xp = GetVersionEx (&version) + && version.dwPlatformId == VER_PLATFORM_WIN32_NT + && (version.dwMajorVersion > 5 + || (version.dwMajorVersion == 5 && version.dwMinorVersion >= 1)); + } + return is_win_xp; +} + +#endif + #endif #else @@ -275,23 +328,22 @@ __gnat_set_text_mode (int handle ATTRIBUTE_UNUSED) char * __gnat_ttyname (int filedes) { -#ifndef __vxworks +#if defined (__vxworks) || defined (__nucleus) + return ""; +#else extern char *ttyname (int); return ttyname (filedes); - -#else - return ""; - -#endif +#endif /* defined (__vxworks) || defined (__nucleus) */ } #endif #if defined (linux) || defined (sun) || defined (sgi) || defined (__EMX__) \ || (defined (__osf__) && ! defined (__alpha_vxworks)) || defined (WINNT) \ - || defined (__MACHTEN__) || defined (hpux) || defined (_AIX) \ + || defined (__MACHTEN__) || defined (__hpux__) || defined (_AIX) \ || (defined (__svr4__) && defined (i386)) || defined (__Lynx__) \ - || defined (__CYGWIN__) + || defined (__CYGWIN__) || defined (__FreeBSD__) || defined (__OpenBSD__) \ + || defined (__GLIBC__) #ifdef __MINGW32__ #if OLD_MINGW @@ -346,9 +398,10 @@ getc_immediate_common (FILE *stream, { #if defined (linux) || defined (sun) || defined (sgi) || defined (__EMX__) \ || (defined (__osf__) && ! defined (__alpha_vxworks)) \ - || defined (__CYGWIN32__) || defined (__MACHTEN__) || defined (hpux) \ + || defined (__CYGWIN32__) || defined (__MACHTEN__) || defined (__hpux__) \ || defined (_AIX) || (defined (__svr4__) && defined (i386)) \ - || defined (__Lynx__) + || defined (__Lynx__) || defined (__FreeBSD__) || defined (__OpenBSD__) \ + || defined (__GLIBC__) char c; int nread; int good_one = 0; @@ -365,9 +418,10 @@ getc_immediate_common (FILE *stream, termios_rec.c_lflag = termios_rec.c_lflag & ~ICANON & ~ECHO; #if defined(linux) || defined (sun) || defined (sgi) || defined (__EMX__) \ - || defined (__osf__) || defined (__MACHTEN__) || defined (hpux) \ + || defined (__osf__) || defined (__MACHTEN__) || defined (__hpux__) \ || defined (_AIX) || (defined (__svr4__) && defined (i386)) \ - || defined (__Lynx__) + || defined (__Lynx__) || defined (__FreeBSD__) || defined (__OpenBSD__) \ + || defined (__GLIBC__) eof_ch = termios_rec.c_cc[VEOF]; /* If waiting (i.e. Get_Immediate (Char)), set MIN = 1 and wait for @@ -637,8 +691,6 @@ rts_get_nShowCmd (void) /* This gets around a problem with using the old threads library on VMS 7.0. */ -#include - extern long get_gmtoff (void); long @@ -653,29 +705,57 @@ get_gmtoff (void) } #endif -/* Definition of __gnat_locatime_r used by a-calend.adb */ +/* 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). */ + +long __gnat_invalid_tzoff = 259273; + +/* Definition of __gnat_localtime_r used by a-calend.adb */ + +#if defined (__EMX__) || defined (__MINGW32__) + +#ifdef CERT + +/* For the Cert run times on native Windows we use dummy functions + for locking and unlocking tasks since we do not support multiple + threads on this configuration (Cert run time on native Windows). */ + +void dummy (void) {} + +void (*Lock_Task) () = &dummy; +void (*Unlock_Task) () = &dummy; + +#else -#if defined (_AIX) || defined (__EMX__) #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); -/* Provide reentrant version of localtime on Aix and OS/2. Note that AiX does - provide localtime_r, but in the library libc_r which doesn't get included - systematically, so we can't use it. */ +#endif + +/* Reentrant localtime for Windows and OS/2. */ -extern struct tm *__gnat_localtime_r (const time_t *, struct tm *); +extern struct tm * +__gnat_localtime_tzoff (const time_t *, struct tm *, long *); struct tm * -__gnat_localtime_r (const time_t *timer, struct tm *tp) +__gnat_localtime_tzoff (const time_t *timer, struct tm *tp, long *off) { + DWORD dwRet; struct tm *tmp; + TIME_ZONE_INFORMATION tzi; (*Lock_Task) (); tmp = localtime (timer); memcpy (tp, tmp, sizeof (struct tm)); + dwRet = GetTimeZoneInformation (&tzi); + *off = tzi.Bias; + if (tp->tm_isdst > 0) + *off = *off + tzi.DaylightBias; + *off = *off * -60; (*Unlock_Task) (); return tp; } @@ -689,31 +769,127 @@ __gnat_localtime_r (const time_t *timer, struct tm *tp) spec is required. Only use when ___THREADS_POSIX4ad4__ is defined, the Lynx convention when building against the legacy API. */ -extern struct tm *__gnat_localtime_r (const time_t *, struct tm *); +extern struct tm * +__gnat_localtime_tzoff (const time_t *, struct tm *, long *); struct tm * -__gnat_localtime_r (const time_t *timer, struct tm *tp) +__gnat_localtime_tzoff (const time_t *timer, struct tm *tp, long *off) { + /* Treat all time values in GMT */ localtime_r (tp, timer); + *off = 0; return NULL; } #else -#if defined (VMS) || defined (__MINGW32__) +#if defined (VMS) -/* __gnat_localtime_r is not needed on NT and VMS */ +/* __gnat_localtime_tzoff is not needed on VMS */ #else /* All other targets provide a standard localtime_r */ -extern struct tm *__gnat_localtime_r (const time_t *, struct tm *); +extern struct tm * +__gnat_localtime_tzoff (const time_t *, struct tm *, long *); struct tm * -__gnat_localtime_r (const time_t *timer, struct tm *tp) +__gnat_localtime_tzoff (const time_t *timer, struct tm *tp, long *off) +{ + localtime_r (timer, tp); + +/* AIX, HPUX, SGI Irix, Sun Solaris */ +#if defined (_AIX) || defined (__hpux__) || defined (sgi) || defined (sun) + /* 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 { - return (struct tm *) 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')) + *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, where there exists a component tm_gmtoff + in struct tm */ +#elif defined (__APPLE__) || defined (__FreeBSD__) || defined (linux) ||\ + (defined (__alpha__) && defined (__osf__)) || defined (__GLIBC__) + *off = tp->tm_gmtoff; + +/* All other platforms: Treat all time values in GMT */ +#else + *off = 0; +#endif + return NULL; } + #endif #endif #endif + +#ifdef __vxworks + +#include + +/* __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