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
strtoll(char * nptr,char ** endptr,int base)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 }
104