[crt]
[reactos.git] / reactos / lib / sdk / crt / string / strtoull.c
1 #include <precomp.h>
2
3 unsigned long long
4 strtoull(const char *nptr, char **endptr, int base)
5 {
6 const char *s = nptr;
7 unsigned long long acc;
8 int c;
9 unsigned long long cutoff;
10 int neg = 0, any, cutlim;
11
12 /*
13 * See strtol for comments as to the logic used.
14 */
15 do {
16 c = *s++;
17 } while (isspace(c));
18 if (c == '-')
19 {
20 neg = 1;
21 c = *s++;
22 }
23 else if (c == '+')
24 c = *s++;
25 if ((base == 0 || base == 16) &&
26 c == '0' && (*s == 'x' || *s == 'X'))
27 {
28 c = s[1];
29 s += 2;
30 base = 16;
31 }
32 if (base == 0)
33 base = c == '0' ? 8 : 10;
34 cutoff = (unsigned long long)ULLONG_MAX / (unsigned long long)base;
35 cutlim = (unsigned long long)ULLONG_MAX % (unsigned long long)base;
36 for (acc = 0, any = 0;; c = *s++)
37 {
38 if (isdigit(c))
39 c -= '0';
40 else if (isalpha(c))
41 c -= isupper(c) ? 'A' - 10 : 'a' - 10;
42 else
43 break;
44 if (c >= base)
45 break;
46 if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
47 any = -1;
48 else {
49 any = 1;
50 acc *= base;
51 acc += c;
52 }
53 }
54 if (any < 0)
55 {
56 acc = ULLONG_MAX;
57 #ifndef _LIBCNT_
58 _set_errno(ERANGE);
59 #endif
60 }
61 else if (neg)
62 acc = 0-acc;
63 if (endptr != 0)
64 *endptr = any ? (char *)((size_t)(s - 1)) : (char *)((size_t)nptr);
65 return acc;
66 }