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