Mail Archives: djgpp/2001/03/01/09:12:59
On Thu, 1 Mar 2001, Rafael Garc=EDa wrote:
> > It's a bug in the library; thanks for reporting it. Here's a patch
> > for the strtol function which is responsible for this bug:
> > .........
>=20
> I don't know how to aply that. I only have binary version of the compiler=
.
The patch is for the library, not for the compiler.
All you need to do is download v2/djlsr203.zip (1.5MB), extract strtol.c=20
from there, apply the patch to it, compile it, and put it into libc.a. =20
The DJGPP FAQ explains how to do that in section 21.4. I am attaching=20
below a patched version of strtol.c, so that you could bypass the first=20
step entirely.
> Nor I am interested in substitute all the compiler instalations I can use=
.
Are you interested in having a library that can be trusted? The version=20
of strtol below was thoroughly tested and improved over the years. While=
=20
you did find a bug there, feeding 8-bit characters to strtol is not a=20
very frequent operation; most of the time, strtol and atoi have to deal
with numeric strings, and the library version works very well for those,=20
including some very difficult and subtle cases (take a look at the source=
=20
below, and you will see it).
> #undef atol // now I have to call original ones
> #undef atoi
> #undef strtol
>=20
> long myatol(const char *s) {
> while (isspace(*s)) s++;
> if (*s & 0x80) return 0;
> else return atol(s);
> }
This will not work reliably, because some library functions call strtol=20
internally. They will bypass these macros.
> 1) How can I remove "assignment discards qualifiers from pointer target
> type" warning at
> "*endp=3Ds" line?
Use `unconst'. See the source below for an example.
> 2) Is it possible to know library version, to not use this patch when not
> necessary?...
> Something like #if defined(__DJGPP__) && (__DJGPPVER__<XXX)
See section 8.7 of the DJGPP FAQ list.
Here's the patched strtol:
/* Copyright (C) 2001 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1999 DJ Delorie, see COPYING.DJ for details */
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
#include <limits.h>
#include <ctype.h>
#include <errno.h>
#include <stdlib.h>
#include <libc/unconst.h>
long
strtol(const char *nptr, char **endptr, int base)
{
const char *s =3D nptr;
unsigned long acc;
int c;
unsigned long cutoff;
int neg =3D 0, any, cutlim;
/*
* Skip white space and pick up leading +/- sign if any.
* If base is 0, allow 0x for hex and 0 for octal, else
* assume decimal; if base is already 16, allow 0x.
*/
do {
c =3D *s++;
} while (isspace(c & 0xff));
if (c =3D=3D '-')
{
neg =3D 1;
c =3D *s++;
}
else if (c =3D=3D '+')
c =3D *s++;
if ((base =3D=3D 0 || base =3D=3D 16) &&
c =3D=3D '0' && (*s =3D=3D 'x' || *s =3D=3D 'X'))
{
c =3D s[1];
s +=3D 2;
base =3D 16;
}
if (base =3D=3D 0)
base =3D c =3D=3D '0' ? 8 : 10;
/*
* Compute the cutoff value between legal numbers and illegal
* numbers. That is the largest legal value, divided by the
* base. An input number that is greater than this value, if
* followed by a legal input character, is too big. One that
* is equal to this value may be valid or not; the limit
* between valid and invalid numbers is then based on the last
* digit. For instance, if the range for longs is
* [-2147483648..2147483647] and the input base is 10,
* cutoff will be set to 214748364 and cutlim to either
* 7 (neg=3D=3D0) or 8 (neg=3D=3D1), meaning that if we have accumulated
* a value > 214748364, or equal but the next digit is > 7 (or 8),
* the number is too big, and we will return a range error.
*
* Set any if any `digits' consumed; make it negative to indicate
* overflow.
*/
cutoff =3D neg ? -(unsigned long)LONG_MIN : LONG_MAX;
cutlim =3D cutoff % (unsigned long)base;
cutoff /=3D (unsigned long)base;
for (acc =3D 0, any =3D 0, c &=3D 0xff;; c =3D *s++, c &=3D 0xff)
{
if (isdigit(c))
c -=3D '0';
else if (isalpha(c))
c -=3D isupper(c) ? 'A' - 10 : 'a' - 10;
else
break;
if (c >=3D base)
break;
if (any < 0 || acc > cutoff || (acc =3D=3D cutoff && c > cutlim))
any =3D -1;
else
{
any =3D 1;
acc *=3D base;
acc +=3D c;
}
}
if (any < 0)
{
acc =3D neg ? LONG_MIN : LONG_MAX;
errno =3D ERANGE;
}
else if (neg)
acc =3D -acc;
if (endptr !=3D 0)
*endptr =3D any ? unconst(s, char *) - 1 : unconst(nptr, char *);
return acc;
}
- Raw text -