28 {
29 const char* s = nptr;
30 unsigned long long acc = 0;
31 int c;
32 unsigned long long cutoff;
33 int cutlim;
34 int any = 0;
35 int negative = 0;
36
37 *overflow = 0;
38
39
41
42
43 if (*s == '-') {
44 negative = 1;
45 s++;
46 } else if (*s == '+') {
47 s++;
48 }
49 if (sign_out) *sign_out = negative;
50
51
52 if ((base == 0 || base == 16) && *s == '0' && (s[1] == 'x' || s[1] == 'X')) {
53
54
56 s += 2;
57 base = 16;
58 } else {
59
60
61 if (base == 0) base = 8;
62 }
63 }
64 if (base == 0) {
65 base = *s == '0' ? 8 : 10;
66 }
67
68 if (base < 2 || base > 36) {
69 if (endptr) *endptr = (char*)nptr;
70 return 0;
71 }
72
73 cutoff = ULLONG_MAX / (unsigned long long)base;
74 cutlim = ULLONG_MAX % (unsigned long long)base;
75
76 for (;; s++) {
77 c = *s;
79 c -= '0';
82 else
83 break;
84
85 if (c >= base) break;
86
87 if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) {
88 any = -1;
89 } else {
90 any = 1;
91 acc = acc * base + c;
92 }
93 }
94
95 if (any < 0) {
96 *overflow = 1;
97 acc = ULLONG_MAX;
98 }
99
100
101 if (endptr) {
102 *endptr = (char*)(any ? s : nptr);
103 }
104 return acc;
105}