OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [newlib-1.18.0/] [newlib/] [libc/] [time/] [strptime.c] - Blame information for rev 252

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

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

powered by: WebSVN 2.1.0

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