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 acknowledgement: 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 integer. 42 : : * 43 : : * Ignores `locale' stuff. Assumes that the upper and lower case 44 : : * alphabets and digits are each contiguous. 45 : : */ 46 : : unsigned long strtoul(const char *nptr, char **endptr, register int base) 47 : : { 48 : 0 : register const char *s = nptr; 49 : : register unsigned long acc; 50 : : register int c; 51 : : register unsigned 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) && # # ] 68 [ # # # # ]: 0 : c == '0' && (*s == 'x' || *s == 'X')) { 69 : 0 : c = s[1]; 70 : 0 : s += 2; 71 : 0 : base = 16; 72 : : } 73 : : 74 [ # # ]: 0 : if (base == 0) { 75 [ # # ]: 0 : base = c == '0' ? 8 : 10; 76 : : } 77 : : 78 : 0 : cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; 79 : 0 : cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; 80 : 0 : for (acc = 0, any = 0;; c = *s++) { 81 [ # # ]: 0 : if (isdigit(c)) { 82 : 0 : c -= '0'; 83 [ # # ]: 0 : } else if (isalpha(c)) { 84 [ # # ]: 0 : c -= isupper(c) ? 'A' - 10 : 'a' - 10; 85 : : } else { 86 : 0 : break; 87 : : } 88 [ # # ]: 0 : if (c >= base) { 89 : 0 : break; 90 : : } 91 [ # # # # : 0 : if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) { # # # # ] 92 : 0 : any = -1; 93 : : } else { 94 : 0 : any = 1; 95 : 0 : acc *= base; 96 : 0 : acc += c; 97 : : } 98 : : } 99 [ # # ]: 0 : if (any < 0) { 100 : 0 : acc = ULONG_MAX; 101 : 0 : errno = ERANGE; 102 [ # # ]: 0 : } else if (neg) { 103 : 0 : acc = -acc; 104 : : } 105 [ # # ]: 0 : if (endptr != NULL) { 106 [ # # ]: 0 : *endptr = (char *)(any ? s - 1 : nptr); 107 : : } 108 : 0 : return acc; 109 : : }