1 // SPDX-License-Identifier: BSD-3-Clause 2 /* 3 * Copyright (c) 1994-2009 Red Hat, Inc. 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 are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the documentation 14 * and/or other materials provided with the distribution. 15 * 16 * 3. Neither the name of the copyright holder nor the names of its 17 * contributors may be used to endorse or promote products derived from this 18 * software without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33 /* 34 FUNCTION 35 <<strtoul>>---string to unsigned long 36 37 INDEX 38 strtoul 39 INDEX 40 _strtoul_r 41 42 ANSI_SYNOPSIS 43 #include <stdlib.h> 44 unsigned long strtoul(const char *<[s]>, char **<[ptr]>, 45 int <[base]>); 46 47 unsigned long _strtoul(const char *<[s]>, 48 char **<[ptr]>, int <[base]>); 49 50 TRAD_SYNOPSIS 51 #include <stdlib.h> 52 unsigned long strtoul(<[s]>, <[ptr]>, <[base]>) 53 char *<[s]>; 54 char **<[ptr]>; 55 int <[base]>; 56 57 unsigned long _strtoul(<[s]>, <[ptr]>, <[base]>) 58 char *<[s]>; 59 char **<[ptr]>; 60 int <[base]>; 61 62 DESCRIPTION 63 The function <<strtoul>> converts the string <<*<[s]>>> to 64 an <<unsigned long>>. First, it breaks down the string into three parts: 65 leading whitespace, which is ignored; a subject string consisting 66 of the digits meaningful in the radix specified by <[base]> 67 (for example, <<0>> through <<7>> if the value of <[base]> is 8); 68 and a trailing portion consisting of one or more unparseable characters, 69 which always includes the terminating null character. Then, it attempts 70 to convert the subject string into an unsigned long integer, and returns the 71 result. 72 73 If the value of <[base]> is zero, the subject string is expected to look 74 like a normal C integer constant (save that no optional sign is permitted): 75 a possible <<0x>> indicating hexadecimal radix, and a number. 76 If <[base]> is between 2 and 36, the expected form of the subject is a 77 sequence of digits (which may include letters, depending on the 78 base) representing an integer in the radix specified by <[base]>. 79 The letters <<a>>--<<z>> (or <<A>>--<<Z>>) are used as digits valued from 80 10 to 35. If <[base]> is 16, a leading <<0x>> is permitted. 81 82 The subject sequence is the longest initial sequence of the input 83 string that has the expected form, starting with the first 84 non-whitespace character. If the string is empty or consists entirely 85 of whitespace, or if the first non-whitespace character is not a 86 permissible digit, the subject string is empty. 87 88 If the subject string is acceptable, and the value of <[base]> is zero, 89 <<strtoul>> attempts to determine the radix from the input string. A 90 string with a leading <<0x>> is treated as a hexadecimal value; a string with 91 a leading <<0>> and no <<x>> is treated as octal; all other strings are 92 treated as decimal. If <[base]> is between 2 and 36, it is used as the 93 conversion radix, as described above. Finally, a pointer to the first 94 character past the converted subject string is stored in <[ptr]>, if 95 <[ptr]> is not <<NULL>>. 96 97 If the subject string is empty (that is, if <<*>><[s]> does not start 98 with a substring in acceptable form), no conversion 99 is performed and the value of <[s]> is stored in <[ptr]> (if <[ptr]> is 100 not <<NULL>>). 101 102 103 104 RETURNS 105 <<strtoul>> returns the converted value, if any. If no conversion was 106 made, <<0>> is returned. 107 108 <<strtoul>> returns <<ULONG_MAX>> if the magnitude of the converted 109 value is too large, and sets <<errno>> to <<ERANGE>>. 110 111 PORTABILITY 112 <<strtoul>> is ANSI. 113 114 <<strtoul>> requires no supporting OS subroutines. 115 */ 116 117 /* 118 * Copyright (c) 1990 Regents of the University of California. 119 * All rights reserved. 120 * 121 * Redistribution and use in source and binary forms, with or without 122 * modification, are permitted provided that the following conditions 123 * are met: 124 * 1. Redistributions of source code must retain the above copyright 125 * notice, this list of conditions and the following disclaimer. 126 * 2. Redistributions in binary form must reproduce the above copyright 127 * notice, this list of conditions and the following disclaimer in the 128 * documentation and/or other materials provided with the distribution. 129 * 3. All advertising materials mentioning features or use of this software 130 * must display the following acknowledgement: 131 * This product includes software developed by the University of 132 * California, Berkeley and its contributors. 133 * 4. Neither the name of the University nor the names of its contributors 134 * may be used to endorse or promote products derived from this software 135 * without specific prior written permission. 136 * 137 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 138 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 139 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 140 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 141 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 142 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 143 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 144 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 145 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 146 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 147 * SUCH DAMAGE. 148 */ 149 150 #include "_ansi.h" 151 #include <limits.h> 152 #include <ctype.h> 153 #include <stdlib.h> 154 155 /* 156 * Convert a string to an unsigned long integer. 157 * 158 * Ignores `locale' stuff. Assumes that the upper and lower case 159 * alphabets and digits are each contiguous. 160 */ 161 unsigned long 162 _DEFUN (_strtoul, (nptr, endptr, base), 163 _CONST char *nptr _AND 164 char **endptr _AND 165 int base) 166 { 167 register const unsigned char *s = (const unsigned char *)nptr; 168 register unsigned long acc; 169 register int c; 170 register unsigned long cutoff; 171 register int neg = 0, any, cutlim; 172 173 /* 174 * See strtol for comments as to the logic used. 175 */ 176 do { 177 c = *s++; 178 } while (isspace(c)); 179 if (c == '-') { 180 neg = 1; 181 c = *s++; 182 } else if (c == '+') 183 c = *s++; 184 if ((base == 0 || base == 16) && 185 c == '0' && (*s == 'x' || *s == 'X')) { 186 c = s[1]; 187 s += 2; 188 base = 16; 189 } 190 if (base == 0) 191 base = c == '0' ? 8 : 10; 192 cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; 193 cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; 194 for (acc = 0, any = 0;; c = *s++) { 195 if (isdigit(c)) 196 c -= '0'; 197 else if (isalpha(c)) 198 c -= isupper(c) ? 'A' - 10 : 'a' - 10; 199 else 200 break; 201 if (c >= base) 202 break; 203 if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) 204 any = -1; 205 else { 206 any = 1; 207 acc *= base; 208 acc += c; 209 } 210 } 211 if (any < 0) { 212 acc = ULONG_MAX; 213 } else if (neg) 214 acc = -acc; 215 if (endptr != 0) 216 *endptr = (char *) (any ? (char *)s - 1 : nptr); 217 return (acc); 218 } 219 220 #ifndef _REENT_ONLY 221 222 unsigned long 223 _DEFUN (strtoul, (s, ptr, base), 224 _CONST char *s _AND 225 char **ptr _AND 226 int base) 227 { 228 return _strtoul (s, ptr, base); 229 } 230 231 #endif 232