--- /dev/null
+%
+% (c) The GRASP/AQUA Project, Glasgow University, 1995
+%
+\subsection[getClockTime.lc]{getClockTime Runtime Support}
+
+\begin{code}
+
+#define NON_POSIX_SOURCE /* gettimeofday */
+
+#include "rtsdefs.h"
+#include "stgio.h"
+
+#ifdef HAVE_GETCLOCK
+
+# ifdef HAVE_SYS_TIMERS_H
+# define POSIX_4D9 1
+# include <sys/timers.h>
+# endif
+
+#else
+# ifdef HAVE_GETTIMEOFDAY
+
+# ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+# endif
+
+# else
+
+# ifdef HAVE_TIME_H
+# include <time.h>
+# endif
+
+# endif
+#endif
+
+StgInt
+getClockTime(StgByteArray sec, StgByteArray nsec)
+{
+#ifdef 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;
+#else
+#ifdef 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;
+#else
+ 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;
+#endif
+#endif
+}
+\end{code}
--- /dev/null
+%
+% (c) The GRASP/AQUA Project, Glasgow University, 1995
+%
+\subsection[showTime.lc]{ClockTime.showsPrec Runtime Support}
+
+\begin{code}
+
+#include "rtsdefs.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
+
+StgAddr
+showTime(I_ size, StgByteArray d, StgByteArray buf)
+{
+ time_t t;
+ struct tm *tm;
+
+ switch(size) {
+ default:
+ return (StgAddr)strcpy(buf, "ClockTime.show{LibTime}: out of range");
+ case 0:
+ t = 0;
+ break;
+ case -1:
+ t = - (time_t) ((StgInt *)d)[0];
+ if (t > 0)
+ return
+ (StgAddr)strcpy(buf, "ClockTime.show{LibTime}: out of range");
+ break;
+ case 1:
+ t = (time_t) ((StgInt *)d)[0];
+ if (t < 0)
+ return (StgAddr) strcpy(buf, "ClockTime.show{LibTime}: out of range");
+ break;
+ }
+ tm = localtime(&t);
+ if (tm != NULL && strftime(buf, 32 /*Magic number*/, "%a %b %d %T %Z %Y", tm) > 0)
+ return (StgAddr)buf;
+ return (StgAddr)strcpy(buf, "ClockTime.show{LibTime}: internal error");
+}
+\end{code}
--- /dev/null
+%
+% (c) The GRASP/AQUA Project, Glasgow University, 1995
+%
+\subsection[toClockSec.lc]{toClockSec Runtime Support}
+
+\begin{code}
+
+#include "rtsdefs.h"
+#include "timezone.h"
+#include "stgio.h"
+
+StgAddr
+toClockSec(I_ year, I_ mon, I_ mday, I_ hour, I_ min, I_ sec, I_ tz, 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 = -1;
+
+#ifdef HAVE_MKTIME
+ t = mktime(&tm);
+#else
+#ifdef HAVE_TIMELOCAL
+ t = timelocal(&tm);
+#else
+ t = (time_t) -1;
+#endif
+#endif
+ if (t == (time_t) -1)
+ return NULL;
+
+ *(time_t *)res = t;
+ return res;
+}
+\end{code}
--- /dev/null
+%
+% (c) The GRASP/AQUA Project, Glasgow University, 1995
+%
+\subsection[toLocalTime.lc]{toCalendarTime Runtime Support}
+
+\begin{code}
+
+#include "rtsdefs.h"
+#include "timezone.h"
+#include "stgio.h"
+
+StgAddr
+toLocalTime(I_ size, StgByteArray d, StgByteArray res)
+{
+ struct tm *tm,*tmp=(struct tm *)res;
+ time_t t;
+
+ switch(size) {
+ default:
+ return NULL;
+ case 0:
+ t = 0;
+ break;
+ case -1:
+ t = - (time_t) ((StgInt *)d)[0];
+ if (t > 0)
+ return NULL;
+ break;
+ case 1:
+ t = (time_t) ((StgInt *)d)[0];
+ if (t < 0)
+ return NULL;
+ break;
+ }
+ tm = localtime(&t);
+
+ if (tm == NULL)
+ return NULL;
+
+ /*
+ 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 (StgAddr)res;
+}
+\end{code}
--- /dev/null
+%
+% (c) The GRASP/AQUA Project, Glasgow University, 1995
+%
+\subsection[toUTCTime.lc]{toUTCTime Runtime Support}
+
+\begin{code}
+
+#include "rtsdefs.h"
+#include "timezone.h"
+#include "stgio.h"
+
+StgAddr
+toUTCTime(I_ size, StgByteArray d, StgByteArray res)
+{
+ time_t t;
+ struct tm *tm,*tmp=(struct tm *)res;
+
+ switch(size) {
+ default:
+ return NULL;
+ case 0:
+ t = 0;
+ break;
+ case -1:
+ t = - (time_t) ((StgInt *)d)[0];
+ if (t > 0)
+ return NULL;
+ break;
+ case 1:
+ t = (time_t) ((StgInt *)d)[0];
+ if (t < 0)
+ return NULL;
+ break;
+ }
+ tm = gmtime(&t);
+
+ if (tm == NULL)
+ return NULL;
+
+ /*
+ 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 (StgAddr)res;
+}
+\end{code}