diff options
Diffstat (limited to 'unix/tclUnixTime.c')
| -rw-r--r-- | unix/tclUnixTime.c | 355 | 
1 files changed, 87 insertions, 268 deletions
| diff --git a/unix/tclUnixTime.c b/unix/tclUnixTime.c index b98f2e1..707dfbc 100644 --- a/unix/tclUnixTime.c +++ b/unix/tclUnixTime.c @@ -11,11 +11,8 @@   */  #include "tclInt.h" +#include "tclPort.h"  #include <locale.h> -#if defined(TCL_WIDE_CLICKS) && defined(MAC_OSX_TCL) -#include <mach/mach_time.h> -#endif -  #define TM_YEAR_BASE 1900  #define IsLeapYear(x)	(((x)%4 == 0) && ((x)%100 != 0 || (x)%400 == 0)) @@ -46,20 +43,8 @@ static char *lastTZ = NULL;	/* Holds the last setting of the TZ   * Static functions declared in this file.   */ -static void		SetTZIfNecessary(void); -static void		CleanupMemory(ClientData clientData); -static void		NativeScaleTime(Tcl_Time *timebuf, -			    ClientData clientData); -static void		NativeGetTime(Tcl_Time *timebuf, -			    ClientData clientData); - -/* - * TIP #233 (Virtualized Time): Data for the time hooks, if any. - */ - -Tcl_GetTimeProc *tclGetTimeProcPtr = NativeGetTime; -Tcl_ScaleTimeProc *tclScaleTimeProcPtr = NativeScaleTime; -ClientData tclTimeClientData = NULL; +static void SetTZIfNecessary _ANSI_ARGS_((void)); +static void CleanupMemory _ANSI_ARGS_((ClientData));  /*   *---------------------------------------------------------------------- @@ -79,9 +64,9 @@ ClientData tclTimeClientData = NULL;   */  unsigned long -TclpGetSeconds(void) +TclpGetSeconds()  { -    return time(NULL); +    return time((time_t *) NULL);  }  /* @@ -104,124 +89,27 @@ TclpGetSeconds(void)   */  unsigned long -TclpGetClicks(void) +TclpGetClicks()  {      unsigned long now;  #ifdef NO_GETTOD -    if (tclGetTimeProcPtr != NativeGetTime) { -	Tcl_Time time; - -	(*tclGetTimeProcPtr) (&time, tclTimeClientData); -	now = time.sec*1000000 + time.usec; -    } else { -	/* -	 * A semi-NativeGetTime, specialized to clicks. -	 */ -	struct tms dummy; - -	now = (unsigned long) times(&dummy); -    } +    struct tms dummy;  #else -    Tcl_Time time; - -    (*tclGetTimeProcPtr) (&time, tclTimeClientData); -    now = time.sec*1000000 + time.usec; +    struct timeval date;  #endif -    return now; -} -#ifdef TCL_WIDE_CLICKS - -/* - *----------------------------------------------------------------------------- - * - * TclpGetWideClicks -- - * - *	This procedure returns a WideInt value that represents the highest - *	resolution clock available on the system. There are no garantees on - *	what the resolution will be. In Tcl we will call this value a "click". - *	The start time is also system dependant. - * - * Results: - *	Number of WideInt clicks from some start time. - * - * Side effects: - *	None. - * - *----------------------------------------------------------------------------- - */ - -Tcl_WideInt -TclpGetWideClicks(void) -{ -    Tcl_WideInt now; - -    if (tclGetTimeProcPtr != NativeGetTime) { -	Tcl_Time time; - -	(*tclGetTimeProcPtr) (&time, tclTimeClientData); -	now = (Tcl_WideInt) (time.sec*1000000 + time.usec); -    } else { -#ifdef MAC_OSX_TCL -	now = (Tcl_WideInt) (mach_absolute_time() & INT64_MAX); +#ifdef NO_GETTOD +    now = (unsigned long) times(&dummy);  #else -#error Wide high-resolution clicks not implemented on this platform +    gettimeofday(&date, NULL); +    now = date.tv_sec*1000000 + date.tv_usec;  #endif -    }      return now;  }  /* - *----------------------------------------------------------------------------- - * - * TclpWideClicksToNanoseconds -- - * - *	This procedure converts click values from the TclpGetWideClicks native - *	resolution to nanosecond resolution. - * - * Results: - *	Number of nanoseconds from some start time. - * - * Side effects: - *	None. - * - *----------------------------------------------------------------------------- - */ - -double -TclpWideClicksToNanoseconds( -    Tcl_WideInt clicks) -{ -    double nsec; - -    if (tclGetTimeProcPtr != NativeGetTime) { -	nsec = clicks * 1000; -    } else { -#ifdef MAC_OSX_TCL -	static mach_timebase_info_data_t tb; -	static uint64_t maxClicksForUInt64; -	 -	if (!tb.denom) { -	    mach_timebase_info(&tb); -	    maxClicksForUInt64 = UINT64_MAX / tb.numer; -	} -	if ((uint64_t) clicks < maxClicksForUInt64) { -	    nsec = ((uint64_t) clicks) * tb.numer / tb.denom; -	} else { -	    nsec = ((long double) (uint64_t) clicks) * tb.numer / tb.denom; -	} -#else -#error Wide high-resolution clicks not implemented on this platform -#endif -    } - -    return nsec; -} -#endif /* TCL_WIDE_CLICKS */ - -/*   *----------------------------------------------------------------------   *   * TclpGetTimeZone -- @@ -240,8 +128,8 @@ TclpWideClicksToNanoseconds(   */  int -TclpGetTimeZone( -    unsigned long currentTime) +TclpGetTimeZone(currentTime) +    Tcl_WideInt currentTime;  {      int timeZone; @@ -261,7 +149,7 @@ TclpGetTimeZone(       */      time_t curTime = (time_t) currentTime; -    struct tm *timeDataPtr = TclpLocaltime(&curTime); +    struct tm *timeDataPtr = TclpLocaltime((TclpTime_t) &curTime);      timeZone = timeDataPtr->tm_tzadj / 60;      if (timeDataPtr->tm_isdst) { @@ -276,7 +164,7 @@ TclpGetTimeZone(       */      time_t curTime = (time_t) currentTime; -    struct tm *timeDataPtr = TclpLocaltime(&curTime); +    struct tm *timeDataPtr = TclpLocaltime((TclpTime_t) &curTime);      timeZone = -(timeDataPtr->tm_gmtoff / 60);      if (timeDataPtr->tm_isdst) { @@ -310,7 +198,7 @@ TclpGetTimeZone(      struct tm *stm;      tt = 849268800L;		/* 1996-11-29 12:00:00  GMT */ -    stm = TclpLocaltime(&tt);	/* eg 1996-11-29  6:00:00  CST6CDT */ +    stm = TclpLocaltime((TclpTime_t) &tt);	/* eg 1996-11-29  6:00:00  CST6CDT */      /*       * The calculation below assumes a max of +12 or -12 hours from GMT. @@ -345,9 +233,6 @@ TclpGetTimeZone(   *	Gets the current system time in seconds and microseconds since the   *	beginning of the epoch: 00:00 UCT, January 1, 1970.   * - *	This function is hooked, allowing users to specify their own virtual - *	system time. - *   * Results:   *	Returns the current time in timePtr.   * @@ -358,10 +243,14 @@ TclpGetTimeZone(   */  void -Tcl_GetTime( -    Tcl_Time *timePtr)		/* Location to store time information. */ +Tcl_GetTime(timePtr) +    Tcl_Time *timePtr;		/* Location to store time information. */  { -    (*tclGetTimeProcPtr) (timePtr, tclTimeClientData); +    struct timeval tv; +     +    (void) gettimeofday(&tv, NULL); +    timePtr->sec = tv.tv_sec; +    timePtr->usec = tv.tv_usec;  }  /* @@ -383,9 +272,9 @@ Tcl_GetTime(   */  struct tm * -TclpGetDate( -    CONST time_t *time, -    int useGMT) +TclpGetDate(time, useGMT) +    TclpTime_t time; +    int useGMT;  {      if (useGMT) {  	return TclpGmtime(time); @@ -397,9 +286,48 @@ TclpGetDate(  /*   *----------------------------------------------------------------------   * + * TclpStrftime -- + * + *	On Unix, we can safely call the native strftime implementation, + *	and also ignore the useGMT parameter. + * + * Results: + *	The normal strftime result. + * + * Side effects: + *	None. + * + *---------------------------------------------------------------------- + */ + +size_t +TclpStrftime(s, maxsize, format, t, useGMT) +    char *s; +    size_t maxsize; +    CONST char *format; +    CONST struct tm *t; +    int useGMT; +{ +    if (format[0] == '%' && format[1] == 'Q') { +	/* Format as a stardate */ +	sprintf(s, "Stardate %2d%03d.%01d", +		(((t->tm_year + TM_YEAR_BASE) + 377) - 2323), +		(((t->tm_yday + 1) * 1000) / +			(365 + IsLeapYear((t->tm_year + TM_YEAR_BASE)))), +		(((t->tm_hour * 60) + t->tm_min)/144)); +	return(strlen(s)); +    } +    setlocale(LC_TIME, ""); +    return strftime(s, maxsize, format, t); +} + +/* + *---------------------------------------------------------------------- + *   * TclpGmtime --   * - *	Wrapper around the 'gmtime' library function to make it thread safe. + *	Wrapper around the 'gmtime' library function to make it thread + *	safe.   *   * Results:   *	Returns a pointer to a 'struct tm' in thread-specific data. @@ -411,24 +339,27 @@ TclpGetDate(   */  struct tm * -TclpGmtime( -    CONST time_t *timePtr)	/* Pointer to the number of seconds since the -				 * local system's epoch */ +TclpGmtime(tt) +    TclpTime_t_CONST tt;  { +    CONST time_t *timePtr = (CONST time_t *) tt; +				/* Pointer to the number of seconds +				 * since the local system's epoch */ +      /*       * Get a thread-local buffer to hold the returned time.       */      ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tmKey); -  #ifdef HAVE_GMTIME_R      gmtime_r(timePtr, &(tsdPtr->gmtime_buf));  #else      Tcl_MutexLock(&tmMutex); -    memcpy(&(tsdPtr->gmtime_buf), gmtime(timePtr), sizeof(struct tm)); +    memcpy((VOID *) &(tsdPtr->gmtime_buf), +	    (VOID *) gmtime(timePtr), +	    sizeof(struct tm));      Tcl_MutexUnlock(&tmMutex);  #endif -      return &(tsdPtr->gmtime_buf);  } @@ -450,145 +381,33 @@ TclpGmtime(   */  struct tm * -TclpLocaltime( -    CONST time_t *timePtr)	/* Pointer to the number of seconds since the -				 * local system's epoch */ +TclpLocaltime(tt) +    TclpTime_t_CONST tt;  { +    CONST time_t *timePtr = (CONST time_t *) tt; +				/* Pointer to the number of seconds +				 * since the local system's epoch */      /*       * Get a thread-local buffer to hold the returned time.       */      ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&tmKey); -      SetTZIfNecessary();  #ifdef HAVE_LOCALTIME_R      localtime_r(timePtr, &(tsdPtr->localtime_buf));  #else      Tcl_MutexLock(&tmMutex); -    memcpy(&(tsdPtr->localtime_buf), localtime(timePtr), sizeof(struct tm)); +    memcpy((VOID *) &(tsdPtr -> localtime_buf), +	    (VOID *) localtime(timePtr), +	    sizeof(struct tm));      Tcl_MutexUnlock(&tmMutex);  #endif -      return &(tsdPtr->localtime_buf);  }  /*   *----------------------------------------------------------------------   * - * Tcl_SetTimeProc -- - * - *	TIP #233 (Virtualized Time): Registers two handlers for the - *	virtualization of Tcl's access to time information. - * - * Results: - *	None. - * - * Side effects: - *	Remembers the handlers, alters core behaviour. - * - *---------------------------------------------------------------------- - */ - -void -Tcl_SetTimeProc( -    Tcl_GetTimeProc *getProc, -    Tcl_ScaleTimeProc *scaleProc, -    ClientData clientData) -{ -    tclGetTimeProcPtr = getProc; -    tclScaleTimeProcPtr = scaleProc; -    tclTimeClientData = clientData; -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_QueryTimeProc -- - * - *	TIP #233 (Virtualized Time): Query which time handlers are registered. - * - * Results: - *	None. - * - * Side effects: - *	None. - * - *---------------------------------------------------------------------- - */ - -void -Tcl_QueryTimeProc( -    Tcl_GetTimeProc **getProc, -    Tcl_ScaleTimeProc **scaleProc, -    ClientData *clientData) -{ -    if (getProc) { -	*getProc = tclGetTimeProcPtr; -    } -    if (scaleProc) { -	*scaleProc = tclScaleTimeProcPtr; -    } -    if (clientData) { -	*clientData = tclTimeClientData; -    } -} - -/* - *---------------------------------------------------------------------- - * - * NativeScaleTime -- - * - *	TIP #233: Scale from virtual time to the real-time. For native scaling - *	the relationship is 1:1 and nothing has to be done. - * - * Results: - *	Scales the time in timePtr. - * - * Side effects: - *	See above. - * - *---------------------------------------------------------------------- - */ - -static void -NativeScaleTime( -    Tcl_Time *timePtr, -    ClientData clientData) -{ -    /* Native scale is 1:1. Nothing is done */ -} - -/* - *---------------------------------------------------------------------- - * - * NativeGetTime -- - * - *	TIP #233: Gets the current system time in seconds and microseconds - *	since the beginning of the epoch: 00:00 UCT, January 1, 1970. - * - * Results: - *	Returns the current time in timePtr. - * - * Side effects: - *	None. - * - *---------------------------------------------------------------------- - */ - -static void -NativeGetTime( -    Tcl_Time *timePtr, -    ClientData clientData) -{ -    struct timeval tv; - -    (void) gettimeofday(&tv, NULL); -    timePtr->sec = tv.tv_sec; -    timePtr->usec = tv.tv_usec; -} -/* - *---------------------------------------------------------------------- - *   * SetTZIfNecessary --   *   *	Determines whether a call to 'tzset' is needed prior to the next call @@ -606,7 +425,7 @@ NativeGetTime(   */  static void -SetTZIfNecessary(void) +SetTZIfNecessary()  {      CONST char *newTZ = getenv("TZ"); @@ -645,8 +464,8 @@ SetTZIfNecessary(void)   */  static void -CleanupMemory( -    ClientData ignored) +CleanupMemory(ignored) +    ClientData ignored;  {      ckfree(lastTZ);  } | 
