Subversion Repositories planix.SVN

Rev

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