xref: /reactos/sdk/lib/crt/string/strtoi64.c (revision c2c66aff)
1*c2c66affSColin Finck #include <precomp.h>
2*c2c66affSColin Finck 
3*c2c66affSColin Finck /* Based on Wine Staging 1.9.9 - dlls/msvcrt/string.c */
4*c2c66affSColin Finck 
5*c2c66affSColin Finck /*********************************************************************
6*c2c66affSColin Finck *  _strtoi64_l (MSVCRT.@)
7*c2c66affSColin Finck *
8*c2c66affSColin Finck * FIXME: locale parameter is ignored
9*c2c66affSColin Finck */
_strtoi64_l(const char * nptr,char ** endptr,int base,_locale_t locale)10*c2c66affSColin Finck __int64 CDECL _strtoi64_l(const char *nptr, char **endptr, int base, _locale_t locale)
11*c2c66affSColin Finck {
12*c2c66affSColin Finck     const char *p = nptr;
13*c2c66affSColin Finck     BOOL negative = FALSE;
14*c2c66affSColin Finck     BOOL got_digit = FALSE;
15*c2c66affSColin Finck     __int64 ret = 0;
16*c2c66affSColin Finck 
17*c2c66affSColin Finck #ifndef _LIBCNT_
18*c2c66affSColin Finck     TRACE("(%s %p %d %p)\n", debugstr_a(nptr), endptr, base, locale);
19*c2c66affSColin Finck #endif
20*c2c66affSColin Finck 
21*c2c66affSColin Finck #ifndef __REACTOS__
22*c2c66affSColin Finck     if (!MSVCRT_CHECK_PMT(nptr != NULL)) return 0;
23*c2c66affSColin Finck #endif
24*c2c66affSColin Finck     if (!MSVCRT_CHECK_PMT(base == 0 || base >= 2)) return 0;
25*c2c66affSColin Finck     if (!MSVCRT_CHECK_PMT(base <= 36)) return 0;
26*c2c66affSColin Finck 
27*c2c66affSColin Finck     while (isspace(*nptr)) nptr++;
28*c2c66affSColin Finck 
29*c2c66affSColin Finck     if(*nptr == '-') {
30*c2c66affSColin Finck         negative = TRUE;
31*c2c66affSColin Finck         nptr++;
32*c2c66affSColin Finck     } else if(*nptr == '+')
33*c2c66affSColin Finck         nptr++;
34*c2c66affSColin Finck 
35*c2c66affSColin Finck     if((base==0 || base==16) && *nptr=='0' && tolower(*(nptr+1))=='x') {
36*c2c66affSColin Finck         base = 16;
37*c2c66affSColin Finck         nptr += 2;
38*c2c66affSColin Finck     }
39*c2c66affSColin Finck 
40*c2c66affSColin Finck     if(base == 0) {
41*c2c66affSColin Finck         if(*nptr=='0')
42*c2c66affSColin Finck             base = 8;
43*c2c66affSColin Finck         else
44*c2c66affSColin Finck             base = 10;
45*c2c66affSColin Finck     }
46*c2c66affSColin Finck 
47*c2c66affSColin Finck     while(*nptr) {
48*c2c66affSColin Finck         char cur = tolower(*nptr);
49*c2c66affSColin Finck         int v;
50*c2c66affSColin Finck 
51*c2c66affSColin Finck         if(isdigit(cur)) {
52*c2c66affSColin Finck             if(cur >= '0'+base)
53*c2c66affSColin Finck                 break;
54*c2c66affSColin Finck             v = cur-'0';
55*c2c66affSColin Finck         } else {
56*c2c66affSColin Finck             if(cur<'a' || cur>='a'+base-10)
57*c2c66affSColin Finck                 break;
58*c2c66affSColin Finck             v = cur-'a'+10;
59*c2c66affSColin Finck         }
60*c2c66affSColin Finck         got_digit = TRUE;
61*c2c66affSColin Finck 
62*c2c66affSColin Finck         if(negative)
63*c2c66affSColin Finck             v = -v;
64*c2c66affSColin Finck 
65*c2c66affSColin Finck         nptr++;
66*c2c66affSColin Finck 
67*c2c66affSColin Finck         if(!negative && (ret>_I64_MAX/base || ret*base>_I64_MAX-v)) {
68*c2c66affSColin Finck             ret = _I64_MAX;
69*c2c66affSColin Finck #ifndef _LIBCNT_
70*c2c66affSColin Finck             *_errno() = ERANGE;
71*c2c66affSColin Finck #endif
72*c2c66affSColin Finck         }
73*c2c66affSColin Finck         else if (negative && (ret<_I64_MIN / base || ret*base<_I64_MIN - v)) {
74*c2c66affSColin Finck             ret = _I64_MIN;
75*c2c66affSColin Finck #ifndef _LIBCNT_
76*c2c66affSColin Finck             *_errno() = ERANGE;
77*c2c66affSColin Finck #endif
78*c2c66affSColin Finck         }
79*c2c66affSColin Finck         else
80*c2c66affSColin Finck             ret = ret*base + v;
81*c2c66affSColin Finck     }
82*c2c66affSColin Finck 
83*c2c66affSColin Finck     if(endptr)
84*c2c66affSColin Finck         *endptr = (char*)(got_digit ? nptr : p);
85*c2c66affSColin Finck 
86*c2c66affSColin Finck     return ret;
87*c2c66affSColin Finck }
88*c2c66affSColin Finck 
89*c2c66affSColin Finck __int64
_strtoi64(const char * nptr,char ** endptr,int base)90*c2c66affSColin Finck _strtoi64(const char *nptr, char **endptr, int base)
91*c2c66affSColin Finck {
92*c2c66affSColin Finck     return _strtoi64_l(nptr, endptr, base, NULL);
93*c2c66affSColin Finck }
94*c2c66affSColin Finck 
95*c2c66affSColin Finck 
96*c2c66affSColin Finck /* EOF */
97