os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/compat/strftime.c
Update contrib.
4 * This file contains a modified version of the BSD 4.4 strftime
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.
11 * Changes 2002 Copyright (c) 2002 ActiveState Corporation.
13 * RCS: @(#) $Id: strftime.c,v 1.10.2.3 2005/11/04 18:18:04 kennykb Exp $
17 * Copyright (c) 1989 The Regents of the University of California.
18 * All rights reserved.
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions
23 * 1. Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 * 2. Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in the
27 * documentation and/or other materials provided with the distribution.
28 * 3. All advertising materials mentioning features or use of this software
29 * must display the following acknowledgement:
30 * This product includes software developed by the University of
31 * California, Berkeley and its contributors.
32 * 4. Neither the name of the University nor the names of its contributors
33 * may be used to endorse or promote products derived from this software
34 * without specific prior written permission.
36 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
37 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
39 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
40 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
41 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
42 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
44 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
45 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
49 #if defined(LIBC_SCCS)
50 static char *rcsid = "$Id: strftime.c,v 1.10.2.3 2005/11/04 18:18:04 kennykb Exp $";
51 #endif /* LIBC_SCCS */
59 #define TM_YEAR_BASE 1900
60 #define IsLeapYear(x) ((x % 4 == 0) && (x % 100 != 0 || x % 400 == 0))
65 const char *abmon[12];
71 const char *t_fmt_ampm;
75 * This is the C locale default. On Windows, if we wanted to make this
76 * localized, we would use GetLocaleInfo to get the correct values.
77 * It may be acceptable to do localization of month/day names, as the
78 * numerical values would be considered the locale-independent versions.
80 static const _TimeLocale _DefaultTimeLocale =
83 "Sun","Mon","Tue","Wed","Thu","Fri","Sat",
86 "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
90 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
91 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
94 "January", "February", "March", "April", "May", "June", "July",
95 "August", "September", "October", "November", "December"
100 "%a %b %d %H:%M:%S %Y",
106 static const _TimeLocale *_CurrentTimeLocale = &_DefaultTimeLocale;
111 static int _add _ANSI_ARGS_((const char* str));
112 static int _conv _ANSI_ARGS_((int n, int digits, int pad));
113 static int _secs _ANSI_ARGS_((const struct tm *t));
114 static size_t _fmt _ANSI_ARGS_((const char *format,
115 const struct tm *t));
116 static int ISO8601Week _ANSI_ARGS_((CONST struct tm* t, int *year ));
119 TclpStrftime(s, maxsize, format, t, useGMT)
126 if (format[0] == '%' && format[1] == 'Q') {
127 /* Format as a stardate */
128 sprintf(s, "Stardate %2d%03d.%01d",
129 (((t->tm_year + TM_YEAR_BASE) + 377) - 2323),
130 (((t->tm_yday + 1) * 1000) /
131 (365 + IsLeapYear((t->tm_year + TM_YEAR_BASE)))),
132 (((t->tm_hour * 60) + t->tm_min)/144));
138 * We may be able to skip this for useGMT, but it should be harmless.
144 if ((gsize = maxsize) < 1)
146 if (_fmt(format, t)) {
148 return(maxsize - gsize);
153 #define SUN_WEEK(t) (((t)->tm_yday + 7 - \
155 #define MON_WEEK(t) (((t)->tm_yday + 7 - \
156 ((t)->tm_wday ? (t)->tm_wday - 1 : 6)) / 7)
177 for (; *format; ++format) {
178 if (*format == '%') {
180 if (*format == 'E') {
183 } else if (*format == 'O') {
184 /* Alternate numeric symbols */
192 if (t->tm_wday < 0 || t->tm_wday > 6)
194 if (!_add(_CurrentTimeLocale->day[t->tm_wday]))
198 if (t->tm_wday < 0 || t->tm_wday > 6)
200 if (!_add(_CurrentTimeLocale->abday[t->tm_wday]))
204 if (t->tm_mon < 0 || t->tm_mon > 11)
206 if (!_add(_CurrentTimeLocale->mon[t->tm_mon]))
211 if (t->tm_mon < 0 || t->tm_mon > 11)
213 if (!_add(_CurrentTimeLocale->abmon[t->tm_mon]))
217 if (!_conv((t->tm_year + TM_YEAR_BASE) / 100,
222 if (!_fmt("%m/%d/%y", t))
226 if (!_conv(t->tm_mday, 2, '0'))
230 if (!_conv(t->tm_mday, 2, ' '))
236 ISO8601Week( t, &year );
237 if ( !_conv( year%100, 2, '0' ) ) {
245 ISO8601Week( t, &year );
246 if ( !_conv( year, 4, '0' ) ) {
252 if (!_conv(t->tm_hour, 2, '0'))
256 if (!_conv(t->tm_hour % 12 ?
257 t->tm_hour % 12 : 12, 2, '0'))
261 if (!_conv(t->tm_yday + 1, 3, '0'))
265 if (!_conv(t->tm_hour, 2, ' '))
269 if (!_conv(t->tm_hour % 12 ?
270 t->tm_hour % 12: 12, 2, ' '))
274 if (!_conv(t->tm_min, 2, '0'))
278 if (!_conv(t->tm_mon + 1, 2, '0'))
286 if (!_add(_CurrentTimeLocale->am_pm[t->tm_hour >= 12]))
290 if (!_fmt("%H:%M", t))
294 if (!_fmt(_CurrentTimeLocale->t_fmt_ampm, t))
298 if (!_conv(t->tm_sec, 2, '0'))
306 if (!_fmt("%H:%M:%S", t))
314 if (!_conv(SUN_WEEK(t), 2, '0'))
318 if (!_conv(t->tm_wday ? t->tm_wday : 7, 1, '0'))
323 int week = ISO8601Week( t, NULL );
324 if (!_conv(week, 2, '0'))
329 if (!_conv(MON_WEEK(t), 2, '0'))
333 if (!_conv(t->tm_wday, 1, '0'))
338 * To properly handle the localized time routines on Windows,
339 * we must make use of the special localized calls.
342 if (!GetDateFormat(LOCALE_USER_DEFAULT,
343 DATE_LONGDATE | LOCALE_USE_CP_ACP,
344 &syst, NULL, buf, BUF_SIZ)
350 * %c is created with LONGDATE + " " + TIME on Windows,
351 * so continue to %X case here.
354 if (!GetTimeFormat(LOCALE_USER_DEFAULT,
356 &syst, NULL, buf, BUF_SIZ)
362 if (!GetDateFormat(LOCALE_USER_DEFAULT,
363 DATE_SHORTDATE | LOCALE_USE_CP_ACP,
364 &syst, NULL, buf, BUF_SIZ)
371 if (!_fmt(_CurrentTimeLocale->d_t_fmt, t))
375 if (!_fmt(_CurrentTimeLocale->d_fmt, t))
379 if (!_fmt(_CurrentTimeLocale->t_fmt, t))
384 if (!_conv((t->tm_year + TM_YEAR_BASE) % 100,
389 if (!_conv((t->tm_year + TM_YEAR_BASE), 4, '0'))
393 char *name = (isGMT ? "GMT" : TclpGetTZName(t->tm_isdst));
395 Tcl_UtfToExternal(NULL, NULL, name, -1, 0, NULL,
396 pt, gsize, NULL, &wrote, NULL);
403 * X311J/88-090 (4.12.3.5): if conversion char is
404 * undefined, behavior is undefined. Print out the
405 * character itself as printf(3) does.
427 /* Make a copy, mktime(3) modifies the tm struct. */
430 for (p = buf + sizeof(buf) - 2; s > 0 && p > buf; s /= 10)
431 *p-- = (char)(s % 10 + '0');
436 _conv(n, digits, pad)
443 p = buf + sizeof( buf ) - 1;
446 *p-- = '0'; --digits;
448 for (; n > 0 && p > buf; n /= 10, --digits)
449 *p-- = (char)(n % 10 + '0');
451 while (p > buf && digits-- > 0)
460 for (;; ++pt, --gsize) {
469 ISO8601Week( t, year )
473 /* Find the day-of-year of the Thursday in
474 * the week in question. */
478 if ( t->tm_wday == 0 ) {
479 ydayThursday = t->tm_yday - 3;
481 ydayThursday = t->tm_yday - t->tm_wday + 4;
484 if ( ydayThursday < 0 ) {
486 /* This is the last week of the previous year. */
487 if ( IsLeapYear(( t->tm_year + TM_YEAR_BASE - 1 )) ) {
492 week = ydayThursday / 7 + 1;
493 if ( year != NULL ) {
494 *year = t->tm_year + 1899;
497 } else if ( ( IsLeapYear(( t -> tm_year + TM_YEAR_BASE ))
498 && ydayThursday >= 366 )
499 || ( !IsLeapYear(( t -> tm_year
501 && ydayThursday >= 365 ) ) {
503 /* This is week 1 of the following year */
506 if ( year != NULL ) {
507 *year = t->tm_year + 1901;
512 week = ydayThursday / 7 + 1;
513 if ( year != NULL ) {
514 *year = t->tm_year + 1900;