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