Merge "Refactor the ato* and strto* family."
This commit is contained in:
commit
9dc37b9439
12 changed files with 256 additions and 913 deletions
|
@ -468,9 +468,6 @@ cc_library_static {
|
|||
"upstream-openbsd/lib/libc/stdio/wbuf.c",
|
||||
"upstream-openbsd/lib/libc/stdio/wsetup.c",
|
||||
"upstream-openbsd/lib/libc/stdlib/abs.c",
|
||||
"upstream-openbsd/lib/libc/stdlib/atoi.c",
|
||||
"upstream-openbsd/lib/libc/stdlib/atol.c",
|
||||
"upstream-openbsd/lib/libc/stdlib/atoll.c",
|
||||
"upstream-openbsd/lib/libc/stdlib/getenv.c",
|
||||
"upstream-openbsd/lib/libc/stdlib/getsubopt.c",
|
||||
"upstream-openbsd/lib/libc/stdlib/insque.c",
|
||||
|
@ -482,12 +479,6 @@ cc_library_static {
|
|||
"upstream-openbsd/lib/libc/stdlib/reallocarray.c",
|
||||
"upstream-openbsd/lib/libc/stdlib/remque.c",
|
||||
"upstream-openbsd/lib/libc/stdlib/setenv.c",
|
||||
"upstream-openbsd/lib/libc/stdlib/strtoimax.c",
|
||||
"upstream-openbsd/lib/libc/stdlib/strtol.c",
|
||||
"upstream-openbsd/lib/libc/stdlib/strtoll.c",
|
||||
"upstream-openbsd/lib/libc/stdlib/strtoul.c",
|
||||
"upstream-openbsd/lib/libc/stdlib/strtoull.c",
|
||||
"upstream-openbsd/lib/libc/stdlib/strtoumax.c",
|
||||
"upstream-openbsd/lib/libc/stdlib/system.c",
|
||||
"upstream-openbsd/lib/libc/stdlib/tfind.c",
|
||||
"upstream-openbsd/lib/libc/stdlib/tsearch.c",
|
||||
|
@ -1375,6 +1366,7 @@ cc_library_static {
|
|||
"bionic/string_l.cpp",
|
||||
"bionic/strings_l.cpp",
|
||||
"bionic/strsignal.cpp",
|
||||
"bionic/strtol.cpp",
|
||||
"bionic/strtold.cpp",
|
||||
"bionic/swab.cpp",
|
||||
"bionic/symlink.cpp",
|
||||
|
|
232
libc/bionic/strtol.cpp
Normal file
232
libc/bionic/strtol.cpp
Normal file
|
@ -0,0 +1,232 @@
|
|||
/*
|
||||
* Copyright (c) 1992 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
template <typename T, T Min, T Max> T StrToI(const char* nptr, char** endptr, int base) {
|
||||
// Ensure that base is between 2 and 36 inclusive, or the special value of 0.
|
||||
if (base < 0 || base == 1 || base > 36) {
|
||||
if (endptr != nullptr) *endptr = const_cast<char*>(nptr);
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 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.
|
||||
const char* s = nptr;
|
||||
int c;
|
||||
do {
|
||||
c = static_cast<unsigned char>(*s++);
|
||||
} while (isspace(c));
|
||||
int neg;
|
||||
if (c == '-') {
|
||||
neg = 1;
|
||||
c = *s++;
|
||||
} else {
|
||||
neg = 0;
|
||||
if (c == '+') c = *s++;
|
||||
}
|
||||
if ((base == 0 || base == 16) && c == '0' &&
|
||||
(*s == 'x' || *s == 'X') && isxdigit(static_cast<unsigned char>(s[1]))) {
|
||||
c = s[1];
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
if (base == 0) base = (c == '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 intmax_t is
|
||||
// [-9223372036854775808..9223372036854775807] and the input base
|
||||
// is 10, cutoff will be set to 922337203685477580 and cutlim to
|
||||
// either 7 (neg==0) or 8 (neg==1), meaning that if we have
|
||||
// accumulated a value > 922337203685477580, or equal but the
|
||||
// next digit is > 7 (or 8), the number is too big, and we will
|
||||
// return a range error.
|
||||
T cutoff = neg ? Min : Max;
|
||||
int cutlim = cutoff % base;
|
||||
cutoff /= base;
|
||||
if (neg) {
|
||||
if (cutlim > 0) {
|
||||
cutlim -= base;
|
||||
cutoff += 1;
|
||||
}
|
||||
cutlim = -cutlim;
|
||||
}
|
||||
|
||||
// Set `any` if any digits consumed; make it negative to indicate overflow.
|
||||
int any = 0;
|
||||
T acc = 0;
|
||||
for (; ; c = static_cast<unsigned char>(*s++)) {
|
||||
if (isdigit(c)) {
|
||||
c -= '0';
|
||||
} else if (isalpha(c)) {
|
||||
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
if (c >= base) break;
|
||||
if (any < 0) continue;
|
||||
if (neg) {
|
||||
if (acc < cutoff || (acc == cutoff && c > cutlim)) {
|
||||
any = -1;
|
||||
acc = Min;
|
||||
errno = ERANGE;
|
||||
} else {
|
||||
any = 1;
|
||||
acc *= base;
|
||||
acc -= c;
|
||||
}
|
||||
} else {
|
||||
if (acc > cutoff || (acc == cutoff && c > cutlim)) {
|
||||
any = -1;
|
||||
acc = Max;
|
||||
errno = ERANGE;
|
||||
} else {
|
||||
any = 1;
|
||||
acc *= base;
|
||||
acc += c;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (endptr != nullptr) *endptr = const_cast<char*>(any ? s - 1 : nptr);
|
||||
return acc;
|
||||
}
|
||||
|
||||
template <typename T, T Max> T StrToU(const char* nptr, char** endptr, int base) {
|
||||
if (base < 0 || base == 1 || base > 36) {
|
||||
if (endptr != nullptr) *endptr = const_cast<char*>(nptr);
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* s = nptr;
|
||||
int c;
|
||||
do {
|
||||
c = static_cast<unsigned char>(*s++);
|
||||
} while (isspace(c));
|
||||
int neg;
|
||||
if (c == '-') {
|
||||
neg = 1;
|
||||
c = *s++;
|
||||
} else {
|
||||
neg = 0;
|
||||
if (c == '+') c = *s++;
|
||||
}
|
||||
if ((base == 0 || base == 16) && c == '0' &&
|
||||
(*s == 'x' || *s == 'X') && isxdigit(static_cast<unsigned char>(s[1]))) {
|
||||
c = s[1];
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
if (base == 0) base = (c == '0') ? 8 : 10;
|
||||
|
||||
T cutoff = Max / static_cast<T>(base);
|
||||
int cutlim = Max % static_cast<T>(base);
|
||||
T acc = 0;
|
||||
int any = 0;
|
||||
for (; ; c = static_cast<unsigned char>(*s++)) {
|
||||
if (isdigit(c)) {
|
||||
c -= '0';
|
||||
} else if (isalpha(c)) {
|
||||
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
if (c >= base) break;
|
||||
if (any < 0) continue;
|
||||
if (acc > cutoff || (acc == cutoff && c > cutlim)) {
|
||||
any = -1;
|
||||
acc = Max;
|
||||
errno = ERANGE;
|
||||
} else {
|
||||
any = 1;
|
||||
acc *= static_cast<T>(base);
|
||||
acc += c;
|
||||
}
|
||||
}
|
||||
if (neg && any > 0) acc = -acc;
|
||||
if (endptr != nullptr) *endptr = const_cast<char*>(any ? s - 1 : nptr);
|
||||
return acc;
|
||||
}
|
||||
|
||||
int atoi(const char* s) {
|
||||
return strtol(s, nullptr, 10);
|
||||
}
|
||||
|
||||
long atol(const char* s) {
|
||||
return strtol(s, nullptr, 10);
|
||||
}
|
||||
|
||||
long long atoll(const char* s) {
|
||||
return strtoll(s, nullptr, 10);
|
||||
}
|
||||
|
||||
intmax_t strtoimax(const char* s, char** end, int base) {
|
||||
return StrToI<intmax_t, INTMAX_MIN, INTMAX_MAX>(s, end, base);
|
||||
}
|
||||
|
||||
long strtol(const char* s, char** end, int base) {
|
||||
return StrToI<long, LONG_MIN, LONG_MAX>(s, end, base);
|
||||
}
|
||||
|
||||
long long strtoll(const char* s, char** end, int base) {
|
||||
return StrToI<long long, LLONG_MIN, LLONG_MAX>(s, end, base);
|
||||
}
|
||||
|
||||
// Public API since L, but not in any header.
|
||||
extern "C" long long strtoq(const char* s, char** end, int base) {
|
||||
return strtoll(s, end, base);
|
||||
}
|
||||
|
||||
unsigned long strtoul(const char* s, char** end, int base) {
|
||||
return StrToU<unsigned long, ULONG_MAX>(s, end, base);
|
||||
}
|
||||
|
||||
unsigned long long strtoull(const char* s, char** end, int base) {
|
||||
return StrToU<unsigned long long, ULLONG_MAX>(s, end, base);
|
||||
}
|
||||
|
||||
uintmax_t strtoumax(const char* s, char** end, int base) {
|
||||
return StrToU<uintmax_t, UINTMAX_MAX>(s, end, base);
|
||||
}
|
||||
|
||||
// Public API since L, but not in any header.
|
||||
extern "C" unsigned long long strtouq(const char* s, char** end, int base) {
|
||||
return strtoull(s, end, base);
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
/* $OpenBSD: atoi.c,v 1.6 2015/09/13 08:31:47 guenther Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1988 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
int
|
||||
atoi(const char *str)
|
||||
{
|
||||
return((int)strtol(str, (char **)NULL, 10));
|
||||
}
|
||||
DEF_STRONG(atoi);
|
|
@ -1,37 +0,0 @@
|
|||
/* $OpenBSD: atol.c,v 1.5 2005/08/08 08:05:36 espie Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1988 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
long
|
||||
atol(const char *str)
|
||||
{
|
||||
return(strtol(str, (char **)NULL, 10));
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
/* $OpenBSD: atoll.c,v 1.3 2005/08/08 08:05:36 espie Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1988 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
long long
|
||||
atoll(str)
|
||||
const char *str;
|
||||
{
|
||||
return(strtoll(str, (char **)NULL, 10));
|
||||
}
|
|
@ -1,151 +0,0 @@
|
|||
/* $OpenBSD: strtoimax.c,v 1.4 2017/07/06 16:23:11 millert Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1992 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
/*
|
||||
* Convert a string to an intmax_t
|
||||
*
|
||||
* Ignores `locale' stuff. Assumes that the upper and lower case
|
||||
* alphabets and digits are each contiguous.
|
||||
*/
|
||||
intmax_t
|
||||
strtoimax(const char *nptr, char **endptr, int base)
|
||||
{
|
||||
const char *s;
|
||||
intmax_t acc, cutoff;
|
||||
int c;
|
||||
int neg, any, cutlim;
|
||||
|
||||
/*
|
||||
* Ensure that base is between 2 and 36 inclusive, or the special
|
||||
* value of 0.
|
||||
*/
|
||||
if (base < 0 || base == 1 || base > 36) {
|
||||
if (endptr != 0)
|
||||
*endptr = (char *)nptr;
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
s = nptr;
|
||||
do {
|
||||
c = (unsigned char) *s++;
|
||||
} while (isspace(c));
|
||||
if (c == '-') {
|
||||
neg = 1;
|
||||
c = *s++;
|
||||
} else {
|
||||
neg = 0;
|
||||
if (c == '+')
|
||||
c = *s++;
|
||||
}
|
||||
if ((base == 0 || base == 16) && c == '0' &&
|
||||
(*s == 'x' || *s == 'X') && isxdigit((unsigned char)s[1])) {
|
||||
c = s[1];
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
if (base == 0)
|
||||
base = c == '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 intmax_t is
|
||||
* [-9223372036854775808..9223372036854775807] and the input base
|
||||
* is 10, cutoff will be set to 922337203685477580 and cutlim to
|
||||
* either 7 (neg==0) or 8 (neg==1), meaning that if we have
|
||||
* accumulated a value > 922337203685477580, 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 ? INTMAX_MIN : INTMAX_MAX;
|
||||
cutlim = cutoff % base;
|
||||
cutoff /= base;
|
||||
if (neg) {
|
||||
if (cutlim > 0) {
|
||||
cutlim -= base;
|
||||
cutoff += 1;
|
||||
}
|
||||
cutlim = -cutlim;
|
||||
}
|
||||
for (acc = 0, any = 0;; c = (unsigned char) *s++) {
|
||||
if (isdigit(c))
|
||||
c -= '0';
|
||||
else if (isalpha(c))
|
||||
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
|
||||
else
|
||||
break;
|
||||
if (c >= base)
|
||||
break;
|
||||
if (any < 0)
|
||||
continue;
|
||||
if (neg) {
|
||||
if (acc < cutoff || (acc == cutoff && c > cutlim)) {
|
||||
any = -1;
|
||||
acc = INTMAX_MIN;
|
||||
errno = ERANGE;
|
||||
} else {
|
||||
any = 1;
|
||||
acc *= base;
|
||||
acc -= c;
|
||||
}
|
||||
} else {
|
||||
if (acc > cutoff || (acc == cutoff && c > cutlim)) {
|
||||
any = -1;
|
||||
acc = INTMAX_MAX;
|
||||
errno = ERANGE;
|
||||
} else {
|
||||
any = 1;
|
||||
acc *= base;
|
||||
acc += c;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (endptr != 0)
|
||||
*endptr = (char *) (any ? s - 1 : nptr);
|
||||
return (acc);
|
||||
}
|
||||
DEF_STRONG(strtoimax);
|
|
@ -1,151 +0,0 @@
|
|||
/* $OpenBSD: strtol.c,v 1.12 2017/07/06 16:23:11 millert Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* Convert a string to a long integer.
|
||||
*
|
||||
* Ignores `locale' stuff. Assumes that the upper and lower case
|
||||
* alphabets and digits are each contiguous.
|
||||
*/
|
||||
long
|
||||
strtol(const char *nptr, char **endptr, int base)
|
||||
{
|
||||
const char *s;
|
||||
long acc, cutoff;
|
||||
int c;
|
||||
int neg, any, cutlim;
|
||||
|
||||
/*
|
||||
* Ensure that base is between 2 and 36 inclusive, or the special
|
||||
* value of 0.
|
||||
*/
|
||||
if (base < 0 || base == 1 || base > 36) {
|
||||
if (endptr != 0)
|
||||
*endptr = (char *)nptr;
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
s = nptr;
|
||||
do {
|
||||
c = (unsigned char) *s++;
|
||||
} while (isspace(c));
|
||||
if (c == '-') {
|
||||
neg = 1;
|
||||
c = *s++;
|
||||
} else {
|
||||
neg = 0;
|
||||
if (c == '+')
|
||||
c = *s++;
|
||||
}
|
||||
if ((base == 0 || base == 16) && c == '0' &&
|
||||
(*s == 'x' || *s == 'X') && isxdigit((unsigned char)s[1])) {
|
||||
c = s[1];
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
if (base == 0)
|
||||
base = c == '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==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 ? LONG_MIN : LONG_MAX;
|
||||
cutlim = cutoff % base;
|
||||
cutoff /= base;
|
||||
if (neg) {
|
||||
if (cutlim > 0) {
|
||||
cutlim -= base;
|
||||
cutoff += 1;
|
||||
}
|
||||
cutlim = -cutlim;
|
||||
}
|
||||
for (acc = 0, any = 0;; c = (unsigned char) *s++) {
|
||||
if (isdigit(c))
|
||||
c -= '0';
|
||||
else if (isalpha(c))
|
||||
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
|
||||
else
|
||||
break;
|
||||
if (c >= base)
|
||||
break;
|
||||
if (any < 0)
|
||||
continue;
|
||||
if (neg) {
|
||||
if (acc < cutoff || (acc == cutoff && c > cutlim)) {
|
||||
any = -1;
|
||||
acc = LONG_MIN;
|
||||
errno = ERANGE;
|
||||
} else {
|
||||
any = 1;
|
||||
acc *= base;
|
||||
acc -= c;
|
||||
}
|
||||
} else {
|
||||
if (acc > cutoff || (acc == cutoff && c > cutlim)) {
|
||||
any = -1;
|
||||
acc = LONG_MAX;
|
||||
errno = ERANGE;
|
||||
} else {
|
||||
any = 1;
|
||||
acc *= base;
|
||||
acc += c;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (endptr != 0)
|
||||
*endptr = (char *) (any ? s - 1 : nptr);
|
||||
return (acc);
|
||||
}
|
||||
DEF_STRONG(strtol);
|
|
@ -1,156 +0,0 @@
|
|||
/* $OpenBSD: strtoll.c,v 1.10 2017/07/06 16:23:11 millert Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1992 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* Convert a string to a long long.
|
||||
*
|
||||
* Ignores `locale' stuff. Assumes that the upper and lower case
|
||||
* alphabets and digits are each contiguous.
|
||||
*/
|
||||
long long
|
||||
strtoll(const char *nptr, char **endptr, int base)
|
||||
{
|
||||
const char *s;
|
||||
long long acc, cutoff;
|
||||
int c;
|
||||
int neg, any, cutlim;
|
||||
|
||||
/*
|
||||
* Ensure that base is between 2 and 36 inclusive, or the special
|
||||
* value of 0.
|
||||
*/
|
||||
if (base < 0 || base == 1 || base > 36) {
|
||||
if (endptr != 0)
|
||||
*endptr = (char *)nptr;
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
s = nptr;
|
||||
do {
|
||||
c = (unsigned char) *s++;
|
||||
} while (isspace(c));
|
||||
if (c == '-') {
|
||||
neg = 1;
|
||||
c = *s++;
|
||||
} else {
|
||||
neg = 0;
|
||||
if (c == '+')
|
||||
c = *s++;
|
||||
}
|
||||
if ((base == 0 || base == 16) && c == '0' &&
|
||||
(*s == 'x' || *s == 'X') && isxdigit((unsigned char)s[1])) {
|
||||
c = s[1];
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
if (base == 0)
|
||||
base = c == '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 long longs is
|
||||
* [-9223372036854775808..9223372036854775807] and the input base
|
||||
* is 10, cutoff will be set to 922337203685477580 and cutlim to
|
||||
* either 7 (neg==0) or 8 (neg==1), meaning that if we have
|
||||
* accumulated a value > 922337203685477580, 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 ? LLONG_MIN : LLONG_MAX;
|
||||
cutlim = cutoff % base;
|
||||
cutoff /= base;
|
||||
if (neg) {
|
||||
if (cutlim > 0) {
|
||||
cutlim -= base;
|
||||
cutoff += 1;
|
||||
}
|
||||
cutlim = -cutlim;
|
||||
}
|
||||
for (acc = 0, any = 0;; c = (unsigned char) *s++) {
|
||||
if (isdigit(c))
|
||||
c -= '0';
|
||||
else if (isalpha(c))
|
||||
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
|
||||
else
|
||||
break;
|
||||
if (c >= base)
|
||||
break;
|
||||
if (any < 0)
|
||||
continue;
|
||||
if (neg) {
|
||||
if (acc < cutoff || (acc == cutoff && c > cutlim)) {
|
||||
any = -1;
|
||||
acc = LLONG_MIN;
|
||||
errno = ERANGE;
|
||||
} else {
|
||||
any = 1;
|
||||
acc *= base;
|
||||
acc -= c;
|
||||
}
|
||||
} else {
|
||||
if (acc > cutoff || (acc == cutoff && c > cutlim)) {
|
||||
any = -1;
|
||||
acc = LLONG_MAX;
|
||||
errno = ERANGE;
|
||||
} else {
|
||||
any = 1;
|
||||
acc *= base;
|
||||
acc += c;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (endptr != 0)
|
||||
*endptr = (char *) (any ? s - 1 : nptr);
|
||||
return (acc);
|
||||
}
|
||||
DEF_STRONG(strtoll);
|
||||
|
||||
__weak_alias(strtoq, strtoll);
|
|
@ -1,110 +0,0 @@
|
|||
/* $OpenBSD: strtoul.c,v 1.11 2017/07/06 16:23:11 millert Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* Convert a string to an unsigned long integer.
|
||||
*
|
||||
* Ignores `locale' stuff. Assumes that the upper and lower case
|
||||
* alphabets and digits are each contiguous.
|
||||
*/
|
||||
unsigned long
|
||||
strtoul(const char *nptr, char **endptr, int base)
|
||||
{
|
||||
const char *s;
|
||||
unsigned long acc, cutoff;
|
||||
int c;
|
||||
int neg, any, cutlim;
|
||||
|
||||
/*
|
||||
* See strtol for comments as to the logic used.
|
||||
*/
|
||||
if (base < 0 || base == 1 || base > 36) {
|
||||
if (endptr != 0)
|
||||
*endptr = (char *)nptr;
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
s = nptr;
|
||||
do {
|
||||
c = (unsigned char) *s++;
|
||||
} while (isspace(c));
|
||||
if (c == '-') {
|
||||
neg = 1;
|
||||
c = *s++;
|
||||
} else {
|
||||
neg = 0;
|
||||
if (c == '+')
|
||||
c = *s++;
|
||||
}
|
||||
if ((base == 0 || base == 16) && c == '0' &&
|
||||
(*s == 'x' || *s == 'X') && isxdigit((unsigned char)s[1])) {
|
||||
c = s[1];
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
if (base == 0)
|
||||
base = c == '0' ? 8 : 10;
|
||||
|
||||
cutoff = ULONG_MAX / (unsigned long)base;
|
||||
cutlim = ULONG_MAX % (unsigned long)base;
|
||||
for (acc = 0, any = 0;; c = (unsigned char) *s++) {
|
||||
if (isdigit(c))
|
||||
c -= '0';
|
||||
else if (isalpha(c))
|
||||
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
|
||||
else
|
||||
break;
|
||||
if (c >= base)
|
||||
break;
|
||||
if (any < 0)
|
||||
continue;
|
||||
if (acc > cutoff || (acc == cutoff && c > cutlim)) {
|
||||
any = -1;
|
||||
acc = ULONG_MAX;
|
||||
errno = ERANGE;
|
||||
} else {
|
||||
any = 1;
|
||||
acc *= (unsigned long)base;
|
||||
acc += c;
|
||||
}
|
||||
}
|
||||
if (neg && any > 0)
|
||||
acc = -acc;
|
||||
if (endptr != 0)
|
||||
*endptr = (char *) (any ? s - 1 : nptr);
|
||||
return (acc);
|
||||
}
|
||||
DEF_STRONG(strtoul);
|
|
@ -1,114 +0,0 @@
|
|||
/* $OpenBSD: strtoull.c,v 1.9 2017/07/06 16:23:11 millert Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1992 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
/*
|
||||
* Convert a string to an unsigned long long.
|
||||
*
|
||||
* Ignores `locale' stuff. Assumes that the upper and lower case
|
||||
* alphabets and digits are each contiguous.
|
||||
*/
|
||||
unsigned long long
|
||||
strtoull(const char *nptr, char **endptr, int base)
|
||||
{
|
||||
const char *s;
|
||||
unsigned long long acc, cutoff;
|
||||
int c;
|
||||
int neg, any, cutlim;
|
||||
|
||||
/*
|
||||
* See strtoll for comments as to the logic used.
|
||||
*/
|
||||
if (base < 0 || base == 1 || base > 36) {
|
||||
if (endptr != 0)
|
||||
*endptr = (char *)nptr;
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
s = nptr;
|
||||
do {
|
||||
c = (unsigned char) *s++;
|
||||
} while (isspace(c));
|
||||
if (c == '-') {
|
||||
neg = 1;
|
||||
c = *s++;
|
||||
} else {
|
||||
neg = 0;
|
||||
if (c == '+')
|
||||
c = *s++;
|
||||
}
|
||||
if ((base == 0 || base == 16) && c == '0' &&
|
||||
(*s == 'x' || *s == 'X') && isxdigit((unsigned char)s[1])) {
|
||||
c = s[1];
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
if (base == 0)
|
||||
base = c == '0' ? 8 : 10;
|
||||
|
||||
cutoff = ULLONG_MAX / (unsigned long long)base;
|
||||
cutlim = ULLONG_MAX % (unsigned long long)base;
|
||||
for (acc = 0, any = 0;; c = (unsigned char) *s++) {
|
||||
if (isdigit(c))
|
||||
c -= '0';
|
||||
else if (isalpha(c))
|
||||
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
|
||||
else
|
||||
break;
|
||||
if (c >= base)
|
||||
break;
|
||||
if (any < 0)
|
||||
continue;
|
||||
if (acc > cutoff || (acc == cutoff && c > cutlim)) {
|
||||
any = -1;
|
||||
acc = ULLONG_MAX;
|
||||
errno = ERANGE;
|
||||
} else {
|
||||
any = 1;
|
||||
acc *= (unsigned long long)base;
|
||||
acc += c;
|
||||
}
|
||||
}
|
||||
if (neg && any > 0)
|
||||
acc = -acc;
|
||||
if (endptr != 0)
|
||||
*endptr = (char *) (any ? s - 1 : nptr);
|
||||
return (acc);
|
||||
}
|
||||
DEF_STRONG(strtoull);
|
||||
|
||||
__weak_alias(strtouq, strtoull);
|
|
@ -1,109 +0,0 @@
|
|||
/* $OpenBSD: strtoumax.c,v 1.4 2017/07/06 16:23:11 millert Exp $ */
|
||||
/*
|
||||
* Copyright (c) 1992 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
/*
|
||||
* Convert a string to a uintmax_t.
|
||||
*
|
||||
* Ignores `locale' stuff. Assumes that the upper and lower case
|
||||
* alphabets and digits are each contiguous.
|
||||
*/
|
||||
uintmax_t
|
||||
strtoumax(const char *nptr, char **endptr, int base)
|
||||
{
|
||||
const char *s;
|
||||
uintmax_t acc, cutoff;
|
||||
int c;
|
||||
int neg, any, cutlim;
|
||||
|
||||
/*
|
||||
* See strtoimax for comments as to the logic used.
|
||||
*/
|
||||
if (base < 0 || base == 1 || base > 36) {
|
||||
if (endptr != 0)
|
||||
*endptr = (char *)nptr;
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
s = nptr;
|
||||
do {
|
||||
c = (unsigned char) *s++;
|
||||
} while (isspace(c));
|
||||
if (c == '-') {
|
||||
neg = 1;
|
||||
c = *s++;
|
||||
} else {
|
||||
neg = 0;
|
||||
if (c == '+')
|
||||
c = *s++;
|
||||
}
|
||||
if ((base == 0 || base == 16) && c == '0' &&
|
||||
(*s == 'x' || *s == 'X') && isxdigit((unsigned char)s[1])) {
|
||||
c = s[1];
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
if (base == 0)
|
||||
base = c == '0' ? 8 : 10;
|
||||
|
||||
cutoff = UINTMAX_MAX / (uintmax_t)base;
|
||||
cutlim = UINTMAX_MAX % (uintmax_t)base;
|
||||
for (acc = 0, any = 0;; c = (unsigned char) *s++) {
|
||||
if (isdigit(c))
|
||||
c -= '0';
|
||||
else if (isalpha(c))
|
||||
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
|
||||
else
|
||||
break;
|
||||
if (c >= base)
|
||||
break;
|
||||
if (any < 0)
|
||||
continue;
|
||||
if (acc > cutoff || (acc == cutoff && c > cutlim)) {
|
||||
any = -1;
|
||||
acc = UINTMAX_MAX;
|
||||
errno = ERANGE;
|
||||
} else {
|
||||
any = 1;
|
||||
acc *= (uintmax_t)base;
|
||||
acc += c;
|
||||
}
|
||||
}
|
||||
if (neg && any > 0)
|
||||
acc = -acc;
|
||||
if (endptr != 0)
|
||||
*endptr = (char *) (any ? s - 1 : nptr);
|
||||
return (acc);
|
||||
}
|
||||
DEF_STRONG(strtoumax);
|
|
@ -32,6 +32,9 @@
|
|||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include <limits>
|
||||
#include <sstream>
|
||||
|
||||
// The random number generator tests all set the seed, get four values, reset the seed and check
|
||||
// that they get the first two values repeated, and then reset the seed and check two more values
|
||||
// to rule out the possibility that we're just going round a cycle of four values.
|
||||
|
@ -672,6 +675,26 @@ static void CheckStrToInt(T fn(const char* s, char** end, int base)) {
|
|||
// If we see "0x" *not* followed by a hex digit, we shouldn't swallow the 'x'.
|
||||
ASSERT_EQ(T(0), fn("0xy", &end_p, 16));
|
||||
ASSERT_EQ('x', *end_p);
|
||||
|
||||
if (std::numeric_limits<T>::is_signed) {
|
||||
// Minimum (such as -128).
|
||||
std::string min{(std::stringstream{} << std::numeric_limits<T>::min()).str()};
|
||||
ASSERT_EQ(std::numeric_limits<T>::min(), fn(min.c_str(), &end_p, 0));
|
||||
// Too negative (such as -129).
|
||||
min.back() = (min.back() + 1);
|
||||
errno = 0;
|
||||
ASSERT_EQ(std::numeric_limits<T>::min(), fn(min.c_str(), &end_p, 0));
|
||||
ASSERT_EQ(ERANGE, errno);
|
||||
}
|
||||
|
||||
// Maximum (such as 127).
|
||||
std::string max{(std::stringstream{} << std::numeric_limits<T>::max()).str()};
|
||||
ASSERT_EQ(std::numeric_limits<T>::max(), fn(max.c_str(), &end_p, 0));
|
||||
// Too positive (such as 128).
|
||||
max.back() = (max.back() + 1);
|
||||
errno = 0;
|
||||
ASSERT_EQ(std::numeric_limits<T>::max(), fn(max.c_str(), &end_p, 0));
|
||||
ASSERT_EQ(ERANGE, errno);
|
||||
}
|
||||
|
||||
TEST(stdlib, strtol_smoke) {
|
||||
|
|
Loading…
Reference in a new issue