Mercurial > ecos
diff packages/language/c/libc/current/include/time.inl @ 2:443894e2e912 ecos-v1_2_1-release
Block commit of eCos version 1.2.1
| author | jlarmour |
|---|---|
| date | Tue, 11 May 1999 12:24:34 +0000 |
| parents | |
| children | c38311975d4f |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/packages/language/c/libc/current/include/time.inl @@ -0,0 +1,853 @@ +#ifndef CYGONCE_LIBC_TIME_INL +#define CYGONCE_LIBC_TIME_INL +//=========================================================================== +// +// time.inl +// +// Inline implementations of date and time routines from <time.h> +// +//=========================================================================== +//####COPYRIGHTBEGIN#### +// +// ------------------------------------------- +// The contents of this file are subject to the Cygnus eCos Public License +// Version 1.0 (the "License"); you may not use this file except in +// compliance with the License. You may obtain a copy of the License at +// http://sourceware.cygnus.com/ecos +// +// Software distributed under the License is distributed on an "AS IS" +// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the +// License for the specific language governing rights and limitations under +// the License. +// +// The Original Code is eCos - Embedded Cygnus Operating System, released +// September 30, 1998. +// +// The Initial Developer of the Original Code is Cygnus. Portions created +// by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. +// ------------------------------------------- +// +//####COPYRIGHTEND#### +//=========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): jlarmour +// Contributors: jlarmour +// Date: 1999-02-25 +// Purpose: Provide inline implementations for some of the date and time +// routines declared in <time.h> for ISO C section 7.12 and +// POSIX 1003.1 8.3.4-8.3.7 +// Description: +// Usage: Do not include this file directly. Instead include <time.h> +// +//####DESCRIPTIONEND#### +// +//=========================================================================== + +// CONFIGURATION + +#include <pkgconf/libc.h> // C library configuration + +// INCLUDES + +#include <cyg/infra/cyg_type.h> // Common type definitions and support +#include <time.h> // Header for this file +#include <cyg/infra/cyg_ass.h> // Assertion infrastructure +#include <cyg/infra/cyg_trac.h> // Tracing infrastructure + +// DEFINES + +// The following are overriden by the libc implementation to get a non-inline +// version to prevent duplication of code + +#ifndef CYGPRI_LIBC_TIME_ASCTIME_R_INLINE +# define CYGPRI_LIBC_TIME_ASCTIME_R_INLINE extern __inline__ +#endif + +#ifndef CYGPRI_LIBC_TIME_CTIME_R_INLINE +# define CYGPRI_LIBC_TIME_CTIME_R_INLINE extern __inline__ +#endif + +#ifndef CYGPRI_LIBC_TIME_GMTIME_R_INLINE +# define CYGPRI_LIBC_TIME_GMTIME_R_INLINE extern __inline__ +#endif + +#ifndef CYGPRI_LIBC_TIME_LOCALTIME_R_INLINE +# define CYGPRI_LIBC_TIME_LOCALTIME_R_INLINE extern __inline__ +#endif + +#ifndef CYGPRI_LIBC_TIME_DIFFTIME_INLINE +# define CYGPRI_LIBC_TIME_DIFFTIME_INLINE extern __inline__ +#endif + +#ifndef CYGPRI_LIBC_TIME_MKTIME_INLINE +# define CYGPRI_LIBC_TIME_MKTIME_INLINE extern __inline__ +#endif + +#ifndef CYGPRI_LIBC_TIME_ASCTIME_INLINE +# define CYGPRI_LIBC_TIME_ASCTIME_INLINE extern __inline__ +#endif + +#ifndef CYGPRI_LIBC_TIME_CTIME_INLINE +# define CYGPRI_LIBC_TIME_CTIME_INLINE extern __inline__ +#endif + +#ifndef CYGPRI_LIBC_TIME_GMTIME_INLINE +# define CYGPRI_LIBC_TIME_GMTIME_INLINE extern __inline__ +#endif + +#ifndef CYGPRI_LIBC_TIME_LOCALTIME_INLINE +# define CYGPRI_LIBC_TIME_LOCALTIME_INLINE extern __inline__ +#endif + +#ifndef CYGPRI_LIBC_TIME_GETZONEOFFSETS_INLINE +# define CYGPRI_LIBC_TIME_GETZONEOFFSETS_INLINE extern __inline__ +#endif + +#ifndef CYGPRI_LIBC_TIME_SETZONEOFFSETS_INLINE +# define CYGPRI_LIBC_TIME_SETZONEOFFSETS_INLINE extern __inline__ +#endif + +#ifndef CYGPRI_LIBC_TIME_SETDST_INLINE +# define CYGPRI_LIBC_TIME_SETDST_INLINE extern __inline__ +#endif + +#define CYGNUM_LIBC_TIME_EPOCH_WDAY 4 // Jan 1st 1970 was a Thursday + +#ifdef __cplusplus +extern "C" { +#endif + +// EXTERNS + +// These are used in the dst access functions below. Do not access these +// directly - use the functions declared in time.h instead + +extern Cyg_libc_time_dst cyg_libc_time_current_dst_stat; +extern time_t cyg_libc_time_current_std_offset; +extern time_t cyg_libc_time_current_dst_offset; + +// INLINE FUNCTIONS + +//=========================================================================== +// +// Utility functions + +////////////////////////////////// +// cyg_libc_time_year_is_leap() // +////////////////////////////////// +// +// This returns true if the year is a leap year. +// The argument is of type int in line with struct tm +// + +static __inline__ cyg_bool +cyg_libc_time_year_is_leap( int __year ) +{ + cyg_bool _leap=false; + + if (!(__year % 400)) + _leap = true; + else if (!(__year % 4) && (__year % 100)) + _leap = true; + return _leap; +} // cyg_libc_time_year_is_leap() + + +//////////////////////////////////// +// cyg_libc_time_getzoneoffsets() // +//////////////////////////////////// +// +// This function retrieves the current state of the Daylight Savings Time +// and the offsets of both STD and DST +// The offsets are both in time_t's i.e. seconds +// + +CYGPRI_LIBC_TIME_GETZONEOFFSETS_INLINE Cyg_libc_time_dst +cyg_libc_time_getzoneoffsets( time_t *__stdoffset, time_t *__dstoffset ) +{ + CYG_REPORT_FUNCNAMETYPE("cyg_libc_time_getzoneoffsets", + "returning DST state %d"); + CYG_REPORT_FUNCARG2("__stdoffset is at address %08x, " + "__dstoffset is at %08x", __stdoffset, __dstoffset); + + CYG_CHECK_DATA_PTR(__stdoffset, "__stdoffset is not a valid pointer!"); + CYG_CHECK_DATA_PTR(__dstoffset, "__dstoffset is not a valid pointer!"); + + *__stdoffset = cyg_libc_time_current_std_offset; + *__dstoffset = cyg_libc_time_current_dst_offset; + + CYG_REPORT_RETVAL(cyg_libc_time_current_dst_stat); + + return cyg_libc_time_current_dst_stat; +} // cyg_libc_time_getzoneoffsets() + + +//////////////////////////////////// +// cyg_libc_time_setzoneoffsets() // +//////////////////////////////////// +// +// This function sets the offsets used when Daylight Savings Time is enabled +// or disabled. The offsets are in time_t's i.e. seconds +// + +CYGPRI_LIBC_TIME_SETZONEOFFSETS_INLINE void +cyg_libc_time_setzoneoffsets( time_t __stdoffset, time_t __dstoffset ) +{ + CYG_REPORT_FUNCNAME("cyg_libc_time_setzoneoffsets"); + CYG_REPORT_FUNCARG2DV(__stdoffset, __dstoffset); + + cyg_libc_time_current_std_offset = __stdoffset; + cyg_libc_time_current_dst_offset = __dstoffset; + + CYG_REPORT_RETURN(); +} // cyg_libc_time_setzoneoffsets() + + +//////////////////////////// +// cyg_libc_time_setdst() // +//////////////////////////// +// +// This function sets the state of Daylight Savings Time: on, off, or unknown +// + +CYGPRI_LIBC_TIME_SETDST_INLINE void +cyg_libc_time_setdst( Cyg_libc_time_dst __state ) +{ + CYG_REPORT_FUNCNAME("cyg_libc_time_setdst"); + CYG_REPORT_FUNCARG1("__state=%d", __state); + + cyg_libc_time_current_dst_stat = __state; + + CYG_REPORT_RETURN(); +} // cyg_libc_time_setdst() + + + +//=========================================================================== +// +// POSIX 1003.1 functions + +///////////////////////////////// +// asctime_r() - POSIX.1 8.3.4 // +///////////////////////////////// +// +// This returns a textual representation of a struct tm, and writes +// the string to return into __buf +// + +#ifdef CYGIMP_LIBC_TIME_ASCTIME_R_INLINE + +#include <stdio.h> // for sprintf() +#include <sys/timeutil.h> // for cyg_libc_time_{day,month}_name +#include <string.h> // for memcpy() +#include <stdlib.h> // for cyg_libc_itoa() + +CYGPRI_LIBC_TIME_ASCTIME_R_INLINE char * +__asctime_r( const struct tm *__timeptr, char *__buf ) +{ + cyg_uint8 __i; + + // These initializers are [4] since C++ dictates you _must_ leave space + // for the trailing '\0', even though ISO C says you don't need to! + + CYG_REPORT_FUNCNAMETYPE("__asctime_r", "returning \"%s\""); + CYG_REPORT_FUNCARG2("__timeptr = %08x, __buf = %08x", __timeptr, __buf); + + // paranoia - most of these aren't required but could be helpful to + // a programmer debugging their own app. + CYG_CHECK_DATA_PTR(__timeptr, "__timeptr is not a valid pointer!"); + CYG_CHECK_DATA_PTR(__buf, "__buf is not a valid pointer!"); + + CYG_PRECONDITION((__timeptr->tm_sec >= 0) && (__timeptr->tm_sec < 62), + "__timeptr->tm_sec out of range!"); + CYG_PRECONDITION((__timeptr->tm_min >= 0) && (__timeptr->tm_min < 60), + "__timeptr->tm_min out of range!"); + CYG_PRECONDITION((__timeptr->tm_hour >= 0) && (__timeptr->tm_hour < 24), + "__timeptr->tm_hour out of range!"); + // Currently I don't check _actual_ numbers of days in each month here + // FIXME: No reason why not though + CYG_PRECONDITION((__timeptr->tm_mday >= 1) && (__timeptr->tm_mday < 32), + "__timeptr->tm_mday out of range!"); + CYG_PRECONDITION((__timeptr->tm_mon >= 0) && (__timeptr->tm_mon < 12), + "__timeptr->tm_mon out of range!"); + CYG_PRECONDITION((__timeptr->tm_wday >= 0) && (__timeptr->tm_wday < 7), + "__timeptr->tm_wday out of range!"); + CYG_PRECONDITION((__timeptr->tm_yday >= 0) && (__timeptr->tm_yday < 366), + "__timeptr->tm_yday out of range!"); + CYG_PRECONDITION((__timeptr->tm_year > -1900) && + (__timeptr->tm_year < 8100), + "__timeptr->tm_year out of range!"); + + // we can't use strftime because ISO C is stupid enough not to allow + // the strings in asctime() to be localized. Duh. + + // day of the week + memcpy(&__buf[0], cyg_libc_time_day_name[__timeptr->tm_wday], 3); + __buf[3] = ' '; + + // month + memcpy(&__buf[4], cyg_libc_time_month_name[__timeptr->tm_mon], 3); + __buf[7] = ' '; + + __i = 8; + + // day of the month + __i += cyg_libc_itoa( (cyg_uint8 *)&__buf[__i], __timeptr->tm_mday, 2, + true); + __buf[__i++] = ' '; + + // hour + __i += cyg_libc_itoa( (cyg_uint8 *)&__buf[__i], __timeptr->tm_hour, 2, + true); + __buf[__i++] = ':'; + + // minute + __i += cyg_libc_itoa( (cyg_uint8 *)&__buf[__i], __timeptr->tm_min, 2, + true); + __buf[__i++] = ':'; + + // second + __i += cyg_libc_itoa((cyg_uint8 *) &__buf[__i], __timeptr->tm_sec, 2, + true); + __buf[__i++] = ' '; + + // year + __i += cyg_libc_itoa( (cyg_uint8 *)&__buf[__i], 1900+__timeptr->tm_year, + 0, true); + + __buf[__i++] = '\n'; + __buf[__i++] = '\0'; + + CYG_REPORT_RETVAL(__buf); + return __buf; +} // __asctime_r() + +# ifdef CYGFUN_LIBC_TIME_POSIX +# define asctime_r(__timeptr, __buf) __asctime_r(__timeptr, __buf) +# endif + +#else + +extern char * +__asctime_r( const struct tm *__timeptr, char *__buf ); + +#endif // ifdef CYGIMP_LIBC_TIME_ASCTIME_R_INLINE + +//////////////////////////////// +// gmtime_r() - POSIX.1 8.3.6 // +//////////////////////////////// +// +// This converts a time_t into a struct tm expressed in UTC, and stores +// the result in the space occupied by __result +// + +#ifdef CYGIMP_LIBC_TIME_GMTIME_R_INLINE + +#include <sys/timeutil.h> // for cyg_libc_time_month_lengths + +CYGPRI_LIBC_TIME_GMTIME_R_INLINE struct tm * +__gmtime_r( const time_t *__timer, struct tm *__result ) +{ + time_t _tim; + const cyg_uint8 *_months_p; + + CYG_REPORT_FUNCNAMETYPE("__gmtime_r", "returning %08x"); + CYG_CHECK_DATA_PTR(__timer, "__timer is not a valid pointer!"); + CYG_CHECK_DATA_PTR(__result, "__result is not a valid pointer!"); + CYG_REPORT_FUNCARG2("*__timer=%d, __result is at %08x", + *__timer, __result); + +#define CYGNUM_LIBC_TIME_SECSPERDAY (60*60*24) +#define CYGNUM_LIBC_TIME_SECSPERYEAR (CYGNUM_LIBC_TIME_SECSPERDAY * 365) +#define CYGNUM_LIBC_TIME_SECSPERLEAPYEAR (CYGNUM_LIBC_TIME_SECSPERDAY * 366) + + _tim = *__timer; + + // First, work out year. Start off with 1970 and work forwards or backwards + // depending on the sign of _tim + __result->tm_year = 70; + + // we also work out the day of the week of the start of the year as we + // go along + __result->tm_wday = CYGNUM_LIBC_TIME_EPOCH_WDAY; + + while (_tim < 0) { + // Work backwards + + --__result->tm_year; + + // Check for a leap year. + if (cyg_libc_time_year_is_leap(1900 + __result->tm_year)) { + _tim += CYGNUM_LIBC_TIME_SECSPERLEAPYEAR; + __result->tm_wday -= 366; + } // if + else { + _tim += CYGNUM_LIBC_TIME_SECSPERYEAR; + __result->tm_wday -= 365; + } // else + + } // while + + while (_tim >= CYGNUM_LIBC_TIME_SECSPERYEAR) { + // Work forwards + + if (cyg_libc_time_year_is_leap(1900 + __result->tm_year)) { + + // But if this is a leap year, its possible that we are in the + // middle of the last "extra" day + if (_tim < CYGNUM_LIBC_TIME_SECSPERLEAPYEAR) + break; + + _tim -= CYGNUM_LIBC_TIME_SECSPERLEAPYEAR; + __result->tm_wday += 366; + } // if + else { + _tim -= CYGNUM_LIBC_TIME_SECSPERYEAR; + __result->tm_wday += 365; + } + ++__result->tm_year; + } // while + + // Day of the year. We know _tim is +ve now + CYG_ASSERT(_tim >= 0, + "Number of seconds since start of year is negative!"); + // assign tm_mday as well for further below + __result->tm_mday = __result->tm_yday = _tim / CYGNUM_LIBC_TIME_SECSPERDAY; + + // Day of the week. Normalize to be 0..6, and note that it might + // be negative, so we have to deal with the modulus being + // implementation-defined for -ve numbers (ISO C 6.3.5) + __result->tm_wday = (((__result->tm_wday + __result->tm_yday)%7)+7)%7; + + // Month and Day of the month + + _months_p = cyg_libc_time_month_lengths[ + cyg_libc_time_year_is_leap(1900 + __result->tm_year)]; + + for (__result->tm_mon = 0; + __result->tm_mday > _months_p[__result->tm_mon]; + ++__result->tm_mon) { + + __result->tm_mday -= _months_p[__result->tm_mon]; + + } // for + + // The month day is now in the range 0..30 + // We move it to 1..31 + ++__result->tm_mday; + + _tim -= __result->tm_yday*CYGNUM_LIBC_TIME_SECSPERDAY; + + // hours, mins secs + __result->tm_hour = (int) (_tim / 3600); + _tim %= 3600; + __result->tm_min = (int) (_tim / 60); + __result->tm_sec = (int) (_tim % 60); + + __result->tm_isdst = 0; // gmtime always returns non-DST + + CYG_REPORT_RETVAL(__result); + + return __result; +} // __gmtime_r() + +# ifdef CYGFUN_LIBC_TIME_POSIX +# define gmtime_r(__timer, __result) __gmtime_r(__timer, __result) +# endif + +#else + +extern struct tm * +__gmtime_r( const time_t *__timer, struct tm *__result ); + +#endif // ifdef CYGIMP_LIBC_TIME_GMTIME_R_INLINE + +/////////////////////////////////// +// localtime_r() - POSIX.1 8.3.7 // +/////////////////////////////////// +// +// This converts a time_t into a struct tm expressed in local time, and +// stores the result in the space occupied by __result +// + +#ifdef CYGIMP_LIBC_TIME_LOCALTIME_R_INLINE + +#include <sys/timeutil.h> // for cyg_libc_time_normalize_structtm() + +CYGPRI_LIBC_TIME_LOCALTIME_R_INLINE struct tm * +__localtime_r( const time_t *__timer, struct tm *__result ) +{ + time_t __stdoffset, __dstoffset; + CYG_REPORT_FUNCNAMETYPE("__localtime_r", "returning %08x"); + CYG_CHECK_DATA_PTR(__timer, "__timer is not a valid pointer!"); + CYG_CHECK_DATA_PTR(__result, "__result is not a valid pointer!"); + CYG_REPORT_FUNCARG2("*__timer=%d, __result is at %08x", + *__timer, __result); + + __gmtime_r(__timer, __result); + + // Adjust for STD/DST + __result->tm_isdst = cyg_libc_time_getzoneoffsets(&__stdoffset, + &__dstoffset); + + if (__result->tm_isdst == 0) { // STD + __result->tm_sec += __stdoffset; + cyg_libc_time_normalize_structtm( __result ); + } // if + else if (__result->tm_isdst > 0) { // DST + __result->tm_sec += __dstoffset; + cyg_libc_time_normalize_structtm( __result ); + } // if + // Don't do anything for tm_isdst == -1 + + CYG_REPORT_RETVAL(__result); + + return __result; +} // __localtime_r() + +# ifdef CYGFUN_LIBC_TIME_POSIX +# define localtime_r(__timer, __result) __localtime_r(__timer, __result) +# endif + +#else + +extern struct tm * +__localtime_r( const time_t *__timer, struct tm *__result ); + +#endif // ifdef CYGIMP_LIBC_TIME_LOCALTIME_R_INLINE + +/////////////////////////////// +// ctime_r() - POSIX.1 8.3.5 // +/////////////////////////////// +// +// This returns the equivalent of ctime() but writes to __buf +// to store the returned string +// + +#ifdef CYGIMP_LIBC_TIME_CTIME_R_INLINE + +CYGPRI_LIBC_TIME_CTIME_R_INLINE char * +__ctime_r( const time_t *__timer, char *__buf ) +{ + struct tm _mytm; + + CYG_REPORT_FUNCNAMETYPE("__ctime_r", "returning \"%s\""); + + CYG_CHECK_DATA_PTR(__timer, "__timer is not a valid pointer!"); + CYG_CHECK_DATA_PTR(__buf, "__buf is not a valid pointer!"); + + CYG_REPORT_FUNCARG2("*__timer = %d, __buf=%08x", *__timer, __buf); + + __localtime_r( __timer, &_mytm ); + + __asctime_r(&_mytm, __buf); + + CYG_REPORT_RETVAL(__buf); + + return __buf; +} // __ctime_r() + +# ifdef CYGFUN_LIBC_TIME_POSIX +# define ctime_r(__timer, __buf) __ctime_r(__timer, __buf) +# endif + +#else + +extern char * +__ctime_r( const time_t *__timer, char *__buf ); + +#endif // ifdef CYGIMP_LIBC_TIME_CTIME_R_INLINE + +//=========================================================================== +// +// ISO C functions + +// Time manipulation functions - ISO C 7.12.2 + +///////////////////////////////// +// difftime() - ISO C 7.12.2.2 // +///////////////////////////////// +// +// This returns (__time1 - __time0) in seconds +// + +#ifdef CYGIMP_LIBC_TIME_DIFFTIME_INLINE + +CYGPRI_LIBC_TIME_DIFFTIME_INLINE double +__difftime( time_t __time1, time_t __time0 ) +{ + double _ret; + + CYG_REPORT_FUNCNAMETYPE("__difftime", "returning %f"); + CYG_REPORT_FUNCARG2("__time1=%d, __time0=%d", __time1, __time0); + + _ret = (double)(__time1 - __time0); + + CYG_REPORT_RETVAL(_ret); + + return _ret; +} // __difftime() + +# define difftime(__time1, __time0) __difftime(__time1, __time0) + +#else + +extern double +__difftime( time_t __time1, time_t __time0 ); + +#endif // ifdef CYGIMP_LIBC_TIME_DIFFTIME_INLINE + +/////////////////////////////// +// mktime() - ISO C 7.12.2.3 // +/////////////////////////////// +// +// This converts a "struct tm" to a "time_t" +// + +#ifdef CYGIMP_LIBC_TIME_MKTIME_INLINE + +#include <sys/timeutil.h> // for cyg_libc_time_normalize_structtm() + // and cyg_libc_time_month_lengths + +CYGPRI_LIBC_TIME_MKTIME_INLINE time_t +__mktime( struct tm *__timeptr ) +{ + time_t _ret; + cyg_count16 _i; + cyg_count32 _daycount; + cyg_bool _leap; + + CYG_REPORT_FUNCNAMETYPE("__mktime", "returning %d"); + CYG_REPORT_FUNCARG1( "__timeptr is at address %08x", __timeptr); + + CYG_CHECK_DATA_PTR(__timeptr, "__timeptr is not a valid pointer!"); + + // First deal with STD/DST. If tm_isdst==-1 (the "autodetect" value) + // we assume its already in UTC. FIXME: is this correct behaviour? Hmm.... + +#if 0 +// FIXME: This doesn't seem to be the way to go + if (__timeptr->tm_isdst == 0) { // STD + // take _off_ the std offset to get us back to UTC from localtime + __timeptr->tm_sec -= (int)cyg_libc_time_current_std_offset; + } // if + else if (__timeptr->tm_isdst > 0) { // DST + // take _off_ the dst offset to get us back to UTC from localtime + __timeptr->tm_sec -= (int)cyg_libc_time_current_dst_offset; + } // if +#endif + + cyg_libc_time_normalize_structtm(__timeptr); + + // check if a time_t can hold the year. FIXME: we assume it is + // 32 bits which gives the year range 1902 - 2038 + if ( (__timeptr->tm_year <= 2) || (__timeptr->tm_year >= 138) ) { + CYG_REPORT_RETVAL(-1); + return (time_t)-1; + } + + // fill in the rest of the struct tm i.e. tm_wday and tm_yday + + _leap = cyg_libc_time_year_is_leap(1900 + __timeptr->tm_year); + + for (_i=0, _daycount=0; _i<12; ++_i) { + if (_i == __timeptr->tm_mon) { + _daycount += __timeptr->tm_mday - 1; + break; + } // if + else { + _daycount += cyg_libc_time_month_lengths[_leap][_i]; + } // else + } // for + + CYG_ASSERT(_i<12, "Reached end of year. __timeptr->tm_mon must be bad"); + + __timeptr->tm_yday = _daycount; + + // now tm_wday + + if (__timeptr->tm_year > 70) { + for (_i=70; _i < __timeptr->tm_year; ++_i) + _daycount += (cyg_libc_time_year_is_leap(1900 + _i) ? 366 : 365); + } // if + else if (__timeptr->tm_year < 70) { + for (_i=70; _i > __timeptr->tm_year; --_i) + _daycount -= (cyg_libc_time_year_is_leap(1900 + _i-1) ? 366 : 365); + } // else if + + __timeptr->tm_wday = (_daycount + CYGNUM_LIBC_TIME_EPOCH_WDAY) % 7; + + // if _daycount was negative, on some targets the modulo operator will + // return negative, so we adjust for that + + if (__timeptr->tm_wday < 0) + __timeptr->tm_wday += 7; + + // now finally work out return value + + _ret = __timeptr->tm_sec + 60*__timeptr->tm_min + 60*60*__timeptr->tm_hour; + _ret += _daycount*24*60*60; + + CYG_REPORT_RETVAL(_ret); + + return _ret; +} // __mktime() + +# define mktime(__timeptr) __mktime(__timeptr) + +#else + +extern time_t +__mktime( struct tm *__timeptr ); + +#endif // ifdef CYGIMP_LIBC_TIME_MKTIME_INLINE + +// Time conversion functions - ISO C 7.12.3 + +//////////////////////////////// +// asctime() - ISO C 7.12.3.1 // +//////////////////////////////// +// +// This returns a textual representation of a struct tm +// + +#ifdef CYGIMP_LIBC_TIME_ASCTIME_INLINE + +extern char cyg_libc_time_asctime_buf[]; + +CYGPRI_LIBC_TIME_ASCTIME_INLINE char * +__asctime( const struct tm *__timeptr ) +{ + CYG_REPORT_FUNCNAMETYPE("__asctime", "returning \"%s\""); + CYG_REPORT_FUNCARG1("__timeptr = %08x", __timeptr); + + // paranoia + CYG_CHECK_DATA_PTR(__timeptr, "__timeptr is not a valid pointer!"); + + (void)__asctime_r( __timeptr, cyg_libc_time_asctime_buf ); + + CYG_REPORT_RETVAL(cyg_libc_time_asctime_buf); + + return cyg_libc_time_asctime_buf; +} // __asctime() + +# define asctime(__timeptr) __asctime(__timeptr) + +#else + +extern char * +__asctime( const struct tm *__timeptr ); + +#endif // ifdef CYGIMP_LIBC_TIME_ASCTIME_INLINE + +/////////////////////////////// +// gmtime() - ISO C 7.12.3.3 // +/////////////////////////////// +// +// This converts a time_t into a struct tm expressed in UTC +// + +#ifdef CYGIMP_LIBC_TIME_GMTIME_INLINE + +extern struct tm cyg_libc_time_gmtime_buf; + +CYGPRI_LIBC_TIME_GMTIME_INLINE struct tm * +__gmtime( const time_t *__timer ) +{ + CYG_REPORT_FUNCNAMETYPE("__gmtime", "returning %08x"); + CYG_CHECK_DATA_PTR(__timer, "__timer is not a valid pointer!"); + CYG_REPORT_FUNCARG1("*__timer=%d", *__timer); + + __gmtime_r(__timer, &cyg_libc_time_gmtime_buf); + + CYG_REPORT_RETVAL(&cyg_libc_time_gmtime_buf); + + return &cyg_libc_time_gmtime_buf; +} // __gmtime() + +# define gmtime(__timer) __gmtime(__timer) + +#else + +extern struct tm * +__gmtime( const time_t *__timer); + +#endif // ifdef CYGIMP_LIBC_TIME_GMTIME_INLINE + +////////////////////////////////// +// localtime() - ISO C 7.12.3.4 // +////////////////////////////////// +// +// This converts a time_t into a struct tm expressed in local time +// + +#ifdef CYGIMP_LIBC_TIME_LOCALTIME_INLINE + +extern struct tm cyg_libc_time_localtime_buf; + +CYGPRI_LIBC_TIME_LOCALTIME_INLINE struct tm * +__localtime( const time_t *__timer ) +{ + CYG_REPORT_FUNCNAMETYPE("__localtime", "returning %08x"); + CYG_CHECK_DATA_PTR(__timer, "__timer is not a valid pointer!"); + CYG_REPORT_FUNCARG1("*__timer=%d", *__timer); + + __localtime_r(__timer, &cyg_libc_time_localtime_buf); + + CYG_REPORT_RETVAL(&cyg_libc_time_localtime_buf); + + return &cyg_libc_time_localtime_buf; +} // __localtime() + +# define localtime(__timer) __localtime(__timer) + +#else + +extern struct tm * +__localtime( const time_t *__timer ); + +#endif // ifdef CYGIMP_LIBC_TIME_LOCALTIME_INLINE + +////////////////////////////// +// ctime() - ISO C 7.12.3.2 // +////////////////////////////// +// +// This returns asctime(localtime(__timeptr)) +// + +#ifdef CYGIMP_LIBC_TIME_CTIME_INLINE + +CYGPRI_LIBC_TIME_CTIME_INLINE char * +__ctime( const time_t *__timer ) +{ + char *_str; + + CYG_REPORT_FUNCNAMETYPE("__ctime", "returning \"%s\""); + CYG_CHECK_DATA_PTR( __timer, "__timer is not a valid pointer!"); + CYG_REPORT_FUNCARG1("*__timer = %d", *__timer); + + _str = __asctime(__localtime(__timer)); + + CYG_REPORT_RETVAL(_str); + + return _str; +} // __ctime() + +# define ctime(__timer) __ctime(__timer) + +#else + +extern char * +__ctime( const time_t *__timer ); + +#endif // ifdef CYGIMP_LIBC_TIME_CTIME_INLINE + + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // CYGONCE_LIBC_TIME_INL multiple inclusion protection + +// EOF time.inl
