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
+63
View File
@@ -13718,3 +13718,66 @@ lib/sh/snprintf.c
if `.' hasn't been encountered ((flags&PF_DOT) == 0); otherwise treat
it as the first digit of a precision specifier. Fixes bug reported
by Petr Sumbera <petr.sumbera@sun.com>
4/15
----
lib/sh/snprintf.c
- vsnprintf_internal: if the '0' and '-' flags both occur, the '0'
flag is ignored -- Posix. Start of a series of fixes based on
tests and patches from Petr Sumbera <petr.sumbera@sun.com>
- PUT_PLUS: make sure PF_PLUS flag is specified before putting the `+'
- vsnprintf_internal: when '+' is read as a flag, don't set right-
justify flag if the LADJUST (`-') flag has already been supplied
- floating: make sure to output space padding before the `+', zero
padding after
- exponent: make sure to output space padding before the `+', zero
padding after
- exponent: only subtract one from the width for the decimal point
if we're really going to print one
- floating: use presence of PF_PLUS flag to decide whether to account
for the `+' in the padded field width. Ditto for exponent()
4/16
----
lib/sh/snprintf.c
- vsnprint_internal: only reduce precision by 1 when processing the `g'
format if it's > 0. A precision of 0 should stay 0; otherwise it
gets set to -1 (NOT_FOUND) and converted to the default
- number, lnumber: if an explicit precision is supplied, turn off the
zero-padding flag and set the pad character back to space
- number, lnumber: only account for a `+' when performing the field
width calculation if the coversion is base 10; we don't add a `+'
for other bases
4/18
----
tests/printf3.sub
- try using "perl -e 'print time'" to get the current time in seconds
since the epoch if "date +%s" is not available (solaris 8-10)
4/19
----
tests/run-printf
- use cat -v instead of relying on diff -a being available to convert
control characters to ascii and avoid the dreaded "Binary files
/tmp/xx and printf.right differ"
4/20
----
lib/sh/strftime.c
- incoporated new version from Aharon Robbins <arnold@skeeve.com>
4/22
----
doc/{bash.1,bashref.texi}
- slight change to the description of /dev/tcp and /dev/udp
subst.c
- match_wpattern: logic fix to the calculation of `simple' (was |=,
needs to be &=). Bug report from Mike Frysinger <vapier@gentoo.org>,
fix from Andreas Schwab <schwab@linux-m68k.org>
bashline.c
- bash_filename_stat_hook: add code from bash_directory_completion_hook
that performs pathname canonicalization in the same way that cd and
other builtins will do
+78
View File
@@ -13698,3 +13698,81 @@ doc/{bash.1,bashref.texi}
period for a complete line of input, not just any input. Fixes
problem reported in Ubuntu bug 957303:
https://bugs.launchpad.net/ubuntu/+source/bash/+bug/957303
- HISTFILE: document change to write history list to history file in
any shell with history enabled, not just interactive shells. This
seems to be more logical behavior. Suggested by Greg Wooledge
<wooledg@eeg.ccf.org>
4/12
----
lib/readline/colors.h
- only include stdbool.h if HAVE_STDBOOL_H is defined
- if HAVE_STDBOOL_H is not defined, provide enough definition for the
library to use `bool', `true', and `false'
lib/readline/parse-colors.[ch]
- don't try to include <stdbool.h> at all; rely on colors.h to do it
lib/sh/snprintf.c
- vsnprintf_internal: only treat '0' as a flag to indicate zero padding
if `.' hasn't been encountered ((flags&PF_DOT) == 0); otherwise treat
it as the first digit of a precision specifier. Fixes bug reported
by Petr Sumbera <petr.sumbera@sun.com>
4/15
----
lib/sh/snprintf.c
- vsnprintf_internal: if the '0' and '-' flags both occur, the '0'
flag is ignored -- Posix. Start of a series of fixes based on
tests and patches from Petr Sumbera <petr.sumbera@sun.com>
- PUT_PLUS: make sure PF_PLUS flag is specified before putting the `+'
- vsnprintf_internal: when '+' is read as a flag, don't set right-
justify flag if the LADJUST (`-') flag has already been supplied
- floating: make sure to output space padding before the `+', zero
padding after
- exponent: make sure to output space padding before the `+', zero
padding after
- exponent: only subtract one from the width for the decimal point
if we're really going to print one
- floating: use presence of PF_PLUS flag to decide whether to account
for the `+' in the padded field width. Ditto for exponent()
4/16
----
lib/sh/snprintf.c
- vsnprint_internal: only reduce precision by 1 when processing the `g'
format if it's > 0. A precision of 0 should stay 0; otherwise it
gets set to -1 (NOT_FOUND) and converted to the default
- number, lnumber: if an explicit precision is supplied, turn off the
zero-padding flag and set the pad character back to space
- number, lnumber: only account for a `+' when performing the field
width calculation if the coversion is base 10; we don't add a `+'
for other bases
4/18
----
tests/printf3.sub
- try using "perl -e 'print time'" to get the current time in seconds
since the epoch if "date +%s" is not available (solaris 8-10)
4/19
----
tests/run-printf
- use cat -v instead of relying on diff -a being available to convert
control characters to ascii and avoid the dreaded "Binary files
/tmp/xx and printf.right differ"
4/20
----
lib/sh/strftime.c
- incoporated new version from Aharon Robbins <arnold@skeeve.com>
4/22
----
doc/{bash.1,bashref.texi}
- slight change to the description of /dev/tcp and /dev/udp
subst.c
- match_wpattern: logic fix to the calculation of `simple' (was |=,
needs to be &=). Bug report from Mike Frysinger <vapier@gentoo.org>,
fix from Andreas Schwab <schwab@linux-m68k.org>
+1
View File
@@ -1001,6 +1001,7 @@ tests/printf.right f
tests/printf1.sub f
tests/printf2.sub f
tests/printf3.sub f
tests/printf4.sub f
tests/quote.tests f
tests/quote.right f
tests/read.tests f
+24
View File
@@ -2988,6 +2988,30 @@ bash_filename_stat_hook (dirname)
free (new_dirname);
}
/* This is very similar to the code in bash_directory_completion_hook below,
but without spelling correction and not worrying about whether or not
we change relative pathnames. */
if (no_symbolic_links == 0 && (local_dirname[0] != '.' || local_dirname[1]))
{
char *temp1, *temp2;
t = get_working_directory ("symlink-hook");
temp1 = make_absolute (local_dirname, t);
free (t);
temp2 = sh_canonpath (temp1, PATH_CHECKDOTDOT|PATH_CHECKEXISTS);
/* If we can't canonicalize, bail. */
if (temp2 == 0)
{
free (temp1);
return return_value;
}
free (local_dirname);
*dirname = temp2;
free (temp1);
}
return (return_value);
}
+4114
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -3470,12 +3470,12 @@ File descriptor 2 is duplicated.
.B /dev/tcp/\fIhost\fP/\fIport\fP
If \fIhost\fP is a valid hostname or Internet address, and \fIport\fP
is an integer port number or service name, \fBbash\fP attempts to open
a TCP connection to the corresponding socket.
the corresponding TCP socket.
.TP
.B /dev/udp/\fIhost\fP/\fIport\fP
If \fIhost\fP is a valid hostname or Internet address, and \fIport\fP
is an integer port number or service name, \fBbash\fP attempts to open
a UDP connection to the corresponding socket.
the corresponding UDP socket.
.PD
.RE
.PP
+3 -3
View File
@@ -1972,7 +1972,7 @@ The name of the file in which command history is saved (see
.SM
.B HISTORY
below). The default value is \fI~/.bash_history\fP. If unset, the
command history is not saved when an interactive shell exits.
command history is not saved when a shell exits.
.TP
.B HISTFILESIZE
The maximum number of lines contained in the history file. When this
@@ -1980,7 +1980,7 @@ variable is assigned a value, the history file is truncated, if
necessary,
to contain no more than that number of lines by removing the oldest entries.
The history file is also truncated to this size after
writing it when an interactive shell exits.
writing it when a shell exits.
If the value is 0, the history file is truncated to zero size.
Non-numeric values and numeric values less than zero inhibit truncation.
The shell sets the default value to the value of \fBHISTSIZE\fP
@@ -6293,7 +6293,7 @@ These timestamps are optionally displayed depending on the value of the
.SM
.B HISTTIMEFORMAT
variable.
When an interactive shell exits, the last
When a shell with history enabled exits, the last
.SM
.B $HISTSIZE
lines are copied from the history list to
+4 -4
View File
@@ -2338,13 +2338,13 @@ File descriptor 2 is duplicated.
@item /dev/tcp/@var{host}/@var{port}
If @var{host} is a valid hostname or Internet address, and @var{port}
is an integer port number or service name, Bash attempts to open a TCP
connection to the corresponding socket.
is an integer port number or service name, Bash attempts to open
the corresponding TCP socket.
@item /dev/udp/@var{host}/@var{port}
If @var{host} is a valid hostname or Internet address, and @var{port}
is an integer port number or service name, Bash attempts to open a UDP
connection to the corresponding socket.
is an integer port number or service name, Bash attempts to open
the corresponding UDP socket.
@end table
A failure to open or create a file causes the redirection to fail.
+2 -2
View File
@@ -5398,7 +5398,7 @@ When this variable is assigned a value, the history file is truncated,
if necessary, to contain no more than that number of lines
by removing the oldest entries.
The history file is also truncated to this size after
writing it when an interactive shell exits.
writing it when a shell exits.
If the value is 0, the history file is truncated to zero size.
Non-numeric values and numeric values less than zero inhibit truncation.
The shell sets the default value to the value of @env{HISTSIZE}
@@ -6080,7 +6080,7 @@ Command history (@pxref{Bash History Facilities})
and history expansion (@pxref{History Interaction})
are enabled by default.
Bash will save the command history to the file named by @env{$HISTFILE}
when an interactive shell exits.
when a shell with history enabled exits.
@item
Alias expansion (@pxref{Aliases}) is performed by default.
+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;
+1 -1
View File
@@ -4172,7 +4172,7 @@ match_wpattern (wstring, indices, wstrlen, wpat, mtype, sp, ep)
simple = (wpat[0] != L'\\' && wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'[');
#if defined (EXTENDED_GLOB)
if (extended_glob)
simple |= (wpat[1] != L'(' || (wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'+' && wpat[0] != L'!' && wpat[0] != L'@')); /*)*/
simple &= (wpat[1] != L'(' || (wpat[0] != L'*' && wpat[0] != L'?' && wpat[0] != L'+' && wpat[0] != L'!' && wpat[0] != L'@')); /*)*/
#endif
/* If the pattern doesn't match anywhere in the string, go ahead and
+9431
View File
File diff suppressed because it is too large Load Diff
+12
View File
@@ -0,0 +1,12 @@
cat <<!
one
two
three
!
history
cat <<!
one
two
three
!
Binary file not shown.
Binary file not shown.
+3
View File
@@ -314,3 +314,6 @@ ${THIS_SH} ./printf1.sub
${THIS_SH} ./printf2.sub
${THIS_SH} ./printf3.sub
${THIS_SH} ./printf4.sub
+6 -1
View File
@@ -5,12 +5,17 @@ SHELLSTART=$(date +%s)
SECS=1275250155
export TZ=EST5EDT
case $SHELLSTART in
*s*) SHELLSTART=$(perl -e 'print time') ; DATESECS=false ;; # take a shot
*) DATESECS=true ;;
esac
printf "%()T\n" $SECS
printf "%(abde)Z\n" -1
printf "%(%e-%b-%Y %T)T\n" $SECS
printf -v v1 "%(%e-%b-%Y %T)T\n" $(date +%s)
printf -v v1 "%(%e-%b-%Y %T)T\n" $( $DATESECS && date +%s || perl -e 'print time')
printf -v v2 "%(%e-%b-%Y %T)T\n" -1
case $v1 in
+61
View File
@@ -0,0 +1,61 @@
LC_ALL=C
LANG=C
SHELLSTART=$(date +%s)
SECS=1275250155
export TZ=EST5EDT
case $SHELLSTART in
*s*) SHELLSTART=$(perl -e 'print time') ;; # take a shot
esac
printf "%()T\n" $SECS
printf "%(abde)Z\n" -1
printf "%(%e-%b-%Y %T)T\n" $SECS
printf -v v1 "%(%e-%b-%Y %T)T\n" $(date +%s)
printf -v v2 "%(%e-%b-%Y %T)T\n" -1
case $v1 in
$v2) ;;
*) echo "current time and -1 possible mismatch|$v1|$v2|" >&2 ;;
esac
unset v1 v2
v1=$(date +%s)
printf -v v2 "%(%s)T" -1
case $v1 in
$v2) ;;
*) echo "current time mismatch:$v1|$v2|" >&2 ;;
esac
unset v1 v2
printf "%(%x %X)T\n" $(( $SECS - 3600 ))
printf -v v1 "%(%F %r)T\n" $SHELLSTART
printf -v v2 "%(%F %r)T\n" -2
case $v1 in
$v2) ;;
*) echo "shell start time and -2 possible mismatch|$v1|$v2|" >&2 ;;
esac
unset v1 v2
printf "current time: %(%F %r)T\n" $SECS
printf "epoch time: %(%F %r %z)T\n" 0
printf "random time: %(%F %r %z)T\n" $SECS
printf "local time: %(%a %b %e %H:%M:%S %Z %Y)T\n" $SECS
# test fieldwidth, justification, precision
printf "%-40.50(%a %b %e %H:%M:%S %Z %Y)T date-style time\n" $SECS
# test fieldwidth, justification, precision, embedded parens
printf "%-40.50(%x (foo) %X)T date-style time\n" $SECS
# problem introduced in bash-4.2 patch 5
unset TZ
printf '%(%Y-%m-%d %H:%M:%S %Z)T\n' >/dev/null
+69
View File
@@ -0,0 +1,69 @@
# Problems with padding, field widths, and `+' through bash-4.2
printf "x%10.0fx\n" 123
printf -v foo "x%10.0fx" 123
echo "$foo"
printf "x%10.0fx\n" 123
printf -v foo "x%10.0fx" 123
echo "$foo"
printf "x%10.fx\n" 123
printf -v foo "x%10.fx" 123
echo "$foo"
printf "x%10.2fx\n" 123
printf -v foo "x%10.2fx" 123
echo "$foo"
printf "x%10.02fx\n" 123
printf -v foo "x%10.02fx" 123
echo "$foo"
printf "x%-010.0fx\n" 123
printf -v foo "x%-010.0fx" 123
echo "$foo"
printf "x%+010.0ex\n" 123
printf -v foo "x%+010.0ex" 123
echo "$foo"
printf "x%+010.0fx\n" 123
printf -v foo "x%+010.0fx" 123
echo "$foo"
printf "x%+010.0gx\n" 123
printf -v foo "x%+010.0gx" 123
echo "$foo"
printf "x%+010.0dx\n" 123
printf -v foo "x%+010.0dx" 123
echo "$foo"
printf "x%+010.0ldx\n" 123
printf -v foo "x%+010.0ldx" 123
echo "$foo"
printf "x%+010.0xx\n" 123
printf -v foo "x%+010.0xx" 123
echo "$foo"
printf "x%-+10.0fx\n" 123
printf -v foo "x%-+10.0fx" 123
echo "$foo"
printf "x%-+10.0dx\n" 123
printf -v foo "x%-+10.0dx" 123
echo "$foo"
printf "%f\n" -123
printf -v foo "%f" -123
echo "$foo"
printf "x%+10.0fx\n" 123
printf -v foo "x%+10.0fx" 123
echo "$foo"
printf "x%+10.0dx\n" 123
printf -v foo "x%+10.0dx" 123
echo "$foo"
+5 -3
View File
@@ -1,5 +1,7 @@
# See whether or not we can use `diff -a'
( diff -a ./printf.tests ./printf.tests >/dev/null 2>&1 ) && AFLAG=-a
#( diff -a ./printf.tests ./printf.tests >/dev/null 2>&1 ) && AFLAG=-a
${THIS_SH} ./printf.tests > /tmp/xx 2>&1
diff $AFLAG /tmp/xx printf.right && rm -f /tmp/xx
# use cat -v (and assume it's there) to make control chars visible
${THIS_SH} ./printf.tests 2>&1 | cat -v > /tmp/xx
#diff $AFLAG /tmp/xx printf.right && rm -f /tmp/xx
diff /tmp/xx printf.right && rm -f /tmp/xx