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/] [strftime.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
//      strftime.cxx
4
//
5
//      ISO C date and time implementation for strftime()
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: jlarmour
45
// Date:         1999-02-26
46
// Purpose:      Provide implementation of the ISO C function strftime()
47
//               from ISO C section 7.12.3.5
48
// Description:  This file provides the implementation of strftime()
49
// Usage:         
50
//
51
//####DESCRIPTIONEND####
52
//
53
//========================================================================
54
 
55
// CONFIGURATION
56
 
57
#include <pkgconf/libc_time.h>          // C library configuration
58
 
59
// INCLUDES
60
 
61
#include <cyg/infra/cyg_type.h>    // Common type definitions and support
62
#include <cyg/infra/cyg_ass.h>     // Assertion infrastructure
63
#include <cyg/infra/cyg_trac.h>    // Tracing infrastructure
64
#include <time.h>                  // Main date and time definitions
65
#include <cyg/libc/time/timeutil.h>// For cyg_libc_time_{day,month}_name{,_len}
66
 
67
// FUNCTION PROTOTYPES
68
 
69
// FIXME: This all needs to be internationalized and localized, both in
70
// terms of reading and writing multibyte characters, and that it should
71
// refer to the settings of LC_TIME
72
 
73
// FUNCTIONS
74
 
75
// This helper function actually processes the format. Which format to insert
76
// is indicated by fmtchar, sizeleft is the maximum space allowed to be used
77
// in buf. The number of bytes written is returned, or -1 if there was no
78
// space
79
 
80
static cyg_int8
81
do_format(cyg_uint8 fmtchar, cyg_ucount32 sizeleft, char *buf,
82
          const struct tm *timeptr)
83
{
84
    cyg_count8 i;
85
 
86
    switch (fmtchar) {
87
    case 'a':
88
        if (sizeleft<3)
89
            return -1;
90
        buf[0] = cyg_libc_time_day_name[timeptr->tm_wday][0];
91
        buf[1] = cyg_libc_time_day_name[timeptr->tm_wday][1];
92
        buf[2] = cyg_libc_time_day_name[timeptr->tm_wday][2];
93
        return 3;
94
    case 'A':
95
        if (sizeleft < cyg_libc_time_day_name_len[timeptr->tm_wday])
96
            return -1;
97
        for (i=0; i<cyg_libc_time_day_name_len[timeptr->tm_wday]; ++i)
98
            buf[i] = cyg_libc_time_day_name[timeptr->tm_wday][i];
99
        return i;
100
#ifdef CYGFUN_LIBC_TIME_SUS_EXTNS
101
    case 'h':
102
        // ** fall through **
103
#endif
104
    case 'b':
105
        if (sizeleft<3)
106
            return -1;
107
        buf[0] = cyg_libc_time_month_name[timeptr->tm_mon][0];
108
        buf[1] = cyg_libc_time_month_name[timeptr->tm_mon][1];
109
        buf[2] = cyg_libc_time_month_name[timeptr->tm_mon][2];
110
        return 3;
111
    case 'B':
112
        if (sizeleft < cyg_libc_time_month_name_len[timeptr->tm_mon])
113
            return -1;
114
        for (i=0; i<cyg_libc_time_month_name_len[timeptr->tm_mon]; ++i)
115
            buf[i] = cyg_libc_time_month_name[timeptr->tm_mon][i];
116
        return i;
117
    case 'c':
118
        if (sizeleft < 26)
119
            return -1;
120
 
121
        // Recurse! Note that we know that we will have left room for the
122
        // trailing NULL in the strftime body
123
 
124
        i = strftime( buf, sizeleft+1, "%a %b %d %I:%M:%S%p %Y", timeptr);
125
 
126
        return ((0==i) ? -1 : i);
127
    case 'd':
128
        if (sizeleft < 2)
129
            return -1;
130
        buf[0] = (timeptr->tm_mday / 10) + '0';
131
        buf[1] = (timeptr->tm_mday % 10) + '0';
132
        return 2;
133
#ifdef CYGFUN_LIBC_TIME_SUS_EXTNS
134
    case 'e':
135
        if (sizeleft < 2)
136
            return -1;
137
        i = (timeptr->tm_mday / 10);
138
        buf[0] = (0 == i) ? ' ' : i + '0';
139
        buf[1] = (timeptr->tm_mday % 10) + '0';
140
        return 2;
141
#endif
142
    case 'H':
143
        if (sizeleft < 2)
144
            return -1;
145
        buf[0] = (timeptr->tm_hour / 10) + '0';
146
        buf[1] = (timeptr->tm_hour % 10) + '0';
147
        return 2;
148
    case 'I':
149
        if (sizeleft < 2)
150
            return -1;
151
        buf[0] = ((timeptr->tm_hour%12 + 1) / 10) + '0';
152
        buf[1] = ((timeptr->tm_hour%12 + 1) % 10) + '0';
153
        return 2;
154
    case 'j':
155
        if (sizeleft < 3)
156
            return -1;
157
        buf[0] = (timeptr->tm_yday / 100) + '0';
158
        buf[1] = ((timeptr->tm_yday % 100) / 10) + '0';
159
        buf[2] = (timeptr->tm_yday % 10) + '0';
160
        return 3;
161
    case 'm':
162
        if (sizeleft < 2)
163
            return -1;
164
        buf[0] = ((timeptr->tm_mon+1) / 10) + '0';
165
        buf[1] = ((timeptr->tm_mon+1) % 10) + '0';
166
        return 2;
167
    case 'M':
168
        if (sizeleft < 2)
169
            return -1;
170
        buf[0] = (timeptr->tm_min / 10) + '0';
171
        buf[1] = (timeptr->tm_min % 10) + '0';
172
        return 2;
173
    case 'p':
174
        if (sizeleft < 2)
175
            return -1;
176
        buf[0] = (timeptr->tm_hour > 11) ? 'p' : 'a';
177
        buf[1] = 'm';
178
        return 2;
179
    case 'S':
180
        if (sizeleft < 2)
181
            return -1;
182
        buf[0] = (timeptr->tm_sec / 10) + '0';
183
        buf[1] = (timeptr->tm_sec % 10) + '0';
184
        return 2;
185
#ifdef CYGFUN_LIBC_TIME_SUS_EXTNS
186
    case 'T':
187
        if (sizeleft < 8)
188
            return -1;
189
 
190
        // Recurse! Note that we know that we will have left room for the
191
        // trailing NULL in the strftime body
192
 
193
        i = strftime( buf, sizeleft+1, "%H:%M:%S", timeptr);
194
 
195
        return ((0==i) ? -1 : i);
196
#endif
197
    case 'U':
198
        if (sizeleft < 2)
199
            return -1;
200
        i = (timeptr->tm_yday - timeptr->tm_wday + 7) / 7;
201
        buf[0] = (i / 10) + '0';
202
        buf[1] = (i % 10) + '0';
203
        return 2;
204
    case 'w':
205
        // Don't need to check size - we'll always be called with sizeleft > 0
206
        buf[0] = timeptr->tm_wday + '0';
207
        return 1;
208
    case 'W':
209
        if (sizeleft < 2)
210
            return -1;
211
        i = (timeptr->tm_yday + ((8-timeptr->tm_wday) % 7)) / 7;
212
        buf[0] = (i / 10) + '0';
213
        buf[1] = (i % 10) + '0';
214
        return 2;
215
    case 'x':
216
        if (sizeleft < 15)
217
            return -1;
218
 
219
        // Recurse! Note that we know that we will have left room for the
220
        // trailing NULL in the strftime body
221
 
222
        i = strftime( buf, sizeleft+1, "%a %b %d %Y", timeptr);
223
 
224
        return (0==i) ? -1 : i;
225
    case 'X':
226
        if (sizeleft < 10)
227
            return -1;
228
 
229
        // Recurse! Note that we know that we will have left room for the
230
        // trailing NULL in the strftime body
231
 
232
        i = strftime( buf, sizeleft+1, "%I:%M:%S%p", timeptr);
233
 
234
        return (0==i) ? -1 : i;
235
    case 'y':
236
        if (sizeleft < 2)
237
            return -1;
238
        buf[0] = ((timeptr->tm_year % 100) / 10) + '0';
239
        buf[1] = ((timeptr->tm_year % 100) % 10) + '0';
240
        return 2;
241
    case 'Y':
242
        if (sizeleft < 4)
243
            return -1;
244
        buf[0] = ((1900+timeptr->tm_year) / 1000) + '0';
245
        buf[1] = (((1900+timeptr->tm_year) % 1000) / 100) + '0';
246
        buf[2] = ((timeptr->tm_year % 100) / 10) + '0';
247
        buf[3] = (timeptr->tm_year % 10) + '0';
248
        return 4;
249
    case 'Z':
250
        // FIXME: Should store zone in timeptr->tm_zone, or failing that
251
        // read TZ env variable using tzset()
252
        return 0;
253
    case '%':
254
        // Don't need to check size - we'll always be called with sizeleft > 0
255
        buf[0] = '%';
256
        return 1;
257
    default:
258
        CYG_FAIL("invalid format character!");
259
        return -1;
260
    } // switch
261
 
262
} // do_format()
263
 
264
externC size_t
265
strftime( char *s, size_t maxsize, const char *format,
266
          const struct tm *timeptr)
267
{
268
    CYG_REPORT_FUNCNAMETYPE("strftime", "returning string length %d");
269
    CYG_CHECK_DATA_PTR(s, "string s is not a valid address!");
270
    CYG_CHECK_DATA_PTR(format, "format string is not at a valid address!");
271
    CYG_CHECK_DATA_PTR(timeptr,
272
                       "struct tm argument is not at a valid address!");
273
    CYG_REPORT_FUNCARG4("s is at address %08x, maxsize=%d, format=\"%s\", "
274
                        "timeptr is at address %08x",
275
                        s, maxsize, format, timeptr);
276
 
277
    CYG_PRECONDITION((timeptr->tm_sec >= 0) && (timeptr->tm_sec < 62),
278
                     "timeptr->tm_sec out of range!");
279
    CYG_PRECONDITION((timeptr->tm_min >= 0) && (timeptr->tm_min < 60),
280
                     "timeptr->tm_min out of range!");
281
    CYG_PRECONDITION((timeptr->tm_hour >= 0) && (timeptr->tm_hour < 24),
282
                     "timeptr->tm_hour out of range!");
283
    // Currently I don't check _actual_ numbers of days in each month here
284
    // FIXME: No reason why not though
285
    CYG_PRECONDITION((timeptr->tm_mday >= 1) && (timeptr->tm_mday < 32),
286
                     "timeptr->tm_mday out of range!");
287
    CYG_PRECONDITION((timeptr->tm_mon >= 0) && (timeptr->tm_mon < 12),
288
                     "timeptr->tm_mon out of range!");
289
    CYG_PRECONDITION((timeptr->tm_wday >= 0) && (timeptr->tm_wday < 7),
290
                     "timeptr->tm_wday out of range!");
291
    CYG_PRECONDITION((timeptr->tm_yday >= 0) && (timeptr->tm_yday < 366),
292
                     "timeptr->tm_yday out of range!");
293
    CYG_PRECONDITION((timeptr->tm_year > -1900) &&
294
                     (timeptr->tm_year < 8100),
295
                     "timeptr->tm_year out of range!");
296
 
297
    if (!maxsize) {
298
        CYG_REPORT_RETVAL(0);
299
        return 0;
300
    } // if
301
 
302
    // lets leave the room for the trailing null up front
303
    --maxsize;
304
 
305
    cyg_ucount32 i, spos;
306
    cyg_int8 dof_ret;
307
 
308
    for (i=0, spos=0; (spos<maxsize) && (format[i] != '\0'); ++i) {
309
        if (format[i] == '%') {
310
            if (format[++i] == '\0')
311
                break;
312
            dof_ret = do_format(format[i], maxsize - spos, &s[spos], timeptr);
313
            // was there room to write _anything_?
314
            if (dof_ret < 0) {
315
                spos=0;  // ISO says we must return 0 and the contents of s
316
                         // are indeterminate
317
                break;
318
            }
319
            spos += dof_ret;
320
        }
321
        else {
322
            s[spos++] = format[i];
323
        } // else
324
    } // for
325
 
326
    s[spos] = '\0';
327
 
328
    CYG_REPORT_RETVAL(spos);
329
    return spos;
330
 
331
} // strftime()
332
 
333
 
334
// EOF strftime.cxx

powered by: WebSVN 2.1.0

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