Commit ef487d06 authored by simonmar's avatar simonmar
Browse files

[project @ 2001-01-12 16:16:36 by simonmar]

Time library FFI'd.
parent 787e7d83
/*
* (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
*
* $Id: getClockTime.c,v 1.8 1999/10/26 09:34:09 sof Exp $
*
* getClockTime Runtime Support
*/
#ifndef _AIX
#define NON_POSIX_SOURCE /* gettimeofday */
#endif
#include "Rts.h"
#include "stgio.h"
/* Note: skewing this code in favour of non-POSIX calls
such as gettimeofday() and getclock() rather than time(),
may seem strange/wrong. There's a good reason for it
though - the non-POSIX calls gives you better precision --
they return usecs (or nsecs) as well as seconds, which
the users of getClockTime() is interested in knowing.
*/
#if defined(HAVE_GETTIMEOFDAY)
# ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
# endif
#elif defined(HAVE_GETCLOCK)
# ifdef HAVE_SYS_TIMERS_H
# define POSIX_4D9 1
# include <sys/timers.h>
# endif
#elif defined(HAVE_TIME_H)
# include <time.h>
#endif
#ifdef HAVE_WINDOWS_H
#include <windows.h>
#include <sys/types.h>
#include <sys/timeb.h>
#endif
StgInt
getClockTime(StgByteArray sec, StgByteArray nsec)
{
#if defined(_WIN32) && !defined(cygwin32_TARGET_OS)
/*
* ftime() as implemented by cygwin (in B20.1) is
* not right, so stay away & use time() there instead.
*/
struct timeb t;
_ftime(&t);
((unsigned int *)sec)[0] = (unsigned int)t.time;
((unsigned int *)nsec)[0] = (unsigned int)t.millitm * 1000;
return 0;
#elif defined(HAVE_GETTIMEOFDAY)
struct timeval tp;
if (gettimeofday(&tp, NULL) != 0) {
cvtErrno();
stdErrno();
return -1;
}
((unsigned long int *)sec)[0] = tp.tv_sec;
((unsigned long int *)nsec)[0] = tp.tv_usec * 1000;
return 0;
#elif defined(HAVE_GETCLOCK)
struct timespec tp;
if (getclock(TIMEOFDAY, &tp) != 0) {
cvtErrno();
stdErrno();
return -1;
}
((unsigned long int *)sec)[0] = tp.tv_sec;
((unsigned long int *)nsec)[0] = tp.tv_nsec;
return 0;
#elif defined(HAVE_TIME_H)
time_t t;
if ((t = time(NULL)) == (time_t) -1) {
cvtErrno();
stdErrno();
return -1;
}
((unsigned long int *)sec)[0] = t;
((unsigned long int *)nsec)[0] = 0;
return 0;
#else
#error "getClockTime: don't know how to get at the clock's time"
#endif
}
/*
* (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
*
* $Id: showTime.c,v 1.8 2000/04/06 17:54:01 rrt Exp $
*
* ClockTime.showsPrec Runtime Support
*/
#include "Rts.h"
#include "stgio.h"
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
StgInt
showTime(I_ size, StgByteArray d, I_ maxsize, StgByteArray buf)
{
time_t t;
struct tm *tm;
/*
* I allege that with the current (9/99) contents of Time.lhs,
* size will always be >= 0. -- sof
*/
switch(size) {
case 0:
t = 0;
break;
case 1:
t = (time_t) ((StgInt *)d)[0];
break;
default:
return (-1);
}
tm = localtime(&t);
#ifdef cygwin32_TARGET_OS
/* Same as in timezone.c: tzset() isn't called automatically */
tzset();
#endif
if (tm != NULL && strftime(buf, maxsize, "%a %b %d %H:%M:%S %Z %Y", tm) > 0) {
return 1;
} else {
return (-1);
}
}
/*
* (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
*
* $Id: timezone.c,v 1.6 1999/12/08 15:47:08 simonmar Exp $
*
* Timezone Runtime Support
*/
#include "Rts.h"
#include "stgio.h"
#include "timezone.h"
StgInt get_tm_sec ( StgAddr x ) { return ((struct tm*)x)->tm_sec; }
StgInt get_tm_min ( StgAddr x ) { return ((struct tm*)x)->tm_min; }
StgInt get_tm_hour ( StgAddr x ) { return ((struct tm*)x)->tm_hour; }
StgInt get_tm_mday ( StgAddr x ) { return ((struct tm*)x)->tm_mday; }
StgInt get_tm_mon ( StgAddr x ) { return ((struct tm*)x)->tm_mon; }
StgInt get_tm_year ( StgAddr x ) { return ((struct tm*)x)->tm_year; }
StgInt get_tm_wday ( StgAddr x ) { return ((struct tm*)x)->tm_wday; }
StgInt get_tm_yday ( StgAddr x ) { return ((struct tm*)x)->tm_yday; }
StgInt get_tm_isdst ( StgAddr x ) { return ((struct tm*)x)->tm_isdst; }
StgAddr prim_ZONE ( StgAddr x ) { return ZONE(x); }
StgInt prim_GMTOFF ( StgAddr x ) { return GMTOFF(x); }
void
prim_SETZONE ( StgAddr x, StgAddr y )
{
SETZONE(x,y);
}
StgInt sizeof_word ( void ) { return (sizeof(unsigned int)); }
StgInt sizeof_struct_tm ( void ) { return (sizeof(struct tm)); }
StgInt sizeof_time_t ( void ) { return (sizeof(time_t) / sizeof(int)); }
char*
get_ZONE (StgAddr x)
{
#ifdef cygwin32_TARGET_OS
/*
* tzname[] isn't properly initialised under cygwin B20.1
* unless tzset() is called, so better do it here.
*/
tzset();
#endif
return (ZONE(x));
}
/*
* (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
*
* $Id: timezone.h,v 1.10 2000/07/17 15:27:15 rrt Exp $
*
* Time-zone support header
*/
#ifndef TIMEZONE_H
#define TIMEZONE_H
#define _OSF_SOURCE
#if HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#if linux_TARGET_OS
/* Sigh, RedHat 5 has the TM_ZONE stuff, but only when _BSD_SOURCE is
* on. The configure script erroneously says we've got TM_ZONE, so
* make sure we use the TZNAME stuff instead.
*
* Aside: tzname is POSIX, whereas tm_zone is BSD. We should be using
* tzname by preference, but the GNU configure stuff gives us HAVE_TM_ZONE
* in preference to HAVE_TZNAME. More sighs.
*/
# undef HAVE_TM_ZONE
# define HAVE_TZNAME 1
/* Double sigh. The timezone variable is only available under Linux
* when we're compiling NON_POSIX_SOURCE (or _GNU_SOURCE or whatever),
* but to make that work we have to make sure NON_POSIX_SOURCE is
* defined before anything from /usr/include is included. To avoid
* infecting too much source with NON_POSIX_SOURCE, we frob it
* below...
*/
#undef HAVE_TIMEZONE
/* The correct solution to this problem would appear to be to ditch
* the standard GNU configure tests for the time stuff, and hack up
* our own that test for POSIX-compliant time support first, then
* BSD-style time stuff.
*/
#endif
#ifdef solaris2_TARGET_OS
#undef HAVE_TIMEZONE
#endif
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
#if HAVE_TM_ZONE
#define ZONE(x) (((struct tm *)x)->tm_zone)
#define SETZONE(x,z) (((struct tm *)x)->tm_zone = z)
#define GMTOFF(x) (((struct tm *)x)->tm_gmtoff)
#else /* ! HAVE_TM_ZONE */
# if HAVE_TZNAME || _WIN32
# if cygwin32_TARGET_OS
# define tzname _tzname
# endif
# ifndef mingw32_TARGET_OS
extern char *tzname[2];
# endif
# define ZONE(x) (((struct tm *)x)->tm_isdst ? tzname[1] : tzname[0])
# define SETZONE(x,z)
# else /* ! HAVE_TZNAME */
/* We're in trouble. If you should end up here, please report this as a bug. */
# error Dont know how to get at timezone name on your OS.
# endif /* ! HAVE_TZNAME */
/* Get the offset in secs from UTC, if (struct tm) doesn't supply it. */
#if defined(mingw32_TARGET_OS) || defined(cygwin32_TARGET_OS)
#define timezone _timezone
#endif
#if !defined(HAVE_TIMEZONE) && !defined(mingw32_TARGET_OS)
extern TYPE_TIMEZONE timezone;
#endif
# if HAVE_ALTZONE
extern time_t altzone;
# define GMTOFF(x) (((struct tm *)x)->tm_isdst ? altzone : timezone )
# else /* ! HAVE_ALTZONE */
/* Assume that DST offset is 1 hour ... */
# define GMTOFF(x) (((struct tm *)x)->tm_isdst ? (timezone - 3600) : timezone )
# endif /* ! HAVE_ALTZONE */
#endif /* ! HAVE_TM_ZONE */
#endif /* TIMEZONE_H */
/*
* (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
*
* $Id: toClockSec.c,v 1.6 2000/06/19 13:28:35 simonmar Exp $
*
* toClockSec Runtime Support
*/
#include "Rts.h"
#include "stgio.h"
#include "timezone.h"
StgInt
toClockSec(I_ year, I_ mon, I_ mday, I_ hour, I_ min, I_ sec, I_ tz, I_ isdst, StgByteArray res)
{
struct tm tm;
time_t t;
tm.tm_year = year - 1900;
tm.tm_mon = mon;
tm.tm_mday = mday;
tm.tm_hour = hour;
tm.tm_min = min;
tm.tm_sec = sec;
tm.tm_isdst = isdst;
#ifdef HAVE_MKTIME
t = mktime(&tm);
#elif defined(HAVE_TIMELOCAL)
t = timelocal(&tm);
#else
t = (time_t) -1;
#endif
if (t == (time_t) -1)
return 0;
/*
* mktime expects its argument to be in the local timezone, but
* toUTCTime makes UTC-encoded CalendarTime's ...
*
* Since there is no any_tz_struct_tm-to-time_t conversion
* function, we have to fake one... :-) If not in all, it works in
* most cases (before, it was the other way round...)
*
* Luckily, mktime tells us, what it *thinks* the timezone is, so,
* to compensate, we add the timezone difference to mktime's
* result.
*/
*(time_t *)res = t + tz - GMTOFF(&tm);
return 1;
}
/*
* (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
*
* $Id: toLocalTime.c,v 1.5 2000/05/28 17:47:27 panne Exp $
*
* toCalendarTime Runtime Support
*/
#include "Rts.h"
#include "stgio.h"
#include "timezone.h"
StgInt
toLocalTime(I_ size, StgByteArray d, StgByteArray res)
{
time_t t;
struct tm *tm,*tmp=(struct tm *)res;
switch(size) {
default:
return 0;
case 0:
t = 0;
break;
case -1:
t = - (time_t) ((StgInt *)d)[0];
if (t > 0)
return 0;
break;
case 1:
t = (time_t) ((StgInt *)d)[0];
if (t < 0)
return 0;
break;
}
tm = localtime(&t);
if (tm == NULL)
return 0;
/*
localtime() may return a ptr to statically allocated storage,
so to make toLocalTime reentrant, we manually copy
the structure into the (struct tm *) passed in.
*/
tmp->tm_sec = tm->tm_sec;
tmp->tm_min = tm->tm_min;
tmp->tm_hour = tm->tm_hour;
tmp->tm_mday = tm->tm_mday;
tmp->tm_mon = tm->tm_mon;
tmp->tm_year = tm->tm_year;
tmp->tm_wday = tm->tm_wday;
tmp->tm_yday = tm->tm_yday;
tmp->tm_isdst = tm->tm_isdst;
/*
If you don't have tm_zone in (struct tm), but
you get at it via the shared tmzone[], you'll
lose. Same goes for the tm_gmtoff field.
*/
#if HAVE_TM_ZONE
strcpy(tmp->tm_zone,tm->tm_zone);
tmp->tm_gmtoff = tm->tm_gmtoff;
#endif
return 1;
}
StgInt
prim_toLocalTime(StgInt64 d, StgByteArray res)
{
time_t t;
struct tm *tm,*tmp=(struct tm *)res;
t = (time_t) d;
if (t < 0)
return 0;
tm = localtime(&t);
if (tm == NULL)
return 0;
/*
localtime() may return a ptr to statically allocated storage,
so to make toLocalTime reentrant, we manually copy
the structure into the (struct tm *) passed in.
*/
tmp->tm_sec = tm->tm_sec;
tmp->tm_min = tm->tm_min;
tmp->tm_hour = tm->tm_hour;
tmp->tm_mday = tm->tm_mday;
tmp->tm_mon = tm->tm_mon;
tmp->tm_year = tm->tm_year;
tmp->tm_wday = tm->tm_wday;
tmp->tm_yday = tm->tm_yday;
tmp->tm_isdst = tm->tm_isdst;
/*
If you don't have tm_zone in (struct tm), but
you get at it via the shared tmzone[], you'll
lose. Same goes for the tm_gmtoff field.
*/
#if HAVE_TM_ZONE
strcpy(tmp->tm_zone,tm->tm_zone);
tmp->tm_gmtoff = tm->tm_gmtoff;
#endif
return 1;
}
/*
* (c) The GRASP/AQUA Project, Glasgow University, 1994-1998
*
* $Id: toUTCTime.c,v 1.5 2000/05/28 17:47:27 panne Exp $
*
* toUTCTime Runtime Support
*/
#include "Rts.h"
#include "stgio.h"
#include "timezone.h"
StgInt
toUTCTime(I_ size, StgByteArray d, StgByteArray res)
{
time_t t;
struct tm *tm,*tmp=(struct tm *)res;
switch(size) {
default:
return 0;
case 0:
t = 0;
break;
case -1:
t = - (time_t) ((StgInt *)d)[0];
if (t > 0)
return 0;
break;
case 1:
t = (time_t) ((StgInt *)d)[0];
if (t < 0)
return 0;
break;
}
tm = gmtime(&t);
if (tm == NULL)
return 0;
/*
gmtime() may return a ptr to statically allocated storage,
so to make toUTCTime reentrant, we manually copy
the structure into the (struct tm *) passed in.
*/
tmp->tm_sec = tm->tm_sec;
tmp->tm_min = tm->tm_min;
tmp->tm_hour = tm->tm_hour;
tmp->tm_mday = tm->tm_mday;
tmp->tm_mon = tm->tm_mon;
tmp->tm_year = tm->tm_year;
tmp->tm_wday = tm->tm_wday;
tmp->tm_yday = tm->tm_yday;
tmp->tm_isdst = tm->tm_isdst;
/*
If you don't have tm_zone in (struct tm), but
you get at it via the shared tmzone[], you'll
lose. Same goes for the tm_gmtoff field.
*/
#if HAVE_TM_ZONE
strcpy(tmp->tm_zone,tm->tm_zone);
tmp->tm_gmtoff = tm->tm_gmtoff;
#endif
return 1;
}
StgInt
prim_toUTCTime(StgInt64 d, StgByteArray res)
{
time_t t;
struct tm *tm,*tmp=(struct tm *)res;
t = (time_t) d;
if (t < 0)
return 0;
tm = gmtime(&t);
if (tm == NULL)
return 0;
/*
gmtime() may return a ptr to statically allocated storage,
so to make toUTCTime reentrant, we manually copy
the structure into the (struct tm *) passed in.
*/
tmp->tm_sec = tm->tm_sec;
tmp->tm_min = tm->tm_min;
tmp->tm_hour = tm->tm_hour;
tmp->tm_mday = tm->tm_mday;
tmp->tm_mon = tm->tm_mon;
tmp->tm_year = tm->tm_year;
tmp->tm_wday = tm->tm_wday;
tmp->tm_yday = tm->tm_yday;
tmp->tm_isdst = tm->tm_isdst;
/*
If you don't have tm_zone in (struct tm), but
you get at it via the shared tmzone[], you'll
lose. Same goes for the tm_gmtoff field.
*/
#if HAVE_TM_ZONE
strcpy(tmp->tm_zone,tm->tm_zone);
tmp->tm_gmtoff = tm->tm_gmtoff;
#endif
return 1;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment