OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [language/] [c/] [libc/] [time/] [v2_0/] [include/] [time.inl] - Blame information for rev 174

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
#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 
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  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 
53
//
54
//####DESCRIPTIONEND####
55
//
56
//===========================================================================
57
 
58
// CONFIGURATION
59
 
60
#include           // C library configuration
61
 
62
// INCLUDES
63
 
64
#include     // Common type definitions and support
65
#include                   // Header for this file
66
#include      // Assertion infrastructure
67
#include     // 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  // for cyg_libc_time_{day,month}_name
261
                                    // and cyg_libc_time_itoa()
262
#include                  // for memcpy()
263
 
264
CYGPRI_LIBC_TIME_ASCTIME_R_INLINE char *
265
__asctime_r( const struct tm *__timeptr, char *__buf )
266
{
267
    cyg_uint8 __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    // 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   // 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   // 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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.