1 /* 2 FUNCTION 3 <<wcstol>>---wide string to long 4 5 INDEX 6 wcstol 7 INDEX 8 _wcstol_r 9 10 ANSI_SYNOPSIS 11 #include <wchar.h> 12 long wcstol(const wchar_t *__restrict <[s]>, 13 wchar_t **__restrict <[ptr]>,int <[base]>); 14 15 long _wcstol_r(void *<[reent]>, 16 const wchar_t *<[s]>, wchar_t **<[ptr]>,int <[base]>); 17 18 TRAD_SYNOPSIS 19 #include <stdlib.h> 20 long wcstol (<[s]>, <[ptr]>, <[base]>) 21 wchar_t *__restrict <[s]>; 22 wchar_t **__restrict <[ptr]>; 23 int <[base]>; 24 25 long _wcstol_r (<[reent]>, <[s]>, <[ptr]>, <[base]>) 26 struct _reent *<[reent]>; 27 wchar_t *<[s]>; 28 wchar_t **<[ptr]>; 29 int <[base]>; 30 31 DESCRIPTION 32 The function <<wcstol>> converts the wide string <<*<[s]>>> to 33 a <<long>>. First, it breaks down the string into three parts: 34 leading whitespace, which is ignored; a subject string consisting 35 of characters resembling an integer in the radix specified by <[base]>; 36 and a trailing portion consisting of zero or more unparseable characters, 37 and always including the terminating null character. Then, it attempts 38 to convert the subject string into a <<long>> and returns the 39 result. 40 41 If the value of <[base]> is 0, the subject string is expected to look 42 like a normal C integer constant: an optional sign, a possible `<<0x>>' 43 indicating a hexadecimal base, and a number. If <[base]> is between 44 2 and 36, the expected form of the subject is a sequence of letters 45 and digits representing an integer in the radix specified by <[base]>, 46 with an optional plus or minus sign. The letters <<a>>--<<z>> (or, 47 equivalently, <<A>>--<<Z>>) are used to signify values from 10 to 35; 48 only letters whose ascribed values are less than <[base]> are 49 permitted. If <[base]> is 16, a leading <<0x>> is permitted. 50 51 The subject sequence is the longest initial sequence of the input 52 string that has the expected form, starting with the first 53 non-whitespace character. If the string is empty or consists entirely 54 of whitespace, or if the first non-whitespace character is not a 55 permissible letter or digit, the subject string is empty. 56 57 If the subject string is acceptable, and the value of <[base]> is zero, 58 <<wcstol>> attempts to determine the radix from the input string. A 59 string with a leading <<0x>> is treated as a hexadecimal value; a string with 60 a leading 0 and no <<x>> is treated as octal; all other strings are 61 treated as decimal. If <[base]> is between 2 and 36, it is used as the 62 conversion radix, as described above. If the subject string begins with 63 a minus sign, the value is negated. Finally, a pointer to the first 64 character past the converted subject string is stored in <[ptr]>, if 65 <[ptr]> is not <<NULL>>. 66 67 If the subject string is empty (or not in acceptable form), no conversion 68 is performed and the value of <[s]> is stored in <[ptr]> (if <[ptr]> is 69 not <<NULL>>). 70 71 The alternate function <<_wcstol_r>> is a reentrant version. The 72 extra argument <[reent]> is a pointer to a reentrancy structure. 73 74 RETURNS 75 <<wcstol>> returns the converted value, if any. If no conversion was 76 made, 0 is returned. 77 78 <<wcstol>> returns <<LONG_MAX>> or <<LONG_MIN>> if the magnitude of 79 the converted value is too large, and sets <<errno>> to <<ERANGE>>. 80 81 PORTABILITY 82 <<wcstol>> is ANSI. 83 84 No supporting OS subroutines are required. 85 */ 86 87 /*- 88 * Copyright (c) 1990 The Regents of the University of California. 89 * All rights reserved. 90 * 91 * Redistribution and use in source and binary forms, with or without 92 * modification, are permitted provided that the following conditions 93 * are met: 94 * 1. Redistributions of source code must retain the above copyright 95 * notice, this list of conditions and the following disclaimer. 96 * 2. Redistributions in binary form must reproduce the above copyright 97 * notice, this list of conditions and the following disclaimer in the 98 * documentation and/or other materials provided with the distribution. 99 * 3. All advertising materials mentioning features or use of this software 100 * must display the following acknowledgement: 101 * This product includes software developed by the University of 102 * California, Berkeley and its contributors. 103 * 4. Neither the name of the University nor the names of its contributors 104 * may be used to endorse or promote products derived from this software 105 * without specific prior written permission. 106 * 107 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 108 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 109 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 110 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 111 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 112 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 113 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 114 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 115 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 116 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 117 * SUCH DAMAGE. 118 */ 119 120 121 #include <_ansi.h> 122 #include <limits.h> 123 #include <wctype.h> 124 #include <errno.h> 125 #include <wchar.h> 126 #include <reent.h> 127 128 #ifndef LONG_MIN 129 #ifdef _LP64 130 #define LONG_MAX 0x7fffffffffffffff 131 #define LONG_MIN (-0x7fffffffffffffffL - 1) 132 #else 133 #define LONG_MAX 0x7fffffffUL 134 #define LONG_MIN (-0x7fffffffL - 1) 135 #endif 136 #endif 137 138 /* 139 * Convert a wide string to a long integer. 140 * 141 * Ignores `locale' stuff. Assumes that the upper and lower case 142 * alphabets and digits are each contiguous. 143 */ 144 long 145 _DEFUN (_wcstol_r, (rptr, nptr, endptr, base), 146 struct _reent *rptr _AND 147 _CONST wchar_t *nptr _AND 148 wchar_t **endptr _AND 149 int base) 150 { 151 register const wchar_t *s = nptr; 152 register unsigned long acc; 153 register int c; 154 register unsigned long cutoff; 155 register int neg = 0, any, cutlim; 156 157 /* 158 * Skip white space and pick up leading +/- sign if any. 159 * If base is 0, allow 0x for hex and 0 for octal, else 160 * assume decimal; if base is already 16, allow 0x. 161 */ 162 do { 163 c = *s++; 164 } while (iswspace(c)); 165 if (c == L'-') { 166 neg = 1; 167 c = *s++; 168 } else if (c == L'+') 169 c = *s++; 170 if ((base == 0 || base == 16) && 171 c == L'0' && (*s == L'x' || *s == L'X')) { 172 c = s[1]; 173 s += 2; 174 base = 16; 175 } 176 if (base == 0) 177 base = c == L'0' ? 8 : 10; 178 179 /* 180 * Compute the cutoff value between legal numbers and illegal 181 * numbers. That is the largest legal value, divided by the 182 * base. An input number that is greater than this value, if 183 * followed by a legal input character, is too big. One that 184 * is equal to this value may be valid or not; the limit 185 * between valid and invalid numbers is then based on the last 186 * digit. For instance, if the range for longs is 187 * [-2147483648..2147483647] and the input base is 10, 188 * cutoff will be set to 214748364 and cutlim to either 189 * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated 190 * a value > 214748364, or equal but the next digit is > 7 (or 8), 191 * the number is too big, and we will return a range error. 192 * 193 * Set any if any `digits' consumed; make it negative to indicate 194 * overflow. 195 */ 196 cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX; 197 cutlim = cutoff % (unsigned long)base; 198 cutoff /= (unsigned long)base; 199 for (acc = 0, any = 0;; c = *s++) { 200 if (iswdigit(c)) 201 c -= L'0'; 202 else if (iswalpha(c)) 203 c -= iswupper(c) ? L'A' - 10 : L'a' - 10; 204 else 205 break; 206 if (c >= base) 207 break; 208 if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) 209 any = -1; 210 else { 211 any = 1; 212 acc *= base; 213 acc += c; 214 } 215 } 216 if (any < 0) { 217 acc = neg ? LONG_MIN : LONG_MAX; 218 rptr->_errno = ERANGE; 219 } else if (neg) 220 acc = -acc; 221 if (endptr != 0) 222 *endptr = (wchar_t *) (any ? s - 1 : nptr); 223 return (acc); 224 } 225 226 #ifndef _REENT_ONLY 227 228 long 229 _DEFUN (wcstol, (s, ptr, base), 230 _CONST wchar_t *__restrict s _AND 231 wchar_t **__restrict ptr _AND 232 int base) 233 { 234 return _wcstol_r (_REENT, s, ptr, base); 235 } 236 237 #endif 238