commit bash-20120420 snapshot

This commit is contained in:
Chet Ramey
2012-05-02 08:28:58 -04:00
parent 63817e33cd
commit e107650cbf
22 changed files with 14389 additions and 55 deletions
+296
View File
@@ -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
View File
@@ -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
View File
@@ -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;