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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [language/] [c/] [libc/] [time/] [v2_0/] [src/] [timeutil.cxx] - Blame information for rev 596

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//========================================================================
2
//
3
//      timeutil.cxx
4
//
5
//      ISO C date and time implementation support functions
6
//
7
//========================================================================
8
//####ECOSGPLCOPYRIGHTBEGIN####
9
// -------------------------------------------
10
// This file is part of eCos, the Embedded Configurable Operating System.
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under
14
// the terms of the GNU General Public License as published by the Free
15
// Software Foundation; either version 2 or (at your option) any later version.
16
//
17
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20
// for more details.
21
//
22
// You should have received a copy of the GNU General Public License along
23
// with eCos; if not, write to the Free Software Foundation, Inc.,
24
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25
//
26
// As a special exception, if other files instantiate templates or use macros
27
// or inline functions from this file, or you compile this file and link it
28
// with other works to produce a work based on this file, this file does not
29
// by itself cause the resulting work to be covered by the GNU General Public
30
// License. However the source code for this file must still be made available
31
// in accordance with section (3) of the GNU General Public License.
32
//
33
// This exception does not invalidate any other reasons why a work based on
34
// this file might be covered by the GNU General Public License.
35
//
36
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37
// at http://sources.redhat.com/ecos/ecos-license/
38
// -------------------------------------------
39
//####ECOSGPLCOPYRIGHTEND####
40
//========================================================================
41
//#####DESCRIPTIONBEGIN####
42
//
43
// Author(s):     jlarmour
44
// Contributors:  
45
// Date:          2000-04-28
46
// Purpose:       Provide support functions used by the ISO C date and time
47
//                implementation
48
// Description:   This file provides the functions:
49
//                  cyg_libc_time_normalize_structtm()
50
//                  cyg_libc_time_getzoneoffsets()
51
//                  cyg_libc_time_setzoneoffsets()
52
//                  cyg_libc_time_setdst()
53
//                  cyg_libc_time_itoa()
54
//                and the globals:
55
//                  cyg_libc_time_day_name
56
//                  cyg_libc_time_day_name_len
57
//                  cyg_libc_time_month_name
58
//                  cyg_libc_time_month_name_len
59
//                  cyg_libc_time_month_lengths
60
//                  cyg_libc_time_current_dst_stat
61
//                  cyg_libc_time_current_std_offset
62
//                  cyg_libc_time_current_dst_offset
63
// Usage:         
64
//
65
//####DESCRIPTIONEND####
66
//
67
//========================================================================
68
 
69
// CONFIGURATION
70
 
71
#include <pkgconf/libc_time.h>          // C library configuration
72
 
73
// INCLUDES
74
 
75
// define these functions as outline, not inline, functions in this file
76
#define CYGPRI_LIBC_TIME_GETZONEOFFSETS_INLINE extern "C"
77
#define CYGPRI_LIBC_TIME_SETZONEOFFSETS_INLINE extern "C"
78
#define CYGPRI_LIBC_TIME_SETDST_INLINE extern "C"
79
 
80
#include <cyg/infra/cyg_type.h>    // Common type definitions and support
81
#include <cyg/libc/time/timeutil.h>// Header for this file
82
#include <time.h>                  // Main date and time definitions
83
#include <stdlib.h>                // for div() and abs()
84
 
85
 
86
// GLOBALS
87
 
88
// FIXME: PR19440 - const char & -fwritable-strings don't mix
89
const char cyg_libc_time_day_name[7][10] = {
90
    "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
91
    "Saturday"
92
};
93
const cyg_uint8 cyg_libc_time_day_name_len[7] = { 6, 6, 7, 9, 8, 6, 8 };
94
 
95
// FIXME: PR19440 - const char & -fwritable-strings don't mix
96
const char cyg_libc_time_month_name[12][10] = {
97
    "January", "February", "March", "April", "May", "June",
98
    "July", "August", "September", "October", "November", "December"
99
};
100
const cyg_uint8 cyg_libc_time_month_name_len[12] = { 7, 8, 5, 5, 3, 4,
101
                                                     4, 6, 9, 7, 8, 8 };
102
 
103
const cyg_uint8 cyg_libc_time_month_lengths[2][12] = {
104
    {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
105
    {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
106
};
107
 
108
Cyg_libc_time_dst cyg_libc_time_current_dst_stat =
109
     (Cyg_libc_time_dst)CYGNUM_LIBC_TIME_DST_DEFAULT_STATE;
110
time_t cyg_libc_time_current_std_offset =
111
     (time_t)CYGNUM_LIBC_TIME_STD_DEFAULT_OFFSET;
112
time_t cyg_libc_time_current_dst_offset =
113
     (time_t)CYGNUM_LIBC_TIME_DST_DEFAULT_OFFSET;
114
 
115
 
116
// FUNCTIONS
117
 
118
////////////////////////////////////////
119
// cyg_libc_time_normalize_structtm() //
120
////////////////////////////////////////
121
//
122
// cyg_libc_time_normalize_structtm() will adjust the fields of a struct tm
123
// so that they are within the normal ranges expected.
124
// tm_wday, tm_yday and tm_isdst are ignored
125
 
126
externC void
127
cyg_libc_time_normalize_structtm( struct tm *timeptr )
128
{
129
    div_t t;
130
 
131
    CYG_REPORT_FUNCNAME("cyg_libc_time_normalize_structtm");
132
    CYG_REPORT_FUNCARG1("timeptr is at address %08x", timeptr);
133
 
134
    // normalize seconds to 0..59
135
    if ((timeptr->tm_sec < 0) || (timeptr->tm_sec > 59)) {
136
        t = div(timeptr->tm_sec, 60);
137
        while (t.rem < 0) {
138
            t.rem += 60;
139
            --t.quot;
140
        }
141
        timeptr->tm_min += t.quot;
142
        timeptr->tm_sec = t.rem;
143
    } // if
144
 
145
    // normalize minutes to 0..59
146
    if ((timeptr->tm_min < 0) || (timeptr->tm_min > 59)) {
147
        t = div(timeptr->tm_min, 60);
148
        while (t.rem < 0) {
149
            t.rem += 60;
150
            --t.quot;
151
        }
152
        timeptr->tm_hour += t.quot;
153
        timeptr->tm_min = t.rem;
154
    } // if
155
 
156
    // normalize hours to 0..23
157
    if ((timeptr->tm_hour < 0) || (timeptr->tm_hour > 23)) {
158
        t = div(timeptr->tm_hour, 24);
159
        while (t.rem < 0) {
160
            t.rem += 24;
161
            --t.quot;
162
        }
163
        timeptr->tm_mday += t.quot;
164
        timeptr->tm_hour = t.rem;
165
    } // if
166
 
167
    // we wait before normalizing tm_mday as per ISO C 7.12.2.3 (although
168
    // actually it only makes sense if you think about it
169
 
170
    // normalize months to 0..11
171
    if ((timeptr->tm_mon < 0) || (timeptr->tm_mon > 11)) {
172
        t = div(timeptr->tm_mon, 12);
173
        while (t.rem < 0) {
174
            t.rem += 12;
175
            --t.quot;
176
        }
177
        timeptr->tm_year += t.quot;
178
        timeptr->tm_mon = t.rem;
179
    } // if
180
 
181
    // now tm_mday which needs to go to 1..31
182
    cyg_bool leap = cyg_libc_time_year_is_leap(timeptr->tm_year);
183
 
184
    while (timeptr->tm_mday < 1) {
185
        // move back a month
186
 
187
        if (--timeptr->tm_mon < 0) {
188
            --timeptr->tm_year;
189
            timeptr->tm_mon = 11;
190
            leap = cyg_libc_time_year_is_leap(timeptr->tm_year);
191
        } // if
192
 
193
        // we move backward the number of days in the _new_ current month
194
        timeptr->tm_mday += cyg_libc_time_month_lengths[leap][timeptr->tm_mon];
195
 
196
    } // while
197
 
198
    while (timeptr->tm_mday >
199
           cyg_libc_time_month_lengths[leap][timeptr->tm_mon]) {
200
 
201
        // move forward a month
202
 
203
        // we move forward the number of days in the _old_ current month
204
        timeptr->tm_mday -= cyg_libc_time_month_lengths[leap][timeptr->tm_mon];
205
 
206
        if (++timeptr->tm_mon > 11) {
207
            ++timeptr->tm_year;
208
            timeptr->tm_mon = 0;
209
            leap = cyg_libc_time_year_is_leap(timeptr->tm_year);
210
        } // if
211
 
212
    } // while
213
 
214
    CYG_REPORT_RETURN();
215
 
216
} // cyg_libc_time_normalize_structtm()
217
 
218
 
219
//////////////////////////
220
// cyg_libc_time_itoa() //
221
//////////////////////////
222
//
223
// This converts num to a string and puts it into s padding with
224
// "0"'s if padzero is set, or spaces otherwise if necessary.
225
// The number of chars written to s is returned
226
//
227
 
228
// This implementation is probably suboptimal in terms of performance
229
// but there wouldn't be much in it with only 11 chars max to convert :-/.
230
// Actually FIXME: what if someone passes a width >11
231
 
232
externC cyg_uint8
233
cyg_libc_time_itoa( cyg_uint8 *s, cyg_int32 num, cyg_uint8 width,
234
                    cyg_bool padzero )
235
{
236
    CYG_REPORT_FUNCNAMETYPE("cyg_libc_time_itoa", "returning %d");
237
    CYG_REPORT_FUNCARG4( "s=%08x, num=%d, width=%d, padzero=%d",
238
                         s, num, width, padzero );
239
 
240
    CYG_CHECK_DATA_PTR(s, "input string not a valid pointer");
241
 
242
    // special case for zero otherwise we'd have to treat it specially later
243
    // on anyway
244
 
245
    if (num==0) {
246
        cyg_ucount8 i;
247
 
248
        for (i=0; i<width; ++i)
249
            s[i] = padzero ? '0' : ' ';
250
        CYG_REPORT_RETVAL(i);
251
        return i;
252
    }
253
 
254
    // return value
255
    cyg_uint8 ret=0;
256
 
257
    // Pre-fiddle for negative numbers
258
    if ((num < 0) && (width > 0)) {
259
        *s++ = '-';
260
        --width;
261
        num = abs(num);
262
        ++ret;
263
    }
264
 
265
    cyg_ucount32 i;
266
    cyg_bool reachednum = false;
267
    cyg_uint8 c, j;
268
 
269
    // i starts off with factor of 10 digits - which is the string length
270
    // of a positive 32-bit number
271
    for (i=1000000000, j=10; i>0; i/=10, --j) {
272
        c = (num / i);
273
 
274
        if (!reachednum && c==0) {
275
            if (j <= width) {
276
                *s++ = padzero ?  '0' : ' ';
277
                ++ret;
278
            }
279
        } // if
280
        else {
281
            *s++ = c + '0';
282
            ++ret;
283
            reachednum = true;
284
        }
285
        num %= i;
286
    } // for
287
 
288
    CYG_POSTCONDITION(ret >= width, "Didn't output enough chars!");
289
 
290
    CYG_REPORT_RETVAL(ret);
291
    return ret;
292
} // cyg_libc_time_itoa()
293
 
294
 
295
// EOF timeutil.cxx

powered by: WebSVN 2.1.0

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