aboutsummaryrefslogtreecommitdiff
path: root/src/kadmin/cli/strftime.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kadmin/cli/strftime.c')
-rw-r--r--src/kadmin/cli/strftime.c881
1 files changed, 438 insertions, 443 deletions
diff --git a/src/kadmin/cli/strftime.c b/src/kadmin/cli/strftime.c
index 484852a..6fb621e 100644
--- a/src/kadmin/cli/strftime.c
+++ b/src/kadmin/cli/strftime.c
@@ -1,469 +1,464 @@
-/* strftime - custom formatting of date and/or time
- Copyright (C) 1989, 1991, 1992 Free Software Foundation, Inc.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-/* Note: this version of strftime lacks locale support,
- but it is standalone.
-
- Performs `%' substitutions similar to those in printf. Except
- where noted, substituted fields have a fixed size; numeric fields are
- padded if necessary. Padding is with zeros by default; for fields
- that display a single number, padding can be changed or inhibited by
- following the `%' with one of the modifiers described below. Unknown
- field specifiers are copied as normal characters. All other
- characters are copied to the output without change.
-
- Supports a superset of the ANSI C field specifiers.
-
- Literal character fields:
- % %
- n newline
- t tab
-
- Numeric modifiers (a nonstandard extension):
- - do not pad the field
- _ pad the field with spaces
-
- Time fields:
- %H hour (00..23)
- %I hour (01..12)
- %k hour ( 0..23)
- %l hour ( 1..12)
- %M minute (00..59)
- %p locale's AM or PM
- %r time, 12-hour (hh:mm:ss [AP]M)
- %R time, 24-hour (hh:mm)
- %s time in seconds since 00:00:00, Jan 1, 1970 (a nonstandard extension)
- %S second (00..61)
- %T time, 24-hour (hh:mm:ss)
- %X locale's time representation (%H:%M:%S)
- %Z time zone (EDT), or nothing if no time zone is determinable
-
- Date fields:
- %a locale's abbreviated weekday name (Sun..Sat)
- %A locale's full weekday name, variable length (Sunday..Saturday)
- %b locale's abbreviated month name (Jan..Dec)
- %B locale's full month name, variable length (January..December)
- %c locale's date and time (Sat Nov 04 12:02:33 EST 1989)
- %C century (00..99)
- %d day of month (01..31)
- %e day of month ( 1..31)
- %D date (mm/dd/yy)
- %h same as %b
- %j day of year (001..366)
- %m month (01..12)
- %U week number of year with Sunday as first day of week (00..53)
- %w day of week (0..6)
- %W week number of year with Monday as first day of week (00..53)
- %x locale's date representation (mm/dd/yy)
- %y last two digits of year (00..99)
- %Y year (1970...)
-
- David MacKenzie <djm@gnu.ai.mit.edu> */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <sys/types.h>
-#if defined(TM_IN_SYS_TIME) || (!defined(HAVE_TM_ZONE) && !defined(HAVE_TZNAME))
-#include <sys/time.h>
+/* $NetBSD: strftime.c,v 1.8 1999/02/07 17:33:30 augustss Exp $ */
+
+/*
+ * Copyright (c) 1989 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+#if 0
+static char *sccsid = "@(#)strftime.c 5.11 (Berkeley) 2/24/91";
#else
-#include <time.h>
-#endif
-
-#ifndef STDC_HEADERS
-time_t mktime ();
+__RCSID("$NetBSD: strftime.c,v 1.8 1999/02/07 17:33:30 augustss Exp $");
#endif
+#endif /* LIBC_SCCS and not lint */
-#if defined(HAVE_TZNAME)
-extern char *tzname[2];
-#endif
-
-/* Types of padding for numbers in date and time. */
-enum padding
-{
- none, blank, zero
-};
+#include <string.h>
+#include <time.h>
-static char const* const days[] =
-{
- "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
+/* begin krb5 hack - replace stuff that would come from netbsd libc */
+#undef _CurrentTimeLocale
+#define _CurrentTimeLocale (&dummy_locale_info)
+
+struct dummy_locale_info_t {
+ char d_t_fmt[15];
+ char t_fmt_ampm[12];
+ char t_fmt[9];
+ char d_fmt[9];
+ char day[7][10];
+ char abday[7][4];
+ char mon[12][10];
+ char abmon[12][4];
+ char am_pm[2][3];
};
-
-static char const * const months[] =
-{
- "January", "February", "March", "April", "May", "June",
- "July", "August", "September", "October", "November", "December"
+static const struct dummy_locale_info_t dummy_locale_info = {
+ "%a %b %d %X %Y", /* %c */
+ "%I:%M:%S %p", /* %r */
+ "%H:%M:%S", /* %X */
+ "%m/%d/%y", /* %x */
+ { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
+ "Saturday" },
+ { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" },
+ { "January", "February", "March", "April", "May", "June",
+ "July", "August", "September", "October", "November", "December" },
+ { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" },
+ { "AM", "PM" },
};
+#undef TM_YEAR_BASE
+#define TM_YEAR_BASE 1900
+
+#undef DAYSPERLYEAR
+#define DAYSPERLYEAR 366
+#undef DAYSPERNYEAR
+#define DAYSPERNYEAR 365
+#undef DAYSPERWEEK
+#define DAYSPERWEEK 7
+#undef isleap
+#define isleap(N) ((N % 4) == 0 && (N % 100 != 0 || N % 400 == 0))
+#undef tzname
+#define tzname my_tzname
+static const char *const tzname[2] = { 0, 0 };
+#undef tzset
+#define tzset()
+#undef __P
+#define __P(X) X /* we already require ansi c in this tree */
+/* end krb5 hack */
+
+static int _add __P((const char *, char **, const char *));
+static int _conv __P((int, int, int, char **, const char *));
+static int _secs __P((const struct tm *, char **, const char *));
+static size_t _fmt __P((const char *, const struct tm *, char **,
+ const char *));
-/* Add character C to STRING and increment LENGTH,
- unless LENGTH would exceed MAX. */
-
-#define add_char(c) \
- do \
- { \
- if (length + 1 <= max) \
- string[length++] = (c); \
- } \
- while (0)
-
-/* Add a 2 digit number to STRING, padding if specified.
- Return the number of characters added, up to MAX. */
-
-static int
-add_num2 (string, num, max, pad)
- char *string;
- int num;
- int max;
- enum padding pad;
-{
- int top = num / 10;
- int length = 0;
-
- if (top == 0 && pad == blank)
- add_char (' ');
- else if (top != 0 || pad == zero)
- add_char (top + '0');
- add_char (num % 10 + '0');
- return length;
-}
-
-/* Add a 3 digit number to STRING, padding if specified.
- Return the number of characters added, up to MAX. */
-
-static int
-add_num3 (string, num, max, pad)
- char *string;
- int num;
- int max;
- enum padding pad;
+size_t
+strftime(s, maxsize, format, t)
+ char *s;
+ size_t maxsize;
+ const char *format;
+ const struct tm *t;
{
- int top = num / 100;
- int mid = (num - top * 100) / 10;
- int length = 0;
-
- if (top == 0 && pad == blank)
- add_char (' ');
- else if (top != 0 || pad == zero)
- add_char (top + '0');
- if (mid == 0 && top == 0 && pad == blank)
- add_char (' ');
- else if (mid != 0 || top != 0 || pad == zero)
- add_char (mid + '0');
- add_char (num % 10 + '0');
- return length;
+ char *pt;
+
+ tzset();
+ if (maxsize < 1)
+ return (0);
+
+ pt = s;
+ if (_fmt(format, t, &pt, s + maxsize)) {
+ *pt = '\0';
+ return (pt - s);
+ } else
+ return (0);
}
-/* Like strncpy except return the number of characters copied. */
-
-static int
-add_str (to, from, max)
- char *to;
- const char *from;
- int max;
+#define SUN_WEEK(t) (((t)->tm_yday + 7 - \
+ ((t)->tm_wday)) / 7)
+#define MON_WEEK(t) (((t)->tm_yday + 7 - \
+ ((t)->tm_wday ? (t)->tm_wday - 1 : 6)) / 7)
+
+static size_t
+_fmt(format, t, pt, ptlim)
+ const char *format;
+ const struct tm *t;
+ char **pt;
+ const char * const ptlim;
{
- int i;
-
- for (i = 0; from[i] && i <= max; ++i)
- to[i] = from[i];
- return i;
+ for (; *format; ++format) {
+ if (*format == '%') {
+ ++format;
+ if (*format == 'E') {
+ /* Alternate Era */
+ ++format;
+ } else if (*format == 'O') {
+ /* Alternate numeric symbols */
+ ++format;
+ }
+ switch (*format) {
+ case '\0':
+ --format;
+ break;
+ case 'A':
+ if (t->tm_wday < 0 || t->tm_wday > 6)
+ return (0);
+ if (!_add(_CurrentTimeLocale->day[t->tm_wday],
+ pt, ptlim))
+ return (0);
+ continue;
+
+ case 'a':
+ if (t->tm_wday < 0 || t->tm_wday > 6)
+ return (0);
+ if (!_add(_CurrentTimeLocale->abday[t->tm_wday],
+ pt, ptlim))
+ return (0);
+ continue;
+ case 'B':
+ if (t->tm_mon < 0 || t->tm_mon > 11)
+ return (0);
+ if (!_add(_CurrentTimeLocale->mon[t->tm_mon],
+ pt, ptlim))
+ return (0);
+ continue;
+ case 'b':
+ case 'h':
+ if (t->tm_mon < 0 || t->tm_mon > 11)
+ return (0);
+ if (!_add(_CurrentTimeLocale->abmon[t->tm_mon],
+ pt, ptlim))
+ return (0);
+ continue;
+ case 'C':
+ if (!_conv((t->tm_year + TM_YEAR_BASE) / 100,
+ 2, '0', pt, ptlim))
+ return (0);
+ continue;
+ case 'c':
+ if (!_fmt(_CurrentTimeLocale->d_t_fmt, t, pt,
+ ptlim))
+ return (0);
+ continue;
+ case 'D':
+ if (!_fmt("%m/%d/%y", t, pt, ptlim))
+ return (0);
+ continue;
+ case 'd':
+ if (!_conv(t->tm_mday, 2, '0', pt, ptlim))
+ return (0);
+ continue;
+ case 'e':
+ if (!_conv(t->tm_mday, 2, ' ', pt, ptlim))
+ return (0);
+ continue;
+ case 'H':
+ if (!_conv(t->tm_hour, 2, '0', pt, ptlim))
+ return (0);
+ continue;
+ case 'I':
+ if (!_conv(t->tm_hour % 12 ?
+ t->tm_hour % 12 : 12, 2, '0', pt, ptlim))
+ return (0);
+ continue;
+ case 'j':
+ if (!_conv(t->tm_yday + 1, 3, '0', pt, ptlim))
+ return (0);
+ continue;
+ case 'k':
+ if (!_conv(t->tm_hour, 2, ' ', pt, ptlim))
+ return (0);
+ continue;
+ case 'l':
+ if (!_conv(t->tm_hour % 12 ?
+ t->tm_hour % 12: 12, 2, ' ', pt, ptlim))
+ return (0);
+ continue;
+ case 'M':
+ if (!_conv(t->tm_min, 2, '0', pt, ptlim))
+ return (0);
+ continue;
+ case 'm':
+ if (!_conv(t->tm_mon + 1, 2, '0', pt, ptlim))
+ return (0);
+ continue;
+ case 'n':
+ if (!_add("\n", pt, ptlim))
+ return (0);
+ continue;
+ case 'p':
+ if (!_add(_CurrentTimeLocale->am_pm[t->tm_hour
+ >= 12], pt, ptlim))
+ return (0);
+ continue;
+ case 'R':
+ if (!_fmt("%H:%M", t, pt, ptlim))
+ return (0);
+ continue;
+ case 'r':
+ if (!_fmt(_CurrentTimeLocale->t_fmt_ampm, t, pt,
+ ptlim))
+ return (0);
+ continue;
+ case 'S':
+ if (!_conv(t->tm_sec, 2, '0', pt, ptlim))
+ return (0);
+ continue;
+ case 's':
+ if (!_secs(t, pt, ptlim))
+ return (0);
+ continue;
+ case 'T':
+ if (!_fmt("%H:%M:%S", t, pt, ptlim))
+ return (0);
+ continue;
+ case 't':
+ if (!_add("\t", pt, ptlim))
+ return (0);
+ continue;
+ case 'U':
+ if (!_conv(SUN_WEEK(t), 2, '0', pt, ptlim))
+ return (0);
+ continue;
+ case 'u':
+ if (!_conv(t->tm_wday ? t->tm_wday : 7, 1, '0',
+ pt, ptlim))
+ return (0);
+ continue;
+ case 'V': /* ISO 8601 week number */
+ case 'G': /* ISO 8601 year (four digits) */
+ case 'g': /* ISO 8601 year (two digits) */
+/*
+** From Arnold Robbins' strftime version 3.0: "the week number of the
+** year (the first Monday as the first day of week 1) as a decimal number
+** (01-53)."
+** (ado, 1993-05-24)
+**
+** From "http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html" by Markus Kuhn:
+** "Week 01 of a year is per definition the first week which has the
+** Thursday in this year, which is equivalent to the week which contains
+** the fourth day of January. In other words, the first week of a new year
+** is the week which has the majority of its days in the new year. Week 01
+** might also contain days from the previous year and the week before week
+** 01 of a year is the last week (52 or 53) of the previous year even if
+** it contains days from the new year. A week starts with Monday (day 1)
+** and ends with Sunday (day 7). For example, the first week of the year
+** 1997 lasts from 1996-12-30 to 1997-01-05..."
+** (ado, 1996-01-02)
+*/
+ {
+ int year;
+ int yday;
+ int wday;
+ int w;
+
+ year = t->tm_year + TM_YEAR_BASE;
+ yday = t->tm_yday;
+ wday = t->tm_wday;
+ for ( ; ; ) {
+ int len;
+ int bot;
+ int top;
+
+ len = isleap(year) ?
+ DAYSPERLYEAR :
+ DAYSPERNYEAR;
+ /*
+ ** What yday (-3 ... 3) does
+ ** the ISO year begin on?
+ */
+ bot = ((yday + 11 - wday) %
+ DAYSPERWEEK) - 3;
+ /*
+ ** What yday does the NEXT
+ ** ISO year begin on?
+ */
+ top = bot -
+ (len % DAYSPERWEEK);
+ if (top < -3)
+ top += DAYSPERWEEK;
+ top += len;
+ if (yday >= top) {
+ ++year;
+ w = 1;
+ break;
+ }
+ if (yday >= bot) {
+ w = 1 + ((yday - bot) /
+ DAYSPERWEEK);
+ break;
+ }
+ --year;
+ yday += isleap(year) ?
+ DAYSPERLYEAR :
+ DAYSPERNYEAR;
+ }
+#ifdef XPG4_1994_04_09
+ if ((w == 52
+ && t->tm_mon == TM_JANUARY)
+ || (w == 1
+ && t->tm_mon == TM_DECEMBER))
+ w = 53;
+#endif /* defined XPG4_1994_04_09 */
+ if (*format == 'V') {
+ if (!_conv(w, 2, '0',
+ pt, ptlim))
+ return (0);
+ } else if (*format == 'g') {
+ if (!_conv(year % 100, 2, '0',
+ pt, ptlim))
+ return (0);
+ } else if (!_conv(year, 4, '0',
+ pt, ptlim))
+ return (0);
+ }
+ continue;
+ case 'W':
+ if (!_conv(MON_WEEK(t), 2, '0', pt, ptlim))
+ return (0);
+ continue;
+ case 'w':
+ if (!_conv(t->tm_wday, 1, '0', pt, ptlim))
+ return (0);
+ continue;
+ case 'x':
+ if (!_fmt(_CurrentTimeLocale->d_fmt, t, pt,
+ ptlim))
+ return (0);
+ continue;
+ case 'X':
+ if (!_fmt(_CurrentTimeLocale->t_fmt, t, pt,
+ ptlim))
+ return (0);
+ continue;
+ case 'y':
+ if (!_conv((t->tm_year + TM_YEAR_BASE) % 100,
+ 2, '0', pt, ptlim))
+ return (0);
+ continue;
+ case 'Y':
+ if (!_conv((t->tm_year + TM_YEAR_BASE), 4, '0',
+ pt, ptlim))
+ return (0);
+ continue;
+ case 'Z':
+ if (tzname[t->tm_isdst ? 1 : 0] &&
+ !_add(tzname[t->tm_isdst ? 1 : 0], pt,
+ ptlim))
+ return (0);
+ continue;
+ case '%':
+ /*
+ * X311J/88-090 (4.12.3.5): if conversion char is
+ * undefined, behavior is undefined. Print out the
+ * character itself as printf(3) does.
+ */
+ default:
+ break;
+ }
+ }
+ if (*pt == ptlim)
+ return (0);
+ *(*pt)++ = *format;
+ }
+ return (ptlim - *pt);
}
static int
-add_num_time_t (string, max, num)
- char *string;
- int max;
- time_t num;
+_secs(t, pt, ptlim)
+ const struct tm *t;
+ char **pt;
+ const char * const ptlim;
{
- /* This buffer is large enough to hold the character representation
- (including the trailing NUL) of any unsigned decimal quantity
- whose binary representation fits in 128 bits. */
- char buf[40];
- int length;
-
- if (sizeof (num) > 16)
- abort ();
- sprintf (buf, "%lu", (unsigned long) num);
- length = add_str (string, buf, max);
- return length;
+ char buf[15];
+ time_t s;
+ char *p;
+ struct tm tmp;
+
+ buf[sizeof (buf) - 1] = '\0';
+ /* Make a copy, mktime(3) modifies the tm struct. */
+ tmp = *t;
+ s = mktime(&tmp);
+ for (p = buf + sizeof(buf) - 2; s > 0 && p > buf; s /= 10)
+ *p-- = (char)(s % 10 + '0');
+ return (_add(++p, pt, ptlim));
}
-/* Return the week in the year of the time in TM, with the weeks
- starting on Sundays. */
-
static int
-sun_week (tm)
- struct tm *tm;
+_conv(n, digits, pad, pt, ptlim)
+ int n, digits;
+ int pad;
+ char **pt;
+ const char * const ptlim;
{
- int dl;
-
- /* Set `dl' to the day in the year of the last day of the week previous
- to the one containing the day specified in TM. If the day specified
- in TM is in the first week of the year, `dl' will be negative or 0.
- Otherwise, calculate the number of complete weeks before our week
- (dl / 7) and add any partial week at the start of the year (dl % 7). */
- dl = tm->tm_yday - tm->tm_wday;
- return dl <= 0 ? 0 : dl / 7 + (dl % 7 != 0);
+ char buf[10];
+ char *p;
+
+ buf[sizeof (buf) - 1] = '\0';
+ for (p = buf + sizeof(buf) - 2; n > 0 && p > buf; n /= 10, --digits)
+ *p-- = n % 10 + '0';
+ while (p > buf && digits-- > 0)
+ *p-- = pad;
+ return (_add(++p, pt, ptlim));
}
-/* Return the week in the year of the time in TM, with the weeks
- starting on Mondays. */
-
static int
-mon_week (tm)
- struct tm *tm;
-{
- int dl, wday;
-
- if (tm->tm_wday == 0)
- wday = 6;
- else
- wday = tm->tm_wday - 1;
- dl = tm->tm_yday - wday;
- return dl <= 0 ? 0 : dl / 7 + (dl % 7 != 0);
-}
-
-#if !defined(HAVE_TM_ZONE) && !defined(HAVE_TZNAME)
-char *
-zone_name (tp)
- struct tm *tp;
+_add(str, pt, ptlim)
+ const char *str;
+ char **pt;
+ const char * const ptlim;
{
- char *timezone ();
- struct timeval tv;
- struct timezone tz;
-
- gettimeofday (&tv, &tz);
- return timezone (tz.tz_minuteswest, tp->tm_isdst);
-}
-#endif
-
-/* Format the time given in TM according to FORMAT, and put the
- results in STRING.
- Return the number of characters (not including terminating null)
- that were put into STRING, or 0 if the length would have
- exceeded MAX. */
-
-size_t
-strftime (string, max, format, tm)
- char *string;
- size_t max;
- const char *format;
- const struct tm *tm;
-{
- enum padding pad; /* Type of padding to apply. */
- size_t length = 0; /* Characters put in STRING so far. */
-
- for (; *format && length < max; ++format)
- {
- if (*format != '%')
- add_char (*format);
- else
- {
- ++format;
- /* Modifiers: */
- if (*format == '-')
- {
- pad = none;
- ++format;
- }
- else if (*format == '_')
- {
- pad = blank;
- ++format;
- }
- else
- pad = zero;
-
- switch (*format)
- {
- /* Literal character fields: */
- case 0:
- case '%':
- add_char ('%');
- break;
- case 'n':
- add_char ('\n');
- break;
- case 't':
- add_char ('\t');
- break;
- default:
- add_char (*format);
- break;
-
- /* Time fields: */
- case 'H':
- case 'k':
- length +=
- add_num2 (&string[length], tm->tm_hour, max - length,
- *format == 'H' ? pad : blank);
- break;
- case 'I':
- case 'l':
- {
- int hour12;
-
- if (tm->tm_hour == 0)
- hour12 = 12;
- else if (tm->tm_hour > 12)
- hour12 = tm->tm_hour - 12;
- else
- hour12 = tm->tm_hour;
- length +=
- add_num2 (&string[length], hour12, max - length,
- *format == 'I' ? pad : blank);
- }
- break;
- case 'M':
- length +=
- add_num2 (&string[length], tm->tm_min, max - length, pad);
- break;
- case 'p':
- if (tm->tm_hour < 12)
- add_char ('A');
- else
- add_char ('P');
- add_char ('M');
- break;
- case 'r':
- length +=
- strftime (&string[length], max - length, "%I:%M:%S %p", tm);
- break;
- case 'R':
- length +=
- strftime (&string[length], max - length, "%H:%M", tm);
- break;
-
- case 's':
- {
- struct tm writable_tm;
- writable_tm = *tm;
- length += add_num_time_t (&string[length], max - length,
- mktime (&writable_tm));
- }
- break;
-
- case 'S':
- length +=
- add_num2 (&string[length], tm->tm_sec, max - length, pad);
- break;
- case 'T':
- length +=
- strftime (&string[length], max - length, "%H:%M:%S", tm);
- break;
- case 'X':
- length +=
- strftime (&string[length], max - length, "%H:%M:%S", tm);
- break;
- case 'Z':
-#ifdef HAVE_TM_ZONE
- length += add_str (&string[length], tm->tm_zone, max - length);
-#else
-#ifdef HAVE_TZNAME
- if (tm->tm_isdst && tzname[1] && *tzname[1])
- length += add_str (&string[length], tzname[1], max - length);
- else
- length += add_str (&string[length], tzname[0], max - length);
-#else
- length += add_str (&string[length], zone_name (tm), max - length);
-#endif
-#endif
- break;
- /* Date fields: */
- case 'a':
- add_char (days[tm->tm_wday][0]);
- add_char (days[tm->tm_wday][1]);
- add_char (days[tm->tm_wday][2]);
- break;
- case 'A':
- length +=
- add_str (&string[length], days[tm->tm_wday], max - length);
- break;
- case 'b':
- case 'h':
- add_char (months[tm->tm_mon][0]);
- add_char (months[tm->tm_mon][1]);
- add_char (months[tm->tm_mon][2]);
- break;
- case 'B':
- length +=
- add_str (&string[length], months[tm->tm_mon], max - length);
- break;
- case 'c':
- length +=
- strftime (&string[length], max - length,
- "%a %b %d %H:%M:%S %Z %Y", tm);
- break;
- case 'C':
- length +=
- add_num2 (&string[length], (tm->tm_year + 1900) / 100,
- max - length, pad);
- break;
- case 'd':
- length +=
- add_num2 (&string[length], tm->tm_mday, max - length, pad);
- break;
- case 'e':
- length +=
- add_num2 (&string[length], tm->tm_mday, max - length, blank);
- break;
- case 'D':
- length +=
- strftime (&string[length], max - length, "%m/%d/%y", tm);
- break;
- case 'j':
- length +=
- add_num3 (&string[length], tm->tm_yday + 1, max - length, pad);
- break;
- case 'm':
- length +=
- add_num2 (&string[length], tm->tm_mon + 1, max - length, pad);
- break;
- case 'U':
- length +=
- add_num2 (&string[length], sun_week (tm), max - length, pad);
- break;
- case 'w':
- add_char (tm->tm_wday + '0');
- break;
- case 'W':
- length +=
- add_num2 (&string[length], mon_week (tm), max - length, pad);
- break;
- case 'x':
- length +=
- strftime (&string[length], max - length, "%m/%d/%y", tm);
- break;
- case 'y':
- length +=
- add_num2 (&string[length], tm->tm_year % 100,
- max - length, pad);
- break;
- case 'Y':
- add_char ((tm->tm_year + 1900) / 1000 + '0');
- length +=
- add_num3 (&string[length],
- (1900 + tm->tm_year) % 1000, max - length, zero);
- break;
- }
+ for (;; ++(*pt)) {
+ if (*pt == ptlim)
+ return (0);
+ if ((**pt = *str++) == '\0')
+ return (1);
}
- }
- add_char (0);
- return length - 1;
}