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