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
+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;