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:
parent
c00f971933
commit
27c7566ca4
@ -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.
|
||||||
|
@ -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. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user