1*c2c66affSColin Finck #include <precomp.h>
2*c2c66affSColin Finck
3*c2c66affSColin Finck
4*c2c66affSColin Finck /*
5*c2c66affSColin Finck * Convert a unicode string to an unsigned long integer.
6*c2c66affSColin Finck *
7*c2c66affSColin Finck * Ignores `locale' stuff. Assumes that the upper and lower case
8*c2c66affSColin Finck * alphabets and digits are each contiguous.
9*c2c66affSColin Finck *
10*c2c66affSColin Finck * @implemented
11*c2c66affSColin Finck */
12*c2c66affSColin Finck unsigned long
13*c2c66affSColin Finck CDECL
wcstoul(const wchar_t * nptr,wchar_t ** endptr,int base)14*c2c66affSColin Finck wcstoul(const wchar_t *nptr, wchar_t **endptr, int base)
15*c2c66affSColin Finck {
16*c2c66affSColin Finck const wchar_t *s = nptr;
17*c2c66affSColin Finck unsigned long acc;
18*c2c66affSColin Finck int c;
19*c2c66affSColin Finck unsigned long cutoff;
20*c2c66affSColin Finck int neg = 0, any, cutlim;
21*c2c66affSColin Finck
22*c2c66affSColin Finck /*
23*c2c66affSColin Finck * See strtol for comments as to the logic used.
24*c2c66affSColin Finck */
25*c2c66affSColin Finck do {
26*c2c66affSColin Finck c = *s++;
27*c2c66affSColin Finck } while (iswctype(c, _SPACE));
28*c2c66affSColin Finck if (c == L'-')
29*c2c66affSColin Finck {
30*c2c66affSColin Finck neg = 1;
31*c2c66affSColin Finck c = *s++;
32*c2c66affSColin Finck }
33*c2c66affSColin Finck else if (c == L'+')
34*c2c66affSColin Finck c = *s++;
35*c2c66affSColin Finck if ((base == 0 || base == 16) &&
36*c2c66affSColin Finck c == L'0' && (*s == L'x' || *s == L'X'))
37*c2c66affSColin Finck {
38*c2c66affSColin Finck c = s[1];
39*c2c66affSColin Finck s += 2;
40*c2c66affSColin Finck base = 16;
41*c2c66affSColin Finck }
42*c2c66affSColin Finck if (base == 0)
43*c2c66affSColin Finck base = c == L'0' ? 8 : 10;
44*c2c66affSColin Finck cutoff = (unsigned long)ULONG_MAX / (unsigned long)base;
45*c2c66affSColin Finck cutlim = (unsigned long)ULONG_MAX % (unsigned long)base;
46*c2c66affSColin Finck for (acc = 0, any = 0;; c = *s++)
47*c2c66affSColin Finck {
48*c2c66affSColin Finck if (iswctype(c, _DIGIT))
49*c2c66affSColin Finck c -= L'0';
50*c2c66affSColin Finck else if (iswctype(c, _ALPHA))
51*c2c66affSColin Finck c -= iswctype(c, _UPPER) ? L'A' - 10 : L'a' - 10;
52*c2c66affSColin Finck else
53*c2c66affSColin Finck break;
54*c2c66affSColin Finck if (c >= base)
55*c2c66affSColin Finck break;
56*c2c66affSColin Finck if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
57*c2c66affSColin Finck any = -1;
58*c2c66affSColin Finck else {
59*c2c66affSColin Finck any = 1;
60*c2c66affSColin Finck acc *= base;
61*c2c66affSColin Finck acc += c;
62*c2c66affSColin Finck }
63*c2c66affSColin Finck }
64*c2c66affSColin Finck if (any < 0)
65*c2c66affSColin Finck {
66*c2c66affSColin Finck acc = ULONG_MAX;
67*c2c66affSColin Finck }
68*c2c66affSColin Finck else if (neg)
69*c2c66affSColin Finck acc = 0-acc;
70*c2c66affSColin Finck if (endptr != 0)
71*c2c66affSColin Finck *endptr = any ? (wchar_t *)((size_t)(s - 1)) : (wchar_t *)((size_t)nptr);
72*c2c66affSColin Finck return acc;
73*c2c66affSColin Finck }
74