mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-07-10 05:30:49 +02:00
commit bash-20120420 snapshot
This commit is contained in:
+296
@@ -0,0 +1,296 @@
|
||||
*** savedir/strftime.c.save1 2011-01-16 15:23:14.000000000 -0500
|
||||
--- strftime.c 2012-04-20 10:16:28.000000000 -0400
|
||||
***************
|
||||
*** 39,42 ****
|
||||
--- 39,43 ----
|
||||
* Updated December, 2001
|
||||
* Updated January, 2011
|
||||
+ * Updated April, 2012
|
||||
*
|
||||
* Fixes from ado@elsie.nci.nih.gov,
|
||||
***************
|
||||
*** 76,79 ****
|
||||
--- 77,81 ----
|
||||
#define HPUX_EXT 1 /* non-conflicting stuff in HP-UX date */
|
||||
#define POSIX_SEMANTICS 1 /* call tzset() if TZ changes */
|
||||
+ #define POSIX_2008 1 /* flag and fw for C, F, G, Y formats */
|
||||
|
||||
#undef strchr /* avoid AIX weirdness */
|
||||
***************
|
||||
*** 97,101 ****
|
||||
#define range(low, item, hi) max(low, min(item, hi))
|
||||
|
||||
! #if !defined(OS2) && !defined(MSDOS) && defined(HAVE_TZNAME)
|
||||
extern char *tzname[2];
|
||||
extern int daylight;
|
||||
--- 99,104 ----
|
||||
#define range(low, item, hi) max(low, min(item, hi))
|
||||
|
||||
! /* Whew! This stuff is a mess. */
|
||||
! #if !defined(OS2) && !defined(MSDOS) && !defined(__CYGWIN__) && defined(HAVE_TZNAME)
|
||||
extern char *tzname[2];
|
||||
extern int daylight;
|
||||
***************
|
||||
*** 103,121 ****
|
||||
extern long int timezone, altzone;
|
||||
#else
|
||||
! # if defined (HPUX)
|
||||
extern long int timezone;
|
||||
# else
|
||||
extern int timezone, altzone;
|
||||
! # endif /* !HPUX */
|
||||
! #endif /* !SOLARIS && !mips && !M_UNIX */
|
||||
#endif
|
||||
|
||||
#undef min /* just in case */
|
||||
|
||||
- /* format for %+ -- currently unused */
|
||||
- #ifndef NATIONAL_FORMAT
|
||||
- #define NATIONAL_FORMAT "%a %b %e %H:%M:%S %Z %Y"
|
||||
- #endif
|
||||
-
|
||||
/* min --- return minimum of two numbers */
|
||||
|
||||
--- 106,121 ----
|
||||
extern long int timezone, altzone;
|
||||
#else
|
||||
! # if defined (HPUX) || defined(__hpux)
|
||||
extern long int timezone;
|
||||
# else
|
||||
+ # if !defined(__CYGWIN__)
|
||||
extern int timezone, altzone;
|
||||
! # endif
|
||||
! # endif
|
||||
! #endif
|
||||
#endif
|
||||
|
||||
#undef min /* just in case */
|
||||
|
||||
/* min --- return minimum of two numbers */
|
||||
|
||||
***************
|
||||
*** 136,139 ****
|
||||
--- 136,167 ----
|
||||
}
|
||||
|
||||
+ #ifdef POSIX_2008
|
||||
+ /* iso_8601_2000_year --- format a year per ISO 8601:2000 as in 1003.1 */
|
||||
+
|
||||
+ static void
|
||||
+ iso_8601_2000_year(char *buf, int year, size_t fw)
|
||||
+ {
|
||||
+ int extra;
|
||||
+ char sign = '\0';
|
||||
+
|
||||
+ if (year >= -9999 && year <= 9999) {
|
||||
+ sprintf(buf, "%0*d", fw, year);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* now things get weird */
|
||||
+ if (year > 9999) {
|
||||
+ sign = '+';
|
||||
+ } else {
|
||||
+ sign = '-';
|
||||
+ year = -year;
|
||||
+ }
|
||||
+
|
||||
+ extra = year / 10000;
|
||||
+ year %= 10000;
|
||||
+ sprintf(buf, "%c_%04d_%d", sign, extra, year);
|
||||
+ }
|
||||
+ #endif /* POSIX_2008 */
|
||||
+
|
||||
/* strftime --- produce formatted time */
|
||||
|
||||
***************
|
||||
*** 156,165 ****
|
||||
--- 184,200 ----
|
||||
#ifndef HAVE_TM_NAME
|
||||
#ifndef HAVE_TZNAME
|
||||
+ #ifndef __CYGWIN__
|
||||
extern char *timezone();
|
||||
struct timeval tv;
|
||||
struct timezone zone;
|
||||
+ #endif /* __CYGWIN__ */
|
||||
#endif /* HAVE_TZNAME */
|
||||
#endif /* HAVE_TM_NAME */
|
||||
#endif /* HAVE_TM_ZONE */
|
||||
+ #ifdef POSIX_2008
|
||||
+ int pad;
|
||||
+ size_t fw;
|
||||
+ char flag;
|
||||
+ #endif /* POSIX_2008 */
|
||||
|
||||
/* various tables, useful in North America */
|
||||
***************
|
||||
*** 235,238 ****
|
||||
--- 270,307 ----
|
||||
continue;
|
||||
}
|
||||
+ #ifdef POSIX_2008
|
||||
+ pad = '\0';
|
||||
+ fw = 0;
|
||||
+ flag = '\0';
|
||||
+ switch (*++format) {
|
||||
+ case '+':
|
||||
+ flag = '+';
|
||||
+ /* fall through */
|
||||
+ case '0':
|
||||
+ pad = '0';
|
||||
+ format++;
|
||||
+ break;
|
||||
+
|
||||
+ case '1':
|
||||
+ case '2':
|
||||
+ case '3':
|
||||
+ case '4':
|
||||
+ case '5':
|
||||
+ case '6':
|
||||
+ case '7':
|
||||
+ case '8':
|
||||
+ case '9':
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ format--;
|
||||
+ goto again;
|
||||
+ }
|
||||
+ for (; isdigit(*format); format++) {
|
||||
+ fw = fw * 10 + (*format - '0');
|
||||
+ }
|
||||
+ format--;
|
||||
+ #endif /* POSIX_2008 */
|
||||
+
|
||||
again:
|
||||
switch (*++format) {
|
||||
***************
|
||||
*** 286,291 ****
|
||||
|
||||
case 'C':
|
||||
century:
|
||||
! sprintf(tbuf, "%02ld", (timeptr->tm_year + 1900L) / 100);
|
||||
break;
|
||||
|
||||
--- 355,371 ----
|
||||
|
||||
case 'C':
|
||||
+ #ifdef POSIX_2008
|
||||
+ if (pad != '\0' && fw > 0) {
|
||||
+ size_t min_fw = (flag ? 3 : 2);
|
||||
+
|
||||
+ fw = max(fw, min_fw);
|
||||
+ sprintf(tbuf, flag
|
||||
+ ? "%+0*ld"
|
||||
+ : "%0*ld", fw,
|
||||
+ (timeptr->tm_year + 1900L) / 100);
|
||||
+ } else
|
||||
+ #endif /* POSIX_2008 */
|
||||
century:
|
||||
! sprintf(tbuf, "%02ld", (timeptr->tm_year + 1900L) / 100);
|
||||
break;
|
||||
|
||||
***************
|
||||
*** 308,312 ****
|
||||
--- 388,415 ----
|
||||
|
||||
case 'F': /* ISO 8601 date representation */
|
||||
+ {
|
||||
+ #ifdef POSIX_2008
|
||||
+ /*
|
||||
+ * Field width for %F is for the whole thing.
|
||||
+ * It must be at least 10.
|
||||
+ */
|
||||
+ char m_d[10];
|
||||
+ strftime(m_d, sizeof m_d, "-%m-%d", timeptr);
|
||||
+ size_t min_fw = 10;
|
||||
+
|
||||
+ if (pad != '\0' && fw > 0) {
|
||||
+ fw = max(fw, min_fw);
|
||||
+ } else {
|
||||
+ fw = min_fw;
|
||||
+ }
|
||||
+
|
||||
+ fw -= 6; /* -XX-XX at end are invariant */
|
||||
+
|
||||
+ iso_8601_2000_year(tbuf, timeptr->tm_year + 1900, fw);
|
||||
+ strcat(tbuf, m_d);
|
||||
+ #else
|
||||
strftime(tbuf, sizeof tbuf, "%Y-%m-%d", timeptr);
|
||||
+ #endif /* POSIX_2008 */
|
||||
+ }
|
||||
break;
|
||||
|
||||
***************
|
||||
*** 330,335 ****
|
||||
y = 1900L + timeptr->tm_year;
|
||||
|
||||
! if (*format == 'G')
|
||||
! sprintf(tbuf, "%ld", y);
|
||||
else
|
||||
sprintf(tbuf, "%02ld", y % 100);
|
||||
--- 433,450 ----
|
||||
y = 1900L + timeptr->tm_year;
|
||||
|
||||
! if (*format == 'G') {
|
||||
! #ifdef POSIX_2008
|
||||
! if (pad != '\0' && fw > 0) {
|
||||
! size_t min_fw = 4;
|
||||
!
|
||||
! fw = max(fw, min_fw);
|
||||
! sprintf(tbuf, flag
|
||||
! ? "%+0*ld"
|
||||
! : "%0*ld", fw,
|
||||
! y);
|
||||
! } else
|
||||
! #endif /* POSIX_2008 */
|
||||
! sprintf(tbuf, "%ld", y);
|
||||
! }
|
||||
else
|
||||
sprintf(tbuf, "%02ld", y % 100);
|
||||
***************
|
||||
*** 456,460 ****
|
||||
|
||||
case 'Y': /* year with century */
|
||||
! fullyear:
|
||||
sprintf(tbuf, "%ld", 1900L + timeptr->tm_year);
|
||||
break;
|
||||
--- 571,585 ----
|
||||
|
||||
case 'Y': /* year with century */
|
||||
! #ifdef POSIX_2008
|
||||
! if (pad != '\0' && fw > 0) {
|
||||
! size_t min_fw = 4;
|
||||
!
|
||||
! fw = max(fw, min_fw);
|
||||
! sprintf(tbuf, flag
|
||||
! ? "%+0*ld"
|
||||
! : "%0*ld", fw,
|
||||
! 1900L + timeptr->tm_year);
|
||||
! } else
|
||||
! #endif /* POSIX_2008 */
|
||||
sprintf(tbuf, "%ld", 1900L + timeptr->tm_year);
|
||||
break;
|
||||
***************
|
||||
*** 497,506 ****
|
||||
* secs west of GMT. Convert to mins east of GMT.
|
||||
*/
|
||||
! # ifdef HPUX
|
||||
off = -timezone / 60;
|
||||
# else
|
||||
/* ADR: 4 August 2001, fixed this per gazelle@interaccess.com */
|
||||
off = -(daylight ? altzone : timezone) / 60;
|
||||
! # endif /* !HPUX */
|
||||
#else /* !HAVE_TZNAME */
|
||||
gettimeofday(& tv, & zone);
|
||||
--- 622,631 ----
|
||||
* secs west of GMT. Convert to mins east of GMT.
|
||||
*/
|
||||
! # if defined(__hpux) || defined (HPUX) || defined(__CYGWIN__)
|
||||
off = -timezone / 60;
|
||||
# else
|
||||
/* ADR: 4 August 2001, fixed this per gazelle@interaccess.com */
|
||||
off = -(daylight ? altzone : timezone) / 60;
|
||||
! # endif
|
||||
#else /* !HAVE_TZNAME */
|
||||
gettimeofday(& tv, & zone);
|
||||
+74
-24
@@ -9,7 +9,7 @@
|
||||
Unix snprintf implementation.
|
||||
derived from inetutils/libinetutils/snprintf.c Version 1.1
|
||||
|
||||
Copyright (C) 2001,2006,2010 Free Software Foundation, Inc.
|
||||
Copyright (C) 2001,2006,2010,2012 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Bash. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Revision History:
|
||||
Original (pre-bash) Revision History:
|
||||
|
||||
1.1:
|
||||
* added changes from Miles Bader
|
||||
@@ -50,7 +50,6 @@
|
||||
* Currently doesn't handle (and bash/readline doesn't use):
|
||||
* * *M$ width, precision specifications
|
||||
* * %N$ numbered argument conversions
|
||||
* * inf, nan floating values imperfect (if isinf(), isnan() not in libc)
|
||||
* * support for `F' is imperfect with ldfallback(), since underlying
|
||||
* printf may not handle it -- should ideally have another autoconf test
|
||||
*/
|
||||
@@ -390,7 +389,7 @@ static void xfree __P((void *));
|
||||
while (0)
|
||||
|
||||
#define PUT_PLUS(d, p, zero) \
|
||||
if ((d) > zero && (p)->justify == RIGHT) \
|
||||
if (((p)->flags & PF_PLUS) && (d) > zero) \
|
||||
PUT_CHAR('+', p)
|
||||
|
||||
#define PUT_SPACE(d, p, zero) \
|
||||
@@ -605,10 +604,9 @@ numtoa(number, base, precision, fract)
|
||||
register int i, j;
|
||||
double ip, fp; /* integer and fraction part */
|
||||
double fraction;
|
||||
int digits = MAX_INT - 1;
|
||||
int digits, sign;
|
||||
static char integral_part[MAX_INT];
|
||||
static char fraction_part[MAX_FRACT];
|
||||
double sign;
|
||||
int ch;
|
||||
|
||||
/* taking care of the obvious case: 0.0 */
|
||||
@@ -626,8 +624,12 @@ numtoa(number, base, precision, fract)
|
||||
return integral_part;
|
||||
}
|
||||
|
||||
/* -0 is tricky */
|
||||
sign = (number == -0.) ? '-' : ((number < 0.) ? '-' : '+');
|
||||
digits = MAX_INT - 1;
|
||||
|
||||
/* for negative numbers */
|
||||
if ((sign = number) < 0.)
|
||||
if (sign == '-')
|
||||
{
|
||||
number = -number;
|
||||
digits--; /* sign consume one digit */
|
||||
@@ -662,7 +664,7 @@ numtoa(number, base, precision, fract)
|
||||
integral_part[i] = '9';
|
||||
|
||||
/* put the sign ? */
|
||||
if (sign < 0.)
|
||||
if (sign == '-')
|
||||
integral_part[i++] = '-';
|
||||
|
||||
integral_part[i] = '\0';
|
||||
@@ -701,9 +703,13 @@ number(p, d, base)
|
||||
long sd;
|
||||
int flags;
|
||||
|
||||
/* An explicit precision turns off the zero-padding flag. */
|
||||
/* An explicit precision turns off the zero-padding flag and sets the
|
||||
pad character back to space. */
|
||||
if ((p->flags & PF_ZEROPAD) && p->precision >= 0 && (p->flags & PF_DOT))
|
||||
p->flags &= ~PF_ZEROPAD;
|
||||
{
|
||||
p->flags &= ~PF_ZEROPAD;
|
||||
p->pad = ' ';
|
||||
}
|
||||
|
||||
sd = d; /* signed for ' ' padding in base 10 */
|
||||
flags = 0;
|
||||
@@ -720,7 +726,8 @@ number(p, d, base)
|
||||
tmp = t;
|
||||
}
|
||||
|
||||
p->width -= strlen(tmp);
|
||||
/* need to add one for any `+', but we only add one in base 10 */
|
||||
p->width -= strlen(tmp) + (base == 10 && d > 0 && (p->flags & PF_PLUS));
|
||||
PAD_RIGHT(p);
|
||||
|
||||
if ((p->flags & PF_DOT) && p->precision > 0)
|
||||
@@ -772,9 +779,13 @@ lnumber(p, d, base)
|
||||
long long sd;
|
||||
int flags;
|
||||
|
||||
/* An explicit precision turns off the zero-padding flag. */
|
||||
/* An explicit precision turns off the zero-padding flag and sets the
|
||||
pad character back to space. */
|
||||
if ((p->flags & PF_ZEROPAD) && p->precision >= 0 && (p->flags & PF_DOT))
|
||||
p->flags &= ~PF_ZEROPAD;
|
||||
{
|
||||
p->flags &= ~PF_ZEROPAD;
|
||||
p->pad = ' ';
|
||||
}
|
||||
|
||||
sd = d; /* signed for ' ' padding in base 10 */
|
||||
flags = (*p->pf == 'x' || *p->pf == 'X' || *p->pf == 'o' || *p->pf == 'u' || *p->pf == 'U') ? FL_UNSIGNED : 0;
|
||||
@@ -790,7 +801,8 @@ lnumber(p, d, base)
|
||||
tmp = t;
|
||||
}
|
||||
|
||||
p->width -= strlen(tmp);
|
||||
/* need to add one for any `+', but we only add one in base 10 */
|
||||
p->width -= strlen(tmp) + (base == 10 && d > 0 && (p->flags & PF_PLUS));
|
||||
PAD_RIGHT(p);
|
||||
|
||||
if ((p->flags & PF_DOT) && p->precision > 0)
|
||||
@@ -1002,12 +1014,28 @@ floating(p, d)
|
||||
|
||||
/* calculate the padding. 1 for the dot */
|
||||
p->width = p->width -
|
||||
/* XXX - should this be d>0. && (p->flags & PF_PLUS) ? */
|
||||
#if 0
|
||||
((d > 0. && p->justify == RIGHT) ? 1:0) -
|
||||
#else
|
||||
((d > 0. && (p->flags & PF_PLUS)) ? 1:0) -
|
||||
#endif
|
||||
((p->flags & PF_SPACE) ? 1:0) -
|
||||
strlen(tmp) - p->precision -
|
||||
((p->precision != 0 || (p->flags & PF_ALTFORM)) ? 1 : 0); /* radix char */
|
||||
PAD_RIGHT(p);
|
||||
PUT_PLUS(d, p, 0.);
|
||||
|
||||
if (p->pad == ' ')
|
||||
{
|
||||
PAD_RIGHT(p);
|
||||
PUT_PLUS(d, p, 0.);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*tmp == '-')
|
||||
PUT_CHAR(*tmp++, p);
|
||||
PUT_PLUS(d, p, 0.);
|
||||
PAD_RIGHT(p);
|
||||
}
|
||||
PUT_SPACE(d, p, 0.);
|
||||
|
||||
while (*tmp)
|
||||
@@ -1051,14 +1079,30 @@ exponent(p, d)
|
||||
tmp = dtoa(d, p->precision, &tmp2);
|
||||
|
||||
/* 1 for unit, 1 for the '.', 1 for 'e|E',
|
||||
* 1 for '+|-', 2 for 'exp' */
|
||||
* 1 for '+|-', 2 for 'exp' (but no `.' if precision == 0 */
|
||||
/* calculate how much padding need */
|
||||
p->width = p->width -
|
||||
/* XXX - should this be d>0. && (p->flags & PF_PLUS) ? */
|
||||
#if 0
|
||||
((d > 0. && p->justify == RIGHT) ? 1:0) -
|
||||
((p->flags & PF_SPACE) ? 1:0) - p->precision - 6;
|
||||
#else
|
||||
((d > 0. && (p->flags & PF_PLUS)) ? 1:0) -
|
||||
#endif
|
||||
(p->precision != 0 || (p->flags & PF_ALTFORM)) -
|
||||
((p->flags & PF_SPACE) ? 1:0) - p->precision - 5;
|
||||
|
||||
PAD_RIGHT(p);
|
||||
PUT_PLUS(d, p, 0.);
|
||||
if (p->pad == ' ')
|
||||
{
|
||||
PAD_RIGHT(p);
|
||||
PUT_PLUS(d, p, 0.);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*tmp == '-')
|
||||
PUT_CHAR(*tmp++, p);
|
||||
PUT_PLUS(d, p, 0.);
|
||||
PAD_RIGHT(p);
|
||||
}
|
||||
PUT_SPACE(d, p, 0.);
|
||||
|
||||
while (*tmp)
|
||||
@@ -1311,7 +1355,8 @@ vsnprintf_internal(data, string, length, format, args)
|
||||
if ((data->flags & PF_DOT) == 0)
|
||||
{
|
||||
data->flags |= PF_PLUS;
|
||||
data->justify = RIGHT;
|
||||
if ((data->flags & PF_LADJUST) == 0)
|
||||
data->justify = RIGHT;
|
||||
}
|
||||
continue;
|
||||
case '\'':
|
||||
@@ -1319,7 +1364,11 @@ vsnprintf_internal(data, string, length, format, args)
|
||||
continue;
|
||||
|
||||
case '0':
|
||||
if ((data->flags & PF_DOT) == 0)
|
||||
/* If we're not specifying precision (in which case we've seen
|
||||
a `.') and we're not performing left-adjustment (in which
|
||||
case the `0' is ignored), a `0' is taken as the zero-padding
|
||||
flag. */
|
||||
if ((data->flags & (PF_DOT|PF_LADJUST)) == 0)
|
||||
{
|
||||
data->flags |= PF_ZEROPAD;
|
||||
data->pad = '0';
|
||||
@@ -1406,8 +1455,9 @@ conv_break:
|
||||
else
|
||||
{
|
||||
/* reduce precision by 1 because of leading digit before
|
||||
decimal point in e format. */
|
||||
data->precision--;
|
||||
decimal point in e format, unless specified as 0. */
|
||||
if (data->precision > 0)
|
||||
data->precision--;
|
||||
exponent(data, d);
|
||||
}
|
||||
state = 0;
|
||||
|
||||
+140
-15
@@ -38,6 +38,7 @@
|
||||
* Updated September, 2000
|
||||
* Updated December, 2001
|
||||
* Updated January, 2011
|
||||
* Updated April, 2012
|
||||
*
|
||||
* Fixes from ado@elsie.nci.nih.gov,
|
||||
* February 1991, May 1992
|
||||
@@ -75,6 +76,7 @@
|
||||
#define VMS_EXT 1 /* include %v for VMS date format */
|
||||
#define HPUX_EXT 1 /* non-conflicting stuff in HP-UX date */
|
||||
#define POSIX_SEMANTICS 1 /* call tzset() if TZ changes */
|
||||
#define POSIX_2008 1 /* flag and fw for C, F, G, Y formats */
|
||||
|
||||
#undef strchr /* avoid AIX weirdness */
|
||||
|
||||
@@ -96,27 +98,25 @@ static int iso8601wknum(const struct tm *timeptr);
|
||||
|
||||
#define range(low, item, hi) max(low, min(item, hi))
|
||||
|
||||
#if !defined(OS2) && !defined(MSDOS) && defined(HAVE_TZNAME)
|
||||
/* Whew! This stuff is a mess. */
|
||||
#if !defined(OS2) && !defined(MSDOS) && !defined(__CYGWIN__) && defined(HAVE_TZNAME)
|
||||
extern char *tzname[2];
|
||||
extern int daylight;
|
||||
#if defined(SOLARIS) || defined(mips) || defined (M_UNIX)
|
||||
extern long int timezone, altzone;
|
||||
#else
|
||||
# if defined (HPUX)
|
||||
# if defined (HPUX) || defined(__hpux)
|
||||
extern long int timezone;
|
||||
# else
|
||||
# if !defined(__CYGWIN__)
|
||||
extern int timezone, altzone;
|
||||
# endif /* !HPUX */
|
||||
#endif /* !SOLARIS && !mips && !M_UNIX */
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#undef min /* just in case */
|
||||
|
||||
/* format for %+ -- currently unused */
|
||||
#ifndef NATIONAL_FORMAT
|
||||
#define NATIONAL_FORMAT "%a %b %e %H:%M:%S %Z %Y"
|
||||
#endif
|
||||
|
||||
/* min --- return minimum of two numbers */
|
||||
|
||||
static inline int
|
||||
@@ -135,6 +135,34 @@ max(int a, int b)
|
||||
return (a > b ? a : b);
|
||||
}
|
||||
|
||||
#ifdef POSIX_2008
|
||||
/* iso_8601_2000_year --- format a year per ISO 8601:2000 as in 1003.1 */
|
||||
|
||||
static void
|
||||
iso_8601_2000_year(char *buf, int year, size_t fw)
|
||||
{
|
||||
int extra;
|
||||
char sign = '\0';
|
||||
|
||||
if (year >= -9999 && year <= 9999) {
|
||||
sprintf(buf, "%0*d", fw, year);
|
||||
return;
|
||||
}
|
||||
|
||||
/* now things get weird */
|
||||
if (year > 9999) {
|
||||
sign = '+';
|
||||
} else {
|
||||
sign = '-';
|
||||
year = -year;
|
||||
}
|
||||
|
||||
extra = year / 10000;
|
||||
year %= 10000;
|
||||
sprintf(buf, "%c_%04d_%d", sign, extra, year);
|
||||
}
|
||||
#endif /* POSIX_2008 */
|
||||
|
||||
/* strftime --- produce formatted time */
|
||||
|
||||
size_t
|
||||
@@ -155,12 +183,19 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
|
||||
#ifndef HAVE_TM_ZONE
|
||||
#ifndef HAVE_TM_NAME
|
||||
#ifndef HAVE_TZNAME
|
||||
#ifndef __CYGWIN__
|
||||
extern char *timezone();
|
||||
struct timeval tv;
|
||||
struct timezone zone;
|
||||
#endif /* __CYGWIN__ */
|
||||
#endif /* HAVE_TZNAME */
|
||||
#endif /* HAVE_TM_NAME */
|
||||
#endif /* HAVE_TM_ZONE */
|
||||
#ifdef POSIX_2008
|
||||
int pad;
|
||||
size_t fw;
|
||||
char flag;
|
||||
#endif /* POSIX_2008 */
|
||||
|
||||
/* various tables, useful in North America */
|
||||
static const char *days_a[] = {
|
||||
@@ -234,6 +269,40 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
|
||||
*s++ = *format;
|
||||
continue;
|
||||
}
|
||||
#ifdef POSIX_2008
|
||||
pad = '\0';
|
||||
fw = 0;
|
||||
flag = '\0';
|
||||
switch (*++format) {
|
||||
case '+':
|
||||
flag = '+';
|
||||
/* fall through */
|
||||
case '0':
|
||||
pad = '0';
|
||||
format++;
|
||||
break;
|
||||
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
break;
|
||||
|
||||
default:
|
||||
format--;
|
||||
goto again;
|
||||
}
|
||||
for (; isdigit(*format); format++) {
|
||||
fw = fw * 10 + (*format - '0');
|
||||
}
|
||||
format--;
|
||||
#endif /* POSIX_2008 */
|
||||
|
||||
again:
|
||||
switch (*++format) {
|
||||
case '\0':
|
||||
@@ -285,8 +354,19 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
#ifdef POSIX_2008
|
||||
if (pad != '\0' && fw > 0) {
|
||||
size_t min_fw = (flag ? 3 : 2);
|
||||
|
||||
fw = max(fw, min_fw);
|
||||
sprintf(tbuf, flag
|
||||
? "%+0*ld"
|
||||
: "%0*ld", fw,
|
||||
(timeptr->tm_year + 1900L) / 100);
|
||||
} else
|
||||
#endif /* POSIX_2008 */
|
||||
century:
|
||||
sprintf(tbuf, "%02ld", (timeptr->tm_year + 1900L) / 100);
|
||||
sprintf(tbuf, "%02ld", (timeptr->tm_year + 1900L) / 100);
|
||||
break;
|
||||
|
||||
case 'd': /* day of the month, 01 - 31 */
|
||||
@@ -307,7 +387,30 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
|
||||
goto again;
|
||||
|
||||
case 'F': /* ISO 8601 date representation */
|
||||
{
|
||||
#ifdef POSIX_2008
|
||||
/*
|
||||
* Field width for %F is for the whole thing.
|
||||
* It must be at least 10.
|
||||
*/
|
||||
char m_d[10];
|
||||
strftime(m_d, sizeof m_d, "-%m-%d", timeptr);
|
||||
size_t min_fw = 10;
|
||||
|
||||
if (pad != '\0' && fw > 0) {
|
||||
fw = max(fw, min_fw);
|
||||
} else {
|
||||
fw = min_fw;
|
||||
}
|
||||
|
||||
fw -= 6; /* -XX-XX at end are invariant */
|
||||
|
||||
iso_8601_2000_year(tbuf, timeptr->tm_year + 1900, fw);
|
||||
strcat(tbuf, m_d);
|
||||
#else
|
||||
strftime(tbuf, sizeof tbuf, "%Y-%m-%d", timeptr);
|
||||
#endif /* POSIX_2008 */
|
||||
}
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
@@ -329,8 +432,20 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
|
||||
else
|
||||
y = 1900L + timeptr->tm_year;
|
||||
|
||||
if (*format == 'G')
|
||||
sprintf(tbuf, "%ld", y);
|
||||
if (*format == 'G') {
|
||||
#ifdef POSIX_2008
|
||||
if (pad != '\0' && fw > 0) {
|
||||
size_t min_fw = 4;
|
||||
|
||||
fw = max(fw, min_fw);
|
||||
sprintf(tbuf, flag
|
||||
? "%+0*ld"
|
||||
: "%0*ld", fw,
|
||||
y);
|
||||
} else
|
||||
#endif /* POSIX_2008 */
|
||||
sprintf(tbuf, "%ld", y);
|
||||
}
|
||||
else
|
||||
sprintf(tbuf, "%02ld", y % 100);
|
||||
break;
|
||||
@@ -455,7 +570,17 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
|
||||
break;
|
||||
|
||||
case 'Y': /* year with century */
|
||||
fullyear:
|
||||
#ifdef POSIX_2008
|
||||
if (pad != '\0' && fw > 0) {
|
||||
size_t min_fw = 4;
|
||||
|
||||
fw = max(fw, min_fw);
|
||||
sprintf(tbuf, flag
|
||||
? "%+0*ld"
|
||||
: "%0*ld", fw,
|
||||
1900L + timeptr->tm_year);
|
||||
} else
|
||||
#endif /* POSIX_2008 */
|
||||
sprintf(tbuf, "%ld", 1900L + timeptr->tm_year);
|
||||
break;
|
||||
|
||||
@@ -496,12 +621,12 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
|
||||
* Systems with tzname[] probably have timezone as
|
||||
* secs west of GMT. Convert to mins east of GMT.
|
||||
*/
|
||||
# ifdef HPUX
|
||||
# if defined(__hpux) || defined (HPUX) || defined(__CYGWIN__)
|
||||
off = -timezone / 60;
|
||||
# else
|
||||
/* ADR: 4 August 2001, fixed this per gazelle@interaccess.com */
|
||||
off = -(daylight ? altzone : timezone) / 60;
|
||||
# endif /* !HPUX */
|
||||
# endif
|
||||
#else /* !HAVE_TZNAME */
|
||||
gettimeofday(& tv, & zone);
|
||||
off = -zone.tz_minuteswest;
|
||||
|
||||
Reference in New Issue
Block a user