/[dtapublic]/projs/trunk/shared_source/c_tcl_base_7_5_w_mods/strftime.c
ViewVC logotype

Annotation of /projs/trunk/shared_source/c_tcl_base_7_5_w_mods/strftime.c

Parent Directory Parent Directory | Revision Log Revision Log


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

Properties

Name Value
svn:eol-style native
svn:keywords Header

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25