Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
 
4
#define ULONG_MAX	4294967295UL
5
 
6
ulong
7
strtoul(char *nptr, char **endptr, int base)
8
{
9
	char *p;
10
	ulong n, nn, m;
11
	int c, ovfl, neg, v, ndig;
12
 
13
	p = nptr;
14
	neg = 0;
15
	n = 0;
16
	ndig = 0;
17
	ovfl = 0;
18
 
19
	/*
20
	 * White space
21
	 */
22
	for(;;p++){
23
		switch(*p){
24
		case ' ':
25
		case '\t':
26
		case '\n':
27
		case '\f':
28
		case '\r':
29
		case '\v':
30
			continue;
31
		}
32
		break;
33
	}
34
 
35
	/*
36
	 * Sign
37
	 */
38
	if(*p=='-' || *p=='+')
39
		if(*p++ == '-')
40
			neg = 1;
41
 
42
	/*
43
	 * Base
44
	 */
45
	if(base==0){
46
		if(*p != '0')
47
			base = 10;
48
		else{
49
			base = 8;
50
			if(p[1]=='x' || p[1]=='X')
51
				base = 16;
52
		}
53
	}
54
 	if(base<2 || 36<base)
55
		goto Return;
56
	if(base==16 && *p=='0'){
57
		if(p[1]=='x' || p[1]=='X')
58
			if(('0' <= p[2] && p[2] <= '9')
59
			 ||('a' <= p[2] && p[2] <= 'f')
60
			 ||('A' <= p[2] && p[2] <= 'F'))
61
				p += 2;
62
	}
63
	/*
64
	 * Non-empty sequence of digits
65
	 */
66
	n = 0;
67
	m = ULONG_MAX/base;
68
	for(;; p++,ndig++){
69
		c = *p;
70
		v = base;
71
		if('0'<=c && c<='9')
72
			v = c - '0';
73
		else if('a'<=c && c<='z')
74
			v = c - 'a' + 10;
75
		else if('A'<=c && c<='Z')
76
			v = c - 'A' + 10;
77
		if(v >= base)
78
			break;
79
		if(n > m)
80
			ovfl = 1;
81
		nn = n*base + v;
82
		if(nn < n)
83
			ovfl = 1;
84
		n = nn;
85
	}
86
 
87
    Return:
88
	if(ndig == 0)
89
		p = nptr;
90
	if(endptr)
91
		*endptr = p;
92
	if(ovfl)
93
		return ULONG_MAX;
94
	if(neg)
95
		return -n;
96
	return n;
97
}