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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 71 - (show annotations) (download)
Sat Nov 5 11:07:06 2016 UTC (8 years, 1 month 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 /* $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