Use free Windows DDK and compile with latest MinGW releases.
[reactos.git] / reactos / lib / msvcrt / stdlib / strtoll.c
1 /* Copyright (C) 1996 DJ Delorie, see COPYING.DJ for details */
2 /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
3 #include <msvcrti.h>
4
5
6 /* constants used in Solaris */
7 #define LLONG_MIN -9223372036854775807L-1L
8 #define LLONG_MAX 9223372036854775807L
9 #define ULLONG_MAX 18446744073709551615UL
10
11 long
12 strtoll(const char *nptr, char **endptr, int base)
13 {
14 const char *s = nptr;
15 unsigned long acc;
16 int c;
17 unsigned long cutoff;
18 int neg = 0, any, cutlim;
19
20 /*
21 * See strtol for comments as to the logic used.
22 */
23 do {
24 c = *s++;
25 } while (isspace(c));
26 if (c == '-')
27 {
28 neg = 1;
29 c = *s++;
30 }
31 else if (c == '+')
32 c = *s++;
33 if ((base == 0 || base == 16) &&
34 c == '0' && (*s == 'x' || *s == 'X'))
35 {
36 c = s[1];
37 s += 2;
38 base = 16;
39 }
40 if (base == 0)
41 base = c == '0' ? 8 : 10;
42
43 /* to prevent overflow, we take max-1 and add 1 after division */
44 cutoff = neg ? -(LLONG_MIN+1) : LLONG_MAX-1;
45 cutlim = cutoff % base;
46 cutoff /= base;
47 if (++cutlim == base)
48 {
49 cutlim = 0;
50 cutoff++;
51 }
52 for (acc = 0, any = 0;; c = *s++)
53 {
54 if (isdigit(c))
55 c -= '0';
56 else if (isalpha(c))
57 c -= isupper(c) ? 'A' - 10 : 'a' - 10;
58 else
59 break;
60 if (c >= base)
61 break;
62 if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
63 any = -1;
64 else
65 {
66 any = 1;
67 acc *= base;
68 acc += c;
69 }
70 }
71 if (any < 0)
72 {
73 acc = neg ? LLONG_MIN : LLONG_MAX;
74 errno = ERANGE;
75 }
76 else if (neg)
77 acc *= -1;
78 if (endptr != 0)
79 *endptr = any ? (char *)s - 1 : (char *)nptr;
80 return acc;
81 }