4
0
mirror of git://sourceware.org/git/newlib-cygwin.git synced 2025-03-01 12:35:44 +08:00

2004-04-23 Jeff Johnston <jjohnstn@redhat.com>

* libc/machine/powerpc/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.
        This is based on Joern's patch of 04/21 for libc/stdio/vfscanf.c.
This commit is contained in:
Jeff Johnston 2004-04-23 21:30:04 +00:00
parent c00f971933
commit 27c7566ca4
2 changed files with 58 additions and 30 deletions

View File

@ -1,3 +1,12 @@
2004-04-23 Jeff Johnston <jjohnstn@redhat.com>
* libc/machine/powerpc/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.
This is based on Joern's patch of 04/21 for libc/stdio/vfscanf.c.
2004-04-23 Jeff Johnston <jjohnstn@redhat.com> 2004-04-23 Jeff Johnston <jjohnstn@redhat.com>
* libc/include/stdio.h: (_ftell_r, _fseek_r): New prototypes. * libc/include/stdio.h: (_ftell_r, _fseek_r): New prototypes.

View File

@ -153,9 +153,9 @@ extern _LONG_DOUBLE _strtold _PARAMS((char *s, char **sptr));
#define LONG 0x01 /* l: long or double */ #define LONG 0x01 /* l: long or double */
#define LONGDBL 0x02 /* L: long double or long long */ #define LONGDBL 0x02 /* L: long double or long long */
#define SHORT 0x04 /* h: short */ #define SHORT 0x04 /* h: short */
#define SUPPRESS 0x08 /* suppress assignment */ #define SUPPRESS 0x10 /* suppress assignment */
#define POINTER 0x10 /* weird %p pointer (`fake hex') */ #define POINTER 0x20 /* weird %p pointer (`fake hex') */
#define NOSKIP 0x20 /* do not skip blanks */ #define NOSKIP 0x40 /* do not skip blanks */
/* /*
* The following are used in numeric conversions only: * The following are used in numeric conversions only:
@ -163,18 +163,19 @@ extern _LONG_DOUBLE _strtold _PARAMS((char *s, char **sptr));
* SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral. * SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral.
*/ */
#define SIGNOK 0x40 /* +/- is (still) legal */ #define SIGNOK 0x80 /* +/- is (still) legal */
#define NDIGITS 0x80 /* no digits detected */ #define NDIGITS 0x100 /* no digits detected */
#define DPTOK 0x100 /* (float) decimal point is still legal */ #define DPTOK 0x200 /* (float) decimal point is still legal */
#define EXPOK 0x200 /* (float) exponent (e+3, etc) still legal */ #define EXPOK 0x400 /* (float) exponent (e+3, etc) still legal */
#define PFXOK 0x100 /* 0x prefix is (still) legal */ #define PFXOK 0x200 /* 0x prefix is (still) legal */
#define NZDIGITS 0x200 /* no zero digits detected */ #define NZDIGITS 0x400 /* no zero digits detected */
#define NNZDIGITS 0x800 /* no non-zero digits detected */
#define VECTOR 0x400 /* v: vector */ #define VECTOR 0x2000 /* v: vector */
#define FIXEDPOINT 0x800 /* r/R: fixed-point */ #define FIXEDPOINT 0x4000 /* r/R: fixed-point */
#define SIGNED 0x1000 /* r: signed fixed-point */ #define SIGNED 0x8000 /* r: signed fixed-point */
/* /*
* Conversion types. * Conversion types.
@ -798,18 +799,19 @@ __svfscanf_r (rptr, fp, fmt0, ap)
continue; continue;
case CT_INT: case CT_INT:
/* scan an integer as if by strtol/strtoul */ unsigned int_width_left = 0;
int_width = width; int_width = width;
#ifdef hardway #ifdef hardway
if (int_width == 0 || int_width > sizeof (buf) - 1) if (int_width == 0 || int_width > sizeof (buf) - 1)
int_width = sizeof (buf) - 1;
#else #else
/* size_t is unsigned, hence this optimisation */ /* size_t is unsigned, hence this optimisation */
if (--int_width > sizeof (buf) - 2) if (int_width - 1 > sizeof (buf) - 2)
int_width = sizeof (buf) - 2;
int_width++;
#endif #endif
flags |= SIGNOK | NDIGITS | NZDIGITS; {
int_width_left = width - (sizeof (buf) - 1);
int_width = sizeof (buf) - 1;
}
flags |= SIGNOK | NDIGITS | NZDIGITS | NNZDIGITS;
for (p = buf; int_width; int_width--) for (p = buf; int_width; int_width--)
{ {
c = *fp->_p; c = *fp->_p;
@ -829,16 +831,25 @@ __svfscanf_r (rptr, fp, fmt0, ap)
* will turn it off if we have scanned any nonzero digits). * will turn it off if we have scanned any nonzero digits).
*/ */
case '0': case '0':
if (! (flags & NNZDIGITS))
goto ok;
if (base == 0) if (base == 0)
{ {
base = 8; base = 8;
flags |= PFXOK; flags |= PFXOK;
} }
if (flags & NZDIGITS) if (flags & NZDIGITS)
flags &= ~(SIGNOK | NZDIGITS | NDIGITS); {
else flags &= ~(SIGNOK | NZDIGITS | NDIGITS);
flags &= ~(SIGNOK | PFXOK | NDIGITS); goto ok;
goto ok; }
flags &= ~(SIGNOK | PFXOK | NDIGITS);
if (int_width_left)
{
int_width_left--;
int_width++;
}
goto skip;
/* 1 through 7 always legal */ /* 1 through 7 always legal */
case '1': case '1':
@ -849,7 +860,7 @@ __svfscanf_r (rptr, fp, fmt0, ap)
case '6': case '6':
case '7': case '7':
base = basefix[base]; base = basefix[base];
flags &= ~(SIGNOK | PFXOK | NDIGITS); flags &= ~(SIGNOK | PFXOK | NDIGITS | NNZDIGITS);
goto ok; goto ok;
/* digits 8 and 9 ok iff decimal or hex */ /* digits 8 and 9 ok iff decimal or hex */
@ -858,7 +869,7 @@ __svfscanf_r (rptr, fp, fmt0, ap)
base = basefix[base]; base = basefix[base];
if (base <= 8) if (base <= 8)
break; /* not legal here */ break; /* not legal here */
flags &= ~(SIGNOK | PFXOK | NDIGITS); flags &= ~(SIGNOK | PFXOK | NDIGITS | NNZDIGITS);
goto ok; goto ok;
/* letters ok iff hex */ /* letters ok iff hex */
@ -877,7 +888,7 @@ __svfscanf_r (rptr, fp, fmt0, ap)
/* no need to fix base here */ /* no need to fix base here */
if (base <= 10) if (base <= 10)
break; /* not legal here */ break; /* not legal here */
flags &= ~(SIGNOK | PFXOK | NDIGITS); flags &= ~(SIGNOK | PFXOK | NDIGITS | NNZDIGITS);
goto ok; goto ok;
/* sign ok only as first character */ /* sign ok only as first character */
@ -912,6 +923,7 @@ __svfscanf_r (rptr, fp, fmt0, ap)
* c is legal: store it and look at the next. * c is legal: store it and look at the next.
*/ */
*p++ = c; *p++ = c;
skip:
if (--fp->_r > 0) if (--fp->_r > 0)
fp->_p++; fp->_p++;
else else
@ -1004,16 +1016,18 @@ __svfscanf_r (rptr, fp, fmt0, ap)
long leading_zeroes = 0; long leading_zeroes = 0;
long zeroes, exp_adjust; long zeroes, exp_adjust;
char *exp_start = NULL; char *exp_start = NULL;
int fl_width = width; unsigned fl_width = width;
unsigned width_left = 0;
#ifdef hardway #ifdef hardway
if (fl_width == 0 || fl_width > sizeof (buf) - 1) if (fl_width == 0 || fl_width > sizeof (buf) - 1)
fl_width = sizeof (buf) - 1;
#else #else
/* size_t is unsigned, hence this optimisation */ /* size_t is unsigned, hence this optimisation */
if (--fl_width > sizeof (buf) - 2) if (fl_width - 1 > sizeof (buf) - 2)
fl_width = sizeof (buf) - 2;
fl_width++;
#endif #endif
{
width_left = fl_width - (sizeof (buf) - 1);
fl_width = sizeof (buf) - 1;
}
flags |= SIGNOK | NDIGITS | DPTOK | EXPOK; flags |= SIGNOK | NDIGITS | DPTOK | EXPOK;
zeroes = 0; zeroes = 0;
exp_adjust = 0; exp_adjust = 0;
@ -1032,6 +1046,11 @@ __svfscanf_r (rptr, fp, fmt0, ap)
{ {
flags &= ~SIGNOK; flags &= ~SIGNOK;
zeroes++; zeroes++;
if (width_left)
{
width_left--;
fl_width++;
}
goto fskip; goto fskip;
} }
/* Fall through. */ /* Fall through. */