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);
|
||||
|
||||
INT __cdecl _wtoi(LPWSTR string);
|
||||
|
||||
/**************************************************************************
|
||||
* DPA_LoadStream [COMCTL32.9]
|
||||
*
|
||||
|
@ -2483,7 +2481,7 @@ COMCTL32_StrToIntA (LPSTR lpString)
|
|||
INT WINAPI
|
||||
COMCTL32_StrToIntW (LPWSTR lpString)
|
||||
{
|
||||
return _wtoi(lpString);
|
||||
return atoiW(lpString);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "ntddk.h"
|
||||
#include "winbase.h"
|
||||
#include "commctrl.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
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++) {
|
||||
ip_addr *= 256;
|
||||
if (GetWindowTextW (infoPtr->Part[i].EditHwnd, field, 4))
|
||||
ip_addr += wcstol(field, 0, 10);
|
||||
ip_addr += atolW(field);
|
||||
else
|
||||
invalid++;
|
||||
}
|
||||
|
@ -320,7 +321,7 @@ static BOOL IPADDRESS_ConstrainField (IPADDRESS_INFO *infoPtr, int currentfield)
|
|||
|
||||
if (!GetWindowTextW (part->EditHwnd, field, 4)) return FALSE;
|
||||
|
||||
curValue = wcstol(field, 0, 10);
|
||||
curValue = atoiW(field);
|
||||
TRACE(" curValue=%d\n", curValue);
|
||||
|
||||
newValue = IPADDRESS_IPNotify(infoPtr, currentfield, curValue);
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "commctrl.h"
|
||||
#include "winnls.h"
|
||||
#include "ntddk.h"
|
||||
#include "wine/unicode.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(updown);
|
||||
|
@ -275,7 +276,7 @@ static BOOL UPDOWN_GetBuddyInt (UPDOWN_INFO *infoPtr)
|
|||
*dst = 0;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -884,7 +884,7 @@ name ntdll
|
|||
@ cdecl _itoa(long ptr long) _itoa
|
||||
@ cdecl _ltoa(long ptr long) _ltoa
|
||||
@ 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 _snwprintf(wstr long wstr) _snwprintf
|
||||
@ cdecl _splitpath(str ptr ptr ptr ptr) _splitpath
|
||||
|
@ -900,8 +900,8 @@ name ntdll
|
|||
@ cdecl _wcslwr(wstr) NTDLL__wcslwr
|
||||
@ cdecl _wcsnicmp(wstr wstr long) NTDLL__wcsnicmp
|
||||
@ cdecl _wcsupr(wstr) NTDLL__wcsupr
|
||||
@ cdecl _wtoi(wstr) _wtoi
|
||||
@ cdecl _wtol(wstr) _wtol
|
||||
@ cdecl _wtoi(wstr) NTDLL__wtoi
|
||||
@ cdecl _wtol(wstr) NTDLL__wtol
|
||||
@ cdecl -noimport abs(long) abs
|
||||
@ cdecl -noimport atan(double) atan
|
||||
@ cdecl -noimport atoi(str) atoi
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
/*********************************************************************
|
||||
* _memicmp (NTDLL.@)
|
||||
*/
|
||||
INT __cdecl _memicmp( LPCSTR s1, LPCSTR s2, DWORD len )
|
||||
INT __cdecl NTDLL__memicmp( LPCSTR s1, LPCSTR s2, DWORD len )
|
||||
{
|
||||
int ret = 0;
|
||||
while (len--)
|
||||
|
|
|
@ -303,51 +303,19 @@ INT __cdecl NTDLL_mbstowcs( LPWSTR dst, LPCSTR src, INT n )
|
|||
|
||||
/*********************************************************************
|
||||
* 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;
|
||||
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;
|
||||
return strtolW( s, end, base );
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* 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;
|
||||
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;
|
||||
return strtoulW( s, end, base );
|
||||
}
|
||||
|
||||
|
||||
|
@ -405,19 +373,17 @@ LPWSTR __cdecl _ultow(ULONG value, LPWSTR string, INT radix)
|
|||
* _wtol (NTDLL.@)
|
||||
* Like atol, but for wide character strings.
|
||||
*/
|
||||
LONG __cdecl _wtol(LPWSTR string)
|
||||
LONG __cdecl NTDLL__wtol(LPWSTR string)
|
||||
{
|
||||
char buffer[30];
|
||||
NTDLL_wcstombs( buffer, string, sizeof(buffer) );
|
||||
return atol( buffer );
|
||||
return strtolW( string, NULL, 10 );
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* _wtoi (NTDLL.@)
|
||||
*/
|
||||
INT __cdecl _wtoi(LPWSTR string)
|
||||
INT __cdecl NTDLL__wtoi(LPWSTR string)
|
||||
{
|
||||
return _wtol(string);
|
||||
return NTDLL__wtol(string);
|
||||
}
|
||||
|
||||
/* INTERNAL: Wide char snprintf
|
||||
|
|
|
@ -6,7 +6,7 @@ MODULE = oleaut32.dll
|
|||
IMPORTS = ole32 user32 gdi32 advapi32 kernel32 ntdll
|
||||
DELAYIMPORTS = comctl32
|
||||
ALTNAMES = ole2disp.dll typelib.dll
|
||||
EXTRALIBS = $(LIBUUID) @JPEGLIB@
|
||||
EXTRALIBS = $(LIBUNICODE) $(LIBUUID) @JPEGLIB@
|
||||
|
||||
LDDLLFLAGS = @LDDLLFLAGS@
|
||||
SYMBOLFILE = $(MODULE).tmp.o
|
||||
|
|
|
@ -70,7 +70,6 @@
|
|||
#include "ole2disp.h"
|
||||
#include "typelib.h"
|
||||
#include "wine/debug.h"
|
||||
#include "ntddk.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
WINE_DECLARE_DEBUG_CHANNEL(typelib);
|
||||
|
@ -287,7 +286,7 @@ HRESULT WINAPI LoadTypeLibEx(
|
|||
/* Look for a trailing '\\' followed by an index */
|
||||
pIndexStr = strrchrW(szFile, '\\');
|
||||
if(pIndexStr && pIndexStr != szFile && *++pIndexStr != '\0') {
|
||||
index = wcstol(pIndexStr, NULL, 10);
|
||||
index = atoiW(pIndexStr);
|
||||
memcpy(szFileCopy, szFile,
|
||||
(pIndexStr - szFile - 1) * sizeof(WCHAR));
|
||||
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)
|
||||
{
|
||||
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 );
|
||||
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) );
|
||||
dirid_str[*len] = 0;
|
||||
dirid = wcstol( dirid_str, &end, 10 );
|
||||
dirid = strtolW( dirid_str, &end, 10 );
|
||||
if (!*end) ret = get_dirid_subst( dirid, len );
|
||||
HeapFree( GetProcessHeap(), 0, dirid_str );
|
||||
return ret;
|
||||
|
|
|
@ -759,7 +759,6 @@ DWORD WINAPI RtlIsTextUnicode(
|
|||
DWORD len,
|
||||
DWORD *pf);
|
||||
|
||||
INT __cdecl wcstol(LPCWSTR,LPWSTR*,INT);
|
||||
int __cdecl swprintf(LPWSTR,LPCWSTR,...);
|
||||
|
||||
/* 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_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 )
|
||||
{
|
||||
return (table->info.char_size == 2) && (table->dbcs.cp2uni_leadbytes[ch]);
|
||||
|
@ -244,8 +250,14 @@ static inline WCHAR *struprW( WCHAR *str )
|
|||
return ret;
|
||||
}
|
||||
|
||||
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 );
|
||||
static inline long int atolW( const WCHAR *str )
|
||||
{
|
||||
return strtolW( str, (WCHAR **)0, 10 );
|
||||
}
|
||||
|
||||
static inline int atoiW( const WCHAR *str )
|
||||
{
|
||||
return (int)atolW( str );
|
||||
}
|
||||
|
||||
#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
|
||||
*/
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "wine/unicode.h"
|
||||
|
||||
int strcmpiW( const WCHAR *str1, const WCHAR *str2 )
|
||||
|
@ -50,3 +52,237 @@ WCHAR *strstrW( const WCHAR *str, const WCHAR *sub )
|
|||
}
|
||||
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