From: Amine Khaldi Date: Mon, 1 Jun 2015 18:49:52 +0000 (+0000) Subject: [CRT][LIBCNTPR] Adopt strtoul() from Wine Staging 1.7.37. Fixes a msvcrt:string test... X-Git-Tag: backups/colins-printing-for-freedom@73041~15^2~225 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=582fcf61a6f929672f81cc0e6e3756e5bf5838b1 [CRT][LIBCNTPR] Adopt strtoul() from Wine Staging 1.7.37. Fixes a msvcrt:string test. CORE-9246 svn path=/trunk/; revision=67995 --- diff --git a/reactos/lib/sdk/crt/string/strtoul.c b/reactos/lib/sdk/crt/string/strtoul.c index ea463469859..cef232a31f1 100644 --- a/reactos/lib/sdk/crt/string/strtoul.c +++ b/reactos/lib/sdk/crt/string/strtoul.c @@ -1,75 +1,110 @@ #include -#include -/* - * Convert a string to an unsigned long integer. - * - * Ignores `locale' stuff. Assumes that the upper and lower case - * alphabets and digits are each contiguous. +/* Based on Wine Staging 1.7.37 - dlls/msvcrt/string.c */ + +/********************************************************************* + * _strtoi64_l (MSVCRT.@) * - * @implemented + * FIXME: locale parameter is ignored */ -unsigned long -strtoul(const char *nptr, char **endptr, int base) +__int64 CDECL strtoi64_l(const char *nptr, char **endptr, int base, _locale_t locale) { - const char *s = nptr; - unsigned long acc; - int c; - unsigned long cutoff; - int neg = 0, any, cutlim; - - /* - * See strtol for comments as to the logic used. - */ - do { - c = *s++; - } while (isspace(c)); - if (c == '-') - { - neg = 1; - c = *s++; - } - else if (c == '+') - c = *s++; - if ((base == 0 || base == 16) && - c == '0' && (*s == 'x' || *s == 'X')) - { - c = s[1]; - s += 2; - base = 16; - } - if (base == 0) - base = c == '0' ? 8 : 10; - cutoff = (unsigned long)ULONG_MAX / (unsigned long)base; - cutlim = (unsigned long)ULONG_MAX % (unsigned long)base; - for (acc = 0, any = 0;; c = *s++) - { - if (isdigit(c)) - c -= '0'; - else if (isalpha(c)) - c -= isupper(c) ? 'A' - 10 : 'a' - 10; - else - break; - if (c >= base) - break; - if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) - any = -1; - else { - any = 1; - acc *= base; - acc += c; + BOOL negative = FALSE; + __int64 ret = 0; + +#ifndef _LIBCNT_ + TRACE("(%s %p %d %p)\n", debugstr_a(nptr), endptr, base, locale); +#endif + + if (!MSVCRT_CHECK_PMT(nptr != NULL)) return 0; + if (!MSVCRT_CHECK_PMT(base == 0 || base >= 2)) return 0; + if (!MSVCRT_CHECK_PMT(base <= 36)) return 0; + + while(isspace(*nptr)) nptr++; + + if(*nptr == '-') { + negative = TRUE; + nptr++; + } else if(*nptr == '+') + nptr++; + + if((base==0 || base==16) && *nptr=='0' && tolower(*(nptr+1))=='x') { + base = 16; + nptr += 2; + } + + if(base == 0) { + if(*nptr=='0') + base = 8; + else + base = 10; + } + + while(*nptr) { + char cur = tolower(*nptr); + int v; + + if(isdigit(cur)) { + if(cur >= '0'+base) + break; + v = cur-'0'; + } else { + if(cur<'a' || cur>='a'+base-10) + break; + v = cur-'a'+10; + } + + if(negative) + v = -v; + + nptr++; + + if(!negative && (ret>_I64_MAX/base || ret*base>_I64_MAX-v)) { + ret = _I64_MAX; +#ifndef _LIBCNT_ + *_errno() = ERANGE; +#endif + } else if(negative && (ret<_I64_MIN/base || ret*base<_I64_MIN-v)) { + ret = _I64_MIN; +#ifndef _LIBCNT_ + *_errno() = ERANGE; +#endif + } else + ret = ret*base + v; } - } - if (any < 0) - { - acc = ULONG_MAX; + + if(endptr) + *endptr = (char*)nptr; + + return ret; +} + +/****************************************************************** + * _strtoul_l (MSVCRT.@) + */ +unsigned long CDECL strtoul_l(const char* nptr, char** end, int base, _locale_t locale) +{ + __int64 ret = strtoi64_l(nptr, end, base, locale); + + if(ret > ULONG_MAX) { + ret = ULONG_MAX; +#ifndef _LIBCNT_ + *_errno() = ERANGE; +#endif + }else if(ret < -(__int64)ULONG_MAX) { + ret = 1; #ifndef _LIBCNT_ - _set_errno(ERANGE); + *_errno() = ERANGE; #endif - } - else if (neg) - acc = 0-acc; - if (endptr != 0) - *endptr = any ? (char *)((size_t)(s - 1)) : (char *)((size_t)nptr); - return acc; + } + + return ret; +} + +/****************************************************************** + * strtoul (MSVCRT.@) + */ +unsigned long CDECL strtoul(const char* nptr, char** end, int base) +{ + return strtoul_l(nptr, end, base, NULL); } diff --git a/reactos/media/doc/README.WINE b/reactos/media/doc/README.WINE index ba8d6a3609a..d88cd9d9765 100644 --- a/reactos/media/doc/README.WINE +++ b/reactos/media/doc/README.WINE @@ -286,6 +286,7 @@ msvcrt - reactos/lib/sdk/crt/process/_cwait.c # Synced to WineStaging-1.7.37 reactos/lib/sdk/crt/signal/xcptinfo.c # Synced to WineStaging-1.7.37 reactos/lib/sdk/crt/string/scanf.c/h # Synced to Wine-1.7.17 + reactos/lib/sdk/crt/string/strtoul.c # Synced to WineStaging-1.7.37 reactos/lib/sdk/crt/strings/wcs.c # Synced at 20080611 reactos/lib/sdk/crt/wine/heap.c # Synced at 20080529 reactos/lib/sdk/crt/wine/undname.c # Synced at 20081130