root / prex0.9.0 / bsp / drv / lib / strtoul.c @ 03e9c04a
History  View  Annotate  Download (2.91 KB)
1 
/*


2 
* Copyright (c) 1990, 1993

3 
* The Regents of the University of California. All rights reserved.

4 
*

5 
* Redistribution and use in source and binary forms, with or without

6 
* modification, are permitted provided that the following conditions

7 
* are met:

8 
* 1. Redistributions of source code must retain the above copyright

9 
* notice, this list of conditions and the following disclaimer.

10 
* 2. Redistributions in binary form must reproduce the above copyright

11 
* notice, this list of conditions and the following disclaimer in the

12 
* documentation and/or other materials provided with the distribution.

13 
* 3. Neither the name of the University nor the names of its contributors

14 
* may be used to endorse or promote products derived from this software

15 
* without specific prior written permission.

16 
*

17 
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND

18 
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE

19 
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE

20 
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE

21 
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL

22 
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS

23 
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)

24 
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT

25 
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY

26 
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF

27 
* SUCH DAMAGE.

28 
*/

29  
30 
#include <ddi.h> 
31 
#include <machine/limits.h> 
32  
33 
/*

34 
* Convert a string to an unsigned long integer.

35 
*

36 
* Ignores `locale' stuff. Assumes that the upper and lower case

37 
* alphabets and digits are each contiguous.

38 
*

39 
* return ULONG_MAX if error.

40 
*/

41 
unsigned long 
42 
strtoul(const char *nptr, char **endptr, int base) 
43 
{ 
44 
const char *s; 
45 
unsigned long acc, cutoff; 
46 
int c;

47 
int neg, any, cutlim;

48  
49 
/*

50 
* See strtol for comments as to the logic used.

51 
*/

52 
s = nptr; 
53 
do {

54 
c = (unsigned char) *s++; 
55 
} while (isspace(c));

56 
if (c == '') { 
57 
neg = 1;

58 
c = *s++; 
59 
} else {

60 
neg = 0;

61 
if (c == '+') 
62 
c = *s++; 
63 
} 
64 
if ((base == 0  base == 16) && 
65 
c == '0' && (*s == 'x'  *s == 'X')) { 
66 
c = s[1];

67 
s += 2;

68 
base = 16;

69 
} 
70 
if (base == 0) 
71 
base = c == '0' ? 8 : 10; 
72  
73 
cutoff = ULONG_MAX / base; 
74 
cutlim = (int)(ULONG_MAX % (unsigned long)base); 
75 
for (acc = 0, any = 0;; c = (unsigned char) *s++) { 
76 
if (isdigit(c))

77 
c = '0';

78 
else if (isalpha(c)) 
79 
c = isupper(c) ? 'A'  10 : 'a'  10; 
80 
else

81 
break;

82 
if (c >= base)

83 
break;

84 
if (any < 0) 
85 
continue;

86 
if (acc > cutoff  (acc == cutoff && c > cutlim)) {

87 
any = 1;

88 
acc = ULONG_MAX; 
89 
} else {

90 
any = 1;

91 
acc *= (unsigned long)base; 
92 
acc += c; 
93 
} 
94 
} 
95 
if (neg && any > 0) 
96 
acc = acc; 
97 
if (endptr != 0) 
98 
/* LINTED interface specification */

99 
*endptr = (char *)(any ? s  1 : nptr); 
100 
return (acc);

101 
} 