Output the extracted number from wxString::ToXXX() even if it returns false.

After the changes in r50710 wxString numeric conversion functions didn't
update their output parameter any more if the conversion failed because not
entire string was converted. This was incompatible with the old behaviour
which some existing code did rely on, so restore it and now always return the
number which was extracted from the beginning of the string if we found
anything at all, even if the function returns false.

Add unit test for the correct behaviour and updated the documentation.

Closes #11126.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@61786 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin 2009-08-30 17:25:19 +00:00
parent 4329eae943
commit 69d31e3130
3 changed files with 38 additions and 16 deletions

View File

@ -884,10 +884,14 @@ public:
@member_group_name{numconv, Conversion to numbers}
The string provides functions for conversion to signed and unsigned integer and
floating point numbers. All functions take a pointer to the variable to
put the numeric value in and return @true if the @b entire string could be
converted to a number.
*/
floating point numbers.
All functions take a pointer to the variable to put the numeric value
in and return @true if the @b entire string could be converted to a
number. Notice if there is a valid number in the beginning of the
string, it is returned in the output parameter even if the function
returns @false because there is more text following it.
*/
//@{
/**
@ -895,7 +899,7 @@ public:
Returns @true on success (the number is stored in the location pointed to by
@a val) or @false if the string does not represent such number (the value of
@a val is not modified in this case).
@a val may still be modified in this case).
Note that unlike ToCDouble() this function uses a localized version of
@c wxStrtod() and thus needs as decimal point (and thousands separator) the
@ -911,6 +915,8 @@ public:
bool ToDouble(double* val) const;
/**
Variant of ToDouble() always working in "C" locale.
Works like ToDouble() but unlike it this function expects the floating point
number to be formatted always with the rules dictated by the "C" locale
(in particular, the decimal point must be a dot), independently from the
@ -925,8 +931,8 @@ public:
Returns @true on success in which case the number is stored in the location
pointed to by @a val or @false if the string does not represent a
valid number in the given base (the value of @a val is not modified
in this case).
valid number in the given base (the value of @a val may still be
modified in this case).
The value of @a base must be comprised between 2 and 36, inclusive, or
be a special value 0 which means that the usual rules of @c C numbers are
@ -949,6 +955,8 @@ public:
bool ToLong(long* val, int base = 10) const;
/**
Variant of ToLong() always working in "C" locale.
Works like ToLong() but unlike it this function expects the integer
number to be formatted always with the rules dictated by the "C" locale,
independently from the current application-wide locale (see wxLocale).
@ -973,8 +981,8 @@ public:
Returns @true on success in which case the number is stored in the
location pointed to by @a val or @false if the string does not
represent a valid number in the given base (the value of @a val is not
modified in this case).
represent a valid number in the given base (the value of @a val may
still be modified in this case).
Please notice that this function behaves in the same way as the standard
@c strtoul() and so it simply converts negative numbers to unsigned
@ -988,6 +996,8 @@ public:
bool ToULong(unsigned long* val, int base = 10) const;
/**
Variant of ToULong() always working in "C" locale.
Works like ToULong() but unlike it this function expects the integer
number to be formatted always with the rules dictated by the "C" locale,
independently from the current application-wide locale (see wxLocale).
@ -997,8 +1007,9 @@ public:
bool ToCULong(unsigned long* val, int base = 10) const;
/**
This is exactly the same as ToULong() but works with 64
bit integer numbers.
This is exactly the same as ToULong() but works with 64 bit integer
numbers.
Please see ToLongLong() for additional remarks.
*/
bool ToULongLong(wxULongLong_t* val, int base = 10) const;

View File

@ -1632,14 +1632,14 @@ int wxString::Find(wxUniChar ch, bool bFromEnd) const
const wxStringCharType *start = wx_str(); \
wxStringCharType *end;
// notice that we return false without modifying the output parameter at all if
// nothing could be parsed but we do modify it and return false then if we did
// parse something successfully but not the entire string
#define WX_STRING_TO_X_TYPE_END \
/* return true only if scan was stopped by the terminating NUL and */ \
/* if the string was not empty to start with and no under/overflow */ \
/* occurred: */ \
if ( *end || end == start DO_IF_NOT_WINCE(|| errno == ERANGE) ) \
if ( end == start DO_IF_NOT_WINCE(|| errno == ERANGE) ) \
return false; \
*pVal = val; \
return true;
return !*end;
bool wxString::ToLong(long *pVal, int base) const
{

View File

@ -602,6 +602,17 @@ void StringTestCase::ToLong()
if ( ld.IsOk() )
CPPUNIT_ASSERT_EQUAL( ld.LValue(), l );
}
// special case: check that the output is not modified if the parsing
// failed completely
l = 17;
CPPUNIT_ASSERT( !wxString("foo").ToLong(&l) );
CPPUNIT_ASSERT_EQUAL( 17, l );
// also check that it is modified if we did parse something successfully in
// the beginning of the string
CPPUNIT_ASSERT( !wxString("9 cats").ToLong(&l) );
CPPUNIT_ASSERT_EQUAL( 9, l );
}
void StringTestCase::ToULong()