+2004-04-21 J"orn Rennecke <joern.rennecke@superh.com>
+
+ * libc/stdio/vfscanf.c (NNZDIGITS): New define.
+ (__svfscanf_r): In integer conversions, leave out leading zeroes
+ which are not part of a base prefix.
+ Keep track of width truncation to fit into buf, not counting left-out
+ zeroes against width till the truncation has been compensated for.
+
2004-04-20 Corinna Vinschen <corinna@vinschen.de>
* libc/include/sys/unistd.h (ttyname_r): Add missing comma.
#define PFXOK 0x200 /* 0x prefix is (still) legal */
#define NZDIGITS 0x400 /* no zero digits detected */
+#define NNZDIGITS 0x800 /* no non-zero digits detected */
/*
* Conversion types.
continue;
case CT_INT:
+ {
/* scan an integer as if by strtol/strtoul */
+ unsigned width_left = 0;
#ifdef hardway
if (width == 0 || width > sizeof (buf) - 1)
- width = sizeof (buf) - 1;
#else
/* size_t is unsigned, hence this optimisation */
- if (--width > sizeof (buf) - 2)
- width = sizeof (buf) - 2;
- width++;
+ if (width - 1 > sizeof (buf) - 2)
#endif
- flags |= SIGNOK | NDIGITS | NZDIGITS;
+ {
+ width_left = width - (sizeof (buf) - 1);
+ width = sizeof (buf) - 1;
+ }
+ flags |= SIGNOK | NDIGITS | NZDIGITS | NNZDIGITS;
for (p = buf; width; width--)
{
c = *fp->_p;
* will turn it off if we have scanned any nonzero digits).
*/
case '0':
+ if (! (flags & NNZDIGITS))
+ goto ok;
if (base == 0)
{
base = 8;
flags |= PFXOK;
}
if (flags & NZDIGITS)
- flags &= ~(SIGNOK | NZDIGITS | NDIGITS);
- else
- flags &= ~(SIGNOK | PFXOK | NDIGITS);
- goto ok;
+ {
+ flags &= ~(SIGNOK | NZDIGITS | NDIGITS);
+ goto ok;
+ }
+ flags &= ~(SIGNOK | PFXOK | NDIGITS);
+ if (width_left)
+ {
+ width_left--;
+ width++;
+ }
+ goto skip;
/* 1 through 7 always legal */
case '1':
case '6':
case '7':
base = basefix[base];
- flags &= ~(SIGNOK | PFXOK | NDIGITS);
+ flags &= ~(SIGNOK | PFXOK | NDIGITS | NNZDIGITS);
goto ok;
/* digits 8 and 9 ok iff decimal or hex */
base = basefix[base];
if (base <= 8)
break; /* not legal here */
- flags &= ~(SIGNOK | PFXOK | NDIGITS);
+ flags &= ~(SIGNOK | PFXOK | NDIGITS | NNZDIGITS);
goto ok;
/* letters ok iff hex */
/* no need to fix base here */
if (base <= 10)
break; /* not legal here */
- flags &= ~(SIGNOK | PFXOK | NDIGITS);
+ flags &= ~(SIGNOK | PFXOK | NDIGITS | NNZDIGITS);
goto ok;
/* sign ok only as first character */
* c is legal: store it and look at the next.
*/
*p++ = c;
+ skip:
if (--fp->_r > 0)
fp->_p++;
else
}
nread += p - buf;
break;
-
+ }
#ifdef FLOATING_POINT
case CT_FLOAT:
{
long leading_zeroes = 0;
long zeroes, exp_adjust;
char *exp_start = NULL;
+ unsigned width_left = 0;
#ifdef hardway
if (width == 0 || width > sizeof (buf) - 1)
- width = sizeof (buf) - 1;
#else
/* size_t is unsigned, hence this optimisation */
- if (--width > sizeof (buf) - 2)
- width = sizeof (buf) - 2;
- width++;
+ if (width - 1 > sizeof (buf) - 2)
#endif
+ {
+ width_left = width - (sizeof (buf) - 1);
+ width = sizeof (buf) - 1;
+ }
flags |= SIGNOK | NDIGITS | DPTOK | EXPOK;
zeroes = 0;
exp_adjust = 0;
{
flags &= ~SIGNOK;
zeroes++;
+ if (width_left)
+ {
+ width_left--;
+ width++;
+ }
goto fskip;
}
/* Fall through. */