blob: 61fb054f3af6718d389f4113e6208ee2f8c1eac9 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
|
/* $NetBSD: strtoul.c,v 1.5 2000/05/25 01:22:41 msaitoh Exp $ */
#include <sys/param.h>
#include <lib/libkern/libkern.h>
#ifndef ULONG_MAX
#define ULONG_MAX ((u_long)(~0L)) /* 0xFFFFFFFF */
#endif
u_long
strtoul(s, ptr, base)
const char *s;
char **ptr;
int base;
{
u_long total = 0;
u_int digit;
const char *start=s;
int did_conversion=0;
int overflow = 0;
int negate = 0;
u_long maxdiv, maxrem;
if (s == NULL) {
if (ptr != NULL)
*ptr = (char *)start;
return 0L;
}
while (*s == ' ')
s++;
if (*s == '+')
s++;
else if (*s == '-')
s++, negate = 1;
if (base==0 || base==16) { /* the 'base==16' is for handling 0x */
int tmp;
/*
* try to infer base from the string
*/
if (*s != '0')
tmp = 10; /* doesn't start with 0 - assume decimal */
else if (s[1] == 'X' || s[1] == 'x')
tmp = 16, s += 2; /* starts with 0x or 0X - hence hex */
else
tmp = 8; /* starts with 0 - hence octal */
if (base==0)
base = (int)tmp;
}
maxdiv = ULONG_MAX / base;
maxrem = ULONG_MAX % base;
while ((digit = *s) != '\0') {
if (digit >= '0' && digit < ('0' + min(base, 10)))
digit -= '0';
else
if (base > 10) {
if (digit >= 'a' && digit < ('a'+(base-10)))
digit = digit - 'a' + 10;
else if (digit >= 'A' && digit < ('A'+(base-10)))
digit = digit - 'A' + 10;
else
break;
}
else
break;
did_conversion = 1;
if (total > maxdiv
|| (total == maxdiv && digit > maxrem))
overflow = 1;
total = (total * base) + digit;
s++;
}
if (overflow) {
if (ptr != NULL)
*ptr = (char *)s;
return (ULONG_MAX);
}
if (ptr != NULL)
*ptr = (char *) ((did_conversion) ? (char *)s : (char *)start);
return negate ? -total : total;
}
/* End of strtoul.c */
|