Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-4-Clause-UC */ 2 : : 3 : : /* 4 : : * Copyright (c) 1990, 1993 5 : : * The Regents of the University of California. All rights reserved. 6 : : * 7 : : * Redistribution and use in source and binary forms, with or without 8 : : * modification, are permitted provided that the following conditions 9 : : * are met: 10 : : * 1. Redistributions of source code must retain the above copyright 11 : : * notice, this list of conditions and the following disclaimer. 12 : : * 2. Redistributions in binary form must reproduce the above copyright 13 : : * notice, this list of conditions and the following disclaimer in the 14 : : * documentation and/or other materials provided with the distribution. 15 : : * 3. All advertising materials mentioning features or use of this software 16 : : * must display the following acknowledgment: 17 : : * This product includes software developed by the University of 18 : : * California, Berkeley and its contributors. 19 : : * 4. Neither the name of the University nor the names of its contributors 20 : : * may be used to endorse or promote products derived from this software 21 : : * without specific prior written permission. 22 : : * 23 : : * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 : : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 : : * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 : : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 : : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 : : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 : : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 : : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 : : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 : : * SUCH DAMAGE. 34 : : */ 35 : : #include <limits.h> 36 : : #include <ctype.h> 37 : : #include <errno.h> 38 : : #include <stdlib.h> 39 : : 40 : : /* 41 : : * Convert a string to an unsigned long long integer. 42 : : * 43 : : * Ignores `locale' stuff. Assumes that the upper and lower case 44 : : * alphabets and digits are each contiguous. 45 : : */ 46 : : unsigned long long strtoull(const char *nptr, char **endptr, register int base) 47 : : { 48 : 0 : register const char *s = nptr; 49 : : register unsigned long long acc; 50 : : register int c; 51 : : register unsigned long long cutoff; 52 : 0 : register int neg = 0, any, cutlim; 53 : : 54 : : /* 55 : : * See strtol for comments as to the logic used. 56 : : */ 57 : : do { 58 : 0 : c = *s++; 59 [ # # ]: 0 : } while (isspace(c)); 60 [ # # ]: 0 : if (c == '-') { 61 : 0 : neg = 1; 62 : 0 : c = *s++; 63 [ # # ]: 0 : } else if (c == '+') { 64 : 0 : c = *s++; 65 : : } 66 : : 67 [ # # # # : 0 : if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X')) { # # # # # # ] 68 : 0 : c = s[1]; 69 : 0 : s += 2; 70 : 0 : base = 16; 71 : : } 72 : : 73 [ # # ]: 0 : if (base == 0) { 74 [ # # ]: 0 : base = c == '0' ? 8 : 10; 75 : : } 76 : : 77 : 0 : cutoff = (unsigned long long)ULLONG_MAX / (unsigned long long)base; 78 : 0 : cutlim = (unsigned long long)ULLONG_MAX % (unsigned long long)base; 79 : 0 : for (acc = 0, any = 0;; c = *s++) { 80 [ # # ]: 0 : if (isdigit(c)) { 81 : 0 : c -= '0'; 82 [ # # ]: 0 : } else if (isalpha(c)) { 83 [ # # ]: 0 : c -= isupper(c) ? 'A' - 10 : 'a' - 10; 84 : : } else { 85 : 0 : break; 86 : : } 87 [ # # ]: 0 : if (c >= base) { 88 : 0 : break; 89 : : } 90 [ # # # # : 0 : if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) { # # # # ] 91 : 0 : any = -1; 92 : : } else { 93 : 0 : any = 1; 94 : 0 : acc *= base; 95 : 0 : acc += c; 96 : : } 97 : : } 98 [ # # ]: 0 : if (any < 0) { 99 : 0 : acc = ULLONG_MAX; 100 : 0 : errno = ERANGE; 101 [ # # ]: 0 : } else if (neg) { 102 : 0 : acc = -acc; 103 : : } 104 [ # # ]: 0 : if (endptr != NULL) { 105 [ # # ]: 0 : *endptr = (char *)(any ? s - 1 : nptr); 106 : : } 107 : 0 : return acc; 108 : : }