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