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