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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [tcl/] [compat/] [strftime.c] - Blame information for rev 1774

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

Line No. Rev Author Line
1 578 markom
/*
2
 * strftime.c --
3
 *
4
 *      This file contains a modified version of the BSD 4.4 strftime
5
 *      function.
6
 *
7
 * This file is a modified version of the strftime.c file from the BSD 4.4
8
 * source.  See the copyright notice below for details on redistribution
9
 * restrictions.  The "license.terms" file does not apply to this file.
10
 *
11
 * RCS: @(#) $Id: strftime.c,v 1.1.1.1 2002-01-16 10:25:23 markom Exp $
12
 */
13
 
14
/*
15
 * Copyright (c) 1989 The Regents of the University of California.
16
 * All rights reserved.
17
 *
18
 * Redistribution and use in source and binary forms, with or without
19
 * modification, are permitted provided that the following conditions
20
 * are met:
21
 * 1. Redistributions of source code must retain the above copyright
22
 *    notice, this list of conditions and the following disclaimer.
23
 * 2. Redistributions in binary form must reproduce the above copyright
24
 *    notice, this list of conditions and the following disclaimer in the
25
 *    documentation and/or other materials provided with the distribution.
26
 * 3. All advertising materials mentioning features or use of this software
27
 *    must display the following acknowledgement:
28
 *      This product includes software developed by the University of
29
 *      California, Berkeley and its contributors.
30
 * 4. Neither the name of the University nor the names of its contributors
31
 *    may be used to endorse or promote products derived from this software
32
 *    without specific prior written permission.
33
 *
34
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
35
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
38
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44
 * SUCH DAMAGE.
45
 */
46
 
47
#if defined(LIBC_SCCS)
48
static char *rcsid = "$Id: strftime.c,v 1.1.1.1 2002-01-16 10:25:23 markom Exp $";
49
#endif /* LIBC_SCCS */
50
 
51
#include <time.h>
52
#include <string.h>
53
#include <locale.h>
54
#include "tclInt.h"
55
#include "tclPort.h"
56
 
57
#define TM_YEAR_BASE   1900
58
 
59
typedef struct {
60
    const char *abday[7];
61
    const char *day[7];
62
    const char *abmon[12];
63
    const char *mon[12];
64
    const char *am_pm[2];
65
    const char *d_t_fmt;
66
    const char *d_fmt;
67
    const char *t_fmt;
68
    const char *t_fmt_ampm;
69
} _TimeLocale;
70
 
71
static const _TimeLocale _DefaultTimeLocale =
72
{
73
    {
74
        "Sun","Mon","Tue","Wed","Thu","Fri","Sat",
75
    },
76
    {
77
        "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
78
        "Friday", "Saturday"
79
    },
80
    {
81
        "Jan", "Feb", "Mar", "Apr", "May", "Jun",
82
        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
83
    },
84
    {
85
        "January", "February", "March", "April", "May", "June", "July",
86
        "August", "September", "October", "November", "December"
87
    },
88
    {
89
        "AM", "PM"
90
    },
91
    "%a %b %d %H:%M:%S %Y",
92
    "%m/%d/%y",
93
    "%H:%M:%S",
94
    "%I:%M:%S %p"
95
};
96
 
97
static const _TimeLocale *_CurrentTimeLocale = &_DefaultTimeLocale;
98
 
99
static size_t gsize;
100
static char *pt;
101
static int               _add _ANSI_ARGS_((const char* str));
102
static int              _conv _ANSI_ARGS_((int n, int digits, int pad));
103
static int              _secs _ANSI_ARGS_((const struct tm *t));
104
static size_t           _fmt _ANSI_ARGS_((const char *format,
105
                            const struct tm *t));
106
 
107
size_t
108
TclStrftime(s, maxsize, format, t)
109
    char *s;
110
    size_t maxsize;
111
    const char *format;
112
    const struct tm *t;
113
{
114
    tzset();
115
 
116
    pt = s;
117
    if ((gsize = maxsize) < 1)
118
        return(0);
119
    if (_fmt(format, t)) {
120
        *pt = '\0';
121
        return(maxsize - gsize);
122
    }
123
    return(0);
124
}
125
 
126
#define SUN_WEEK(t)     (((t)->tm_yday + 7 - \
127
                                ((t)->tm_wday)) / 7)
128
#define MON_WEEK(t)     (((t)->tm_yday + 7 - \
129
                                ((t)->tm_wday ? (t)->tm_wday - 1 : 6)) / 7)
130
 
131
static size_t
132
_fmt(format, t)
133
    const char *format;
134
    const struct tm *t;
135
{
136
    for (; *format; ++format) {
137
        if (*format == '%') {
138
            ++format;
139
            if (*format == 'E') {
140
                                /* Alternate Era */
141
                ++format;
142
            } else if (*format == 'O') {
143
                                /* Alternate numeric symbols */
144
                ++format;
145
            }
146
            switch(*format) {
147
                case '\0':
148
                    --format;
149
                    break;
150
                case 'A':
151
                    if (t->tm_wday < 0 || t->tm_wday > 6)
152
                        return(0);
153
                    if (!_add(_CurrentTimeLocale->day[t->tm_wday]))
154
                        return(0);
155
                    continue;
156
                case 'a':
157
                    if (t->tm_wday < 0 || t->tm_wday > 6)
158
                        return(0);
159
                    if (!_add(_CurrentTimeLocale->abday[t->tm_wday]))
160
                        return(0);
161
                    continue;
162
                case 'B':
163
                    if (t->tm_mon < 0 || t->tm_mon > 11)
164
                        return(0);
165
                    if (!_add(_CurrentTimeLocale->mon[t->tm_mon]))
166
                        return(0);
167
                    continue;
168
                case 'b':
169
                case 'h':
170
                    if (t->tm_mon < 0 || t->tm_mon > 11)
171
                        return(0);
172
                    if (!_add(_CurrentTimeLocale->abmon[t->tm_mon]))
173
                        return(0);
174
                    continue;
175
                case 'C':
176
                    if (!_conv((t->tm_year + TM_YEAR_BASE) / 100,
177
                            2, '0'))
178
                        return(0);
179
                    continue;
180
                case 'c':
181
                    if (!_fmt(_CurrentTimeLocale->d_t_fmt, t))
182
                        return(0);
183
                    continue;
184
                case 'D':
185
                    if (!_fmt("%m/%d/%y", t))
186
                        return(0);
187
                    continue;
188
                case 'd':
189
                    if (!_conv(t->tm_mday, 2, '0'))
190
                        return(0);
191
                    continue;
192
                case 'e':
193
                    if (!_conv(t->tm_mday, 2, ' '))
194
                        return(0);
195
                    continue;
196
                case 'H':
197
                    if (!_conv(t->tm_hour, 2, '0'))
198
                        return(0);
199
                    continue;
200
                case 'I':
201
                    if (!_conv(t->tm_hour % 12 ?
202
                            t->tm_hour % 12 : 12, 2, '0'))
203
                        return(0);
204
                    continue;
205
                case 'j':
206
                    if (!_conv(t->tm_yday + 1, 3, '0'))
207
                        return(0);
208
                    continue;
209
                case 'k':
210
                    if (!_conv(t->tm_hour, 2, ' '))
211
                        return(0);
212
                    continue;
213
                case 'l':
214
                    if (!_conv(t->tm_hour % 12 ?
215
                            t->tm_hour % 12: 12, 2, ' '))
216
                        return(0);
217
                    continue;
218
                case 'M':
219
                    if (!_conv(t->tm_min, 2, '0'))
220
                        return(0);
221
                    continue;
222
                case 'm':
223
                    if (!_conv(t->tm_mon + 1, 2, '0'))
224
                        return(0);
225
                    continue;
226
                case 'n':
227
                    if (!_add("\n"))
228
                        return(0);
229
                    continue;
230
                case 'p':
231
                    if (!_add(_CurrentTimeLocale->am_pm[t->tm_hour >= 12]))
232
                        return(0);
233
                    continue;
234
                case 'R':
235
                    if (!_fmt("%H:%M", t))
236
                        return(0);
237
                    continue;
238
                case 'r':
239
                    if (!_fmt(_CurrentTimeLocale->t_fmt_ampm, t))
240
                        return(0);
241
                    continue;
242
                case 'S':
243
                    if (!_conv(t->tm_sec, 2, '0'))
244
                        return(0);
245
                    continue;
246
                case 's':
247
                    if (!_secs(t))
248
                        return(0);
249
                    continue;
250
                case 'T':
251
                    if (!_fmt("%H:%M:%S", t))
252
                        return(0);
253
                    continue;
254
                case 't':
255
                    if (!_add("\t"))
256
                        return(0);
257
                    continue;
258
                case 'U':
259
                    if (!_conv(SUN_WEEK(t), 2, '0'))
260
                        return(0);
261
                    continue;
262
                case 'u':
263
                    if (!_conv(t->tm_wday ? t->tm_wday : 7, 1, '0'))
264
                        return(0);
265
                    continue;
266
                case 'V':
267
                {
268
                                /* ISO 8601 Week Of Year:
269
                                   If the week (Monday - Sunday) containing
270
                                   January 1 has four or more days in the new
271
                                   year, then it is week 1; otherwise it is
272
                                   week 53 of the previous year and the next
273
                                   week is week one. */
274
 
275
                    int week = MON_WEEK(t);
276
 
277
                    int days = (((t)->tm_yday + 7 - \
278
                            ((t)->tm_wday ? (t)->tm_wday - 1 : 6)) % 7);
279
 
280
 
281
                    if (days >= 4) {
282
                        week++;
283
                    } else if (week == 0) {
284
                        week = 53;
285
                    }
286
 
287
                    if (!_conv(week, 2, '0'))
288
                        return(0);
289
                    continue;
290
                }
291
                case 'W':
292
                    if (!_conv(MON_WEEK(t), 2, '0'))
293
                        return(0);
294
                    continue;
295
                case 'w':
296
                    if (!_conv(t->tm_wday, 1, '0'))
297
                        return(0);
298
                    continue;
299
                case 'x':
300
                    if (!_fmt(_CurrentTimeLocale->d_fmt, t))
301
                        return(0);
302
                    continue;
303
                case 'X':
304
                    if (!_fmt(_CurrentTimeLocale->t_fmt, t))
305
                        return(0);
306
                    continue;
307
                case 'y':
308
                    if (!_conv((t->tm_year + TM_YEAR_BASE) % 100,
309
                            2, '0'))
310
                        return(0);
311
                    continue;
312
                case 'Y':
313
                    if (!_conv((t->tm_year + TM_YEAR_BASE), 4, '0'))
314
                        return(0);
315
                    continue;
316
#ifndef MAC_TCL
317
                case 'Z': {
318
                    char *name = TclpGetTZName();
319
                    if (name && !_add(name)) {
320
                        return 0;
321
                    }
322
                    continue;
323
                }
324
#endif
325
                case '%':
326
                    /*
327
                     * X311J/88-090 (4.12.3.5): if conversion char is
328
                     * undefined, behavior is undefined.  Print out the
329
                     * character itself as printf(3) does.
330
                     */
331
                default:
332
                    break;
333
            }
334
        }
335
        if (!gsize--)
336
            return(0);
337
        *pt++ = *format;
338
    }
339
    return(gsize);
340
}
341
 
342
static int
343
_secs(t)
344
    const struct tm *t;
345
{
346
    static char buf[15];
347
    register time_t s;
348
    register char *p;
349
    struct tm tmp;
350
 
351
    /* Make a copy, mktime(3) modifies the tm struct. */
352
    tmp = *t;
353
    s = mktime(&tmp);
354
    for (p = buf + sizeof(buf) - 2; s > 0 && p > buf; s /= 10)
355
        *p-- = (char)(s % 10 + '0');
356
    return(_add(++p));
357
}
358
 
359
static int
360
_conv(n, digits, pad)
361
    int n, digits;
362
    int pad;
363
{
364
    static char buf[10];
365
    register char *p;
366
 
367
    for (p = buf + sizeof(buf) - 2; n > 0 && p > buf; n /= 10, --digits)
368
        *p-- = (char)(n % 10 + '0');
369
    while (p > buf && digits-- > 0)
370
        *p-- = (char) pad;
371
    return(_add(++p));
372
}
373
 
374
static int
375
_add(str)
376
    const char *str;
377
{
378
    for (;; ++pt, --gsize) {
379
        if (!gsize)
380
            return(0);
381
        if (!(*pt = *str++))
382
            return(1);
383
    }
384
}

powered by: WebSVN 2.1.0

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