t2ex/bsd_source/lib/libc/src_bsd/stdlib/strtoll.c | bare source | permlink (0.02 seconds) |
1: /* $OpenBSD: strtoll.c,v 1.6 2005/11/10 10:00:17 espie Exp $ */ 2: /*- 3: * Copyright (c) 1992 The Regents of the University of California. 4: * All rights reserved. 5: * 6: * Redistribution and use in source and binary forms, with or without 7: * modification, are permitted provided that the following conditions 8: * are met: 9: * 1. Redistributions of source code must retain the above copyright 10: * notice, this list of conditions and the following disclaimer. 11: * 2. Redistributions in binary form must reproduce the above copyright 12: * notice, this list of conditions and the following disclaimer in the 13: * documentation and/or other materials provided with the distribution. 14: * 3. Neither the name of the University nor the names of its contributors 15: * may be used to endorse or promote products derived from this software 16: * without specific prior written permission. 17: * 18: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 19: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 22: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28: * SUCH DAMAGE. 29: */ 30: 31: #include <sys/types.h> 32: 33: #include <ctype.h> 34: #include <errno.h> 35: #include <limits.h> 36: #include <stdlib.h> 37: 38: /* 39: * Convert a string to a long long. 40: * 41: * Ignores `locale' stuff. Assumes that the upper and lower case 42: * alphabets and digits are each contiguous. 43: */ 44: long long 45: strtoll(const char *nptr, char **endptr, int base) 46: { 47: const char *s; 48: long long acc, cutoff; 49: int c; 50: int neg, any, cutlim; 51: 52: /* 53: * Skip white space and pick up leading +/- sign if any. 54: * If base is 0, allow 0x for hex and 0 for octal, else 55: * assume decimal; if base is already 16, allow 0x. 56: */ 57: s = nptr; 58: do { 59: c = (unsigned char) *s++; 60: } while (isspace(c)); 61: if (c == '-') { 62: neg = 1; 63: c = *s++; 64: } else { 65: neg = 0; 66: if (c == '+') 67: c = *s++; 68: } 69: if ((base == 0 || base == 16) && 70: c == '0' && (*s == 'x' || *s == 'X')) { 71: c = s[1]; 72: s += 2; 73: base = 16; 74: } 75: if (base == 0) 76: base = c == '0' ? 8 : 10; 77: 78: /* 79: * Compute the cutoff value between legal numbers and illegal 80: * numbers. That is the largest legal value, divided by the 81: * base. An input number that is greater than this value, if 82: * followed by a legal input character, is too big. One that 83: * is equal to this value may be valid or not; the limit 84: * between valid and invalid numbers is then based on the last 85: * digit. For instance, if the range for long longs is 86: * [-9223372036854775808..9223372036854775807] and the input base 87: * is 10, cutoff will be set to 922337203685477580 and cutlim to 88: * either 7 (neg==0) or 8 (neg==1), meaning that if we have 89: * accumulated a value > 922337203685477580, or equal but the 90: * next digit is > 7 (or 8), the number is too big, and we will 91: * return a range error. 92: * 93: * Set any if any `digits' consumed; make it negative to indicate 94: * overflow. 95: */ 96: cutoff = neg ? LLONG_MIN : LLONG_MAX; 97: cutlim = cutoff % base; 98: cutoff /= base; 99: if (neg) { 100: if (cutlim > 0) { 101: cutlim -= base; 102: cutoff += 1; 103: } 104: cutlim = -cutlim; 105: } 106: for (acc = 0, any = 0;; c = (unsigned char) *s++) { 107: if (isdigit(c)) 108: c -= '0'; 109: else if (isalpha(c)) 110: c -= isupper(c) ? 'A' - 10 : 'a' - 10; 111: else 112: break; 113: if (c >= base) 114: break; 115: if (any < 0) 116: continue; 117: if (neg) { 118: if (acc < cutoff || (acc == cutoff && c > cutlim)) { 119: any = -1; 120: acc = LLONG_MIN; 121: /*errno = ERANGE*/; 122: } else { 123: any = 1; 124: acc *= base; 125: acc -= c; 126: } 127: } else { 128: if (acc > cutoff || (acc == cutoff && c > cutlim)) { 129: any = -1; 130: acc = LLONG_MAX; 131: /*errno = ERANGE*/; 132: } else { 133: any = 1; 134: acc *= base; 135: acc += c; 136: } 137: } 138: } 139: if (endptr != 0) 140: *endptr = (char *) (any ? s - 1 : nptr); 141: return (acc); 142: } 143: 144: #ifdef __weak_alias 145: __weak_alias(strtoq, strtoll); 146: #else 147: quad_t 148: strtoq(const char *nptr, char **endptr, int base) 149: { 150: 151: return ((quad_t)strtoll(nptr, endptr, base)); 152: } 153: #endif