]>
git.saurik.com Git - apple/xnu.git/blob - iokit/Kernel/IOStringFuncs.c
e3742c96463b81f8d9dbf0bbbd41bd4e4ad396d8
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_OSREFERENCE_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
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
28 * @APPLE_LICENSE_OSREFERENCE_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>
89 return (c
>= 'A' && c
<= 'Z');
95 return ((c
>= 'A' && c
<= 'Z') || (c
>= 'a' && c
<= 'z'));
102 return (c
== ' ' || c
== '\t' || c
== '\n' || c
== '\12');
108 return (c
>= '0' && c
<= '9');
112 * Convert a string to a long integer.
114 * Ignores `locale' stuff. Assumes that the upper and lower case
115 * alphabets and digits are each contiguous.
118 strtol(nptr
, endptr
, base
)
123 register const char *s
= nptr
;
124 register unsigned long acc
;
126 register unsigned long cutoff
;
127 register int neg
= 0, any
, cutlim
;
130 * Skip white space and pick up leading +/- sign if any.
131 * If base is 0, allow 0x for hex and 0 for octal, else
132 * assume decimal; if base is already 16, allow 0x.
136 } while (isspace(c
));
142 if ((base
== 0 || base
== 16) &&
143 c
== '0' && (*s
== 'x' || *s
== 'X')) {
147 } else if ((base
== 0 || base
== 2) &&
148 c
== '0' && (*s
== 'b' || *s
== 'B')) {
154 base
= c
== '0' ? 8 : 10;
157 * Compute the cutoff value between legal numbers and illegal
158 * numbers. That is the largest legal value, divided by the
159 * base. An input number that is greater than this value, if
160 * followed by a legal input character, is too big. One that
161 * is equal to this value may be valid or not; the limit
162 * between valid and invalid numbers is then based on the last
163 * digit. For instance, if the range for longs is
164 * [-2147483648..2147483647] and the input base is 10,
165 * cutoff will be set to 214748364 and cutlim to either
166 * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
167 * a value > 214748364, or equal but the next digit is > 7 (or 8),
168 * the number is too big, and we will return a range error.
170 * Set any if any `digits' consumed; make it negative to indicate
173 cutoff
= neg
? -(unsigned long)LONG_MIN
: LONG_MAX
;
174 cutlim
= cutoff
% (unsigned long)base
;
175 cutoff
/= (unsigned long)base
;
176 for (acc
= 0, any
= 0;; c
= *s
++) {
180 c
-= isupper(c
) ? 'A' - 10 : 'a' - 10;
185 if (any
< 0 || acc
> cutoff
|| (acc
== cutoff
&& c
> cutlim
) )
194 acc
= neg
? LONG_MIN
: LONG_MAX
;
199 *endptr
= (char *)(any
? s
- 1 : nptr
);
204 strtoul(nptr
, endptr
, base
)
209 register const char *s
= nptr
;
210 register unsigned long acc
;
212 register unsigned long cutoff
;
213 register int neg
= 0, any
, cutlim
;
216 * See strtol for comments as to the logic used.
220 } while (isspace(c
));
226 if ((base
== 0 || base
== 16) &&
227 c
== '0' && (*s
== 'x' || *s
== 'X')) {
231 } else if ((base
== 0 || base
== 2) &&
232 c
== '0' && (*s
== 'b' || *s
== 'B')) {
238 base
= c
== '0' ? 8 : 10;
239 cutoff
= (unsigned long)ULONG_MAX
/ (unsigned long)base
;
240 cutlim
= (unsigned long)ULONG_MAX
% (unsigned long)base
;
241 for (acc
= 0, any
= 0;; c
= *s
++) {
245 c
-= isupper(c
) ? 'A' - 10 : 'a' - 10;
250 if (any
< 0 || acc
> cutoff
|| (acc
== cutoff
&& c
> cutlim
) )
264 *endptr
= (char *)(any
? s
- 1 : nptr
);
269 * Convert a string to a quad integer.
271 * Ignores `locale' stuff. Assumes that the upper and lower case
272 * alphabets and digits are each contiguous.
275 strtoq(nptr
, endptr
, base
)
280 register const char *s
;
281 register u_quad_t acc
;
283 register u_quad_t qbase
, cutoff
;
284 register int neg
, any
, cutlim
;
287 * Skip white space and pick up leading +/- sign if any.
288 * If base is 0, allow 0x for hex and 0 for octal, else
289 * assume decimal; if base is already 16, allow 0x.
294 } while (isspace(c
));
303 if ((base
== 0 || base
== 16) &&
304 c
== '0' && (*s
== 'x' || *s
== 'X')) {
310 base
= c
== '0' ? 8 : 10;
313 * Compute the cutoff value between legal numbers and illegal
314 * numbers. That is the largest legal value, divided by the
315 * base. An input number that is greater than this value, if
316 * followed by a legal input character, is too big. One that
317 * is equal to this value may be valid or not; the limit
318 * between valid and invalid numbers is then based on the last
319 * digit. For instance, if the range for quads is
320 * [-9223372036854775808..9223372036854775807] and the input base
321 * is 10, cutoff will be set to 922337203685477580 and cutlim to
322 * either 7 (neg==0) or 8 (neg==1), meaning that if we have
323 * accumulated a value > 922337203685477580, or equal but the
324 * next digit is > 7 (or 8), the number is too big, and we will
325 * return a range error.
327 * Set any if any `digits' consumed; make it negative to indicate
330 qbase
= (unsigned)base
;
331 cutoff
= neg
? -(u_quad_t
)QUAD_MIN
: QUAD_MAX
;
332 cutlim
= cutoff
% qbase
;
334 for (acc
= 0, any
= 0;; c
= *s
++) {
338 c
-= isupper(c
) ? 'A' - 10 : 'a' - 10;
343 if (any
< 0 || acc
> cutoff
|| acc
== cutoff
&& c
> cutlim
)
352 acc
= neg
? QUAD_MIN
: QUAD_MAX
;
357 *endptr
= (char *)(any
? s
- 1 : nptr
);
363 * Convert a string to an unsigned quad integer.
365 * Ignores `locale' stuff. Assumes that the upper and lower case
366 * alphabets and digits are each contiguous.
369 strtouq(const char *nptr
,
373 register const char *s
= nptr
;
374 register u_quad_t acc
;
376 register u_quad_t qbase
, cutoff
;
377 register int neg
, any
, cutlim
;
380 * See strtoq for comments as to the logic used.
385 } while (isspace(c
));
394 if ((base
== 0 || base
== 16) &&
395 c
== '0' && (*s
== 'x' || *s
== 'X')) {
401 base
= c
== '0' ? 8 : 10;
402 qbase
= (unsigned)base
;
403 cutoff
= (u_quad_t
)UQUAD_MAX
/ qbase
;
404 cutlim
= (u_quad_t
)UQUAD_MAX
% qbase
;
405 for (acc
= 0, any
= 0;; c
= *s
++) {
409 c
-= isupper(c
) ? 'A' - 10 : 'a' - 10;
414 if (any
< 0 || acc
> cutoff
|| acc
== cutoff
&& c
> cutlim
)
428 *endptr
= (char *)(any
? s
- 1 : nptr
);
437 char *strchr(const char *str
, int ch
)
451 strncat(char *s1
, const char *s2
, unsigned long n
)
460 while ((*s1
++ = *s2
++))