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