prepare move old cruft
[reactos.git] / reactos / lib / crtdll / old cruft / stdlib / strtoull.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 <limits.h>
4 #include <msvcrt/ctype.h>
5 #include <msvcrt/errno.h>
6 #include <msvcrt/stdlib.h>
7 //#include <msvcrt/unconst.h>
8
9 /*
10 * Convert a string to an unsigned long integer.
11 *
12 * Ignores `locale' stuff. Assumes that the upper and lower case
13 * alphabets and digits are each contiguous.
14 */
15 unsigned long
16 strtoull(const char *nptr, char **endptr, int base)
17 {
18 const char *s = nptr;
19 unsigned long acc;
20 int c;
21 unsigned long cutoff;
22 int neg = 0, any, cutlim;
23
24 /*
25 * See strtol for comments as to the logic used.
26 */
27 do {
28 c = *s++;
29 } while (isspace(c));
30 if (c == '-')
31 {
32 neg = 1;
33 c = *s++;
34 }
35 else if (c == '+')
36 c = *s++;
37 if ((base == 0 || base == 16) &&
38 c == '0' && (*s == 'x' || *s == 'X'))
39 {
40 c = s[1];
41 s += 2;
42 base = 16;
43 }
44 if (base == 0)
45 base = c == '0' ? 8 : 10;
46 cutoff = (unsigned long)ULONG_MAX / base;
47 cutlim = (unsigned long)ULONG_MAX % base;
48 for (acc = 0, any = 0;; c = *s++)
49 {
50 if (isdigit(c))
51 c -= '0';
52 else if (isalpha(c))
53 c -= isupper(c) ? 'A' - 10 : 'a' - 10;
54 else
55 break;
56 if (c >= base)
57 break;
58 if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
59 any = -1;
60 else {
61 any = 1;
62 acc *= base;
63 acc += c;
64 }
65 }
66 if (any < 0)
67 {
68 acc = ULONG_MAX;
69 errno = ERANGE;
70 }
71 else if (neg)
72 acc = -acc;
73 if (endptr != 0)
74 *endptr = any ? (char *)s - 1 : (char *)nptr;
75 return acc;
76 }