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/] [strptime.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
// Adapted for use in eCos by Gary Thomas
3
// Copyright (C) 2003 Gary Thomas
4
//
5
 
6
/*
7
 * Copyright (c) 1999 Kungliga Tekniska Högskolan
8
 * (Royal Institute of Technology, Stockholm, Sweden).
9
 * All rights reserved.
10
 *
11
 * Redistribution and use in source and binary forms, with or without
12
 * modification, are permitted provided that the following conditions
13
 * are met:
14
 *
15
 * 1. Redistributions of source code must retain the above copyright
16
 *    notice, this list of conditions and the following disclaimer.
17
 *
18
 * 2. Redistributions in binary form must reproduce the above copyright
19
 *    notice, this list of conditions and the following disclaimer in the
20
 *    documentation and/or other materials provided with the distribution.
21
 *
22
 * 3. Neither the name of KTH nor the names of its contributors may be
23
 *    used to endorse or promote products derived from this software without
24
 *    specific prior written permission.
25
 *
26
 * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
27
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
30
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
33
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
34
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
35
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
36
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
37
 
38
#include <stddef.h>
39
#include <stdlib.h>
40
#include <ctype.h>
41
#include <string.h>
42
#include <time.h>
43
 
44
static const char *weekdays[] = {
45
    "Sunday",
46
    "Monday",
47
    "Tuesday",
48
    "Wednesday",
49
    "Thursday",
50
    "Friday",
51
    "Saturday",
52
    NULL
53
};
54
 
55
static const char *month[] = {
56
    "January",
57
    "February",
58
    "March",
59
    "April",
60
    "May",
61
    "June",
62
    "July",
63
    "August",
64
    "September",
65
    "October",
66
    "November",
67
    "December",
68
    NULL,
69
};
70
 
71
static const char *ampm[] = {
72
    "am",
73
    "pm",
74
    NULL
75
};
76
 
77
/*
78
 * Try to match `*buf' to one of the strings in `strs'.  Return the
79
 * index of the matching string (or -1 if none).  Also advance buf.
80
 */
81
 
82
static int
83
match_string (const char **buf, const char **strs, int ablen)
84
{
85
    int i = 0;
86
 
87
    for (i = 0; strs[i] != NULL; ++i) {
88
        int len = ablen > 0 ? ablen : strlen (strs[i]);
89
 
90
        if (strncasecmp (*buf, strs[i], len) == 0) {
91
            *buf += len;
92
            return i;
93
        }
94
    }
95
    return -1;
96
}
97
 
98
/*
99
 * tm_year is relative this year
100
 */
101
 
102
const int tm_year_base = 1900;
103
 
104
/*
105
 * Return TRUE iff `year' was a leap year.
106
 */
107
 
108
static int
109
is_leap_year (int year)
110
{
111
    return (year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0);
112
}
113
 
114
/*
115
 * Return the weekday [0,6] (0 = Sunday) of the first day of `year'
116
 */
117
 
118
static int
119
first_day (int year)
120
{
121
    int ret = 4;  // Jan 1, 1970 was on Thursday
122
 
123
    for (; year > 1970; --year)
124
        ret = (ret + 365 + is_leap_year (year) ? 1 : 0) % 7;
125
    return ret;
126
}
127
 
128
/*
129
 * Set `timeptr' given `wnum' (week number [0, 53])
130
 */
131
 
132
static void
133
set_week_number_sun (struct tm *timeptr, int wnum)
134
{
135
    int fday = first_day (timeptr->tm_year + tm_year_base);
136
 
137
    timeptr->tm_yday = wnum * 7 + timeptr->tm_wday - fday;
138
    if (timeptr->tm_yday < 0) {
139
        timeptr->tm_wday = fday;
140
        timeptr->tm_yday = 0;
141
    }
142
}
143
 
144
/*
145
 * Set `timeptr' given `wnum' (week number [0, 53])
146
 */
147
 
148
static void
149
set_week_number_mon (struct tm *timeptr, int wnum)
150
{
151
    int fday = (first_day (timeptr->tm_year + tm_year_base) + 6) % 7;
152
 
153
    timeptr->tm_yday = wnum * 7 + (timeptr->tm_wday + 6) % 7 - fday;
154
    if (timeptr->tm_yday < 0) {
155
        timeptr->tm_wday = (fday + 1) % 7;
156
        timeptr->tm_yday = 0;
157
    }
158
}
159
 
160
/*
161
 * Set `timeptr' given `wnum' (week number [0, 53])
162
 */
163
 
164
static void
165
set_week_number_mon4 (struct tm *timeptr, int wnum)
166
{
167
    int fday = (first_day (timeptr->tm_year + tm_year_base) + 6) % 7;
168
    int offset = 0;
169
 
170
    if (fday < 4)
171
        offset += 7;
172
 
173
    timeptr->tm_yday = offset + (wnum - 1) * 7 + timeptr->tm_wday - fday;
174
    if (timeptr->tm_yday < 0) {
175
        timeptr->tm_wday = fday;
176
        timeptr->tm_yday = 0;
177
    }
178
}
179
 
180
/*
181
 *
182
 */
183
 
184
char *
185
strptime (const char *buf, const char *format, struct tm *timeptr)
186
{
187
    char c;
188
 
189
    for (; (c = *format) != '\0'; ++format) {
190
        char *s;
191
        int ret;
192
 
193
        if (isspace (c)) {
194
            while (isspace (*buf))
195
                ++buf;
196
        } else if (c == '%' && format[1] != '\0') {
197
            c = *++format;
198
            if (c == 'E' || c == 'O')
199
                c = *++format;
200
            switch (c) {
201
            case 'A' :
202
                ret = match_string (&buf, weekdays, 0);
203
                if (ret < 0)
204
                    return NULL;
205
                timeptr->tm_wday = ret;
206
                break;
207
            case 'a' :
208
                ret = match_string (&buf, weekdays, 3);
209
                if (ret < 0)
210
                    return NULL;
211
                timeptr->tm_wday = ret;
212
                break;
213
            case 'B' :
214
                ret = match_string (&buf, month, 0);
215
                if (ret < 0)
216
                    return NULL;
217
                timeptr->tm_mon = ret;
218
                break;
219
            case 'b' :
220
            case 'h' :
221
                ret = match_string (&buf, month, 3);
222
                if (ret < 0)
223
                    return NULL;
224
                timeptr->tm_mon = ret;
225
                break;
226
            case 'C' :
227
                ret = strtol (buf, &s, 10);
228
                if (s == buf)
229
                    return NULL;
230
                timeptr->tm_year = (ret * 100) - tm_year_base;
231
                buf = s;
232
                break;
233
            case 'c' :
234
                // Date and Time in the current locale - unsupported
235
                return NULL;
236
            case 'D' :          /* %m/%d/%y */
237
                s = strptime (buf, "%m/%d/%y", timeptr);
238
                if (s == NULL)
239
                    return NULL;
240
                buf = s;
241
                break;
242
            case 'd' :
243
            case 'e' :
244
                ret = strtol (buf, &s, 10);
245
                if (s == buf)
246
                    return NULL;
247
                timeptr->tm_mday = ret;
248
                buf = s;
249
                break;
250
            case 'H' :
251
            case 'k' :
252
                ret = strtol (buf, &s, 10);
253
                if (s == buf)
254
                    return NULL;
255
                timeptr->tm_hour = ret;
256
                buf = s;
257
                break;
258
            case 'I' :
259
            case 'l' :
260
                ret = strtol (buf, &s, 10);
261
                if (s == buf)
262
                    return NULL;
263
                if (ret == 12)
264
                    timeptr->tm_hour = 0;
265
                else
266
                    timeptr->tm_hour = ret;
267
                buf = s;
268
                break;
269
            case 'j' :
270
                ret = strtol (buf, &s, 10);
271
                if (s == buf)
272
                    return NULL;
273
                timeptr->tm_yday = ret - 1;
274
                buf = s;
275
                break;
276
            case 'm' :
277
                ret = strtol (buf, &s, 10);
278
                if (s == buf)
279
                    return NULL;
280
                timeptr->tm_mon = ret - 1;
281
                buf = s;
282
                break;
283
            case 'M' :
284
                ret = strtol (buf, &s, 10);
285
                if (s == buf)
286
                    return NULL;
287
                timeptr->tm_min = ret;
288
                buf = s;
289
                break;
290
            case 'n' :
291
                if (*buf == '\n')
292
                    ++buf;
293
                else
294
                    return NULL;
295
                break;
296
            case 'p' :
297
                ret = match_string (&buf, ampm, 0);
298
                if (ret < 0)
299
                    return NULL;
300
                if (timeptr->tm_hour == 0) {
301
                    if (ret == 1)
302
                        timeptr->tm_hour = 12;
303
                } else
304
                    timeptr->tm_hour += 12;
305
                break;
306
            case 'r' :          /* %I:%M:%S %p */
307
                s = strptime (buf, "%I:%M:%S %p", timeptr);
308
                if (s == NULL)
309
                    return NULL;
310
                buf = s;
311
                break;
312
            case 'R' :          /* %H:%M */
313
                s = strptime (buf, "%H:%M", timeptr);
314
                if (s == NULL)
315
                    return NULL;
316
                buf = s;
317
                break;
318
            case 'S' :
319
                ret = strtol (buf, &s, 10);
320
                if (s == buf)
321
                    return NULL;
322
                timeptr->tm_sec = ret;
323
                buf = s;
324
                break;
325
            case 't' :
326
                if (*buf == '\t')
327
                    ++buf;
328
                else
329
                    return NULL;
330
                break;
331
            case 'T' :          /* %H:%M:%S */
332
            case 'X' :
333
                s = strptime (buf, "%H:%M:%S", timeptr);
334
                if (s == NULL)
335
                    return NULL;
336
                buf = s;
337
                break;
338
            case 'u' :
339
                ret = strtol (buf, &s, 10);
340
                if (s == buf)
341
                    return NULL;
342
                timeptr->tm_wday = ret - 1;
343
                buf = s;
344
                break;
345
            case 'w' :
346
                ret = strtol (buf, &s, 10);
347
                if (s == buf)
348
                    return NULL;
349
                timeptr->tm_wday = ret;
350
                buf = s;
351
                break;
352
            case 'U' :
353
                ret = strtol (buf, &s, 10);
354
                if (s == buf)
355
                    return NULL;
356
                set_week_number_sun (timeptr, ret);
357
                buf = s;
358
                break;
359
            case 'V' :
360
                ret = strtol (buf, &s, 10);
361
                if (s == buf)
362
                    return NULL;
363
                set_week_number_mon4 (timeptr, ret);
364
                buf = s;
365
                break;
366
            case 'W' :
367
                ret = strtol (buf, &s, 10);
368
                if (s == buf)
369
                    return NULL;
370
                set_week_number_mon (timeptr, ret);
371
                buf = s;
372
                break;
373
            case 'x' :
374
                s = strptime (buf, "%Y:%m:%d", timeptr);
375
                if (s == NULL)
376
                    return NULL;
377
                buf = s;
378
                break;
379
            case 'y' :
380
                ret = strtol (buf, &s, 10);
381
                if (s == buf)
382
                    return NULL;
383
                if (ret < 70)
384
                    timeptr->tm_year = 100 + ret;
385
                else
386
                    timeptr->tm_year = ret;
387
                buf = s;
388
                break;
389
            case 'Y' :
390
                ret = strtol (buf, &s, 10);
391
                if (s == buf)
392
                    return NULL;
393
                timeptr->tm_year = ret - tm_year_base;
394
                buf = s;
395
                break;
396
            case 'Z' :
397
                // Timezone spec not handled
398
                return NULL;
399
            case '\0' :
400
                --format;
401
                /* FALLTHROUGH */
402
            case '%' :
403
                if (*buf == '%')
404
                    ++buf;
405
                else
406
                    return NULL;
407
                break;
408
            default :
409
                if (*buf == '%' || *++buf == c)
410
                    ++buf;
411
                else
412
                    return NULL;
413
                break;
414
            }
415
        } else {
416
            if (*buf == c)
417
                ++buf;
418
            else
419
                return NULL;
420
        }
421
    }
422
    return (char *)buf;
423
}
424
 
425
// strptime.cxx

powered by: WebSVN 2.1.0

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