176 lines
5.1 KiB
C
176 lines
5.1 KiB
C
/* time.c
|
|
*
|
|
* $Id$
|
|
*
|
|
* Copyright 1990, 1991, 1992, 1993, 1994, 1995, Oliver Laumann, Berlin
|
|
* Copyright 2002, 2003 Sam Hocevar <sam@hocevar.net>, Paris
|
|
*
|
|
* This software was derived from Elk 1.2, which was Copyright 1987, 1988,
|
|
* 1989, Nixdorf Computer AG and TELES GmbH, Berlin (Elk 1.2 has been written
|
|
* by Oliver Laumann for TELES Telematic Services, Berlin, in a joint project
|
|
* between TELES and Nixdorf Microprocessor Engineering, Berlin).
|
|
*
|
|
* Oliver Laumann, TELES GmbH, Nixdorf Computer AG and Sam Hocevar, as co-
|
|
* owners or individual owners of copyright in this software, grant to any
|
|
* person or company a worldwide, royalty free, license to
|
|
*
|
|
* i) copy this software,
|
|
* ii) prepare derivative works based on this software,
|
|
* iii) distribute copies of this software or derivative works,
|
|
* iv) perform this software, or
|
|
* v) display this software,
|
|
*
|
|
* provided that this notice is not removed and that neither Oliver Laumann
|
|
* nor Teles nor Nixdorf are deemed to have made any representations as to
|
|
* the suitability of this software for any purpose nor are held responsible
|
|
* for any defects of this software.
|
|
*
|
|
* THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE.
|
|
*/
|
|
|
|
#include "unix.h"
|
|
|
|
#include <string.h>
|
|
|
|
#if !defined(HAVE_GETTIMEOFDAY) && defined(HAVE_FTIME)
|
|
# include <sys/timeb.h>
|
|
#endif
|
|
|
|
#ifdef HAVE_GETTIMEOFDAY
|
|
# include <sys/time.h>
|
|
#endif
|
|
|
|
extern time_t time();
|
|
|
|
static Object P_Decode_Time(Object t, Object ret, Object utc) {
|
|
time_t tt;
|
|
struct tm *tp;
|
|
Object *op;
|
|
|
|
Check_Result_Vector(ret, 9);
|
|
Check_Type(utc, T_Boolean);
|
|
tt = (time_t)Get_Unsigned_Long(t);
|
|
tp = Truep(utc) ? gmtime(&tt) : localtime(&tt);
|
|
op = VECTOR(ret)->data;
|
|
*op++ = Make_Integer(tp->tm_sec);
|
|
*op++ = Make_Integer(tp->tm_min);
|
|
*op++ = Make_Integer(tp->tm_hour);
|
|
*op++ = Make_Integer(tp->tm_mday);
|
|
*op++ = Make_Integer(tp->tm_mon);
|
|
*op++ = Make_Integer(tp->tm_year);
|
|
*op++ = Make_Integer(tp->tm_wday);
|
|
*op++ = Make_Integer(tp->tm_yday);
|
|
*op++ = Make_Integer(tp->tm_isdst);
|
|
return Void;
|
|
}
|
|
|
|
static Object P_Nanotime(Object ret) {
|
|
Object x, y;
|
|
#ifdef HAVE_GETTIMEOFDAY
|
|
struct timeval tv;
|
|
struct timezone tz;
|
|
#else
|
|
#ifdef HAVE_FTIME
|
|
struct timeb tb;
|
|
#else
|
|
time_t now;
|
|
int i;
|
|
#endif
|
|
#endif
|
|
GC_Node2;
|
|
|
|
x = Null;
|
|
Check_Result_Vector(ret, 3);
|
|
GC_Link2(ret, x);
|
|
#ifdef HAVE_GETTIMEOFDAY
|
|
(void)gettimeofday(&tv, &tz);
|
|
x = Cons(Null, Make_Unsigned_Long((unsigned long)tv.tv_usec * 1000));
|
|
y = Make_Unsigned_Long((unsigned long)tv.tv_sec);
|
|
Car(x) = y;
|
|
VECTOR(ret)->data[0] = x;
|
|
VECTOR(ret)->data[1] = Make_Integer(tz.tz_minuteswest);
|
|
VECTOR(ret)->data[2] = Make_Integer(tz.tz_dsttime);
|
|
#else
|
|
#ifdef HAVE_FTIME
|
|
(void)ftime(&tb);
|
|
x = Cons(Null, Make_Unsigned_Long((unsigned long)tb.millitm * 1000000));
|
|
y = Make_Unsigned_Long((unsigned long)tb.time);
|
|
Car(x) = y;
|
|
VECTOR(ret)->data[0] = x;
|
|
VECTOR(ret)->data[1] = Make_Integer(tb.timezone);
|
|
VECTOR(ret)->data[2] = Make_Integer(tb.dstflag);
|
|
#else
|
|
(void)time(&now);
|
|
x = Cons(Make_Unsigned_Long((unsigned long)now), Make_Integer(0));
|
|
VECTOR(ret)->data[0] = x;
|
|
VECTOR(ret)->data[1] = Make_Integer(0);
|
|
VECTOR(ret)->data[2] = Make_Integer(0);
|
|
#endif
|
|
#endif
|
|
GC_Unlink;
|
|
return Void;
|
|
}
|
|
|
|
static Object P_Time() {
|
|
time_t t = time((time_t *)0);
|
|
return Make_Unsigned_Long((unsigned long)t);
|
|
}
|
|
|
|
static struct tm *Get_Tm(Object v) {
|
|
static struct tm tm;
|
|
int i, n;
|
|
Object *op;
|
|
static struct { int min, max; } bounds[] = {
|
|
{ 0, 61 }, /* sec */
|
|
{ 0, 59 }, /* min */
|
|
{ 0, 23 }, /* hour */
|
|
{ 1, 31 }, /* mday */
|
|
{ 0, 11 }, /* mon */
|
|
{ 0, 65535 }, /* year */
|
|
{ 0, 7 }, /* wday */
|
|
{ 0, 365 } /* yday */
|
|
};
|
|
|
|
Check_Result_Vector(v, 9);
|
|
for (op = VECTOR(v)->data, i = 0; i < 7; i++, op++)
|
|
if ((n = Get_Integer(*op)) < bounds[i].min || n > bounds[i].max)
|
|
Range_Error(*op);
|
|
op = VECTOR(v)->data;
|
|
tm.tm_sec = Get_Integer(*op++);
|
|
tm.tm_min = Get_Integer(*op++);
|
|
tm.tm_hour = Get_Integer(*op++);
|
|
tm.tm_mday = Get_Integer(*op++);
|
|
tm.tm_mon = Get_Integer(*op++);
|
|
tm.tm_year = Get_Integer(*op++);
|
|
tm.tm_wday = Get_Integer(*op++);
|
|
tm.tm_yday = Get_Integer(*op++);
|
|
tm.tm_isdst = Get_Integer(*op);
|
|
return &tm;
|
|
}
|
|
|
|
static Object P_Time_To_String(Object t) {
|
|
time_t tt;
|
|
char *ret;
|
|
|
|
switch (TYPE(t)) {
|
|
case T_Fixnum: case T_Bignum:
|
|
tt = (time_t)Get_Unsigned_Long(t);
|
|
ret = ctime(&tt);
|
|
break;
|
|
case T_Vector:
|
|
ret = asctime(Get_Tm(t));
|
|
break;
|
|
default:
|
|
Wrong_Type_Combination(t, "integer or vector");
|
|
/*NOTREACHED*/
|
|
}
|
|
return Make_String(ret, strlen(ret));
|
|
}
|
|
|
|
void elk_init_unix_time() {
|
|
Def_Prim(P_Time, "unix-time", 0, 0, EVAL);
|
|
Def_Prim(P_Decode_Time, "unix-decode-time-vector-fill!", 3, 3, EVAL);
|
|
Def_Prim(P_Time_To_String, "unix-time->string-internal", 1, 1, EVAL);
|
|
Def_Prim(P_Nanotime, "unix-nanotime-vector-fill!", 1, 1, EVAL);
|
|
}
|