Unify the implementation of strto{l,ul,ll,ull,imax,umax,q,uq} into one

version for signed and one version for unsigned data types.

Add a check for supported bases and set errno (userland) or panic
(kernel, libsa) otherwise.

Make strto{ll,ull,imax,umax} normal symbols and just keep the underscore
versions as strong alias.

Obtained from DragonFly, based on the wide char version from Citrus.
Reviewed by christos@
This commit is contained in:
joerg 2008-08-20 12:42:26 +00:00
parent 5744f667c6
commit 245e086321
15 changed files with 423 additions and 1171 deletions

View File

@ -0,0 +1,166 @@
/* $NetBSD: _strtol.h,v 1.1 2008/08/20 12:42:26 joerg Exp $ */
/*-
* Copyright (c) 1990, 1993
* 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.
*
* Original version ID:
* NetBSD: src/lib/libc/locale/_wcstol.h,v 1.2 2003/08/07 16:43:03 agc Exp
*/
/*
* function template for strtol, strtoll and strtoimax.
*
* parameters:
* _FUNCNAME : function name
* __INT : return type
* __INT_MIN : lower limit of the return type
* __INT_MAX : upper limit of the return type
*/
__INT
_FUNCNAME(const char *nptr, char **endptr, int base)
{
const char *s;
__INT acc, cutoff;
unsigned char c;
int i, neg, any, cutlim;
_DIAGASSERT(nptr != NULL);
/* endptr may be NULL */
/* check base value */
if (base && (base < 2 || base > 36)) {
#if !defined(_KERNEL) && !defined(_STANDALONE)
errno = EINVAL;
return(0);
#else
panic("%s: invalid base %d", __func__, base);
#endif
}
/*
* 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 = *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')) {
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 ? __INT_MIN : __INT_MAX);
cutlim = (int)(cutoff % base);
cutoff /= base;
if (neg) {
if (cutlim > 0) {
cutlim -= base;
cutoff += 1;
}
cutlim = -cutlim;
}
for (acc = 0, any = 0;; c = *s++) {
if (isdigit(c))
i = c - '0';
else if (isalpha(c))
i = c - (isupper(c) ? 'A' - 10 : 'a' - 10);
else
break;
if (i >= base)
break;
if (any < 0)
continue;
if (neg) {
if (acc < cutoff || (acc == cutoff && i > cutlim)) {
acc = __INT_MIN;
#if !defined(_KERNEL) && !defined(_STANDALONE)
any = -1;
errno = ERANGE;
#else
any = 0;
break;
#endif
} else {
any = 1;
acc *= base;
acc -= i;
}
} else {
if (acc > cutoff || (acc == cutoff && i > cutlim)) {
acc = __INT_MAX;
#if !defined(_KERNEL) && !defined(_STANDALONE)
any = -1;
errno = ERANGE;
#else
any = 0;
break;
#endif
} else {
any = 1;
acc *= base;
acc += i;
}
}
}
if (endptr != NULL)
/* LINTED interface specification */
*endptr = __UNCONST(any ? s - 1 : nptr);
return(acc);
}

View File

@ -0,0 +1,128 @@
/* $NetBSD: _strtoul.h,v 1.1 2008/08/20 12:42:26 joerg Exp $ */
/*-
* Copyright (c) 1990, 1993
* 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.
*
* Original version ID:
* NetBSD: src/lib/libc/locale/_wcstoul.h,v 1.2 2003/08/07 16:43:03 agc Exp
*/
/*
* function template for strtoul, strtoull and strtoumax.
*
* parameters:
* _FUNCNAME : function name
* __UINT : return type
* __UINT_MAX : upper limit of the return type
*/
__UINT
_FUNCNAME(const char *nptr, char **endptr, int base)
{
const char *s;
__UINT acc, cutoff;
unsigned char c;
int i, neg, any, cutlim;
_DIAGASSERT(nptr != NULL);
/* endptr may be NULL */
/* check base value */
if (base && (base < 2 || base > 36)) {
#if !defined(_KERNEL) && !defined(_STANDALONE)
errno = EINVAL;
return(0);
#else
panic("%s: invalid base %d", __func__, base);
#endif
}
/*
* 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 = *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')) {
c = s[1];
s += 2;
base = 16;
}
if (base == 0)
base = (c == '0' ? 8 : 10);
/*
* See strtol for comments as to the logic used.
*/
cutoff = __UINT_MAX / (__UINT)base;
cutlim = (int)(__UINT_MAX % (__UINT)base);
for (acc = 0, any = 0;; c = *s++) {
if (isdigit(c))
i = c - '0';
else if (isalpha(c))
i = c - (isupper(c) ? 'A' - 10 : 'a' - 10);
else
break;
if (i >= base)
break;
if (any < 0)
continue;
if (acc > cutoff || (acc == cutoff && i > cutlim)) {
acc = __UINT_MAX;
#if !defined(_KERNEL) && !defined(_STANDALONE)
any = -1;
errno = ERANGE;
#else
any = 0;
break;
#endif
} else {
any = 1;
acc *= (__UINT)base;
acc += i;
}
}
if (neg && any > 0)
acc = -acc;
if (endptr != NULL)
/* LINTED interface specification */
*endptr = __UNCONST(any ? s - 1 : nptr);
return(acc);
}

View File

@ -1,8 +1,9 @@
/* $NetBSD: strtoll.c,v 1.2 2006/12/18 00:41:54 christos Exp $ */
/* $NetBSD: strtoll.c,v 1.3 2008/08/20 12:42:26 joerg Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
* Copyright (c) 2005 The DragonFly Project. All rights reserved.
* Copyright (c) 2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -12,14 +13,11 @@
* 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
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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)
@ -29,177 +27,28 @@
* SUCH DAMAGE.
*/
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif
#include <sys/cdefs.h>
__RCSID("$NetBSD: strtoll.c,v 1.3 2008/08/20 12:42:26 joerg Exp $");
#if !defined(_KERNEL) && !defined(_STANDALONE)
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "from: @(#)strtoq.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: strtoll.c,v 1.2 2006/12/18 00:41:54 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
#ifdef _LIBC
#include "namespace.h"
#endif
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
#ifdef _LIBC
#ifdef __weak_alias
__weak_alias(strtoll, _strtoll)
#endif
#endif
#else /* !_KERNEL && !_STANDALONE */
#else
#include <sys/param.h>
#include <lib/libkern/libkern.h>
#define isspace(x) ((x) == ' ' || (x) == '\t' || (x) == '\n' || (x) == '\r')
#define isdigit(x) ((x) >= '0' && (x) <= '9')
#define isalpha(x) (((x) >= 'a' && (x) <= 'z') || ((x) >= 'A' && (x) <= 'Z'))
#define toupper(x) ((x) & ~0x20)
#endif
#if !HAVE_STRTOLL
/*
* Convert a string to a long long integer.
*
* Ignores `locale' stuff. Assumes that the upper and lower case
* alphabets and digits are each contiguous.
*/
/* LONGLONG */
long long int
#ifdef _LIBC
_strtoll(nptr, endptr, base)
#else
strtoll(nptr, endptr, base)
#endif
const char *nptr;
char **endptr;
int base;
{
const char *s;
/* LONGLONG */
long long int acc, cutoff;
int c;
int neg, any, cutlim;
#define _FUNCNAME strtoll
#define __INT long long
#define __INT_MIN LLONG_MIN
#define __INT_MAX LLONG_MAX
_DIAGASSERT(nptr != NULL);
/* endptr may be NULL */
#include "_strtol.h"
/*
* 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')) {
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 = (int)(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)) {
#if defined(_KERNEL) || defined(_STANDALONE)
c = toupper(c) - 'A' + 10;
#else
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
#endif
} else
break;
if (c >= base)
break;
if (any < 0)
continue;
if (neg) {
if (acc < cutoff || (acc == cutoff && c > cutlim)) {
#if defined(_KERNEL) || defined(_STANDALONE)
if (endptr)
*endptr = __UNCONST(nptr);
return (LLONG_MIN);
#else
any = -1;
acc = LLONG_MIN;
errno = ERANGE;
#endif
} else {
any = 1;
acc *= base;
acc -= c;
}
} else {
if (acc > cutoff || (acc == cutoff && c > cutlim)) {
#if defined(_KERNEL) || defined(_STANDALONE)
if (endptr)
*endptr = __UNCONST(nptr);
return (LLONG_MAX);
#else
any = -1;
acc = LLONG_MAX;
errno = ERANGE;
#endif
} else {
any = 1;
acc *= base;
acc += c;
}
}
}
if (endptr != 0)
*endptr = __UNCONST(any ? s - 1 : nptr);
return (acc);
}
#if !defined(_KERNEL) && !defined(_STANDALONE)
__strong_alias(_strtoll, strtoll)
#endif

View File

@ -1,8 +1,9 @@
/* $NetBSD: strtoul.c,v 1.1 2005/12/20 19:28:52 christos Exp $ */
/* $NetBSD: strtoul.c,v 1.2 2008/08/20 12:42:26 joerg Exp $ */
/*
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
/*-
* Copyright (c) 2005 The DragonFly Project. All rights reserved.
* Copyright (c) 2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -12,14 +13,11 @@
* 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
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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)
@ -29,110 +27,23 @@
* SUCH DAMAGE.
*/
#if !defined(_KERNEL) && !defined(_STANDALONE)
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)strtoul.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: strtoul.c,v 1.1 2005/12/20 19:28:52 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
__RCSID("$NetBSD: strtoul.c,v 1.2 2008/08/20 12:42:26 joerg Exp $");
#if !defined(_KERNEL) && !defined(_STANDALONE)
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
#else
#include <sys/param.h>
#include <lib/libkern/libkern.h>
#define isspace(x) ((x) == ' ' || (x) == '\t' || (x) == '\n' || (x) == '\r')
#define isdigit(x) ((x) >= '0' && (x) <= '9')
#define isalpha(x) (((x) >= 'a' && (x) <= 'z') || ((x) >= 'A' && (x) <= 'Z'))
#define toupper(x) ((x) & ~0x20)
#endif
/*
* 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(nptr, endptr, base)
const char *nptr;
char **endptr;
int base;
{
const char *s;
unsigned long acc, cutoff;
int c;
int neg, any, cutlim;
#define _FUNCNAME strtoul
#define __UINT unsigned long int
#define __UINT_MAX ULONG_MAX
_DIAGASSERT(nptr != NULL);
/* endptr may be NULL */
/*
* See strtol for comments as to the logic used.
*/
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')) {
c = s[1];
s += 2;
base = 16;
}
if (base == 0)
base = c == '0' ? 8 : 10;
cutoff = ULONG_MAX / (unsigned long)base;
cutlim = (int)(ULONG_MAX % (unsigned long)base);
for (acc = 0, any = 0;; c = (unsigned char) *s++) {
if (isdigit(c))
c -= '0';
else if (isalpha(c)) {
#if defined(_KERNEL) || defined(_STANDALONE)
c = toupper(c) - 'A' + 10;
#else
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
#endif
} else
break;
if (c >= base)
break;
if (any < 0)
continue;
if (acc > cutoff || (acc == cutoff && c > cutlim)) {
#if defined(_KERNEL) || defined(_STANDALONE)
if (endptr)
*endptr = __UNCONST(nptr);
return ULONG_MAX;
#else
any = -1;
acc = ULONG_MAX;
errno = ERANGE;
#endif
} else {
any = 1;
acc *= (unsigned long)base;
acc += c;
}
}
if (neg && any > 0)
acc = -acc;
if (endptr != NULL)
*endptr = __UNCONST(any ? s - 1 : nptr);
return (acc);
}
#include "_strtoul.h"

View File

@ -1,8 +1,9 @@
/* $NetBSD: strtoull.c,v 1.1 2006/10/08 03:14:55 thorpej Exp $ */
/* $NetBSD: strtoull.c,v 1.2 2008/08/20 12:42:26 joerg Exp $ */
/*
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
/*-
* Copyright (c) 2005 The DragonFly Project. All rights reserved.
* Copyright (c) 2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -12,14 +13,11 @@
* 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
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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)
@ -29,121 +27,27 @@
* SUCH DAMAGE.
*/
#if !defined(_KERNEL) && !defined(_STANDALONE)
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "from: @(#)strtoul.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: strtoull.c,v 1.1 2006/10/08 03:14:55 thorpej Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
__RCSID("$NetBSD: strtoull.c,v 1.2 2008/08/20 12:42:26 joerg Exp $");
#include "namespace.h"
#if !defined(_KERNEL) && !defined(_STANDALONE)
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
#ifdef __weak_alias
__weak_alias(strtoull, _strtoull)
#endif
#else /* !_KERNEL && !_STANDALONE */
#else
#include <sys/param.h>
#include <lib/libkern/libkern.h>
#define isspace(x) ((x) == ' ' || (x) == '\t' || (x) == '\n' || (x) == '\r')
#define isdigit(x) ((x) >= '0' && (x) <= '9')
#define isalpha(x) (((x) >= 'a' && (x) <= 'z') || ((x) >= 'A' && (x) <= 'Z'))
#define toupper(x) ((x) & ~0x20)
#endif
/*
* Convert a string to an unsigned long long integer.
*
* Ignores `locale' stuff. Assumes that the upper and lower case
* alphabets and digits are each contiguous.
*/
/* LONGLONG */
unsigned long long int
strtoull(nptr, endptr, base)
const char *nptr;
char **endptr;
int base;
{
const char *s;
/* LONGLONG */
unsigned long long int acc, cutoff;
int c;
int neg, any, cutlim;
#define _FUNCNAME strtoull
#define __UINT unsigned long long int
#define __UINT_MAX ULLONG_MAX
_DIAGASSERT(nptr != NULL);
/* endptr may be NULL */
#include "_strtoul.h"
/*
* See strtol for comments as to the logic used.
*/
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')) {
c = s[1];
s += 2;
base = 16;
}
if (base == 0)
base = c == '0' ? 8 : 10;
/* LONGLONG */
cutoff = ULLONG_MAX / (unsigned long long int)base;
/* LONGLONG */
cutlim = (int)(ULLONG_MAX % (unsigned long long int)base);
for (acc = 0, any = 0;; c = (unsigned char) *s++) {
if (isdigit(c))
c -= '0';
else if (isalpha(c)) {
#if defined(_KERNEL) || defined(_STANDALONE)
c = toupper(c) - 'A' + 10;
#else
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
#if !defined(_KERNEL) && !defined(_STANDALONE)
__strong_alias(_strtoull, strtoull)
#endif
} else
break;
if (c >= base)
break;
if (any < 0)
continue;
if (acc > cutoff || (acc == cutoff && c > cutlim)) {
#if defined(_KERNEL) || defined(_STANDALONE)
if (endptr)
*endptr = __UNCONST(nptr);
return (ULLONG_MAX);
#else
any = -1;
acc = ULLONG_MAX;
errno = ERANGE;
#endif
} else {
any = 1;
/* LONGLONG */
acc *= (unsigned long long int)base;
acc += c;
}
}
if (neg && any > 0)
acc = -acc;
if (endptr != 0)
*endptr = __UNCONST(any ? s - 1 : nptr);
return (acc);
}

View File

@ -1,8 +1,9 @@
/* $NetBSD: strtoumax.c,v 1.1 2006/04/22 15:33:33 thorpej Exp $ */
/* $NetBSD: strtoumax.c,v 1.2 2008/08/20 12:42:26 joerg Exp $ */
/*
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
/*-
* Copyright (c) 2005 The DragonFly Project. All rights reserved.
* Copyright (c) 2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -12,14 +13,11 @@
* 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
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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)
@ -29,113 +27,28 @@
* SUCH DAMAGE.
*/
#if !defined(_KERNEL) && !defined(_STANDALONE)
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "from: @(#)strtoul.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: strtoumax.c,v 1.1 2006/04/22 15:33:33 thorpej Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
__RCSID("$NetBSD: strtoumax.c,v 1.2 2008/08/20 12:42:26 joerg Exp $");
#if !defined(_KERNEL) && !defined(_STANDALONE)
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <inttypes.h>
#include <stddef.h>
#ifdef __weak_alias
__weak_alias(strtoumax, _strtoumax)
#endif
#else /* !_KERNEL && !_STANDALONE */
#include <stdint.h>
#include <stdlib.h>
#else
#include <sys/param.h>
#include <lib/libkern/libkern.h>
#endif /* !_KERNEL && !_STANDALONE */
/*
* Convert a string to an uintmax_t.
*
* Ignores `locale' stuff. Assumes that the upper and lower case
* alphabets and digits are each contiguous.
*/
uintmax_t
strtoumax(nptr, endptr, base)
const char *nptr;
char **endptr;
int base;
{
const char *s;
uintmax_t acc, cutoff;
int c;
int neg, any, cutlim;
_DIAGASSERT(nptr != NULL);
/* endptr may be NULL */
/*
* See strtol for comments as to the logic used.
*/
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')) {
c = s[1];
s += 2;
base = 16;
}
if (base == 0)
base = c == '0' ? 8 : 10;
cutoff = UINTMAX_MAX / (uintmax_t)base;
cutlim = (int)(UINTMAX_MAX % (uintmax_t)base);
for (acc = 0, any = 0;; c = (unsigned char) *s++) {
if (isdigit(c))
c -= '0';
else if (isalpha(c)) {
#if defined(_KERNEL) || defined(_STANDALONE)
c = toupper(c) - 'A' + 10;
#else
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
#endif
} else
break;
if (c >= base)
break;
if (any < 0)
continue;
if (acc > cutoff || (acc == cutoff && c > cutlim)) {
#if defined(_KERNEL) || defined(_STANDALONE)
if (endptr)
*endptr = __UNCONST(nptr);
return UINTMAX_MAX;
#else
any = -1;
acc = UINTMAX_MAX;
errno = ERANGE;
#define _FUNCNAME strtoumax
#define __UINT uintmax_t
#define __UINT_MAX UINTMAX_MAX
#include "_strtoul.h"
#if !defined(_KERNEL) && !defined(_STANDALONE)
__strong_alias(_strtoumax, strtoumax)
#endif
} else {
any = 1;
acc *= (uintmax_t)base;
acc += c;
}
}
if (neg && any > 0)
acc = -acc;
if (endptr != 0)
*endptr = __UNCONST(any ? s - 1 : nptr);
return (acc);
}

View File

@ -1,10 +1,10 @@
# $NetBSD: Makefile.inc,v 1.69 2008/08/04 21:29:27 matt Exp $
# $NetBSD: Makefile.inc,v 1.70 2008/08/20 12:42:26 joerg Exp $
# from: @(#)Makefile.inc 8.3 (Berkeley) 2/4/95
# stdlib sources
.PATH: ${ARCHDIR}/stdlib ${.CURDIR}/stdlib
SRCS+= _rand48.c _strtoimax.c _strtoumax.c _strtoll.c _strtoull.c \
SRCS+= _rand48.c \
a64l.c abort.c atexit.c atof.c atoi.c atol.c atoll.c \
bsearch.c drand48.c exit.c \
getenv.c getopt.c getopt_long.c getsubopt.c \
@ -23,6 +23,11 @@ SRCS+= jemalloc.c
SRCS+= malloc.c
.endif
CPPFLAGS.strtoimax.c+= -I${.CURDIR}/../../common/lib/libc/stdlib
CPPFLAGS.strtol.c+= -I${.CURDIR}/../../common/lib/libc/stdlib
CPPFLAGS.strtoq.c+= -I${.CURDIR}/../../common/lib/libc/stdlib
CPPFLAGS.strtouq.c+= -I${.CURDIR}/../../common/lib/libc/stdlib
# machine-dependent stdlib sources
# m-d Makefile.inc must include sources for:
# abs() div() labs() ldiv() llabs() imaxabs() imaxdiv()

View File

@ -1,50 +0,0 @@
/* $NetBSD: _strtoimax.c,v 1.4 2005/09/13 01:44:10 christos Exp $ */
/*
* Copyright (c) 1996 Christos Zoulas. 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Christos Zoulas.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: _strtoimax.c,v 1.4 2005/09/13 01:44:10 christos Exp $");
#endif /* LIBC_SCCS and not lint */
#if defined(__indr_reference)
__indr_reference(_strtoimax, strtoimax)
#else
#include <inttypes.h>
intmax_t _strtoimax(const char *, char **, int);
intmax_t
strtoimax(const char *nptr, char **endptr, int base)
{
return _strtoimax(nptr, endptr, base);
}
#endif

View File

@ -1,52 +0,0 @@
/* $NetBSD: _strtoll.c,v 1.5 2005/09/13 01:44:10 christos Exp $ */
/*
* Copyright (c) 1996 Christos Zoulas. 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Christos Zoulas.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: _strtoll.c,v 1.5 2005/09/13 01:44:10 christos Exp $");
#endif /* LIBC_SCCS and not lint */
#if defined(__indr_reference)
__indr_reference(_strtoll, strtoll)
#else
#include <stdlib.h>
/* LONGLONG */
long long int _strtoll(const char *, char **, int);
/* LONGLONG */
long long int
strtoll(const char *nptr, char **endptr, int base)
{
return _strtoll(nptr, endptr, base);
}
#endif

View File

@ -1,52 +0,0 @@
/* $NetBSD: _strtoull.c,v 1.5 2005/09/13 01:44:10 christos Exp $ */
/*
* Copyright (c) 1996 Christos Zoulas. 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Christos Zoulas.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: _strtoull.c,v 1.5 2005/09/13 01:44:10 christos Exp $");
#endif /* LIBC_SCCS and not lint */
#if defined(__indr_reference)
__indr_reference(_strtoull, strtoull)
#else
#include <stdlib.h>
/* LONGLONG */
unsigned long long int _strtoull(const char *, char **, int);
/* LONGLONG */
unsigned long long int
strtoull(const char *nptr, char **endptr, int base)
{
return _strtoull(nptr, endptr, base);
}
#endif

View File

@ -1,50 +0,0 @@
/* $NetBSD: _strtoumax.c,v 1.4 2005/09/13 01:44:10 christos Exp $ */
/*
* Copyright (c) 1996 Christos Zoulas. 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Christos Zoulas.
* 4. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: _strtoumax.c,v 1.4 2005/09/13 01:44:10 christos Exp $");
#endif /* LIBC_SCCS and not lint */
#if defined(__indr_reference)
__indr_reference(_strtoumax, strtoumax)
#else
#include <inttypes.h>
uintmax_t _strtoumax(const char *, char **, int);
uintmax_t
strtoumax(const char *nptr, char **endptr, int base)
{
return _strtoumax(nptr, endptr, base);
}
#endif

View File

@ -1,8 +1,9 @@
/* $NetBSD: strtoimax.c,v 1.5 2006/12/18 00:40:14 christos Exp $ */
/* $DragonFly: src/lib/libc/stdlib/strtoimax.c,v 1.2 2008/08/19 15:50:24 joerg Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
* Copyright (c) 2005 The DragonFly Project. All rights reserved.
* Copyright (c) 2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -12,14 +13,11 @@
* 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
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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)
@ -30,134 +28,21 @@
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "from: @(#)strtoq.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: strtoimax.c,v 1.5 2006/12/18 00:40:14 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
__RCSID("$NetBSD: strtoimax.c,v 1.6 2008/08/20 12:42:26 joerg Exp $");
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <inttypes.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#ifdef __weak_alias
__weak_alias(strtoimax, _strtoimax)
#endif
#define _FUNCNAME strtoimax
#define __INT intmax_t
#define __INT_MIN INTMAX_MIN
#define __INT_MAX INTMAX_MAX
/*
* 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(nptr, endptr, base)
const char *nptr;
char **endptr;
int base;
{
const char *s;
intmax_t acc, cutoff;
int c;
int neg, any, cutlim;
#include "_strtol.h"
_DIAGASSERT(nptr != NULL);
/* endptr may be NULL */
/*
* 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')) {
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 = (int)(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 = __UNCONST(any ? s - 1 : nptr);
return (acc);
}
__strong_alias(_strtoimax, strtoimax)

View File

@ -1,8 +1,9 @@
/* $NetBSD: strtol.c,v 1.17 2005/11/29 03:12:00 christos Exp $ */
/* $NetBSD: strtol.c,v 1.18 2008/08/20 12:42:26 joerg Exp $ */
/*-
* Copyright (c) 1990, 1993
* The Regents of the University of California. All rights reserved.
* Copyright (c) 2005 The DragonFly Project. All rights reserved.
* Copyright (c) 2003 Citrus Project,
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -12,14 +13,11 @@
* 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
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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)
@ -30,128 +28,18 @@
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)strtol.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: strtol.c,v 1.17 2005/11/29 03:12:00 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
__RCSID("$NetBSD: strtol.c,v 1.18 2008/08/20 12:42:26 joerg Exp $");
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
#define _FUNCNAME strtol
#define __INT long
#define __INT_MIN LONG_MIN
#define __INT_MAX LONG_MAX
/*
* 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(nptr, endptr, base)
const char *nptr;
char **endptr;
int base;
{
const char *s;
long acc, cutoff;
int c;
int neg, any, cutlim;
_DIAGASSERT(nptr != NULL);
/* endptr may be NULL */
/*
* 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')) {
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 = (int)(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 = __UNCONST(any ? s - 1 : nptr);
return (acc);
}
#include "_strtol.h"

View File

@ -1,8 +1,8 @@
/* $NetBSD: strtoq.c,v 1.18 2006/12/18 00:40:14 christos Exp $ */
/* $NetBSD: strtoq.c,v 1.19 2008/08/20 12:42:26 joerg Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
* Copyright (c) 2008 Joerg Sonnenberger <joerg@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -12,14 +12,11 @@
* 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
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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)
@ -30,130 +27,18 @@
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)strtoq.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: strtoq.c,v 1.18 2006/12/18 00:40:14 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
__RCSID("$NetBSD: strtoq.c,v 1.19 2008/08/20 12:42:26 joerg Exp $");
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
/*
* Convert a string to a quad integer.
*
* Ignores `locale' stuff. Assumes that the upper and lower case
* alphabets and digits are each contiguous.
*/
quad_t
strtoq(nptr, endptr, base)
const char *nptr;
char **endptr;
int base;
{
const char *s;
quad_t acc, cutoff;
int c;
int neg, any, cutlim;
#define _FUNCNAME strtoq
#define __INT quad_t
#define __INT_MIN QUAD_MIN
#define __INT_MAX QUAD_MAX
_DIAGASSERT(nptr != NULL);
/* endptr may be NULL */
/*
* 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')) {
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 quads 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 ? QUAD_MIN : QUAD_MAX;
cutlim = (int)(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 = QUAD_MIN;
errno = ERANGE;
} else {
any = 1;
acc *= base;
acc -= c;
}
} else {
if (acc > cutoff || (acc == cutoff && c > cutlim)) {
any = -1;
acc = QUAD_MAX;
errno = ERANGE;
} else {
any = 1;
acc *= base;
acc += c;
}
}
}
if (endptr != 0)
*endptr = __UNCONST(any ? s - 1 : nptr);
return (acc);
}
#include "_strtol.h"

View File

@ -1,8 +1,8 @@
/* $NetBSD: strtouq.c,v 1.18 2005/11/29 03:12:00 christos Exp $ */
/* $NetBSD: strtouq.c,v 1.19 2008/08/20 12:42:26 joerg Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
* Copyright (c) 2008 Joerg Sonnenberger <joerg@NetBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -12,14 +12,11 @@
* 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
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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)
@ -30,92 +27,17 @@
*/
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid[] = "@(#)strtouq.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: strtouq.c,v 1.18 2005/11/29 03:12:00 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
__RCSID("$NetBSD: strtouq.c,v 1.19 2008/08/20 12:42:26 joerg Exp $");
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdint.h>
#include <stdlib.h>
/*
* Convert a string to an unsigned quad integer.
*
* Ignores `locale' stuff. Assumes that the upper and lower case
* alphabets and digits are each contiguous.
*/
u_quad_t
strtouq(nptr, endptr, base)
const char *nptr;
char **endptr;
int base;
{
const char *s;
u_quad_t acc, cutoff;
int c;
int neg, any, cutlim;
#define _FUNCNAME strtouq
#define __UINT u_quad_t
#define __UINT_MAX QUAD_MAX
_DIAGASSERT(nptr != NULL);
/* endptr may be NULL */
/*
* See strtoq for comments as to the logic used.
*/
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')) {
c = s[1];
s += 2;
base = 16;
}
if (base == 0)
base = c == '0' ? 8 : 10;
cutoff = UQUAD_MAX / (u_quad_t)base;
cutlim = (int)(UQUAD_MAX % (u_quad_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 = UQUAD_MAX;
errno = ERANGE;
} else {
any = 1;
acc *= (u_quad_t)base;
acc += c;
}
}
if (neg && any > 0)
acc = -acc;
if (endptr != 0)
*endptr = __UNCONST(any ? s - 1 : nptr);
return (acc);
}
#include "_strtoul.h"