Mercurial > ecos-v3_0-branch
comparison packages/language/c/libc/time/current/include/time.inl @ 115:6ed91473a1cd ecos-sw-2000-08-21
Merge from eCos master repository on 2000-08-21-22:40:54-BST
| author | jlarmour |
|---|---|
| date | Fri, 25 Aug 2000 17:32:38 +0000 |
| parents | |
| children | 0ae0bc38e387 |
comparison
equal
deleted
inserted
replaced
| 114:5ad2b71d525e | 115:6ed91473a1cd |
|---|---|
| 1 #ifndef CYGONCE_LIBC_TIME_INL | |
| 2 #define CYGONCE_LIBC_TIME_INL | |
| 3 //=========================================================================== | |
| 4 // | |
| 5 // time.inl | |
| 6 // | |
| 7 // Inline implementations of date and time routines from <time.h> | |
| 8 // | |
| 9 //=========================================================================== | |
| 10 //####COPYRIGHTBEGIN#### | |
| 11 // | |
| 12 // ------------------------------------------- | |
| 13 // The contents of this file are subject to the Red Hat eCos Public License | |
| 14 // Version 1.1 (the "License"); you may not use this file except in | |
| 15 // compliance with the License. You may obtain a copy of the License at | |
| 16 // http://www.redhat.com/ | |
| 17 // | |
| 18 // Software distributed under the License is distributed on an "AS IS" | |
| 19 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the | |
| 20 // License for the specific language governing rights and limitations under | |
| 21 // the License. | |
| 22 // | |
| 23 // The Original Code is eCos - Embedded Configurable Operating System, | |
| 24 // released September 30, 1998. | |
| 25 // | |
| 26 // The Initial Developer of the Original Code is Red Hat. | |
| 27 // Portions created by Red Hat are | |
| 28 // Copyright (C) 1998, 1999, 2000 Red Hat, Inc. | |
| 29 // All Rights Reserved. | |
| 30 // ------------------------------------------- | |
| 31 // | |
| 32 //####COPYRIGHTEND#### | |
| 33 //=========================================================================== | |
| 34 //#####DESCRIPTIONBEGIN#### | |
| 35 // | |
| 36 // Author(s): jlarmour | |
| 37 // Contributors: | |
| 38 // Date: 1999-02-25 | |
| 39 // Purpose: Provide inline implementations for some of the date and time | |
| 40 // routines declared in <time.h> for ISO C section 7.12 and | |
| 41 // POSIX 1003.1 8.3.4-8.3.7 | |
| 42 // Description: | |
| 43 // Usage: Do not include this file directly. Instead include <time.h> | |
| 44 // | |
| 45 //####DESCRIPTIONEND#### | |
| 46 // | |
| 47 //=========================================================================== | |
| 48 | |
| 49 // CONFIGURATION | |
| 50 | |
| 51 #include <pkgconf/libc_time.h> // C library configuration | |
| 52 | |
| 53 // INCLUDES | |
| 54 | |
| 55 #include <cyg/infra/cyg_type.h> // Common type definitions and support | |
| 56 #include <time.h> // Header for this file | |
| 57 #include <cyg/infra/cyg_ass.h> // Assertion infrastructure | |
| 58 #include <cyg/infra/cyg_trac.h> // Tracing infrastructure | |
| 59 | |
| 60 // DEFINES | |
| 61 | |
| 62 // The following are overriden by the libc implementation to get a non-inline | |
| 63 // version to prevent duplication of code | |
| 64 | |
| 65 #ifndef CYGPRI_LIBC_TIME_ASCTIME_R_INLINE | |
| 66 # define CYGPRI_LIBC_TIME_ASCTIME_R_INLINE extern __inline__ | |
| 67 #endif | |
| 68 | |
| 69 #ifndef CYGPRI_LIBC_TIME_CTIME_R_INLINE | |
| 70 # define CYGPRI_LIBC_TIME_CTIME_R_INLINE extern __inline__ | |
| 71 #endif | |
| 72 | |
| 73 #ifndef CYGPRI_LIBC_TIME_GMTIME_R_INLINE | |
| 74 # define CYGPRI_LIBC_TIME_GMTIME_R_INLINE extern __inline__ | |
| 75 #endif | |
| 76 | |
| 77 #ifndef CYGPRI_LIBC_TIME_LOCALTIME_R_INLINE | |
| 78 # define CYGPRI_LIBC_TIME_LOCALTIME_R_INLINE extern __inline__ | |
| 79 #endif | |
| 80 | |
| 81 #ifndef CYGPRI_LIBC_TIME_DIFFTIME_INLINE | |
| 82 # define CYGPRI_LIBC_TIME_DIFFTIME_INLINE extern __inline__ | |
| 83 #endif | |
| 84 | |
| 85 #ifndef CYGPRI_LIBC_TIME_MKTIME_INLINE | |
| 86 # define CYGPRI_LIBC_TIME_MKTIME_INLINE extern __inline__ | |
| 87 #endif | |
| 88 | |
| 89 #ifndef CYGPRI_LIBC_TIME_ASCTIME_INLINE | |
| 90 # define CYGPRI_LIBC_TIME_ASCTIME_INLINE extern __inline__ | |
| 91 #endif | |
| 92 | |
| 93 #ifndef CYGPRI_LIBC_TIME_CTIME_INLINE | |
| 94 # define CYGPRI_LIBC_TIME_CTIME_INLINE extern __inline__ | |
| 95 #endif | |
| 96 | |
| 97 #ifndef CYGPRI_LIBC_TIME_GMTIME_INLINE | |
| 98 # define CYGPRI_LIBC_TIME_GMTIME_INLINE extern __inline__ | |
| 99 #endif | |
| 100 | |
| 101 #ifndef CYGPRI_LIBC_TIME_LOCALTIME_INLINE | |
| 102 # define CYGPRI_LIBC_TIME_LOCALTIME_INLINE extern __inline__ | |
| 103 #endif | |
| 104 | |
| 105 #ifndef CYGPRI_LIBC_TIME_GETZONEOFFSETS_INLINE | |
| 106 # define CYGPRI_LIBC_TIME_GETZONEOFFSETS_INLINE extern __inline__ | |
| 107 #endif | |
| 108 | |
| 109 #ifndef CYGPRI_LIBC_TIME_SETZONEOFFSETS_INLINE | |
| 110 # define CYGPRI_LIBC_TIME_SETZONEOFFSETS_INLINE extern __inline__ | |
| 111 #endif | |
| 112 | |
| 113 #ifndef CYGPRI_LIBC_TIME_SETDST_INLINE | |
| 114 # define CYGPRI_LIBC_TIME_SETDST_INLINE extern __inline__ | |
| 115 #endif | |
| 116 | |
| 117 #define CYGNUM_LIBC_TIME_EPOCH_WDAY 4 // Jan 1st 1970 was a Thursday | |
| 118 | |
| 119 #ifdef __cplusplus | |
| 120 extern "C" { | |
| 121 #endif | |
| 122 | |
| 123 // EXTERNS | |
| 124 | |
| 125 // These are used in the dst access functions below. Do not access these | |
| 126 // directly - use the functions declared in time.h instead | |
| 127 | |
| 128 extern Cyg_libc_time_dst cyg_libc_time_current_dst_stat; | |
| 129 extern time_t cyg_libc_time_current_std_offset; | |
| 130 extern time_t cyg_libc_time_current_dst_offset; | |
| 131 | |
| 132 // INLINE FUNCTIONS | |
| 133 | |
| 134 //=========================================================================== | |
| 135 // | |
| 136 // Utility functions | |
| 137 | |
| 138 ////////////////////////////////// | |
| 139 // cyg_libc_time_year_is_leap() // | |
| 140 ////////////////////////////////// | |
| 141 // | |
| 142 // This returns true if the year is a leap year. | |
| 143 // The argument is of type int in line with struct tm | |
| 144 // | |
| 145 | |
| 146 static __inline__ cyg_bool | |
| 147 cyg_libc_time_year_is_leap( int __year ) | |
| 148 { | |
| 149 cyg_bool _leap=false; | |
| 150 | |
| 151 if (!(__year % 400)) | |
| 152 _leap = true; | |
| 153 else if (!(__year % 4) && (__year % 100)) | |
| 154 _leap = true; | |
| 155 return _leap; | |
| 156 } // cyg_libc_time_year_is_leap() | |
| 157 | |
| 158 | |
| 159 //////////////////////////////////// | |
| 160 // cyg_libc_time_getzoneoffsets() // | |
| 161 //////////////////////////////////// | |
| 162 // | |
| 163 // This function retrieves the current state of the Daylight Savings Time | |
| 164 // and the offsets of both STD and DST | |
| 165 // The offsets are both in time_t's i.e. seconds | |
| 166 // | |
| 167 | |
| 168 CYGPRI_LIBC_TIME_GETZONEOFFSETS_INLINE Cyg_libc_time_dst | |
| 169 cyg_libc_time_getzoneoffsets( time_t *__stdoffset, time_t *__dstoffset ) | |
| 170 { | |
| 171 CYG_REPORT_FUNCNAMETYPE("cyg_libc_time_getzoneoffsets", | |
| 172 "returning DST state %d"); | |
| 173 CYG_REPORT_FUNCARG2("__stdoffset is at address %08x, " | |
| 174 "__dstoffset is at %08x", __stdoffset, __dstoffset); | |
| 175 | |
| 176 CYG_CHECK_DATA_PTR(__stdoffset, "__stdoffset is not a valid pointer!"); | |
| 177 CYG_CHECK_DATA_PTR(__dstoffset, "__dstoffset is not a valid pointer!"); | |
| 178 | |
| 179 *__stdoffset = cyg_libc_time_current_std_offset; | |
| 180 *__dstoffset = cyg_libc_time_current_dst_offset; | |
| 181 | |
| 182 CYG_REPORT_RETVAL(cyg_libc_time_current_dst_stat); | |
| 183 | |
| 184 return cyg_libc_time_current_dst_stat; | |
| 185 } // cyg_libc_time_getzoneoffsets() | |
| 186 | |
| 187 | |
| 188 //////////////////////////////////// | |
| 189 // cyg_libc_time_setzoneoffsets() // | |
| 190 //////////////////////////////////// | |
| 191 // | |
| 192 // This function sets the offsets used when Daylight Savings Time is enabled | |
| 193 // or disabled. The offsets are in time_t's i.e. seconds | |
| 194 // | |
| 195 | |
| 196 CYGPRI_LIBC_TIME_SETZONEOFFSETS_INLINE void | |
| 197 cyg_libc_time_setzoneoffsets( time_t __stdoffset, time_t __dstoffset ) | |
| 198 { | |
| 199 CYG_REPORT_FUNCNAME("cyg_libc_time_setzoneoffsets"); | |
| 200 CYG_REPORT_FUNCARG2DV(__stdoffset, __dstoffset); | |
| 201 | |
| 202 cyg_libc_time_current_std_offset = __stdoffset; | |
| 203 cyg_libc_time_current_dst_offset = __dstoffset; | |
| 204 | |
| 205 CYG_REPORT_RETURN(); | |
| 206 } // cyg_libc_time_setzoneoffsets() | |
| 207 | |
| 208 | |
| 209 //////////////////////////// | |
| 210 // cyg_libc_time_setdst() // | |
| 211 //////////////////////////// | |
| 212 // | |
| 213 // This function sets the state of Daylight Savings Time: on, off, or unknown | |
| 214 // | |
| 215 | |
| 216 CYGPRI_LIBC_TIME_SETDST_INLINE void | |
| 217 cyg_libc_time_setdst( Cyg_libc_time_dst __state ) | |
| 218 { | |
| 219 CYG_REPORT_FUNCNAME("cyg_libc_time_setdst"); | |
| 220 CYG_REPORT_FUNCARG1("__state=%d", __state); | |
| 221 | |
| 222 cyg_libc_time_current_dst_stat = __state; | |
| 223 | |
| 224 CYG_REPORT_RETURN(); | |
| 225 } // cyg_libc_time_setdst() | |
| 226 | |
| 227 | |
| 228 | |
| 229 //=========================================================================== | |
| 230 // | |
| 231 // POSIX 1003.1 functions | |
| 232 | |
| 233 ///////////////////////////////// | |
| 234 // asctime_r() - POSIX.1 8.3.4 // | |
| 235 ///////////////////////////////// | |
| 236 // | |
| 237 // This returns a textual representation of a struct tm, and writes | |
| 238 // the string to return into __buf | |
| 239 // | |
| 240 | |
| 241 #ifdef CYGIMP_LIBC_TIME_ASCTIME_R_INLINE | |
| 242 | |
| 243 #include <stdio.h> // for sprintf() | |
| 244 #include <cyg/libc/time/timeutil.h> // for cyg_libc_time_{day,month}_name | |
| 245 // and cyg_libc_time_itoa() | |
| 246 #include <string.h> // for memcpy() | |
| 247 | |
| 248 CYGPRI_LIBC_TIME_ASCTIME_R_INLINE char * | |
| 249 asctime_r( const struct tm *__timeptr, char *__buf ) | |
| 250 { | |
| 251 cyg_uint8 __i; | |
| 252 | |
| 253 // These initializers are [4] since C++ dictates you _must_ leave space | |
| 254 // for the trailing '\0', even though ISO C says you don't need to! | |
| 255 | |
| 256 CYG_REPORT_FUNCNAMETYPE("asctime_r", "returning \"%s\""); | |
| 257 CYG_REPORT_FUNCARG2("__timeptr = %08x, __buf = %08x", __timeptr, __buf); | |
| 258 | |
| 259 // paranoia - most of these aren't required but could be helpful to | |
| 260 // a programmer debugging their own app. | |
| 261 CYG_CHECK_DATA_PTR(__timeptr, "__timeptr is not a valid pointer!"); | |
| 262 CYG_CHECK_DATA_PTR(__buf, "__buf is not a valid pointer!"); | |
| 263 | |
| 264 CYG_PRECONDITION((__timeptr->tm_sec >= 0) && (__timeptr->tm_sec < 62), | |
| 265 "__timeptr->tm_sec out of range!"); | |
| 266 CYG_PRECONDITION((__timeptr->tm_min >= 0) && (__timeptr->tm_min < 60), | |
| 267 "__timeptr->tm_min out of range!"); | |
| 268 CYG_PRECONDITION((__timeptr->tm_hour >= 0) && (__timeptr->tm_hour < 24), | |
| 269 "__timeptr->tm_hour out of range!"); | |
| 270 // Currently I don't check _actual_ numbers of days in each month here | |
| 271 // FIXME: No reason why not though | |
| 272 CYG_PRECONDITION((__timeptr->tm_mday >= 1) && (__timeptr->tm_mday < 32), | |
| 273 "__timeptr->tm_mday out of range!"); | |
| 274 CYG_PRECONDITION((__timeptr->tm_mon >= 0) && (__timeptr->tm_mon < 12), | |
| 275 "__timeptr->tm_mon out of range!"); | |
| 276 CYG_PRECONDITION((__timeptr->tm_wday >= 0) && (__timeptr->tm_wday < 7), | |
| 277 "__timeptr->tm_wday out of range!"); | |
| 278 CYG_PRECONDITION((__timeptr->tm_yday >= 0) && (__timeptr->tm_yday < 366), | |
| 279 "__timeptr->tm_yday out of range!"); | |
| 280 CYG_PRECONDITION((__timeptr->tm_year > -1900) && | |
| 281 (__timeptr->tm_year < 8100), | |
| 282 "__timeptr->tm_year out of range!"); | |
| 283 | |
| 284 // we can't use strftime because ISO C is stupid enough not to allow | |
| 285 // the strings in asctime() to be localized. Duh. | |
| 286 | |
| 287 // day of the week | |
| 288 memcpy(&__buf[0], cyg_libc_time_day_name[__timeptr->tm_wday], 3); | |
| 289 __buf[3] = ' '; | |
| 290 | |
| 291 // month | |
| 292 memcpy(&__buf[4], cyg_libc_time_month_name[__timeptr->tm_mon], 3); | |
| 293 __buf[7] = ' '; | |
| 294 | |
| 295 __i = 8; | |
| 296 | |
| 297 // day of the month | |
| 298 __i += cyg_libc_time_itoa( (cyg_uint8 *)&__buf[__i], __timeptr->tm_mday, 2, | |
| 299 true); | |
| 300 __buf[__i++] = ' '; | |
| 301 | |
| 302 // hour | |
| 303 __i += cyg_libc_time_itoa( (cyg_uint8 *)&__buf[__i], __timeptr->tm_hour, 2, | |
| 304 true); | |
| 305 __buf[__i++] = ':'; | |
| 306 | |
| 307 // minute | |
| 308 __i += cyg_libc_time_itoa( (cyg_uint8 *)&__buf[__i], __timeptr->tm_min, 2, | |
| 309 true); | |
| 310 __buf[__i++] = ':'; | |
| 311 | |
| 312 // second | |
| 313 __i += cyg_libc_time_itoa((cyg_uint8 *) &__buf[__i], __timeptr->tm_sec, 2, | |
| 314 true); | |
| 315 __buf[__i++] = ' '; | |
| 316 | |
| 317 // year | |
| 318 __i += cyg_libc_time_itoa( (cyg_uint8 *)&__buf[__i], | |
| 319 1900+__timeptr->tm_year, 0, true); | |
| 320 | |
| 321 __buf[__i++] = '\n'; | |
| 322 __buf[__i++] = '\0'; | |
| 323 | |
| 324 CYG_REPORT_RETVAL(__buf); | |
| 325 return __buf; | |
| 326 } // asctime_r() | |
| 327 | |
| 328 #endif // ifdef CYGIMP_LIBC_TIME_ASCTIME_R_INLINE | |
| 329 | |
| 330 //////////////////////////////// | |
| 331 // gmtime_r() - POSIX.1 8.3.6 // | |
| 332 //////////////////////////////// | |
| 333 // | |
| 334 // This converts a time_t into a struct tm expressed in UTC, and stores | |
| 335 // the result in the space occupied by __result | |
| 336 // | |
| 337 | |
| 338 #ifdef CYGIMP_LIBC_TIME_GMTIME_R_INLINE | |
| 339 | |
| 340 #include <cyg/libc/time/timeutil.h> // for cyg_libc_time_month_lengths | |
| 341 | |
| 342 CYGPRI_LIBC_TIME_GMTIME_R_INLINE struct tm * | |
| 343 gmtime_r( const time_t *__timer, struct tm *__result ) | |
| 344 { | |
| 345 time_t _tim; | |
| 346 const cyg_uint8 *_months_p; | |
| 347 | |
| 348 CYG_REPORT_FUNCNAMETYPE("gmtime_r", "returning %08x"); | |
| 349 CYG_CHECK_DATA_PTR(__timer, "__timer is not a valid pointer!"); | |
| 350 CYG_CHECK_DATA_PTR(__result, "__result is not a valid pointer!"); | |
| 351 CYG_REPORT_FUNCARG2("*__timer=%d, __result is at %08x", | |
| 352 *__timer, __result); | |
| 353 | |
| 354 #define CYGNUM_LIBC_TIME_SECSPERDAY (60*60*24) | |
| 355 #define CYGNUM_LIBC_TIME_SECSPERYEAR (CYGNUM_LIBC_TIME_SECSPERDAY * 365) | |
| 356 #define CYGNUM_LIBC_TIME_SECSPERLEAPYEAR (CYGNUM_LIBC_TIME_SECSPERDAY * 366) | |
| 357 | |
| 358 _tim = *__timer; | |
| 359 | |
| 360 // First, work out year. Start off with 1970 and work forwards or backwards | |
| 361 // depending on the sign of _tim | |
| 362 __result->tm_year = 70; | |
| 363 | |
| 364 // we also work out the day of the week of the start of the year as we | |
| 365 // go along | |
| 366 __result->tm_wday = CYGNUM_LIBC_TIME_EPOCH_WDAY; | |
| 367 | |
| 368 while (_tim < 0) { | |
| 369 // Work backwards | |
| 370 | |
| 371 --__result->tm_year; | |
| 372 | |
| 373 // Check for a leap year. | |
| 374 if (cyg_libc_time_year_is_leap(1900 + __result->tm_year)) { | |
| 375 _tim += CYGNUM_LIBC_TIME_SECSPERLEAPYEAR; | |
| 376 __result->tm_wday -= 366; | |
| 377 } // if | |
| 378 else { | |
| 379 _tim += CYGNUM_LIBC_TIME_SECSPERYEAR; | |
| 380 __result->tm_wday -= 365; | |
| 381 } // else | |
| 382 | |
| 383 } // while | |
| 384 | |
| 385 while (_tim >= CYGNUM_LIBC_TIME_SECSPERYEAR) { | |
| 386 // Work forwards | |
| 387 | |
| 388 if (cyg_libc_time_year_is_leap(1900 + __result->tm_year)) { | |
| 389 | |
| 390 // But if this is a leap year, its possible that we are in the | |
| 391 // middle of the last "extra" day | |
| 392 if (_tim < CYGNUM_LIBC_TIME_SECSPERLEAPYEAR) | |
| 393 break; | |
| 394 | |
| 395 _tim -= CYGNUM_LIBC_TIME_SECSPERLEAPYEAR; | |
| 396 __result->tm_wday += 366; | |
| 397 } // if | |
| 398 else { | |
| 399 _tim -= CYGNUM_LIBC_TIME_SECSPERYEAR; | |
| 400 __result->tm_wday += 365; | |
| 401 } | |
| 402 ++__result->tm_year; | |
| 403 } // while | |
| 404 | |
| 405 // Day of the year. We know _tim is +ve now | |
| 406 CYG_ASSERT(_tim >= 0, | |
| 407 "Number of seconds since start of year is negative!"); | |
| 408 __result->tm_yday = _tim / CYGNUM_LIBC_TIME_SECSPERDAY; | |
| 409 | |
| 410 // Day of the week. Normalize to be 0..6, and note that it might | |
| 411 // be negative, so we have to deal with the modulus being | |
| 412 // implementation-defined for -ve numbers (ISO C 6.3.5) | |
| 413 __result->tm_wday = (((__result->tm_wday + __result->tm_yday)%7)+7)%7; | |
| 414 | |
| 415 // Month and Day of the month | |
| 416 | |
| 417 _months_p = cyg_libc_time_month_lengths[ | |
| 418 cyg_libc_time_year_is_leap(1900 + __result->tm_year) ? 1 : 0 ]; | |
| 419 | |
| 420 __result->tm_mday = __result->tm_yday+1; | |
| 421 | |
| 422 for (__result->tm_mon = 0; | |
| 423 __result->tm_mday > _months_p[__result->tm_mon]; | |
| 424 ++__result->tm_mon) { | |
| 425 | |
| 426 __result->tm_mday -= _months_p[__result->tm_mon]; | |
| 427 | |
| 428 } // for | |
| 429 | |
| 430 _tim -= __result->tm_yday*CYGNUM_LIBC_TIME_SECSPERDAY; | |
| 431 | |
| 432 // hours, mins secs | |
| 433 __result->tm_hour = (int) (_tim / 3600); | |
| 434 _tim %= 3600; | |
| 435 __result->tm_min = (int) (_tim / 60); | |
| 436 __result->tm_sec = (int) (_tim % 60); | |
| 437 | |
| 438 __result->tm_isdst = 0; // gmtime always returns non-DST | |
| 439 | |
| 440 CYG_REPORT_RETVAL(__result); | |
| 441 | |
| 442 return __result; | |
| 443 } // gmtime_r() | |
| 444 | |
| 445 #endif // ifdef CYGIMP_LIBC_TIME_GMTIME_R_INLINE | |
| 446 | |
| 447 /////////////////////////////////// | |
| 448 // localtime_r() - POSIX.1 8.3.7 // | |
| 449 /////////////////////////////////// | |
| 450 // | |
| 451 // This converts a time_t into a struct tm expressed in local time, and | |
| 452 // stores the result in the space occupied by __result | |
| 453 // | |
| 454 | |
| 455 #ifdef CYGIMP_LIBC_TIME_LOCALTIME_R_INLINE | |
| 456 | |
| 457 #include <cyg/libc/time/timeutil.h> // for cyg_libc_time_normalize_structtm() | |
| 458 | |
| 459 CYGPRI_LIBC_TIME_LOCALTIME_R_INLINE struct tm * | |
| 460 localtime_r( const time_t *__timer, struct tm *__result ) | |
| 461 { | |
| 462 time_t __stdoffset, __dstoffset; | |
| 463 CYG_REPORT_FUNCNAMETYPE("localtime_r", "returning %08x"); | |
| 464 CYG_CHECK_DATA_PTR(__timer, "__timer is not a valid pointer!"); | |
| 465 CYG_CHECK_DATA_PTR(__result, "__result is not a valid pointer!"); | |
| 466 CYG_REPORT_FUNCARG2("*__timer=%d, __result is at %08x", | |
| 467 *__timer, __result); | |
| 468 | |
| 469 gmtime_r(__timer, __result); | |
| 470 | |
| 471 // Adjust for STD/DST | |
| 472 __result->tm_isdst = cyg_libc_time_getzoneoffsets(&__stdoffset, | |
| 473 &__dstoffset); | |
| 474 | |
| 475 if (__result->tm_isdst == 0) { // STD | |
| 476 __result->tm_sec += __stdoffset; | |
| 477 cyg_libc_time_normalize_structtm( __result ); | |
| 478 } // if | |
| 479 else if (__result->tm_isdst > 0) { // DST | |
| 480 __result->tm_sec += __dstoffset; | |
| 481 cyg_libc_time_normalize_structtm( __result ); | |
| 482 } // if | |
| 483 // Don't do anything for tm_isdst == -1 | |
| 484 | |
| 485 CYG_REPORT_RETVAL(__result); | |
| 486 | |
| 487 return __result; | |
| 488 } // localtime_r() | |
| 489 | |
| 490 #endif // ifdef CYGIMP_LIBC_TIME_LOCALTIME_R_INLINE | |
| 491 | |
| 492 | |
| 493 /////////////////////////////// | |
| 494 // ctime_r() - POSIX.1 8.3.5 // | |
| 495 /////////////////////////////// | |
| 496 // | |
| 497 // This returns the equivalent of ctime() but writes to __buf | |
| 498 // to store the returned string | |
| 499 // | |
| 500 | |
| 501 #ifdef CYGIMP_LIBC_TIME_CTIME_R_INLINE | |
| 502 | |
| 503 CYGPRI_LIBC_TIME_CTIME_R_INLINE char * | |
| 504 ctime_r( const time_t *__timer, char *__buf ) | |
| 505 { | |
| 506 struct tm _mytm; | |
| 507 | |
| 508 CYG_REPORT_FUNCNAMETYPE("ctime_r", "returning \"%s\""); | |
| 509 | |
| 510 CYG_CHECK_DATA_PTR(__timer, "__timer is not a valid pointer!"); | |
| 511 CYG_CHECK_DATA_PTR(__buf, "__buf is not a valid pointer!"); | |
| 512 | |
| 513 CYG_REPORT_FUNCARG2("*__timer = %d, __buf=%08x", *__timer, __buf); | |
| 514 | |
| 515 localtime_r( __timer, &_mytm ); | |
| 516 | |
| 517 asctime_r(&_mytm, __buf); | |
| 518 | |
| 519 CYG_REPORT_RETVAL(__buf); | |
| 520 | |
| 521 return __buf; | |
| 522 } // ctime_r() | |
| 523 | |
| 524 #endif // ifdef CYGIMP_LIBC_TIME_CTIME_R_INLINE | |
| 525 | |
| 526 | |
| 527 //=========================================================================== | |
| 528 // | |
| 529 // ISO C functions | |
| 530 | |
| 531 // Time manipulation functions - ISO C 7.12.2 | |
| 532 | |
| 533 ///////////////////////////////// | |
| 534 // difftime() - ISO C 7.12.2.2 // | |
| 535 ///////////////////////////////// | |
| 536 // | |
| 537 // This returns (__time1 - __time0) in seconds | |
| 538 // | |
| 539 | |
| 540 #ifdef CYGIMP_LIBC_TIME_DIFFTIME_INLINE | |
| 541 | |
| 542 CYGPRI_LIBC_TIME_DIFFTIME_INLINE double | |
| 543 difftime( time_t __time1, time_t __time0 ) | |
| 544 { | |
| 545 double _ret; | |
| 546 | |
| 547 CYG_REPORT_FUNCNAMETYPE("difftime", "returning %f"); | |
| 548 CYG_REPORT_FUNCARG2("__time1=%d, __time0=%d", __time1, __time0); | |
| 549 | |
| 550 _ret = (double)(__time1 - __time0); | |
| 551 | |
| 552 CYG_REPORT_RETVAL(_ret); | |
| 553 | |
| 554 return _ret; | |
| 555 } // difftime() | |
| 556 | |
| 557 #endif // ifdef CYGIMP_LIBC_TIME_DIFFTIME_INLINE | |
| 558 | |
| 559 /////////////////////////////// | |
| 560 // mktime() - ISO C 7.12.2.3 // | |
| 561 /////////////////////////////// | |
| 562 // | |
| 563 // This converts a "struct tm" to a "time_t" | |
| 564 // | |
| 565 | |
| 566 #ifdef CYGIMP_LIBC_TIME_MKTIME_INLINE | |
| 567 | |
| 568 #include <cyg/libc/time/timeutil.h> // for cyg_libc_time_normalize_structtm() | |
| 569 // and cyg_libc_time_month_lengths | |
| 570 | |
| 571 CYGPRI_LIBC_TIME_MKTIME_INLINE time_t | |
| 572 mktime( struct tm *__timeptr ) | |
| 573 { | |
| 574 time_t _ret; | |
| 575 cyg_count16 _i; | |
| 576 cyg_count32 _daycount; | |
| 577 cyg_bool _leap; | |
| 578 | |
| 579 CYG_REPORT_FUNCNAMETYPE("mktime", "returning %d"); | |
| 580 CYG_REPORT_FUNCARG1( "__timeptr is at address %08x", __timeptr); | |
| 581 | |
| 582 CYG_CHECK_DATA_PTR(__timeptr, "__timeptr is not a valid pointer!"); | |
| 583 | |
| 584 // First deal with STD/DST. If tm_isdst==-1 (the "autodetect" value) | |
| 585 // we assume its already in UTC. FIXME: is this correct behaviour? Hmm.... | |
| 586 | |
| 587 #if 0 | |
| 588 // FIXME: This doesn't seem to be the way to go | |
| 589 if (__timeptr->tm_isdst == 0) { // STD | |
| 590 // take _off_ the std offset to get us back to UTC from localtime | |
| 591 __timeptr->tm_sec -= (int)cyg_libc_time_current_std_offset; | |
| 592 } // if | |
| 593 else if (__timeptr->tm_isdst > 0) { // DST | |
| 594 // take _off_ the dst offset to get us back to UTC from localtime | |
| 595 __timeptr->tm_sec -= (int)cyg_libc_time_current_dst_offset; | |
| 596 } // if | |
| 597 #endif | |
| 598 | |
| 599 cyg_libc_time_normalize_structtm(__timeptr); | |
| 600 | |
| 601 // check if a time_t can hold the year. FIXME: we assume it is | |
| 602 // 32 bits which gives the year range 1902 - 2038 | |
| 603 if ( (__timeptr->tm_year <= 2) || (__timeptr->tm_year >= 138) ) { | |
| 604 CYG_REPORT_RETVAL(-1); | |
| 605 return (time_t)-1; | |
| 606 } | |
| 607 | |
| 608 // fill in the rest of the struct tm i.e. tm_wday and tm_yday | |
| 609 | |
| 610 _leap = cyg_libc_time_year_is_leap(1900 + __timeptr->tm_year); | |
| 611 | |
| 612 for (_i=0, _daycount=0; _i<12; ++_i) { | |
| 613 if (_i == __timeptr->tm_mon) { | |
| 614 _daycount += __timeptr->tm_mday - 1; | |
| 615 break; | |
| 616 } // if | |
| 617 else { | |
| 618 _daycount += cyg_libc_time_month_lengths[_leap][_i]; | |
| 619 } // else | |
| 620 } // for | |
| 621 | |
| 622 CYG_ASSERT(_i<12, "Reached end of year. __timeptr->tm_mon must be bad"); | |
| 623 | |
| 624 __timeptr->tm_yday = _daycount; | |
| 625 | |
| 626 // now tm_wday | |
| 627 | |
| 628 if (__timeptr->tm_year > 70) { | |
| 629 for (_i=70; _i < __timeptr->tm_year; ++_i) | |
| 630 _daycount += (cyg_libc_time_year_is_leap(1900 + _i) ? 366 : 365); | |
| 631 } // if | |
| 632 else if (__timeptr->tm_year < 70) { | |
| 633 for (_i=70; _i > __timeptr->tm_year; --_i) | |
| 634 _daycount -= (cyg_libc_time_year_is_leap(1900 + _i-1) ? 366 : 365); | |
| 635 } // else if | |
| 636 | |
| 637 __timeptr->tm_wday = (_daycount + CYGNUM_LIBC_TIME_EPOCH_WDAY) % 7; | |
| 638 | |
| 639 // if _daycount was negative, on some targets the modulo operator will | |
| 640 // return negative, so we adjust for that | |
| 641 | |
| 642 if (__timeptr->tm_wday < 0) | |
| 643 __timeptr->tm_wday += 7; | |
| 644 | |
| 645 // now finally work out return value | |
| 646 | |
| 647 _ret = __timeptr->tm_sec + 60*__timeptr->tm_min + 60*60*__timeptr->tm_hour; | |
| 648 _ret += _daycount*24*60*60; | |
| 649 | |
| 650 CYG_REPORT_RETVAL(_ret); | |
| 651 | |
| 652 return _ret; | |
| 653 } // mktime() | |
| 654 | |
| 655 #endif // ifdef CYGIMP_LIBC_TIME_MKTIME_INLINE | |
| 656 | |
| 657 | |
| 658 // Time conversion functions - ISO C 7.12.3 | |
| 659 | |
| 660 //////////////////////////////// | |
| 661 // asctime() - ISO C 7.12.3.1 // | |
| 662 //////////////////////////////// | |
| 663 // | |
| 664 // This returns a textual representation of a struct tm | |
| 665 // | |
| 666 | |
| 667 #ifdef CYGIMP_LIBC_TIME_ASCTIME_INLINE | |
| 668 | |
| 669 extern char cyg_libc_time_asctime_buf[]; | |
| 670 | |
| 671 CYGPRI_LIBC_TIME_ASCTIME_INLINE char * | |
| 672 asctime( const struct tm *__timeptr ) | |
| 673 { | |
| 674 CYG_REPORT_FUNCNAMETYPE("__asctime", "returning \"%s\""); | |
| 675 CYG_REPORT_FUNCARG1("__timeptr = %08x", __timeptr); | |
| 676 | |
| 677 // paranoia | |
| 678 CYG_CHECK_DATA_PTR(__timeptr, "__timeptr is not a valid pointer!"); | |
| 679 | |
| 680 (void)asctime_r( __timeptr, cyg_libc_time_asctime_buf ); | |
| 681 | |
| 682 CYG_REPORT_RETVAL(cyg_libc_time_asctime_buf); | |
| 683 | |
| 684 return cyg_libc_time_asctime_buf; | |
| 685 } // asctime() | |
| 686 | |
| 687 #endif // ifdef CYGIMP_LIBC_TIME_ASCTIME_INLINE | |
| 688 | |
| 689 | |
| 690 /////////////////////////////// | |
| 691 // gmtime() - ISO C 7.12.3.3 // | |
| 692 /////////////////////////////// | |
| 693 // | |
| 694 // This converts a time_t into a struct tm expressed in UTC | |
| 695 // | |
| 696 | |
| 697 #ifdef CYGIMP_LIBC_TIME_GMTIME_INLINE | |
| 698 | |
| 699 extern struct tm cyg_libc_time_gmtime_buf; | |
| 700 | |
| 701 CYGPRI_LIBC_TIME_GMTIME_INLINE struct tm * | |
| 702 gmtime( const time_t *__timer ) | |
| 703 { | |
| 704 CYG_REPORT_FUNCNAMETYPE("gmtime", "returning %08x"); | |
| 705 CYG_CHECK_DATA_PTR(__timer, "__timer is not a valid pointer!"); | |
| 706 CYG_REPORT_FUNCARG1("*__timer=%d", *__timer); | |
| 707 | |
| 708 gmtime_r(__timer, &cyg_libc_time_gmtime_buf); | |
| 709 | |
| 710 CYG_REPORT_RETVAL(&cyg_libc_time_gmtime_buf); | |
| 711 | |
| 712 return &cyg_libc_time_gmtime_buf; | |
| 713 } // gmtime() | |
| 714 | |
| 715 #endif // ifdef CYGIMP_LIBC_TIME_GMTIME_INLINE | |
| 716 | |
| 717 | |
| 718 ////////////////////////////////// | |
| 719 // localtime() - ISO C 7.12.3.4 // | |
| 720 ////////////////////////////////// | |
| 721 // | |
| 722 // This converts a time_t into a struct tm expressed in local time | |
| 723 // | |
| 724 | |
| 725 #ifdef CYGIMP_LIBC_TIME_LOCALTIME_INLINE | |
| 726 | |
| 727 extern struct tm cyg_libc_time_localtime_buf; | |
| 728 | |
| 729 CYGPRI_LIBC_TIME_LOCALTIME_INLINE struct tm * | |
| 730 localtime( const time_t *__timer ) | |
| 731 { | |
| 732 CYG_REPORT_FUNCNAMETYPE("localtime", "returning %08x"); | |
| 733 CYG_CHECK_DATA_PTR(__timer, "__timer is not a valid pointer!"); | |
| 734 CYG_REPORT_FUNCARG1("*__timer=%d", *__timer); | |
| 735 | |
| 736 localtime_r(__timer, &cyg_libc_time_localtime_buf); | |
| 737 | |
| 738 CYG_REPORT_RETVAL(&cyg_libc_time_localtime_buf); | |
| 739 | |
| 740 return &cyg_libc_time_localtime_buf; | |
| 741 } // localtime() | |
| 742 | |
| 743 #endif // ifdef CYGIMP_LIBC_TIME_LOCALTIME_INLINE | |
| 744 | |
| 745 | |
| 746 ////////////////////////////// | |
| 747 // ctime() - ISO C 7.12.3.2 // | |
| 748 ////////////////////////////// | |
| 749 // | |
| 750 // This returns asctime(localtime(__timeptr)) | |
| 751 // | |
| 752 | |
| 753 #ifdef CYGIMP_LIBC_TIME_CTIME_INLINE | |
| 754 | |
| 755 CYGPRI_LIBC_TIME_CTIME_INLINE char * | |
| 756 ctime( const time_t *__timer ) | |
| 757 { | |
| 758 char *_str; | |
| 759 | |
| 760 CYG_REPORT_FUNCNAMETYPE("ctime", "returning \"%s\""); | |
| 761 CYG_CHECK_DATA_PTR( __timer, "__timer is not a valid pointer!"); | |
| 762 CYG_REPORT_FUNCARG1("*__timer = %d", *__timer); | |
| 763 | |
| 764 _str = asctime(localtime(__timer)); | |
| 765 | |
| 766 CYG_REPORT_RETVAL(_str); | |
| 767 | |
| 768 return _str; | |
| 769 } // ctime() | |
| 770 | |
| 771 #endif // ifdef CYGIMP_LIBC_TIME_CTIME_INLINE | |
| 772 | |
| 773 | |
| 774 #ifdef __cplusplus | |
| 775 } // extern "C" | |
| 776 #endif | |
| 777 | |
| 778 #endif // CYGONCE_LIBC_TIME_INL multiple inclusion protection | |
| 779 | |
| 780 // EOF time.inl |
