]>
git.saurik.com Git - apple/xnu.git/blob - iokit/Kernel/IOStringFuncs.c
   2  * Copyright (c) 1998-2016 Apple Inc. All rights reserved. 
   4  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 
   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. 
  15  * Please obtain a copy of the License at 
  16  * http://www.opensource.apple.com/apsl/ and read it before using this file. 
  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. 
  26  * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 
  30  *      Copyright (c) 1995 NeXT Computer, Inc.  All rights reserved. 
  32  * strol.c - The functions strtol() & strtoul() are exported as public API 
  33  *           via the header file ~driverkit/generalFuncs.h 
  36  * 25-Oct-1995    Dean Reece at NeXT 
  37  *      Created based on BSD4.4's strtol.c & strtoul.c. 
  38  *      Removed dependency on _ctype_ by static versions of isupper()... 
  39  *      Added support for "0b101..." binary constants. 
  40  *      Commented out references to errno. 
  44  * Copyright (c) 1990, 1993 
  45  *      The Regents of the University of California.  All rights reserved. 
  47  * Redistribution and use in source and binary forms, with or without 
  48  * modification, are permitted provided that the following conditions 
  50  * 1. Redistributions of source code must retain the above copyright 
  51  *    notice, this list of conditions and the following disclaimer. 
  52  * 2. Redistributions in binary form must reproduce the above copyright 
  53  *    notice, this list of conditions and the following disclaimer in the 
  54  *    documentation and/or other materials provided with the distribution. 
  55  * 3. All advertising materials mentioning features or use of this software 
  56  *    must display the following acknowledgement: 
  57  *      This product includes software developed by the University of 
  58  *      California, Berkeley and its contributors. 
  59  * 4. Neither the name of the University nor the names of its contributors 
  60  *    may be used to endorse or promote products derived from this software 
  61  *    without specific prior written permission. 
  63  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 
  64  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
  65  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
  66  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 
  67  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
  68  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
  69  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
  70  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
  71  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
  72  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
  81 #include <sys/types.h> 
  82 #include <machine/limits.h> 
  85 long strtol(const char *nptr
, char **endptr
, int base
); 
  86 unsigned long strtoul(const char *nptr
, char **endptr
, int base
); 
  87 quad_t 
strtoq(const char *nptr
, char **endptr
, int base
); 
  88 u_quad_t 
strtouq(const char *nptr
, char **endptr
, int base
); 
  89 char *strncat(char *s1
, const char *s2
, unsigned long n
); 
  97     return (c 
>= 'A' && c 
<= 'Z'); 
 103     return ((c 
>= 'A' && c 
<= 'Z') || (c 
>= 'a' && c 
<= 'z')); 
 110     return (c 
== ' ' || c 
== '\t' || c 
== '\n' || c 
== '\12'); 
 116     return (c 
>= '0' && c 
<= '9'); 
 120  * Convert a string to a long integer. 
 122  * Ignores `locale' stuff.  Assumes that the upper and lower case 
 123  * alphabets and digits are each contiguous. 
 126 strtol(const char *nptr
, char **endptr
, int base
) 
 128         const char *s 
= nptr
; 
 131         unsigned long cutoff
; 
 132         int neg 
= 0, any
, cutlim
; 
 135          * Skip white space and pick up leading +/- sign if any. 
 136          * If base is 0, allow 0x for hex and 0 for octal, else 
 137          * assume decimal; if base is already 16, allow 0x. 
 141         } while (isspace(c
)); 
 147         if ((base 
== 0 || base 
== 16) && 
 148             c 
== '0' && (*s 
== 'x' || *s 
== 'X')) { 
 152         } else if ((base 
== 0 || base 
== 2) && 
 153             c 
== '0' && (*s 
== 'b' || *s 
== 'B')) { 
 159                 base 
= c 
== '0' ? 8 : 10; 
 162          * Compute the cutoff value between legal numbers and illegal 
 163          * numbers.  That is the largest legal value, divided by the 
 164          * base.  An input number that is greater than this value, if 
 165          * followed by a legal input character, is too big.  One that 
 166          * is equal to this value may be valid or not; the limit 
 167          * between valid and invalid numbers is then based on the last 
 168          * digit.  For instance, if the range for longs is 
 169          * [-2147483648..2147483647] and the input base is 10, 
 170          * cutoff will be set to 214748364 and cutlim to either 
 171          * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated 
 172          * a value > 214748364, or equal but the next digit is > 7 (or 8), 
 173          * the number is too big, and we will return a range error. 
 175          * Set any if any `digits' consumed; make it negative to indicate 
 178         cutoff 
= neg 
? -(unsigned long)LONG_MIN 
: LONG_MAX
; 
 179         cutlim 
= cutoff 
% (unsigned long)base
; 
 180         cutoff 
/= (unsigned long)base
; 
 181         for (acc 
= 0, any 
= 0;; c 
= *s
++) { 
 185                         c 
-= isupper(c
) ? 'A' - 10 : 'a' - 10; 
 190                 if (any 
< 0 || acc 
> cutoff 
|| (acc 
== cutoff 
&& c 
> cutlim
) ) 
 199                 acc 
= neg 
? LONG_MIN 
: LONG_MAX
; 
 207                         *endptr 
= __CAST_AWAY_QUALIFIER(s 
- 1, const, char *); 
 211                         *endptr 
= __CAST_AWAY_QUALIFIER(nptr
, const, char *); 
 218 strtoul(const char *nptr
, char **endptr
, int base
) 
 220         const char *s 
= nptr
; 
 223         unsigned long cutoff
; 
 224         int neg 
= 0, any
, cutlim
; 
 227          * See strtol for comments as to the logic used. 
 231         } while (isspace(c
)); 
 237         if ((base 
== 0 || base 
== 16) && 
 238             c 
== '0' && (*s 
== 'x' || *s 
== 'X')) { 
 242         } else if ((base 
== 0 || base 
== 2) && 
 243             c 
== '0' && (*s 
== 'b' || *s 
== 'B')) { 
 249                 base 
= c 
== '0' ? 8 : 10; 
 250         cutoff 
= (unsigned long)ULONG_MAX 
/ (unsigned long)base
; 
 251         cutlim 
= (unsigned long)ULONG_MAX 
% (unsigned long)base
; 
 252         for (acc 
= 0, any 
= 0;; c 
= *s
++) { 
 256                         c 
-= isupper(c
) ? 'A' - 10 : 'a' - 10; 
 261                 if (any 
< 0 || acc 
> cutoff 
|| (acc 
== cutoff 
&& c 
> cutlim
) ) 
 278                         *endptr 
= __CAST_AWAY_QUALIFIER(s 
- 1, const, char *); 
 282                         *endptr 
= __CAST_AWAY_QUALIFIER(nptr
, const, char *); 
 290  * Convert a string to a quad integer. 
 292  * Ignores `locale' stuff.  Assumes that the upper and lower case 
 293  * alphabets and digits are each contiguous. 
 296 strtoq(const char *nptr
, char **endptr
, int base
) 
 301         u_quad_t qbase
, cutoff
; 
 302         int neg
, any
, cutlim
; 
 305          * Skip white space and pick up leading +/- sign if any. 
 306          * If base is 0, allow 0x for hex and 0 for octal, else 
 307          * assume decimal; if base is already 16, allow 0x. 
 312         } while (isspace(c
)); 
 321         if ((base 
== 0 || base 
== 16) && 
 322             c 
== '0' && (*s 
== 'x' || *s 
== 'X')) { 
 328                 base 
= c 
== '0' ? 8 : 10; 
 331          * Compute the cutoff value between legal numbers and illegal 
 332          * numbers.  That is the largest legal value, divided by the 
 333          * base.  An input number that is greater than this value, if 
 334          * followed by a legal input character, is too big.  One that 
 335          * is equal to this value may be valid or not; the limit 
 336          * between valid and invalid numbers is then based on the last 
 337          * digit.  For instance, if the range for quads is 
 338          * [-9223372036854775808..9223372036854775807] and the input base 
 339          * is 10, cutoff will be set to 922337203685477580 and cutlim to 
 340          * either 7 (neg==0) or 8 (neg==1), meaning that if we have 
 341          * accumulated a value > 922337203685477580, or equal but the 
 342          * next digit is > 7 (or 8), the number is too big, and we will 
 343          * return a range error. 
 345          * Set any if any `digits' consumed; make it negative to indicate 
 348         qbase 
= (unsigned)base
; 
 349         cutoff 
= neg 
? -(u_quad_t
)QUAD_MIN 
: QUAD_MAX
; 
 350         cutlim 
= cutoff 
% qbase
; 
 352         for (acc 
= 0, any 
= 0;; c 
= *s
++) { 
 356                         c 
-= isupper(c
) ? 'A' - 10 : 'a' - 10; 
 361                 if (any 
< 0 || acc 
> cutoff 
|| (acc 
== cutoff 
&& c 
> cutlim
)) 
 370                 acc 
= neg 
? QUAD_MIN 
: QUAD_MAX
; 
 378                         *endptr 
= __CAST_AWAY_QUALIFIER(s 
- 1, const, char *); 
 382                         *endptr 
= __CAST_AWAY_QUALIFIER(nptr
, const, char *); 
 391  * Convert a string to an unsigned quad integer. 
 393  * Ignores `locale' stuff.  Assumes that the upper and lower case 
 394  * alphabets and digits are each contiguous. 
 397 strtouq(const char *nptr
, 
 401         const char *s 
= nptr
; 
 404         u_quad_t qbase
, cutoff
; 
 405         int neg
, any
, cutlim
; 
 408          * See strtoq for comments as to the logic used. 
 413         } while (isspace(c
)); 
 422         if ((base 
== 0 || base 
== 16) && 
 423             c 
== '0' && (*s 
== 'x' || *s 
== 'X')) { 
 429                 base 
= c 
== '0' ? 8 : 10; 
 430         qbase 
= (unsigned)base
; 
 431         cutoff 
= (u_quad_t
)UQUAD_MAX 
/ qbase
; 
 432         cutlim 
= (u_quad_t
)UQUAD_MAX 
% qbase
; 
 433         for (acc 
= 0, any 
= 0;; c 
= *s
++) { 
 437                         c 
-= isupper(c
) ? 'A' - 10 : 'a' - 10; 
 442                 if (any 
< 0 || acc 
> cutoff 
|| (acc 
== cutoff 
&& c 
> cutlim
)) 
 459                         *endptr 
= __CAST_AWAY_QUALIFIER(s 
- 1, const, char *); 
 463                         *endptr 
= __CAST_AWAY_QUALIFIER(nptr
, const, char *); 
 476 strncat(char *s1
, const char *s2
, unsigned long n
) 
 485         while ((*s1
++ = *s2
++))