1/* 2 * Copyright (c) 1998-2006 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28/* Copyright (c) 1995 NeXT Computer, Inc. All rights reserved. 29 * 30 * strol.c - The functions strtol() & strtoul() are exported as public API 31 * via the header file ~driverkit/generalFuncs.h 32 * 33 * HISTORY 34 * 25-Oct-1995 Dean Reece at NeXT 35 * Created based on BSD4.4's strtol.c & strtoul.c. 36 * Removed dependency on _ctype_ by static versions of isupper()... 37 * Added support for "0b101..." binary constants. 38 * Commented out references to errno. 39 */ 40 41/*- 42 * Copyright (c) 1990, 1993 43 * The Regents of the University of California. All rights reserved. 44 * 45 * Redistribution and use in source and binary forms, with or without 46 * modification, are permitted provided that the following conditions 47 * are met: 48 * 1. Redistributions of source code must retain the above copyright 49 * notice, this list of conditions and the following disclaimer. 50 * 2. Redistributions in binary form must reproduce the above copyright 51 * notice, this list of conditions and the following disclaimer in the 52 * documentation and/or other materials provided with the distribution. 53 * 3. All advertising materials mentioning features or use of this software 54 * must display the following acknowledgement: 55 * This product includes software developed by the University of 56 * California, Berkeley and its contributors. 57 * 4. Neither the name of the University nor the names of its contributors 58 * may be used to endorse or promote products derived from this software 59 * without specific prior written permission. 60 * 61 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 62 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 63 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 64 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 65 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 66 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 67 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 68 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 69 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 70 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 71 * SUCH DAMAGE. 72 */ 73 74/* 75#include <string.h> 76#include <stdlib.h> 77#include <limits.h> 78*/ 79#include <sys/types.h> 80#include <machine/limits.h> 81 82typedef int BOOL; 83 84static inline BOOL 85isupper(char c) 86{ 87 return (c >= 'A' && c <= 'Z'); 88} 89 90static inline BOOL 91isalpha(char c) 92{ 93 return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')); 94} 95 96 97static inline BOOL 98isspace(char c) 99{ 100 return (c == ' ' || c == '\t' || c == '\n' || c == '\12'); 101} 102 103static inline BOOL 104isdigit(char c) 105{ 106 return (c >= '0' && c <= '9'); 107} 108 109/* 110 * Convert a string to a long integer. 111 * 112 * Ignores `locale' stuff. Assumes that the upper and lower case 113 * alphabets and digits are each contiguous. 114 */ 115long 116strtol(const char *nptr, char **endptr, int base) 117{ 118 register const char *s = nptr; 119 register unsigned long acc; 120 register int c; 121 register unsigned long cutoff; 122 register int neg = 0, any, cutlim; 123 124 /* 125 * Skip white space and pick up leading +/- sign if any. 126 * If base is 0, allow 0x for hex and 0 for octal, else 127 * assume decimal; if base is already 16, allow 0x. 128 */ 129 do { 130 c = *s++; 131 } while (isspace(c)); 132 if (c == '-') { 133 neg = 1; 134 c = *s++; 135 } else if (c == '+') 136 c = *s++; 137 if ((base == 0 || base == 16) && 138 c == '0' && (*s == 'x' || *s == 'X')) { 139 c = s[1]; 140 s += 2; 141 base = 16; 142 } else if ((base == 0 || base == 2) && 143 c == '0' && (*s == 'b' || *s == 'B')) { 144 c = s[1]; 145 s += 2; 146 base = 2; 147 } 148 if (base == 0) 149 base = c == '0' ? 8 : 10; 150 151 /* 152 * Compute the cutoff value between legal numbers and illegal 153 * numbers. That is the largest legal value, divided by the 154 * base. An input number that is greater than this value, if 155 * followed by a legal input character, is too big. One that 156 * is equal to this value may be valid or not; the limit 157 * between valid and invalid numbers is then based on the last 158 * digit. For instance, if the range for longs is 159 * [-2147483648..2147483647] and the input base is 10, 160 * cutoff will be set to 214748364 and cutlim to either 161 * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated 162 * a value > 214748364, or equal but the next digit is > 7 (or 8), 163 * the number is too big, and we will return a range error. 164 * 165 * Set any if any `digits' consumed; make it negative to indicate 166 * overflow. 167 */ 168 cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX; 169 cutlim = cutoff % (unsigned long)base; 170 cutoff /= (unsigned long)base; 171 for (acc = 0, any = 0;; c = *s++) { 172 if (isdigit(c)) 173 c -= '0'; 174 else if (isalpha(c)) 175 c -= isupper(c) ? 'A' - 10 : 'a' - 10; 176 else 177 break; 178 if (c >= base) 179 break; 180 if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim) ) 181 any = -1; 182 else { 183 any = 1; 184 acc *= base; 185 acc += c; 186 } 187 } 188 if (any < 0) { 189 acc = neg ? LONG_MIN : LONG_MAX; 190// errno = ERANGE; 191 } else if (neg) 192 acc = -acc; 193 if (endptr != 0) 194 *endptr = (char *)(any ? s - 1 : nptr); 195 return (acc); 196} 197 198unsigned long 199strtoul(const char *nptr, char **endptr, int base) 200{ 201 register const char *s = nptr; 202 register unsigned long acc; 203 register int c; 204 register unsigned long cutoff; 205 register int neg = 0, any, cutlim; 206 207 /* 208 * See strtol for comments as to the logic used. 209 */ 210 do { 211 c = *s++; 212 } while (isspace(c)); 213 if (c == '-') { 214 neg = 1; 215 c = *s++; 216 } else if (c == '+') 217 c = *s++; 218 if ((base == 0 || base == 16) && 219 c == '0' && (*s == 'x' || *s == 'X')) { 220 c = s[1]; 221 s += 2; 222 base = 16; 223 } else if ((base == 0 || base == 2) && 224 c == '0' && (*s == 'b' || *s == 'B')) { 225 c = s[1]; 226 s += 2; 227 base = 2; 228 } 229 if (base == 0) 230 base = c == '0' ? 8 : 10; 231 cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; 232 cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; 233 for (acc = 0, any = 0;; c = *s++) { 234 if (isdigit(c)) 235 c -= '0'; 236 else if (isalpha(c)) 237 c -= isupper(c) ? 'A' - 10 : 'a' - 10; 238 else 239 break; 240 if (c >= base) 241 break; 242 if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim) ) 243 any = -1; 244 else { 245 any = 1; 246 acc *= base; 247 acc += c; 248 } 249 } 250 if (any < 0) { 251 acc = ULONG_MAX; 252// errno = ERANGE; 253 } else if (neg) 254 acc = -acc; 255 if (endptr != 0) 256 *endptr = (char *)(any ? s - 1 : nptr); 257 return (acc); 258} 259 260/* 261 * Convert a string to a quad integer. 262 * 263 * Ignores `locale' stuff. Assumes that the upper and lower case 264 * alphabets and digits are each contiguous. 265 */ 266quad_t 267strtoq(const char *nptr, char **endptr, int base) 268{ 269 register const char *s; 270 register u_quad_t acc; 271 register int c; 272 register u_quad_t qbase, cutoff; 273 register int neg, any, cutlim; 274 275 /* 276 * Skip white space and pick up leading +/- sign if any. 277 * If base is 0, allow 0x for hex and 0 for octal, else 278 * assume decimal; if base is already 16, allow 0x. 279 */ 280 s = nptr; 281 do { 282 c = *s++; 283 } while (isspace(c)); 284 if (c == '-') { 285 neg = 1; 286 c = *s++; 287 } else { 288 neg = 0; 289 if (c == '+') 290 c = *s++; 291 } 292 if ((base == 0 || base == 16) && 293 c == '0' && (*s == 'x' || *s == 'X')) { 294 c = s[1]; 295 s += 2; 296 base = 16; 297 } 298 if (base == 0) 299 base = c == '0' ? 8 : 10; 300 301 /* 302 * Compute the cutoff value between legal numbers and illegal 303 * numbers. That is the largest legal value, divided by the 304 * base. An input number that is greater than this value, if 305 * followed by a legal input character, is too big. One that 306 * is equal to this value may be valid or not; the limit 307 * between valid and invalid numbers is then based on the last 308 * digit. For instance, if the range for quads is 309 * [-9223372036854775808..9223372036854775807] and the input base 310 * is 10, cutoff will be set to 922337203685477580 and cutlim to 311 * either 7 (neg==0) or 8 (neg==1), meaning that if we have 312 * accumulated a value > 922337203685477580, or equal but the 313 * next digit is > 7 (or 8), the number is too big, and we will 314 * return a range error. 315 * 316 * Set any if any `digits' consumed; make it negative to indicate 317 * overflow. 318 */ 319 qbase = (unsigned)base; 320 cutoff = neg ? -(u_quad_t)QUAD_MIN : QUAD_MAX; 321 cutlim = cutoff % qbase; 322 cutoff /= qbase; 323 for (acc = 0, any = 0;; c = *s++) { 324 if (isdigit(c)) 325 c -= '0'; 326 else if (isalpha(c)) 327 c -= isupper(c) ? 'A' - 10 : 'a' - 10; 328 else 329 break; 330 if (c >= base) 331 break; 332 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) 333 any = -1; 334 else { 335 any = 1; 336 acc *= qbase; 337 acc += c; 338 } 339 } 340 if (any < 0) { 341 acc = neg ? QUAD_MIN : QUAD_MAX; 342// errno = ERANGE; 343 } else if (neg) 344 acc = -acc; 345 if (endptr != 0) 346 *endptr = (char *)(any ? s - 1 : nptr); 347 return (acc); 348} 349 350 351/* 352 * Convert a string to an unsigned quad integer. 353 * 354 * Ignores `locale' stuff. Assumes that the upper and lower case 355 * alphabets and digits are each contiguous. 356 */ 357u_quad_t 358strtouq(const char *nptr, 359 char **endptr, 360 register int base) 361{ 362 register const char *s = nptr; 363 register u_quad_t acc; 364 register int c; 365 register u_quad_t qbase, cutoff; 366 register int neg, any, cutlim; 367 368 /* 369 * See strtoq for comments as to the logic used. 370 */ 371 s = nptr; 372 do { 373 c = *s++; 374 } while (isspace(c)); 375 if (c == '-') { 376 neg = 1; 377 c = *s++; 378 } else { 379 neg = 0; 380 if (c == '+') 381 c = *s++; 382 } 383 if ((base == 0 || base == 16) && 384 c == '0' && (*s == 'x' || *s == 'X')) { 385 c = s[1]; 386 s += 2; 387 base = 16; 388 } 389 if (base == 0) 390 base = c == '0' ? 8 : 10; 391 qbase = (unsigned)base; 392 cutoff = (u_quad_t)UQUAD_MAX / qbase; 393 cutlim = (u_quad_t)UQUAD_MAX % qbase; 394 for (acc = 0, any = 0;; c = *s++) { 395 if (isdigit(c)) 396 c -= '0'; 397 else if (isalpha(c)) 398 c -= isupper(c) ? 'A' - 10 : 'a' - 10; 399 else 400 break; 401 if (c >= base) 402 break; 403 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) 404 any = -1; 405 else { 406 any = 1; 407 acc *= qbase; 408 acc += c; 409 } 410 } 411 if (any < 0) { 412 acc = UQUAD_MAX; 413// errno = ERANGE; 414 } else if (neg) 415 acc = -acc; 416 if (endptr != 0) 417 *endptr = (char *)(any ? s - 1 : nptr); 418 return (acc); 419} 420 421 422/* 423 * 424 */ 425 426char *strchr(const char *str, int ch) 427{ 428 do { 429 if (*str == ch) 430 return((char *)str); 431 } while (*str++); 432 return ((char *) 0); 433} 434 435/* 436 * 437 */ 438 439char * 440strncat(char *s1, const char *s2, unsigned long n) 441{ 442 char *os1; 443 int i = n; 444 445 os1 = s1; 446 while (*s1++) 447 ; 448 --s1; 449 while ((*s1++ = *s2++)) 450 if (--i < 0) { 451 *--s1 = '\0'; 452 break; 453 } 454 return(os1); 455} 456