mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
added atoi() and atol()
svn path=/trunk/; revision=802
This commit is contained in:
parent
8b829113cb
commit
0d630c9ee3
1 changed files with 71 additions and 3 deletions
|
@ -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
|
||||
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue