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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [language/] [c/] [libc/] [time/] [current/] [src/] [strftime.cxx] - Blame information for rev 810

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

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

powered by: WebSVN 2.1.0

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