mirror of
https://github.com/adtools/clib2.git
synced 2025-12-08 14:59:05 +00:00
- strtoimax(), strtoumax(), strtod(), strtof(), strtol(), strtoll(),
strtoul() and strtoull() now count how many digits were converted.
If that number is zero, then the conversion is considered to have
failed: 0 is returned, errno is set to ERANGE and the 'ptr' parameter
reference is initialized with a pointer to the string to be converted.
This has two consequences:
1) A floating point number that has no digits in the significand
is no longer converted to zero. For example ".e10" can no longer
result in a successful conversion.
2) You can detect if a conversion is successful by comparing pointers
after the conversion function has returned:
char * str;
char * ptr;
long n;
n = strtol(str,&ptr,10);
if(n == 0 && str == ptr)
printf("conversion has failed");
git-svn-id: file:///Users/olsen/Code/migration-svn-zu-git/logical-line-staging/clib2/trunk@15030 87f5fb63-7c3d-0410-a384-fd976d0f7a62
This commit is contained in:
@ -1,3 +1,25 @@
|
||||
- strtoimax(), strtoumax(), strtod(), strtof(), strtol(), strtoll(),
|
||||
strtoul() and strtoull() now count how many digits were converted.
|
||||
If that number is zero, then the conversion is considered to have
|
||||
failed: 0 is returned, errno is set to ERANGE and the 'ptr' parameter
|
||||
reference is initialized with a pointer to the string to be converted.
|
||||
This has two consequences:
|
||||
|
||||
1) A floating point number that has no digits in the significand
|
||||
is no longer converted to zero. For example ".e10" can no longer
|
||||
result in a successful conversion.
|
||||
|
||||
2) You can detect if a conversion is successful by comparing pointers
|
||||
after the conversion function has returned:
|
||||
|
||||
char * str;
|
||||
char * ptr;
|
||||
long n;
|
||||
|
||||
n = strtol(str,&ptr,10);
|
||||
if(n == 0 && str == ptr)
|
||||
printf("conversion has failed");
|
||||
|
||||
- Following detection of a stack overflow, the startup code eventually
|
||||
called _exit(). It should have called exit() instead.
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: inttypes_strtoimax.c,v 1.1 2005-05-12 13:21:43 obarthel Exp $
|
||||
* $Id: inttypes_strtoimax.c,v 1.2 2005-09-28 09:28:39 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -46,6 +46,8 @@
|
||||
intmax_t
|
||||
strtoimax(const char *str, char **ptr, int base)
|
||||
{
|
||||
const char * stop = str;
|
||||
size_t num_digits_converted = 0;
|
||||
BOOL is_negative;
|
||||
intmax_t result = 0;
|
||||
intmax_t new_sum;
|
||||
@ -172,20 +174,31 @@ strtoimax(const char *str, char **ptr, int base)
|
||||
str++;
|
||||
|
||||
c = (*str);
|
||||
|
||||
num_digits_converted++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Did we convert anything? */
|
||||
if(num_digits_converted == 0)
|
||||
{
|
||||
__set_errno(ERANGE);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(is_negative)
|
||||
result = (-sum);
|
||||
else
|
||||
result = sum;
|
||||
|
||||
stop = str;
|
||||
|
||||
out:
|
||||
|
||||
/* If desired, remember where we stopped reading the
|
||||
number from the buffer. */
|
||||
if(ptr != NULL)
|
||||
(*ptr) = (char *)str;
|
||||
(*ptr) = (char *)stop;
|
||||
|
||||
RETURN(result);
|
||||
return(result);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: inttypes_strtoumax.c,v 1.1 2005-05-12 13:21:43 obarthel Exp $
|
||||
* $Id: inttypes_strtoumax.c,v 1.2 2005-09-28 09:28:39 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -46,6 +46,8 @@
|
||||
uintmax_t
|
||||
strtoumax(const char *str, char **ptr, int base)
|
||||
{
|
||||
const char * stop = str;
|
||||
size_t num_digits_converted = 0;
|
||||
BOOL is_negative;
|
||||
uintmax_t result = 0;
|
||||
uintmax_t new_sum;
|
||||
@ -169,9 +171,22 @@ strtoumax(const char *str, char **ptr, int base)
|
||||
str++;
|
||||
|
||||
c = (*str);
|
||||
|
||||
/* Remember where the conversion stopped and
|
||||
that we converted something. */
|
||||
stop = str;
|
||||
|
||||
num_digits_converted++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Did we convert anything? */
|
||||
if(num_digits_converted == 0)
|
||||
{
|
||||
__set_errno(ERANGE);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(is_negative)
|
||||
result = (-sum);
|
||||
else
|
||||
@ -182,7 +197,7 @@ strtoumax(const char *str, char **ptr, int base)
|
||||
/* If desired, remember where we stopped reading the
|
||||
number from the buffer. */
|
||||
if(ptr != NULL)
|
||||
(*ptr) = (char *)str;
|
||||
(*ptr) = (char *)stop;
|
||||
|
||||
RETURN(result);
|
||||
return(result);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stdlib_strtod.c,v 1.8 2005-05-29 08:19:36 obarthel Exp $
|
||||
* $Id: stdlib_strtod.c,v 1.9 2005-09-28 09:28:39 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -66,6 +66,7 @@
|
||||
double
|
||||
strtod(const char *str, char ** ptr)
|
||||
{
|
||||
const char * stop = str;
|
||||
double sum = 0.0;
|
||||
double result;
|
||||
int is_negative;
|
||||
@ -128,6 +129,8 @@ strtod(const char *str, char ** ptr)
|
||||
str += strlen(str);
|
||||
|
||||
sum = __inf();
|
||||
|
||||
stop = str;
|
||||
}
|
||||
else if (strncasecmp(str,"nan",3) == SAME && (str[3] == '(' || str[3] == '\0'))
|
||||
{
|
||||
@ -146,9 +149,12 @@ strtod(const char *str, char ** ptr)
|
||||
}
|
||||
|
||||
sum = nan(NULL);
|
||||
|
||||
stop = str;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t num_digits_converted = 0;
|
||||
int decimal_point_matches;
|
||||
double new_sum;
|
||||
int error = 0;
|
||||
@ -191,6 +197,8 @@ strtod(const char *str, char ** ptr)
|
||||
else
|
||||
sum = new_sum;
|
||||
}
|
||||
|
||||
num_digits_converted++;
|
||||
}
|
||||
|
||||
/* Did we find the decimal point? We accept both the
|
||||
@ -258,6 +266,8 @@ strtod(const char *str, char ** ptr)
|
||||
|
||||
divisor = divisor / radix;
|
||||
}
|
||||
|
||||
num_digits_converted++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -352,11 +362,22 @@ strtod(const char *str, char ** ptr)
|
||||
}
|
||||
}
|
||||
|
||||
if(error != 0)
|
||||
if(num_digits_converted == 0)
|
||||
{
|
||||
__set_errno(error);
|
||||
__set_errno(ERANGE);
|
||||
|
||||
sum = __get_huge_val();
|
||||
sum = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(error != 0)
|
||||
{
|
||||
__set_errno(error);
|
||||
|
||||
sum = __get_huge_val();
|
||||
}
|
||||
|
||||
stop = str;
|
||||
}
|
||||
}
|
||||
|
||||
@ -365,12 +386,12 @@ strtod(const char *str, char ** ptr)
|
||||
|
||||
result = sum;
|
||||
|
||||
out:
|
||||
|
||||
/* If desired, remember where we stopped reading the
|
||||
number from the buffer. */
|
||||
if(ptr != NULL)
|
||||
(*ptr) = (char *)str;
|
||||
|
||||
out:
|
||||
(*ptr) = (char *)stop;
|
||||
|
||||
RETURN(result);
|
||||
return(result);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stdlib_strtof.c,v 1.8 2005-05-30 18:28:45 obarthel Exp $
|
||||
* $Id: stdlib_strtof.c,v 1.9 2005-09-28 09:28:39 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -66,6 +66,7 @@
|
||||
float
|
||||
strtof(const char *str, char ** ptr)
|
||||
{
|
||||
const char * stop = str;
|
||||
float sum = 0.0;
|
||||
float result;
|
||||
int is_negative;
|
||||
@ -128,6 +129,8 @@ strtof(const char *str, char ** ptr)
|
||||
str += strlen(str);
|
||||
|
||||
sum = __inff();
|
||||
|
||||
stop = str;
|
||||
}
|
||||
else if (strncasecmp(str,"nan",3) == SAME && (str[3] == '(' || str[3] == '\0'))
|
||||
{
|
||||
@ -146,9 +149,12 @@ strtof(const char *str, char ** ptr)
|
||||
}
|
||||
|
||||
sum = nanf(NULL);
|
||||
|
||||
stop = str;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t num_digits_converted = 0;
|
||||
int decimal_point_matches;
|
||||
float new_sum;
|
||||
int error = 0;
|
||||
@ -183,6 +189,8 @@ strtof(const char *str, char ** ptr)
|
||||
|
||||
str++;
|
||||
|
||||
num_digits_converted++;
|
||||
|
||||
if(error == 0)
|
||||
{
|
||||
new_sum = (radix * sum) + c;
|
||||
@ -248,6 +256,8 @@ strtof(const char *str, char ** ptr)
|
||||
|
||||
str++;
|
||||
|
||||
num_digits_converted++;
|
||||
|
||||
if(error == 0 && divisor != 0.0)
|
||||
{
|
||||
new_sum = sum + c * divisor;
|
||||
@ -352,11 +362,22 @@ strtof(const char *str, char ** ptr)
|
||||
}
|
||||
}
|
||||
|
||||
if(error != 0)
|
||||
if(num_digits_converted == 0)
|
||||
{
|
||||
__set_errno(error);
|
||||
__set_errno(ERANGE);
|
||||
|
||||
sum = __get_huge_valf();
|
||||
sum = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
stop = str;
|
||||
|
||||
if(error != 0)
|
||||
{
|
||||
__set_errno(error);
|
||||
|
||||
sum = __get_huge_valf();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -365,12 +386,12 @@ strtof(const char *str, char ** ptr)
|
||||
|
||||
result = sum;
|
||||
|
||||
out:
|
||||
|
||||
/* If desired, remember where we stopped reading the
|
||||
number from the buffer. */
|
||||
if(ptr != NULL)
|
||||
(*ptr) = (char *)str;
|
||||
|
||||
out:
|
||||
(*ptr) = (char *)stop;
|
||||
|
||||
RETURN(result);
|
||||
return(result);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stdlib_strtol.c,v 1.3 2005-02-03 16:56:17 obarthel Exp $
|
||||
* $Id: stdlib_strtol.c,v 1.4 2005-09-28 09:28:39 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -46,6 +46,8 @@
|
||||
long
|
||||
strtol(const char *str, char **ptr, int base)
|
||||
{
|
||||
const char * stop = str;
|
||||
size_t num_digits_converted = 0;
|
||||
BOOL is_negative;
|
||||
long result = 0;
|
||||
long new_sum;
|
||||
@ -103,8 +105,7 @@ strtol(const char *str, char **ptr, int base)
|
||||
is_negative = FALSE;
|
||||
|
||||
/* But there may be a sign we will choose to
|
||||
* ignore.
|
||||
*/
|
||||
ignore. */
|
||||
if(c == '+')
|
||||
str++;
|
||||
}
|
||||
@ -112,8 +113,7 @@ strtol(const char *str, char **ptr, int base)
|
||||
c = (*str);
|
||||
|
||||
/* There may be a leading '0x' to indicate that what
|
||||
* follows is a hexadecimal number.
|
||||
*/
|
||||
follows is a hexadecimal number. */
|
||||
if(base == 0 || base == 16)
|
||||
{
|
||||
if((c == '0') && (str[1] == 'x' || str[1] == 'X'))
|
||||
@ -127,9 +127,8 @@ strtol(const char *str, char **ptr, int base)
|
||||
}
|
||||
|
||||
/* If we still don't know what base to use and the
|
||||
* next letter to follow is a zero then this is
|
||||
* probably a number in octal notation.
|
||||
*/
|
||||
next letter to follow is a zero then this is
|
||||
probably a number in octal notation. */
|
||||
if(base == 0)
|
||||
{
|
||||
if(c == '0')
|
||||
@ -175,21 +174,31 @@ strtol(const char *str, char **ptr, int base)
|
||||
str++;
|
||||
|
||||
c = (*str);
|
||||
|
||||
num_digits_converted++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Did we convert anything? */
|
||||
if(num_digits_converted == 0)
|
||||
{
|
||||
__set_errno(ERANGE);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(is_negative)
|
||||
result = (-sum);
|
||||
else
|
||||
result = sum;
|
||||
|
||||
stop = str;
|
||||
|
||||
out:
|
||||
|
||||
/* If desired, remember where we stopped reading the
|
||||
* number from the buffer.
|
||||
*/
|
||||
number from the buffer. */
|
||||
if(ptr != NULL)
|
||||
(*ptr) = (char *)str;
|
||||
(*ptr) = (char *)stop;
|
||||
|
||||
RETURN(result);
|
||||
return(result);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stdlib_strtoll.c,v 1.3 2005-02-03 16:56:17 obarthel Exp $
|
||||
* $Id: stdlib_strtoll.c,v 1.4 2005-09-28 09:28:39 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -50,6 +50,8 @@
|
||||
long long
|
||||
strtoll(const char *str, char **ptr, int base)
|
||||
{
|
||||
const char * stop = str;
|
||||
size_t num_digits_converted = 0;
|
||||
BOOL is_negative;
|
||||
long long result = 0;
|
||||
long long new_sum;
|
||||
@ -107,8 +109,7 @@ strtoll(const char *str, char **ptr, int base)
|
||||
is_negative = FALSE;
|
||||
|
||||
/* But there may be a sign we will choose to
|
||||
* ignore.
|
||||
*/
|
||||
ignore. */
|
||||
if(c == '+')
|
||||
str++;
|
||||
}
|
||||
@ -116,8 +117,7 @@ strtoll(const char *str, char **ptr, int base)
|
||||
c = (*str);
|
||||
|
||||
/* There may be a leading '0x' to indicate that what
|
||||
* follows is a hexadecimal number.
|
||||
*/
|
||||
follows is a hexadecimal number. */
|
||||
if(base == 0 || base == 16)
|
||||
{
|
||||
if((c == '0') && (str[1] == 'x' || str[1] == 'X'))
|
||||
@ -131,9 +131,8 @@ strtoll(const char *str, char **ptr, int base)
|
||||
}
|
||||
|
||||
/* If we still don't know what base to use and the
|
||||
* next letter to follow is a zero then this is
|
||||
* probably a number in octal notation.
|
||||
*/
|
||||
next letter to follow is a zero then this is
|
||||
probably a number in octal notation. */
|
||||
if(base == 0)
|
||||
{
|
||||
if(c == '0')
|
||||
@ -179,21 +178,31 @@ strtoll(const char *str, char **ptr, int base)
|
||||
str++;
|
||||
|
||||
c = (*str);
|
||||
|
||||
num_digits_converted++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Did we convert anything? */
|
||||
if(num_digits_converted == 0)
|
||||
{
|
||||
__set_errno(ERANGE);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(is_negative)
|
||||
result = (-sum);
|
||||
else
|
||||
result = sum;
|
||||
|
||||
stop = str;
|
||||
|
||||
out:
|
||||
|
||||
/* If desired, remember where we stopped reading the
|
||||
* number from the buffer.
|
||||
*/
|
||||
number from the buffer. */
|
||||
if(ptr != NULL)
|
||||
(*ptr) = (char *)str;
|
||||
(*ptr) = (char *)stop;
|
||||
|
||||
RETURN(result);
|
||||
return(result);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stdlib_strtoul.c,v 1.3 2005-02-03 16:56:17 obarthel Exp $
|
||||
* $Id: stdlib_strtoul.c,v 1.4 2005-09-28 09:28:39 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -46,6 +46,8 @@
|
||||
unsigned long
|
||||
strtoul(const char *str, char **ptr, int base)
|
||||
{
|
||||
const char * stop = str;
|
||||
size_t num_digits_converted = 0;
|
||||
BOOL is_negative;
|
||||
unsigned long result = 0;
|
||||
unsigned long new_sum;
|
||||
@ -103,8 +105,7 @@ strtoul(const char *str, char **ptr, int base)
|
||||
is_negative = FALSE;
|
||||
|
||||
/* But there may be a sign we will choose to
|
||||
* ignore.
|
||||
*/
|
||||
ignore. */
|
||||
if(c == '+')
|
||||
str++;
|
||||
}
|
||||
@ -112,8 +113,7 @@ strtoul(const char *str, char **ptr, int base)
|
||||
c = (*str);
|
||||
|
||||
/* There may be a leading '0x' to indicate that what
|
||||
* follows is a hexadecimal number.
|
||||
*/
|
||||
follows is a hexadecimal number. */
|
||||
if(base == 0 || base == 16)
|
||||
{
|
||||
if((c == '0') && (str[1] == 'x' || str[1] == 'X'))
|
||||
@ -127,9 +127,8 @@ strtoul(const char *str, char **ptr, int base)
|
||||
}
|
||||
|
||||
/* If we still don't know what base to use and the
|
||||
* next letter to follow is a zero then this is
|
||||
* probably a number in octal notation.
|
||||
*/
|
||||
next letter to follow is a zero then this is
|
||||
probably a number in octal notation. */
|
||||
if(base == 0)
|
||||
{
|
||||
if(c == '0')
|
||||
@ -172,21 +171,31 @@ strtoul(const char *str, char **ptr, int base)
|
||||
str++;
|
||||
|
||||
c = (*str);
|
||||
|
||||
num_digits_converted++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Did we convert anything? */
|
||||
if(num_digits_converted == 0)
|
||||
{
|
||||
__set_errno(ERANGE);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(is_negative)
|
||||
result = (-sum);
|
||||
else
|
||||
result = sum;
|
||||
|
||||
stop = str;
|
||||
|
||||
out:
|
||||
|
||||
/* If desired, remember where we stopped reading the
|
||||
* number from the buffer.
|
||||
*/
|
||||
number from the buffer. */
|
||||
if(ptr != NULL)
|
||||
(*ptr) = (char *)str;
|
||||
(*ptr) = (char *)stop;
|
||||
|
||||
RETURN(result);
|
||||
return(result);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: stdlib_strtoull.c,v 1.3 2005-02-03 16:56:17 obarthel Exp $
|
||||
* $Id: stdlib_strtoull.c,v 1.4 2005-09-28 09:28:39 obarthel Exp $
|
||||
*
|
||||
* :ts=4
|
||||
*
|
||||
@ -50,6 +50,8 @@
|
||||
unsigned long long
|
||||
strtoull(const char *str, char **ptr, int base)
|
||||
{
|
||||
const char * stop = str;
|
||||
size_t num_digits_converted = 0;
|
||||
BOOL is_negative;
|
||||
unsigned long long result = 0;
|
||||
unsigned long long new_sum;
|
||||
@ -107,8 +109,7 @@ strtoull(const char *str, char **ptr, int base)
|
||||
is_negative = FALSE;
|
||||
|
||||
/* But there may be a sign we will choose to
|
||||
* ignore.
|
||||
*/
|
||||
ignore. */
|
||||
if(c == '+')
|
||||
str++;
|
||||
}
|
||||
@ -116,8 +117,7 @@ strtoull(const char *str, char **ptr, int base)
|
||||
c = (*str);
|
||||
|
||||
/* There may be a leading '0x' to indicate that what
|
||||
* follows is a hexadecimal number.
|
||||
*/
|
||||
follows is a hexadecimal number. */
|
||||
if(base == 0 || base == 16)
|
||||
{
|
||||
if((c == '0') && (str[1] == 'x' || str[1] == 'X'))
|
||||
@ -131,9 +131,8 @@ strtoull(const char *str, char **ptr, int base)
|
||||
}
|
||||
|
||||
/* If we still don't know what base to use and the
|
||||
* next letter to follow is a zero then this is
|
||||
* probably a number in octal notation.
|
||||
*/
|
||||
next letter to follow is a zero then this is
|
||||
probably a number in octal notation. */
|
||||
if(base == 0)
|
||||
{
|
||||
if(c == '0')
|
||||
@ -176,21 +175,31 @@ strtoull(const char *str, char **ptr, int base)
|
||||
str++;
|
||||
|
||||
c = (*str);
|
||||
|
||||
num_digits_converted++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Did we convert anything? */
|
||||
if(num_digits_converted == 0)
|
||||
{
|
||||
__set_errno(ERANGE);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if(is_negative)
|
||||
result = (-sum);
|
||||
else
|
||||
result = sum;
|
||||
|
||||
stop = str;
|
||||
|
||||
out:
|
||||
|
||||
/* If desired, remember where we stopped reading the
|
||||
* number from the buffer.
|
||||
*/
|
||||
number from the buffer. */
|
||||
if(ptr != NULL)
|
||||
(*ptr) = (char *)str;
|
||||
(*ptr) = (char *)stop;
|
||||
|
||||
RETURN(result);
|
||||
return(result);
|
||||
|
||||
Reference in New Issue
Block a user