/* time related system calls */ /* Copyright (c) 1992, 1999, 2001 John E. Davis * This file is part of the S-Lang library. * * You may distribute under the terms of either the GNU General Public * License or the Perl Artistic License. */ #include "slinclud.h" #include #include #if defined(__BORLANDC__) # include #endif #if defined(__GO32__) || defined(__WATCOMC__) # include # include #endif #include #include "slang.h" #include "_slang.h" #ifdef __WIN32__ #include /* Sleep is defined badly in MSVC... */ # ifdef _MSC_VER # define sleep(n) _sleep((n)*1000) # else # ifdef sleep # undef sleep # endif # define sleep(x) if(x)Sleep((x)*1000) # endif #endif #if defined(IBMPC_SYSTEM) /* For other system (Unix and VMS), _SLusleep is in sldisply.c */ int _SLusleep (unsigned long s) { sleep (s/1000000L); s = s % 1000000L; # if defined(__WIN32__) Sleep (s/1000); #else # if defined(__IBMC__) DosSleep(s/1000); # else # if defined(_MSC_VER) _sleep (s/1000); # endif # endif #endif return 0; } #endif #if defined(__IBMC__) && !defined(_AIX) /* sleep is not a standard function in VA3. */ unsigned int sleep (unsigned int seconds) { DosSleep(1000L * ((long)seconds)); return 0; } #endif static char *ctime_cmd (unsigned long *tt) { char *t; t = ctime ((time_t *) tt); t[24] = 0; /* knock off \n */ return (t); } static void sleep_cmd (void) { unsigned int secs; #if SLANG_HAS_FLOAT unsigned long usecs; double x; if (-1 == SLang_pop_double (&x, NULL, NULL)) return; if (x < 0.0) x = 0.0; secs = (unsigned int) x; sleep (secs); x -= (double) secs; usecs = (unsigned long) (1e6 * x); if (usecs > 0) _SLusleep (usecs); #else if (-1 == SLang_pop_uinteger (&secs)) return; if (secs != 0) sleep (secs); #endif } static unsigned long _time_cmd (void) { return (unsigned long) time (NULL); } #if defined(__GO32__) static char *djgpp_current_time (void) /*{{{*/ { union REGS rg; unsigned int year; unsigned char month, day, weekday, hour, minute, sec; char days[] = "SunMonTueWedThuFriSat"; char months[] = "JanFebMarAprMayJunJulAugSepOctNovDec"; static char the_date[26]; rg.h.ah = 0x2A; #ifndef __WATCOMC__ int86(0x21, &rg, &rg); year = rg.x.cx & 0xFFFF; #else int386(0x21, &rg, &rg); year = rg.x.ecx & 0xFFFF; #endif month = 3 * (rg.h.dh - 1); day = rg.h.dl; weekday = 3 * rg.h.al; rg.h.ah = 0x2C; #ifndef __WATCOMC__ int86(0x21, &rg, &rg); #else int386(0x21, &rg, &rg); #endif hour = rg.h.ch; minute = rg.h.cl; sec = rg.h.dh; /* we want this form: Thu Apr 14 15:43:39 1994\n */ sprintf(the_date, "%.3s %.3s%3d %02d:%02d:%02d %d\n", days + weekday, months + month, day, hour, minute, sec, year); return the_date; } /*}}}*/ #endif char *SLcurrent_time_string (void) /*{{{*/ { char *the_time; #ifndef __GO32__ time_t myclock; myclock = time((time_t *) 0); the_time = (char *) ctime(&myclock); #else the_time = djgpp_current_time (); #endif /* returns the form Sun Sep 16 01:03:52 1985\n\0 */ the_time[24] = '\0'; return(the_time); } /*}}}*/ static int push_tm_struct (struct tm *tms) { char *field_names [9]; unsigned char field_types[9]; VOID_STAR field_values [9]; int int_values [9]; unsigned int i; if (tms == NULL) return SLang_push_null (); field_names [0] = "tm_sec"; int_values [0] = tms->tm_sec; field_names [1] = "tm_min"; int_values [1] = tms->tm_min; field_names [2] = "tm_hour"; int_values [2] = tms->tm_hour; field_names [3] = "tm_mday"; int_values [3] = tms->tm_mday; field_names [4] = "tm_mon"; int_values [4] = tms->tm_mon; field_names [5] = "tm_year"; int_values [5] = tms->tm_year; field_names [6] = "tm_wday"; int_values [6] = tms->tm_wday; field_names [7] = "tm_yday"; int_values [7] = tms->tm_yday; field_names [8] = "tm_isdst"; int_values [8] = tms->tm_isdst; for (i = 0; i < 9; i++) { field_types [i] = SLANG_INT_TYPE; field_values [i] = (VOID_STAR) (int_values + i); } return SLstruct_create_struct (9, field_names, field_types, field_values); } static void localtime_cmd (long *t) { time_t tt = (time_t) *t; (void) push_tm_struct (localtime (&tt)); } static void gmtime_cmd (long *t) { #ifdef HAVE_GMTIME time_t tt = (time_t) *t; (void) push_tm_struct (gmtime (&tt)); #else localtime_cmd (t); #endif } #ifdef HAVE_TIMES # ifdef HAVE_SYS_TIMES_H # include # endif #include #ifdef CLK_TCK # define SECS_PER_TICK (1.0/(double)CLK_TCK) #else # ifdef CLOCKS_PER_SEC # define SECS_PER_TICK (1.0/(double)CLOCKS_PER_SEC) # else # define SECS_PER_TICK (1.0/60.0) # endif #endif static void times_cmd (void) { double dvals[4]; struct tms t; VOID_STAR field_values[4]; char *field_names[4]; unsigned int i; unsigned char field_types[4]; (void) times (&t); field_names[0] = "tms_utime"; dvals[0] = (double)t.tms_utime; field_names[1] = "tms_stime"; dvals[1] = (double)t.tms_stime; field_names[2] = "tms_cutime"; dvals[2] = (double)t.tms_cutime; field_names[3] = "tms_cstime"; dvals[3] = (double)t.tms_cstime; for (i = 0; i < 4; i++) { dvals[i] *= SECS_PER_TICK; field_values[i] = (VOID_STAR) &dvals[i]; field_types[i] = SLANG_DOUBLE_TYPE; } (void) SLstruct_create_struct (4, field_names, field_types, field_values); } static struct tms Tic_TMS; static void tic_cmd (void) { (void) times (&Tic_TMS); } static double toc_cmd (void) { struct tms t; double d; (void) times (&t); d = ((t.tms_utime - Tic_TMS.tms_utime) + (t.tms_stime - Tic_TMS.tms_stime)) * SECS_PER_TICK; Tic_TMS = t; return d; } #endif /* HAVE_TIMES */ static SLang_Intrin_Fun_Type Time_Funs_Table [] = { MAKE_INTRINSIC_1("ctime", ctime_cmd, SLANG_STRING_TYPE, SLANG_ULONG_TYPE), MAKE_INTRINSIC_0("sleep", sleep_cmd, SLANG_VOID_TYPE), MAKE_INTRINSIC_0("_time", _time_cmd, SLANG_ULONG_TYPE), MAKE_INTRINSIC_0("time", SLcurrent_time_string, SLANG_STRING_TYPE), MAKE_INTRINSIC_1("localtime", localtime_cmd, SLANG_VOID_TYPE, SLANG_LONG_TYPE), MAKE_INTRINSIC_1("gmtime", gmtime_cmd, SLANG_VOID_TYPE, SLANG_LONG_TYPE), #ifdef HAVE_TIMES MAKE_INTRINSIC_0("times", times_cmd, SLANG_VOID_TYPE), MAKE_INTRINSIC_0("tic", tic_cmd, SLANG_VOID_TYPE), MAKE_INTRINSIC_0("toc", toc_cmd, SLANG_DOUBLE_TYPE), #endif SLANG_END_INTRIN_FUN_TABLE }; int _SLang_init_sltime (void) { #ifdef HAVE_TIMES (void) tic_cmd (); #endif return SLadd_intrin_fun_table (Time_Funs_Table, NULL); }