added atoi() and atol()

svn path=/trunk/; revision=802
This commit is contained in:
Eric Kohl 1999-11-27 11:32:43 +00:00
parent 8b829113cb
commit 0d630c9ee3

View file

@ -11,6 +11,7 @@
/* INCLUDES *****************************************************************/
#include <ctype.h>
#include <limits.h>
#include <stdlib.h>
/* GLOBALS ****************************************************************/
@ -19,17 +20,84 @@ static unsigned long long next = 0;
/* FUNCTIONS ****************************************************************/
#if 0
int atoi(const char *str)
{
return (int)atol (str);
}
/*
* NOTE: no error
*/
long atol(const char *str)
{
return strtol(str, 0, 10);
const char *s = str;
unsigned long acc;
int c;
unsigned long cutoff;
int neg = 0, any, cutlim;
/*
* Skip white space and pick up leading +/- sign if any.
*/
do {
c = *s++;
} while (isspace(c));
if (c == '-')
{
neg = 1;
c = *s++;
}
else if (c == '+')
c = *s++;
/*
* 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==0) or 8 (neg==1), 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 = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
cutlim = cutoff % (unsigned long)10;
cutoff /= (unsigned long)10;
for (acc = 0, any = 0;; c = *s++)
{
if (isdigit(c))
c -= '0';
else
break;
if (c >= 10)
break;
if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
any = -1;
else
{
any = 1;
acc *= 10;
acc += c;
}
}
if (any < 0)
{
acc = neg ? LONG_MIN : LONG_MAX;
}
else if (neg)
acc = -acc;
return acc;
}
#endif
/*