Implemented strtolW/strtoulW in libwine_unicode and used it to replace
wcstol and friends.
This commit is contained in:
parent
1f18f61bfa
commit
9b6f433ebb
|
@ -67,8 +67,6 @@ typedef struct _LOADDATA
|
||||||
|
|
||||||
typedef HRESULT (CALLBACK *DPALOADPROC)(LPLOADDATA,IStream*,LPARAM);
|
typedef HRESULT (CALLBACK *DPALOADPROC)(LPLOADDATA,IStream*,LPARAM);
|
||||||
|
|
||||||
INT __cdecl _wtoi(LPWSTR string);
|
|
||||||
|
|
||||||
/**************************************************************************
|
/**************************************************************************
|
||||||
* DPA_LoadStream [COMCTL32.9]
|
* DPA_LoadStream [COMCTL32.9]
|
||||||
*
|
*
|
||||||
|
@ -2483,7 +2481,7 @@ COMCTL32_StrToIntA (LPSTR lpString)
|
||||||
INT WINAPI
|
INT WINAPI
|
||||||
COMCTL32_StrToIntW (LPWSTR lpString)
|
COMCTL32_StrToIntW (LPWSTR lpString)
|
||||||
{
|
{
|
||||||
return _wtoi(lpString);
|
return atoiW(lpString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "ntddk.h"
|
#include "ntddk.h"
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "commctrl.h"
|
#include "commctrl.h"
|
||||||
|
#include "wine/unicode.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(ipaddress);
|
WINE_DEFAULT_DEBUG_CHANNEL(ipaddress);
|
||||||
|
@ -237,7 +238,7 @@ static int IPADDRESS_GetAddress (IPADDRESS_INFO *infoPtr, LPDWORD ip_address)
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
ip_addr *= 256;
|
ip_addr *= 256;
|
||||||
if (GetWindowTextW (infoPtr->Part[i].EditHwnd, field, 4))
|
if (GetWindowTextW (infoPtr->Part[i].EditHwnd, field, 4))
|
||||||
ip_addr += wcstol(field, 0, 10);
|
ip_addr += atolW(field);
|
||||||
else
|
else
|
||||||
invalid++;
|
invalid++;
|
||||||
}
|
}
|
||||||
|
@ -320,7 +321,7 @@ static BOOL IPADDRESS_ConstrainField (IPADDRESS_INFO *infoPtr, int currentfield)
|
||||||
|
|
||||||
if (!GetWindowTextW (part->EditHwnd, field, 4)) return FALSE;
|
if (!GetWindowTextW (part->EditHwnd, field, 4)) return FALSE;
|
||||||
|
|
||||||
curValue = wcstol(field, 0, 10);
|
curValue = atoiW(field);
|
||||||
TRACE(" curValue=%d\n", curValue);
|
TRACE(" curValue=%d\n", curValue);
|
||||||
|
|
||||||
newValue = IPADDRESS_IPNotify(infoPtr, currentfield, curValue);
|
newValue = IPADDRESS_IPNotify(infoPtr, currentfield, curValue);
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "commctrl.h"
|
#include "commctrl.h"
|
||||||
#include "winnls.h"
|
#include "winnls.h"
|
||||||
#include "ntddk.h"
|
#include "ntddk.h"
|
||||||
|
#include "wine/unicode.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(updown);
|
WINE_DEFAULT_DEBUG_CHANNEL(updown);
|
||||||
|
@ -275,7 +276,7 @@ static BOOL UPDOWN_GetBuddyInt (UPDOWN_INFO *infoPtr)
|
||||||
*dst = 0;
|
*dst = 0;
|
||||||
|
|
||||||
/* try to convert the number and validate it */
|
/* try to convert the number and validate it */
|
||||||
newVal = wcstol(txt, &src, infoPtr->Base);
|
newVal = strtolW(txt, &src, infoPtr->Base);
|
||||||
if(*src || !UPDOWN_InBounds (infoPtr, newVal)) return FALSE;
|
if(*src || !UPDOWN_InBounds (infoPtr, newVal)) return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -884,7 +884,7 @@ name ntdll
|
||||||
@ cdecl _itoa(long ptr long) _itoa
|
@ cdecl _itoa(long ptr long) _itoa
|
||||||
@ cdecl _ltoa(long ptr long) _ltoa
|
@ cdecl _ltoa(long ptr long) _ltoa
|
||||||
@ cdecl _memccpy(ptr ptr long long) memccpy
|
@ cdecl _memccpy(ptr ptr long long) memccpy
|
||||||
@ cdecl _memicmp(str str long) _memicmp
|
@ cdecl _memicmp(str str long) NTDLL__memicmp
|
||||||
@ varargs _snprintf(ptr long ptr) snprintf
|
@ varargs _snprintf(ptr long ptr) snprintf
|
||||||
@ varargs _snwprintf(wstr long wstr) _snwprintf
|
@ varargs _snwprintf(wstr long wstr) _snwprintf
|
||||||
@ cdecl _splitpath(str ptr ptr ptr ptr) _splitpath
|
@ cdecl _splitpath(str ptr ptr ptr ptr) _splitpath
|
||||||
|
@ -900,8 +900,8 @@ name ntdll
|
||||||
@ cdecl _wcslwr(wstr) NTDLL__wcslwr
|
@ cdecl _wcslwr(wstr) NTDLL__wcslwr
|
||||||
@ cdecl _wcsnicmp(wstr wstr long) NTDLL__wcsnicmp
|
@ cdecl _wcsnicmp(wstr wstr long) NTDLL__wcsnicmp
|
||||||
@ cdecl _wcsupr(wstr) NTDLL__wcsupr
|
@ cdecl _wcsupr(wstr) NTDLL__wcsupr
|
||||||
@ cdecl _wtoi(wstr) _wtoi
|
@ cdecl _wtoi(wstr) NTDLL__wtoi
|
||||||
@ cdecl _wtol(wstr) _wtol
|
@ cdecl _wtol(wstr) NTDLL__wtol
|
||||||
@ cdecl -noimport abs(long) abs
|
@ cdecl -noimport abs(long) abs
|
||||||
@ cdecl -noimport atan(double) atan
|
@ cdecl -noimport atan(double) atan
|
||||||
@ cdecl -noimport atoi(str) atoi
|
@ cdecl -noimport atoi(str) atoi
|
||||||
|
|
|
@ -29,7 +29,7 @@
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* _memicmp (NTDLL.@)
|
* _memicmp (NTDLL.@)
|
||||||
*/
|
*/
|
||||||
INT __cdecl _memicmp( LPCSTR s1, LPCSTR s2, DWORD len )
|
INT __cdecl NTDLL__memicmp( LPCSTR s1, LPCSTR s2, DWORD len )
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
while (len--)
|
while (len--)
|
||||||
|
|
|
@ -303,51 +303,19 @@ INT __cdecl NTDLL_mbstowcs( LPWSTR dst, LPCSTR src, INT n )
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* wcstol (NTDLL.@)
|
* wcstol (NTDLL.@)
|
||||||
* Like strtol, but for wide character strings.
|
|
||||||
*/
|
*/
|
||||||
INT __cdecl NTDLL_wcstol(LPCWSTR s,LPWSTR *end,INT base)
|
long __cdecl NTDLL_wcstol(LPCWSTR s,LPWSTR *end,INT base)
|
||||||
{
|
{
|
||||||
UNICODE_STRING uni;
|
return strtolW( s, end, base );
|
||||||
ANSI_STRING ansi;
|
|
||||||
INT ret;
|
|
||||||
LPSTR endA;
|
|
||||||
|
|
||||||
RtlInitUnicodeString( &uni, s );
|
|
||||||
RtlUnicodeStringToAnsiString( &ansi, &uni, TRUE );
|
|
||||||
ret = strtol( ansi.Buffer, &endA, base );
|
|
||||||
if (end)
|
|
||||||
{
|
|
||||||
DWORD len;
|
|
||||||
RtlMultiByteToUnicodeSize( &len, ansi.Buffer, endA - ansi.Buffer );
|
|
||||||
*end = (LPWSTR)s + len/sizeof(WCHAR);
|
|
||||||
}
|
|
||||||
RtlFreeAnsiString( &ansi );
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* wcstoul (NTDLL.@)
|
* wcstoul (NTDLL.@)
|
||||||
* Like strtoul, but for wide character strings.
|
|
||||||
*/
|
*/
|
||||||
INT __cdecl NTDLL_wcstoul(LPCWSTR s,LPWSTR *end,INT base)
|
unsigned long __cdecl NTDLL_wcstoul(LPCWSTR s,LPWSTR *end,INT base)
|
||||||
{
|
{
|
||||||
UNICODE_STRING uni;
|
return strtoulW( s, end, base );
|
||||||
ANSI_STRING ansi;
|
|
||||||
INT ret;
|
|
||||||
LPSTR endA;
|
|
||||||
|
|
||||||
RtlInitUnicodeString( &uni, s );
|
|
||||||
RtlUnicodeStringToAnsiString( &ansi, &uni, TRUE );
|
|
||||||
ret = strtoul( ansi.Buffer, &endA, base );
|
|
||||||
if (end)
|
|
||||||
{
|
|
||||||
DWORD len;
|
|
||||||
RtlMultiByteToUnicodeSize( &len, ansi.Buffer, endA - ansi.Buffer );
|
|
||||||
*end = (LPWSTR)s + len/sizeof(WCHAR);
|
|
||||||
}
|
|
||||||
RtlFreeAnsiString( &ansi );
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -405,19 +373,17 @@ LPWSTR __cdecl _ultow(ULONG value, LPWSTR string, INT radix)
|
||||||
* _wtol (NTDLL.@)
|
* _wtol (NTDLL.@)
|
||||||
* Like atol, but for wide character strings.
|
* Like atol, but for wide character strings.
|
||||||
*/
|
*/
|
||||||
LONG __cdecl _wtol(LPWSTR string)
|
LONG __cdecl NTDLL__wtol(LPWSTR string)
|
||||||
{
|
{
|
||||||
char buffer[30];
|
return strtolW( string, NULL, 10 );
|
||||||
NTDLL_wcstombs( buffer, string, sizeof(buffer) );
|
|
||||||
return atol( buffer );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********************************************************************
|
/*********************************************************************
|
||||||
* _wtoi (NTDLL.@)
|
* _wtoi (NTDLL.@)
|
||||||
*/
|
*/
|
||||||
INT __cdecl _wtoi(LPWSTR string)
|
INT __cdecl NTDLL__wtoi(LPWSTR string)
|
||||||
{
|
{
|
||||||
return _wtol(string);
|
return NTDLL__wtol(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* INTERNAL: Wide char snprintf
|
/* INTERNAL: Wide char snprintf
|
||||||
|
|
|
@ -6,7 +6,7 @@ MODULE = oleaut32.dll
|
||||||
IMPORTS = ole32 user32 gdi32 advapi32 kernel32 ntdll
|
IMPORTS = ole32 user32 gdi32 advapi32 kernel32 ntdll
|
||||||
DELAYIMPORTS = comctl32
|
DELAYIMPORTS = comctl32
|
||||||
ALTNAMES = ole2disp.dll typelib.dll
|
ALTNAMES = ole2disp.dll typelib.dll
|
||||||
EXTRALIBS = $(LIBUUID) @JPEGLIB@
|
EXTRALIBS = $(LIBUNICODE) $(LIBUUID) @JPEGLIB@
|
||||||
|
|
||||||
LDDLLFLAGS = @LDDLLFLAGS@
|
LDDLLFLAGS = @LDDLLFLAGS@
|
||||||
SYMBOLFILE = $(MODULE).tmp.o
|
SYMBOLFILE = $(MODULE).tmp.o
|
||||||
|
|
|
@ -70,7 +70,6 @@
|
||||||
#include "ole2disp.h"
|
#include "ole2disp.h"
|
||||||
#include "typelib.h"
|
#include "typelib.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
#include "ntddk.h"
|
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||||
WINE_DECLARE_DEBUG_CHANNEL(typelib);
|
WINE_DECLARE_DEBUG_CHANNEL(typelib);
|
||||||
|
@ -287,7 +286,7 @@ HRESULT WINAPI LoadTypeLibEx(
|
||||||
/* Look for a trailing '\\' followed by an index */
|
/* Look for a trailing '\\' followed by an index */
|
||||||
pIndexStr = strrchrW(szFile, '\\');
|
pIndexStr = strrchrW(szFile, '\\');
|
||||||
if(pIndexStr && pIndexStr != szFile && *++pIndexStr != '\0') {
|
if(pIndexStr && pIndexStr != szFile && *++pIndexStr != '\0') {
|
||||||
index = wcstol(pIndexStr, NULL, 10);
|
index = atoiW(pIndexStr);
|
||||||
memcpy(szFileCopy, szFile,
|
memcpy(szFileCopy, szFile,
|
||||||
(pIndexStr - szFile - 1) * sizeof(WCHAR));
|
(pIndexStr - szFile - 1) * sizeof(WCHAR));
|
||||||
szFileCopy[pIndexStr - szFile - 1] = '\0';
|
szFileCopy[pIndexStr - szFile - 1] = '\0';
|
||||||
|
|
|
@ -315,7 +315,7 @@ static BOOL do_reg_operation( HKEY hkey, const WCHAR *value, INFCONTEXT *context
|
||||||
|
|
||||||
if (type == REG_DWORD)
|
if (type == REG_DWORD)
|
||||||
{
|
{
|
||||||
DWORD dw = str ? wcstol( str, NULL, 16 ) : 0;
|
DWORD dw = str ? strtolW( str, NULL, 16 ) : 0;
|
||||||
TRACE( "setting dword %s to %lx\n", debugstr_w(value), dw );
|
TRACE( "setting dword %s to %lx\n", debugstr_w(value), dw );
|
||||||
RegSetValueExW( hkey, value, 0, type, (BYTE *)&dw, sizeof(dw) );
|
RegSetValueExW( hkey, value, 0, type, (BYTE *)&dw, sizeof(dw) );
|
||||||
}
|
}
|
||||||
|
|
|
@ -327,7 +327,7 @@ static const WCHAR *get_string_subst( struct inf_file *file, const WCHAR *str, u
|
||||||
{
|
{
|
||||||
memcpy( dirid_str, str, *len * sizeof(WCHAR) );
|
memcpy( dirid_str, str, *len * sizeof(WCHAR) );
|
||||||
dirid_str[*len] = 0;
|
dirid_str[*len] = 0;
|
||||||
dirid = wcstol( dirid_str, &end, 10 );
|
dirid = strtolW( dirid_str, &end, 10 );
|
||||||
if (!*end) ret = get_dirid_subst( dirid, len );
|
if (!*end) ret = get_dirid_subst( dirid, len );
|
||||||
HeapFree( GetProcessHeap(), 0, dirid_str );
|
HeapFree( GetProcessHeap(), 0, dirid_str );
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -759,7 +759,6 @@ DWORD WINAPI RtlIsTextUnicode(
|
||||||
DWORD len,
|
DWORD len,
|
||||||
DWORD *pf);
|
DWORD *pf);
|
||||||
|
|
||||||
INT __cdecl wcstol(LPCWSTR,LPWSTR*,INT);
|
|
||||||
int __cdecl swprintf(LPWSTR,LPCWSTR,...);
|
int __cdecl swprintf(LPWSTR,LPCWSTR,...);
|
||||||
|
|
||||||
/* resource functions */
|
/* resource functions */
|
||||||
|
|
|
@ -71,6 +71,12 @@ extern int cp_wcstombs( const union cptable *table, int flags,
|
||||||
extern int utf8_wcstombs( const WCHAR *src, int srclen, char *dst, int dstlen );
|
extern int utf8_wcstombs( const WCHAR *src, int srclen, char *dst, int dstlen );
|
||||||
extern int utf8_mbstowcs( int flags, const char *src, int srclen, WCHAR *dst, int dstlen );
|
extern int utf8_mbstowcs( int flags, const char *src, int srclen, WCHAR *dst, int dstlen );
|
||||||
|
|
||||||
|
extern int strcmpiW( const WCHAR *str1, const WCHAR *str2 );
|
||||||
|
extern int strncmpiW( const WCHAR *str1, const WCHAR *str2, int n );
|
||||||
|
extern WCHAR *strstrW( const WCHAR *str, const WCHAR *sub );
|
||||||
|
extern long int strtolW( const WCHAR *nptr, WCHAR **endptr, int base );
|
||||||
|
extern unsigned long int strtoulW( const WCHAR *nptr, WCHAR **endptr, int base );
|
||||||
|
|
||||||
static inline int is_dbcs_leadbyte( const union cptable *table, unsigned char ch )
|
static inline int is_dbcs_leadbyte( const union cptable *table, unsigned char ch )
|
||||||
{
|
{
|
||||||
return (table->info.char_size == 2) && (table->dbcs.cp2uni_leadbytes[ch]);
|
return (table->info.char_size == 2) && (table->dbcs.cp2uni_leadbytes[ch]);
|
||||||
|
@ -244,8 +250,14 @@ static inline WCHAR *struprW( WCHAR *str )
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int strcmpiW( const WCHAR *str1, const WCHAR *str2 );
|
static inline long int atolW( const WCHAR *str )
|
||||||
extern int strncmpiW( const WCHAR *str1, const WCHAR *str2, int n );
|
{
|
||||||
extern WCHAR *strstrW( const WCHAR *str, const WCHAR *sub );
|
return strtolW( str, (WCHAR **)0, 10 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int atoiW( const WCHAR *str )
|
||||||
|
{
|
||||||
|
return (int)atolW( str );
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* __WINE_UNICODE_H */
|
#endif /* __WINE_UNICODE_H */
|
||||||
|
|
236
unicode/string.c
236
unicode/string.c
|
@ -18,6 +18,8 @@
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#include "wine/unicode.h"
|
#include "wine/unicode.h"
|
||||||
|
|
||||||
int strcmpiW( const WCHAR *str1, const WCHAR *str2 )
|
int strcmpiW( const WCHAR *str1, const WCHAR *str2 )
|
||||||
|
@ -50,3 +52,237 @@ WCHAR *strstrW( const WCHAR *str, const WCHAR *sub )
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* strtolW and strtoulW implementation based on the GNU C library code */
|
||||||
|
/* Copyright (C) 1991,92,94,95,96,97,98,99,2000,2001 Free Software Foundation, Inc. */
|
||||||
|
|
||||||
|
long int strtolW( const WCHAR *nptr, WCHAR **endptr, int base )
|
||||||
|
{
|
||||||
|
int negative;
|
||||||
|
register unsigned long int cutoff;
|
||||||
|
register unsigned int cutlim;
|
||||||
|
register unsigned long int i;
|
||||||
|
register const WCHAR *s;
|
||||||
|
register WCHAR c;
|
||||||
|
const WCHAR *save, *end;
|
||||||
|
int overflow;
|
||||||
|
|
||||||
|
if (base < 0 || base == 1 || base > 36) return 0;
|
||||||
|
|
||||||
|
save = s = nptr;
|
||||||
|
|
||||||
|
/* Skip white space. */
|
||||||
|
while (isspaceW (*s))
|
||||||
|
++s;
|
||||||
|
if (!*s) goto noconv;
|
||||||
|
|
||||||
|
/* Check for a sign. */
|
||||||
|
negative = 0;
|
||||||
|
if (*s == '-')
|
||||||
|
{
|
||||||
|
negative = 1;
|
||||||
|
++s;
|
||||||
|
}
|
||||||
|
else if (*s == '+')
|
||||||
|
++s;
|
||||||
|
|
||||||
|
/* Recognize number prefix and if BASE is zero, figure it out ourselves. */
|
||||||
|
if (*s == '0')
|
||||||
|
{
|
||||||
|
if ((base == 0 || base == 16) && toupperW(s[1]) == 'X')
|
||||||
|
{
|
||||||
|
s += 2;
|
||||||
|
base = 16;
|
||||||
|
}
|
||||||
|
else if (base == 0)
|
||||||
|
base = 8;
|
||||||
|
}
|
||||||
|
else if (base == 0)
|
||||||
|
base = 10;
|
||||||
|
|
||||||
|
/* Save the pointer so we can check later if anything happened. */
|
||||||
|
save = s;
|
||||||
|
end = NULL;
|
||||||
|
|
||||||
|
cutoff = ULONG_MAX / (unsigned long int) base;
|
||||||
|
cutlim = ULONG_MAX % (unsigned long int) base;
|
||||||
|
|
||||||
|
overflow = 0;
|
||||||
|
i = 0;
|
||||||
|
c = *s;
|
||||||
|
for (;c != '\0'; c = *++s)
|
||||||
|
{
|
||||||
|
if (s == end)
|
||||||
|
break;
|
||||||
|
if (c >= '0' && c <= '9')
|
||||||
|
c -= '0';
|
||||||
|
else if (isalphaW (c))
|
||||||
|
c = toupperW (c) - 'A' + 10;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
if ((int) c >= base)
|
||||||
|
break;
|
||||||
|
/* Check for overflow. */
|
||||||
|
if (i > cutoff || (i == cutoff && c > cutlim))
|
||||||
|
overflow = 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i *= (unsigned long int) base;
|
||||||
|
i += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if anything actually happened. */
|
||||||
|
if (s == save)
|
||||||
|
goto noconv;
|
||||||
|
|
||||||
|
/* Store in ENDPTR the address of one character
|
||||||
|
past the last character we converted. */
|
||||||
|
if (endptr != NULL)
|
||||||
|
*endptr = (WCHAR *)s;
|
||||||
|
|
||||||
|
/* Check for a value that is within the range of
|
||||||
|
`unsigned LONG int', but outside the range of `LONG int'. */
|
||||||
|
if (overflow == 0
|
||||||
|
&& i > (negative
|
||||||
|
? -((unsigned long int) (LONG_MIN + 1)) + 1
|
||||||
|
: (unsigned long int) LONG_MAX))
|
||||||
|
overflow = 1;
|
||||||
|
|
||||||
|
if (overflow)
|
||||||
|
{
|
||||||
|
return negative ? LONG_MIN : LONG_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the result of the appropriate sign. */
|
||||||
|
return negative ? -i : i;
|
||||||
|
|
||||||
|
noconv:
|
||||||
|
/* We must handle a special case here: the base is 0 or 16 and the
|
||||||
|
first two characters are '0' and 'x', but the rest are no
|
||||||
|
hexadecimal digits. This is no error case. We return 0 and
|
||||||
|
ENDPTR points to the `x`. */
|
||||||
|
if (endptr != NULL)
|
||||||
|
{
|
||||||
|
if (save - nptr >= 2 && toupperW (save[-1]) == 'X'
|
||||||
|
&& save[-2] == '0')
|
||||||
|
*endptr = (WCHAR *)&save[-1];
|
||||||
|
else
|
||||||
|
/* There was no number to convert. */
|
||||||
|
*endptr = (WCHAR *)nptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned long int strtoulW( const WCHAR *nptr, WCHAR **endptr, int base )
|
||||||
|
{
|
||||||
|
int negative;
|
||||||
|
register unsigned long int cutoff;
|
||||||
|
register unsigned int cutlim;
|
||||||
|
register unsigned long int i;
|
||||||
|
register const WCHAR *s;
|
||||||
|
register WCHAR c;
|
||||||
|
const WCHAR *save, *end;
|
||||||
|
int overflow;
|
||||||
|
|
||||||
|
if (base < 0 || base == 1 || base > 36) return 0;
|
||||||
|
|
||||||
|
save = s = nptr;
|
||||||
|
|
||||||
|
/* Skip white space. */
|
||||||
|
while (isspaceW (*s))
|
||||||
|
++s;
|
||||||
|
if (!*s) goto noconv;
|
||||||
|
|
||||||
|
/* Check for a sign. */
|
||||||
|
negative = 0;
|
||||||
|
if (*s == '-')
|
||||||
|
{
|
||||||
|
negative = 1;
|
||||||
|
++s;
|
||||||
|
}
|
||||||
|
else if (*s == '+')
|
||||||
|
++s;
|
||||||
|
|
||||||
|
/* Recognize number prefix and if BASE is zero, figure it out ourselves. */
|
||||||
|
if (*s == '0')
|
||||||
|
{
|
||||||
|
if ((base == 0 || base == 16) && toupperW(s[1]) == 'X')
|
||||||
|
{
|
||||||
|
s += 2;
|
||||||
|
base = 16;
|
||||||
|
}
|
||||||
|
else if (base == 0)
|
||||||
|
base = 8;
|
||||||
|
}
|
||||||
|
else if (base == 0)
|
||||||
|
base = 10;
|
||||||
|
|
||||||
|
/* Save the pointer so we can check later if anything happened. */
|
||||||
|
save = s;
|
||||||
|
end = NULL;
|
||||||
|
|
||||||
|
cutoff = ULONG_MAX / (unsigned long int) base;
|
||||||
|
cutlim = ULONG_MAX % (unsigned long int) base;
|
||||||
|
|
||||||
|
overflow = 0;
|
||||||
|
i = 0;
|
||||||
|
c = *s;
|
||||||
|
for (;c != '\0'; c = *++s)
|
||||||
|
{
|
||||||
|
if (s == end)
|
||||||
|
break;
|
||||||
|
if (c >= '0' && c <= '9')
|
||||||
|
c -= '0';
|
||||||
|
else if (isalphaW (c))
|
||||||
|
c = toupperW (c) - 'A' + 10;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
if ((int) c >= base)
|
||||||
|
break;
|
||||||
|
/* Check for overflow. */
|
||||||
|
if (i > cutoff || (i == cutoff && c > cutlim))
|
||||||
|
overflow = 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i *= (unsigned long int) base;
|
||||||
|
i += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if anything actually happened. */
|
||||||
|
if (s == save)
|
||||||
|
goto noconv;
|
||||||
|
|
||||||
|
/* Store in ENDPTR the address of one character
|
||||||
|
past the last character we converted. */
|
||||||
|
if (endptr != NULL)
|
||||||
|
*endptr = (WCHAR *)s;
|
||||||
|
|
||||||
|
if (overflow)
|
||||||
|
{
|
||||||
|
return ULONG_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the result of the appropriate sign. */
|
||||||
|
return negative ? -i : i;
|
||||||
|
|
||||||
|
noconv:
|
||||||
|
/* We must handle a special case here: the base is 0 or 16 and the
|
||||||
|
first two characters are '0' and 'x', but the rest are no
|
||||||
|
hexadecimal digits. This is no error case. We return 0 and
|
||||||
|
ENDPTR points to the `x`. */
|
||||||
|
if (endptr != NULL)
|
||||||
|
{
|
||||||
|
if (save - nptr >= 2 && toupperW (save[-1]) == 'X'
|
||||||
|
&& save[-2] == '0')
|
||||||
|
*endptr = (WCHAR *)&save[-1];
|
||||||
|
else
|
||||||
|
/* There was no number to convert. */
|
||||||
|
*endptr = (WCHAR *)nptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue