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 UVLONG_MAX	(1LL<<63)
5
 
6
uvlong
7
strtoull(char *nptr, char **endptr, int base)
8
{
9
	char *p;
10
	uvlong n, nn, m;
11
	int c, ovfl, v, neg, 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
		base = 10;
47
		if(*p == '0') {
48
			base = 8;
49
			if(p[1] == 'x' || p[1] == 'X'){
50
				p += 2;
51
				base = 16;
52
			}
53
		}
54
	} else
55
	if(base == 16 && *p == '0') {
56
		if(p[1] == 'x' || p[1] == 'X')
57
			p += 2;
58
	} else
59
	if(base < 0 || 36 < base)
60
		goto Return;
61
 
62
	/*
63
	 * Non-empty sequence of digits
64
	 */
65
	m = UVLONG_MAX/base;
66
	for(;; p++,ndig++) {
67
		c = *p;
68
		v = base;
69
		if('0' <= c && c <= '9')
70
			v = c - '0';
71
		else
72
		if('a' <= c && c <= 'z')
73
			v = c - 'a' + 10;
74
		else
75
		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 UVLONG_MAX;
94
	if(neg)
95
		return -n;
96
	return n;
97
}