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. Neither the name of the University nor the names of its contributors 130 * may be used to endorse or promote products derived from this software 131 * without specific prior written permission. 132 * 133 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 134 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 135 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 136 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 137 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 138 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 139 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 140 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 141 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 142 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 143 * SUCH DAMAGE. 144 */ 145 146 #include "_ansi.h" 147 #include <limits.h> 148 #include <ctype.h> 149 #include <stdlib.h> 150 151 /* 152 * Convert a string to an unsigned long integer. 153 * 154 * Ignores `locale' stuff. Assumes that the upper and lower case 155 * alphabets and digits are each contiguous. 156 */ 157 unsigned long 158 _DEFUN (_strtoul, (nptr, endptr, base), 159 _CONST char *nptr _AND 160 char **endptr _AND 161 int base) 162 { 163 register const unsigned char *s = (const unsigned char *)nptr; 164 register unsigned long acc; 165 register int c; 166 register unsigned long cutoff; 167 register int neg = 0, any, cutlim; 168 169 /* 170 * See strtol for comments as to the logic used. 171 */ 172 do { 173 c = *s++; 174 } while (isspace(c)); 175 if (c == '-') { 176 neg = 1; 177 c = *s++; 178 } else if (c == '+') 179 c = *s++; 180 if ((base == 0 || base == 16) && 181 c == '0' && (*s == 'x' || *s == 'X')) { 182 c = s[1]; 183 s += 2; 184 base = 16; 185 } 186 if (base == 0) 187 base = c == '0' ? 8 : 10; 188 cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; 189 cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; 190 for (acc = 0, any = 0;; c = *s++) { 191 if (isdigit(c)) 192 c -= '0'; 193 else if (isalpha(c)) 194 c -= isupper(c) ? 'A' - 10 : 'a' - 10; 195 else 196 break; 197 if (c >= base) 198 break; 199 if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) 200 any = -1; 201 else { 202 any = 1; 203 acc *= base; 204 acc += c; 205 } 206 } 207 if (any < 0) { 208 acc = ULONG_MAX; 209 } else if (neg) 210 acc = -acc; 211 if (endptr != 0) 212 *endptr = (char *) (any ? (char *)s - 1 : nptr); 213 return (acc); 214 } 215 216 #ifndef _REENT_ONLY 217 218 unsigned long 219 _DEFUN (strtoul, (s, ptr, base), 220 _CONST char *s _AND 221 char **ptr _AND 222 int base) 223 { 224 return _strtoul (s, ptr, base); 225 } 226 227 #endif 228