summaryrefslogtreecommitdiffstats
path: root/lib/libc/stdlib/strtoull.c
diff options
context:
space:
mode:
authorache <ache@FreeBSD.org>2001-09-04 16:39:11 +0000
committerache <ache@FreeBSD.org>2001-09-04 16:39:11 +0000
commitcd61d5ab4817c934f249aeb6e7b6ccf8ee382706 (patch)
tree7bcee0477a1db7819fa0b437d2bfb0714a1119df /lib/libc/stdlib/strtoull.c
parent29e117e97875b5c4c297c48dae32a287e46e1785 (diff)
downloadFreeBSD-src-cd61d5ab4817c934f249aeb6e7b6ccf8ee382706.zip
FreeBSD-src-cd61d5ab4817c934f249aeb6e7b6ccf8ee382706.tar.gz
Locale *is* used in strto*l*(), at least for isspace(), so remove
'locale not used' statement from comments and BUGS section of manpage. strtol(): fix non-portable 'cutoff' calculation using the same method as in strtoll(). Cleanup 'cutoff' calculation, remove unneded casts. Misc. cleanup to make all functions looks the same. Implement EINVAL reaction per POSIX, document it in manpage, corresponding POSIX example quotes here: ------------------------------------------------ If the subject sequence is empty or does not have the expected form, no conversion is performed; the value of str is stored in the object pointed to by endptr, provided that endptr is not a null pointer. If no conversion could be performed, 0 shall be returned and errno may be set to [EINVAL]. [EINVAL] The value of base is not supported. Since 0, {LONG_MIN} or {LLONG_MIN}, and {LONG_MAX} or {LLONG_MAX} are returned on error and are also valid returns on success, an application wishing to check for error situations should set errno to 0, then call strtol( ) or strtoll ( ), then check errno. -----------------------------------------------------
Diffstat (limited to 'lib/libc/stdlib/strtoull.c')
-rw-r--r--lib/libc/stdlib/strtoull.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/lib/libc/stdlib/strtoull.c b/lib/libc/stdlib/strtoull.c
index 3e7c943..ac0935e 100644
--- a/lib/libc/stdlib/strtoull.c
+++ b/lib/libc/stdlib/strtoull.c
@@ -50,7 +50,7 @@ static const char rcsid[] =
/*
* Convert a string to an unsigned long long integer.
*
- * Ignores `locale' stuff. Assumes that the upper and lower case
+ * Assumes that the upper and lower case
* alphabets and digits are each contiguous.
*/
unsigned long long
@@ -59,10 +59,10 @@ strtoull(nptr, endptr, base)
char **endptr;
register int base;
{
- register const char *s = nptr;
+ register const char *s;
register unsigned long long acc;
register unsigned char c;
- register unsigned long long qbase, cutoff;
+ register unsigned long long cutoff;
register int neg, any, cutlim;
/*
@@ -88,10 +88,13 @@ strtoull(nptr, endptr, base)
}
if (base == 0)
base = c == '0' ? 8 : 10;
- qbase = (unsigned)base;
- cutoff = (unsigned long long)ULLONG_MAX / qbase;
- cutlim = (unsigned long long)ULLONG_MAX % qbase;
- for (acc = 0, any = 0;; c = *s++) {
+ any = 0;
+ if (base < 2 || base > 36)
+ goto noconv;
+
+ cutoff = ULLONG_MAX / base;
+ cutlim = ULLONG_MAX % base;
+ for (acc = 0; ; c = *s++) {
if (!isascii(c))
break;
if (isdigit(c))
@@ -106,16 +109,19 @@ strtoull(nptr, endptr, base)
any = -1;
else {
any = 1;
- acc *= qbase;
+ acc *= base;
acc += c;
}
}
if (any < 0) {
acc = ULLONG_MAX;
errno = ERANGE;
+ } else if (!any) {
+noconv:
+ errno = EINVAL;
} else if (neg)
acc = -acc;
- if (endptr != 0)
+ if (endptr != NULL)
*endptr = (char *)(any ? s - 1 : nptr);
return (acc);
}
OpenPOWER on IntegriCloud