diff options
Diffstat (limited to 'contrib/sendmail/libsm/strto.c')
-rw-r--r-- | contrib/sendmail/libsm/strto.c | 254 |
1 files changed, 0 insertions, 254 deletions
diff --git a/contrib/sendmail/libsm/strto.c b/contrib/sendmail/libsm/strto.c deleted file mode 100644 index 87e84bfeaa568..0000000000000 --- a/contrib/sendmail/libsm/strto.c +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. - * All rights reserved. - * Copyright (c) 1992 - * The Regents of the University of California. All rights reserved. - * - * By using this file, you agree to the terms and conditions set - * forth in the LICENSE file which can be found at the top level of - * the sendmail distribution. - */ - -#include <sm/gen.h> -SM_IDSTR(id, "@(#)$Id: strto.c,v 1.18 2001/12/30 04:59:37 gshapiro Exp $") - -#include <sys/param.h> -#include <sys/types.h> -#include <stdlib.h> -#include <ctype.h> -#include <errno.h> -#include <sm/limits.h> -#include <sm/conf.h> -#include <sm/string.h> - -/* -** SM_STRTOLL -- Convert a string to a (signed) long long integer. -** -** Ignores `locale' stuff. Assumes that the upper and lower case -** alphabets and digits are each contiguous. -** -** Parameters: -** nptr -- string containing number -** endptr -- location of first invalid character -** base -- numeric base that 'nptr' number is based in -** -** Returns: -** Failure: on underflow LLONG_MIN is returned; on overflow -** LLONG_MAX is returned and errno is set. -** When 'endptr' == '\0' then the entire string 'nptr' -** was valid. -** Success: returns the converted number -*/ - -LONGLONG_T -sm_strtoll(nptr, endptr, base) - const char *nptr; - char **endptr; - register int base; -{ - register bool neg; - register const char *s; - register LONGLONG_T acc, cutoff; - register int c; - register int any, cutlim; - - /* - ** 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 (isascii(c) && isspace(c)); - if (c == '-') - { - neg = true; - c = *s++; - } - else - { - neg = false; - 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-long's is - ** [-9223372036854775808..9223372036854775807] and the input base - ** is 10, cutoff will be set to 922337203685477580 and cutlim to - ** either 7 (!neg) or 8 (neg), 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 (isascii(c) && isdigit(c)) - c -= '0'; - else if (isascii(c) && 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; -} - -/* -** SM_STRTOULL -- 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. -** -** Parameters: -** nptr -- string containing (unsigned) number -** endptr -- location of first invalid character -** base -- numeric base that 'nptr' number is based in -** -** Returns: -** Failure: on overflow ULLONG_MAX is returned and errno is set. -** When 'endptr' == '\0' then the entire string 'nptr' -** was valid. -** Success: returns the converted number -*/ - -ULONGLONG_T -sm_strtoull(nptr, endptr, base) - const char *nptr; - char **endptr; - register int base; -{ - register const char *s; - register ULONGLONG_T acc, cutoff; - register int c; - register bool neg; - register int any, cutlim; - - /* See sm_strtoll for comments as to the logic used. */ - s = nptr; - do - { - c = (unsigned char) *s++; - } while (isascii(c) && isspace(c)); - neg = (c == '-'); - if (neg) - { - c = *s++; - } - else - { - 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 = ULLONG_MAX / (ULONGLONG_T)base; - cutlim = ULLONG_MAX % (ULONGLONG_T)base; - for (acc = 0, any = 0;; c = (unsigned char) *s++) - { - if (isascii(c) && isdigit(c)) - c -= '0'; - else if (isascii(c) && 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 *= (ULONGLONG_T)base; - acc += c; - } - } - if (neg && any > 0) - acc = -((LONGLONG_T) acc); - if (endptr != 0) - *endptr = (char *) (any ? s - 1 : nptr); - return acc; -} |