abandon attempts to make wxAnyStrPtr behave as bool: user-defined logical operators don't short circuit silently breaking existing code so it is better to not provide them at all; instead simply return bool from the new versions taking wxString::const_iterator; advise to use the new versions in the new code and so in our own files

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@59829 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2009-03-25 09:54:10 +00:00
parent 9c4ae52877
commit c398434d92
7 changed files with 190 additions and 160 deletions

View File

@@ -39,6 +39,9 @@ changes:
the returned string could be NULL and so a separate helper class is used. If the returned string could be NULL and so a separate helper class is used. If
you obtain compilation errors because of this, you can always correct them by you obtain compilation errors because of this, you can always correct them by
explicitly assigning the function return value to a variable of wanted type. explicitly assigning the function return value to a variable of wanted type.
A slightly more intrusive but better solution is to use ParseXXX() version
with wxString::const_iterator output parameter which simply returns bool to
indicate the parsing success.
- Some structure fields which used to be of type "const wxChar *" (such as - Some structure fields which used to be of type "const wxChar *" (such as
wxCmdLineEntryDesc::shortName, longName and description fields) are now of wxCmdLineEntryDesc::shortName, longName and description fields) are now of

View File

@@ -136,13 +136,5 @@ private:
wxDECLARE_NO_ASSIGN_CLASS(wxAnyStrPtr); wxDECLARE_NO_ASSIGN_CLASS(wxAnyStrPtr);
}; };
// at least for VC6 and VC7 these operators are needed too, otherwise boolean
// expressions involving wxAnyStrPtr don't compile because of ambiguity between
// built-in overloads of these operators for (bool, bool/char*/wchar_t*)
inline bool operator||(const wxAnyStrPtr& p, bool v) { return (bool)p || v; }
inline bool operator||(bool v, const wxAnyStrPtr& p) { return v || (bool)p; }
inline bool operator&&(const wxAnyStrPtr& p, bool v) { return (bool)p && v; }
inline bool operator&&(bool v, const wxAnyStrPtr& p) { return v && (bool)p; }
#endif // _WX_ANYSTR_H_ #endif // _WX_ANYSTR_H_

View File

@@ -1099,36 +1099,41 @@ public:
inline wxTimeSpan Subtract(const wxDateTime& dt) const; inline wxTimeSpan Subtract(const wxDateTime& dt) const;
inline wxTimeSpan operator-(const wxDateTime& dt2) const; inline wxTimeSpan operator-(const wxDateTime& dt2) const;
// conversion to/from text: all conversions from text return an object // conversion to/from text
// representing the next character following the date specification (i.e.
// the one where the scan had to stop) or a special NULL-like object
// on failure -- this object is necessary to preserve compatibility with
// the existing code assigning the return value of these functions to
// either char* or wxChar* (new code should treat the return value as bool
// and use end parameter to retrieve the end of the scan)
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
// all conversions functions return true to indicate whether parsing
// succeeded or failed and fill in the provided end iterator, which must
// not be NULL, with the location of the character where the parsing
// stopped (this will be end() of the passed string if everything was
// parsed)
// parse a string in RFC 822 format (found e.g. in mail headers and // parse a string in RFC 822 format (found e.g. in mail headers and
// having the form "Wed, 10 Feb 1999 19:07:07 +0100") // having the form "Wed, 10 Feb 1999 19:07:07 +0100")
wxAnyStrPtr ParseRfc822Date(const wxString& date, bool ParseRfc822Date(const wxString& date,
wxString::const_iterator *end = NULL); wxString::const_iterator *end);
// parse a date/time in the given format (see strptime(3)), fill in // parse a date/time in the given format (see strptime(3)), fill in
// the missing (in the string) fields with the values of dateDef (by // the missing (in the string) fields with the values of dateDef (by
// default, they will not change if they had valid values or will // default, they will not change if they had valid values or will
// default to Today() otherwise) // default to Today() otherwise)
wxAnyStrPtr ParseFormat(const wxString& date, bool ParseFormat(const wxString& date,
const wxString& format = wxDefaultDateTimeFormat, const wxString& format,
const wxDateTime& dateDef = wxDefaultDateTime, const wxDateTime& dateDef,
wxString::const_iterator *end = NULL); wxString::const_iterator *end);
wxAnyStrPtr ParseFormat(const wxString& date, bool ParseFormat(const wxString& date,
const wxString& format, const wxString& format,
wxString::const_iterator *end) wxString::const_iterator *end)
{ {
return ParseFormat(date, format, wxDefaultDateTime, end); return ParseFormat(date, format, wxDefaultDateTime, end);
} }
bool ParseFormat(const wxString& date,
wxString::const_iterator *end)
{
return ParseFormat(date, wxDefaultDateTimeFormat, wxDefaultDateTime, end);
}
// parse a string containing date, time or both in ISO 8601 format // parse a string containing date, time or both in ISO 8601 format
// //
@@ -1136,49 +1141,36 @@ public:
// provide compatibility overloads for them // provide compatibility overloads for them
bool ParseISODate(const wxString& date) bool ParseISODate(const wxString& date)
{ {
// FIXME-VC6: notice that writing "return ParseFormat() && ..." crashes
// VC6 with internal compiler error so don't attempt to
// simplify this code like this
wxString::const_iterator end; wxString::const_iterator end;
if ( !ParseFormat(date, wxS("%Y-%m-%d"), &end) ) return ParseFormat(date, wxS("%Y-%m-%d"), &end) && end == date.end();
return false;
return end == date.end();
} }
bool ParseISOTime(const wxString& time) bool ParseISOTime(const wxString& time)
{ {
wxString::const_iterator end; wxString::const_iterator end;
if ( !ParseFormat(time, wxS("%H:%M:%S"), &end) ) return ParseFormat(time, wxS("%H:%M:%S"), &end) && end == time.end();
return false;
return end == time.end();
} }
bool ParseISOCombined(const wxString& datetime, char sep = 'T') bool ParseISOCombined(const wxString& datetime, char sep = 'T')
{ {
wxString::const_iterator end; wxString::const_iterator end;
const wxString fmt = wxS("%Y-%m-%d") + wxString(sep) + wxS("%H:%M:%S"); const wxString fmt = wxS("%Y-%m-%d") + wxString(sep) + wxS("%H:%M:%S");
if ( !ParseFormat(datetime, fmt, &end) ) return ParseFormat(datetime, fmt, &end) && end == datetime.end();
return false;
return end == datetime.end();
} }
// parse a string containing the date/time in "free" format, this // parse a string containing the date/time in "free" format, this
// function will try to make an educated guess at the string contents // function will try to make an educated guess at the string contents
wxAnyStrPtr ParseDateTime(const wxString& datetime, bool ParseDateTime(const wxString& datetime,
wxString::const_iterator *end = NULL); wxString::const_iterator *end);
// parse a string containing the date only in "free" format (less // parse a string containing the date only in "free" format (less
// flexible than ParseDateTime) // flexible than ParseDateTime)
wxAnyStrPtr ParseDate(const wxString& date, bool ParseDate(const wxString& date,
wxString::const_iterator *end = NULL); wxString::const_iterator *end);
// parse a string containing the time only in "free" format // parse a string containing the time only in "free" format
wxAnyStrPtr ParseTime(const wxString& time, bool ParseTime(const wxString& time,
wxString::const_iterator *end = NULL); wxString::const_iterator *end);
// this function accepts strftime()-like format string (default // this function accepts strftime()-like format string (default
@@ -1203,6 +1195,52 @@ public:
wxString FormatISOCombined(char sep = 'T') const wxString FormatISOCombined(char sep = 'T') const
{ return FormatISODate() + sep + FormatISOTime(); } { return FormatISODate() + sep + FormatISOTime(); }
// backwards compatible versions of the parsing functions: they return an
// object representing the next character following the date specification
// (i.e. the one where the scan had to stop) or a special NULL-like object
// on failure
//
// they're not deprecated because a lot of existing code uses them and
// there is no particular harm in keeping them but you should still prefer
// the versions above in the new code
wxAnyStrPtr ParseRfc822Date(const wxString& date)
{
wxString::const_iterator end;
return ParseRfc822Date(date, &end) ? wxAnyStrPtr(date, end)
: wxAnyStrPtr();
}
wxAnyStrPtr ParseFormat(const wxString& date,
const wxString& format = wxDefaultDateTimeFormat,
const wxDateTime& dateDef = wxDefaultDateTime)
{
wxString::const_iterator end;
return ParseFormat(date, format, dateDef, &end) ? wxAnyStrPtr(date, end)
: wxAnyStrPtr();
}
wxAnyStrPtr ParseDateTime(const wxString& datetime)
{
wxString::const_iterator end;
return ParseDateTime(datetime, &end) ? wxAnyStrPtr(datetime, end)
: wxAnyStrPtr();
}
wxAnyStrPtr ParseDate(const wxString& date)
{
wxString::const_iterator end;
return ParseDate(date, &end) ? wxAnyStrPtr(date, end)
: wxAnyStrPtr();
}
wxAnyStrPtr ParseTime(const wxString& time)
{
wxString::const_iterator end;
return ParseTime(time, &end) ? wxAnyStrPtr(time, end)
: wxAnyStrPtr();
}
// implementation // implementation
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------

View File

@@ -812,8 +812,7 @@ public:
@see Format() @see Format()
*/ */
const char* ParseDate(const wxString& date, bool ParseDate(const wxString& date, wxString::const_iterator *end);
wxString::const_iterator* end = NULL);
/** /**
Parses the string @a datetime containing the date and time in free Parses the string @a datetime containing the date and time in free
@@ -827,8 +826,7 @@ public:
See ParseFormat() for the description of function parameters and return See ParseFormat() for the description of function parameters and return
value. value.
*/ */
const char* ParseDateTime(const wxString& datetime, bool ParseDateTime(const wxString& datetime, wxString::const_iterator *end);
wxString::const_iterator* end = NULL);
/** /**
This function parses the string @a date according to the given This function parses the string @a date according to the given
@@ -849,12 +847,7 @@ public:
@a dateDef. If it is not specified, Today() is used as the default @a dateDef. If it is not specified, Today() is used as the default
date. date.
Notice that the return value of this method is not actually a pointer Example of using this function:
but rather an object of a special proxy class which is convertible to
either @c char* or @c wchar_t* pointer. This is needed for
compatibility with the existing code but the new code should use @a end
parameter instead and just test whether the return value is @NULL or
not, e.g.:
@code @code
wxDateTime dt; wxDateTime dt;
wxString str = "..."; wxString str = "...";
@@ -875,26 +868,32 @@ public:
Used to fill in the date components not specified in the @a date Used to fill in the date components not specified in the @a date
string. string.
@param end @param end
If non-@NULL, will be filled with the iterator pointing to the Will be filled with the iterator pointing to the location where the
location where the parsing stopped. If the entire string was parsing stopped if the function returns @true. If the entire string
consumed, it is set to @c date.end(). was consumed, it is set to @c date.end(). Notice that this argument
must be non-@NULL.
@return @return
Pointer-like object indicating the location where the scan stopped @true if at least part of the string was parsed successfully,
if parsing was successful or @NULL-like otherwise. @false otherwise.
@see Format() @see Format()
*/ */
const char* ParseFormat(const wxString& date, bool ParseFormat(const wxString& date,
const wxString& format = wxDefaultDateTimeFormat, const wxString& format = wxDefaultDateTimeFormat,
const wxDateTime& dateDef = wxDefaultDateTime, const wxDateTime& dateDef = wxDefaultDateTime,
wxString::const_iterator* end = NULL); wxString::const_iterator *end);
/** /**
@overload @overload
*/ */
const char* ParseFormat(const wxString& date, bool ParseFormat(const wxString& date,
const wxString& format = wxDefaultDateTimeFormat, const wxString& format = wxDefaultDateTimeFormat,
wxString::const_iterator* end = NULL); wxString::const_iterator *end);
/**
@overload
*/
bool ParseFormat(const wxString& date, wxString::const_iterator *end);
/** /**
This function parses the string containing the date and time in ISO This function parses the string containing the date and time in ISO
@@ -944,8 +943,7 @@ public:
See ParseFormat() for the description of function parameters and return See ParseFormat() for the description of function parameters and return
value. value.
*/ */
const char* ParseRfc822Date(const wxString& date, bool ParseRfc822Date(const wxString& date, wxString::const_iterator *end);
wxString::const_iterator* end = NULL);
/** /**
This functions is like ParseDateTime(), but only allows the time to be This functions is like ParseDateTime(), but only allows the time to be
@@ -954,8 +952,7 @@ public:
See ParseFormat() for the description of function parameters and return See ParseFormat() for the description of function parameters and return
value. value.
*/ */
const char* ParseTime(const wxString& time, bool ParseTime(const wxString& time, wxString::const_iterator *end);
wxString::const_iterator* end = NULL);
//@} //@}

View File

@@ -869,8 +869,8 @@ int wxCmdLineParser::Parse(bool showUsage)
case wxCMD_LINE_VAL_DATE: case wxCMD_LINE_VAL_DATE:
{ {
wxDateTime dt; wxDateTime dt;
const char *res = dt.ParseDate(value); wxString::const_iterator end;
if ( !res || *res ) if ( !dt.ParseDate(value) || end != value.end() )
{ {
errorMsg << wxString::Format(_("Option '%s': '%s' cannot be converted to a date."), errorMsg << wxString::Format(_("Option '%s': '%s' cannot be converted to a date."),
name.c_str(), value.c_str()) name.c_str(), value.c_str())

View File

@@ -682,7 +682,7 @@ wxString wxDateTime::Format(const wxString& format, const TimeZone& tz) const
// //
// this function is "strict" by design - it must reject anything except true // this function is "strict" by design - it must reject anything except true
// RFC822 time specs. // RFC822 time specs.
wxAnyStrPtr bool
wxDateTime::ParseRfc822Date(const wxString& date, wxString::const_iterator *end) wxDateTime::ParseRfc822Date(const wxString& date, wxString::const_iterator *end)
{ {
wxString::const_iterator p = date.begin(); wxString::const_iterator p = date.begin();
@@ -692,7 +692,7 @@ wxDateTime::ParseRfc822Date(const wxString& date, wxString::const_iterator *end)
const wxString::const_iterator endWday = p + WDAY_LEN; const wxString::const_iterator endWday = p + WDAY_LEN;
const wxString wday(p, endWday); const wxString wday(p, endWday);
if ( GetWeekDayFromName(wday, Name_Abbr, DateLang_English) == Inv_WeekDay ) if ( GetWeekDayFromName(wday, Name_Abbr, DateLang_English) == Inv_WeekDay )
return wxAnyStrPtr(); return false;
//else: ignore week day for now, we could also check that it really //else: ignore week day for now, we could also check that it really
// corresponds to the specified date // corresponds to the specified date
@@ -700,11 +700,11 @@ wxDateTime::ParseRfc822Date(const wxString& date, wxString::const_iterator *end)
// 2. separating comma // 2. separating comma
if ( *p++ != ',' || *p++ != ' ' ) if ( *p++ != ',' || *p++ != ' ' )
return wxAnyStrPtr(); return false;
// 3. day number // 3. day number
if ( !wxIsdigit(*p) ) if ( !wxIsdigit(*p) )
return wxAnyStrPtr(); return false;
wxDateTime_t day = (wxDateTime_t)(*p++ - '0'); wxDateTime_t day = (wxDateTime_t)(*p++ - '0');
if ( wxIsdigit(*p) ) if ( wxIsdigit(*p) )
@@ -714,7 +714,7 @@ wxDateTime::ParseRfc822Date(const wxString& date, wxString::const_iterator *end)
} }
if ( *p++ != ' ' ) if ( *p++ != ' ' )
return wxAnyStrPtr(); return false;
// 4. month name // 4. month name
static const int MONTH_LEN = 3; static const int MONTH_LEN = 3;
@@ -722,20 +722,20 @@ wxDateTime::ParseRfc822Date(const wxString& date, wxString::const_iterator *end)
const wxString monName(p, endMonth); const wxString monName(p, endMonth);
Month mon = GetMonthFromName(monName, Name_Abbr, DateLang_English); Month mon = GetMonthFromName(monName, Name_Abbr, DateLang_English);
if ( mon == Inv_Month ) if ( mon == Inv_Month )
return wxAnyStrPtr(); return false;
p = endMonth; p = endMonth;
if ( *p++ != ' ' ) if ( *p++ != ' ' )
return wxAnyStrPtr(); return false;
// 5. year // 5. year
if ( !wxIsdigit(*p) ) if ( !wxIsdigit(*p) )
return wxAnyStrPtr(); return false;
int year = *p++ - '0'; int year = *p++ - '0';
if ( !wxIsdigit(*p) ) // should have at least 2 digits in the year if ( !wxIsdigit(*p) ) // should have at least 2 digits in the year
return wxAnyStrPtr(); return false;
year *= 10; year *= 10;
year += *p++ - '0'; year += *p++ - '0';
@@ -749,7 +749,7 @@ wxDateTime::ParseRfc822Date(const wxString& date, wxString::const_iterator *end)
if ( !wxIsdigit(*p) ) if ( !wxIsdigit(*p) )
{ {
// no 3 digit years please // no 3 digit years please
return wxAnyStrPtr(); return false;
} }
year *= 10; year *= 10;
@@ -757,30 +757,30 @@ wxDateTime::ParseRfc822Date(const wxString& date, wxString::const_iterator *end)
} }
if ( *p++ != ' ' ) if ( *p++ != ' ' )
return wxAnyStrPtr(); return false;
// 6. time in hh:mm:ss format with seconds being optional // 6. time in hh:mm:ss format with seconds being optional
if ( !wxIsdigit(*p) ) if ( !wxIsdigit(*p) )
return wxAnyStrPtr(); return false;
wxDateTime_t hour = (wxDateTime_t)(*p++ - '0'); wxDateTime_t hour = (wxDateTime_t)(*p++ - '0');
if ( !wxIsdigit(*p) ) if ( !wxIsdigit(*p) )
return wxAnyStrPtr(); return false;
hour *= 10; hour *= 10;
hour = (wxDateTime_t)(hour + (*p++ - '0')); hour = (wxDateTime_t)(hour + (*p++ - '0'));
if ( *p++ != ':' ) if ( *p++ != ':' )
return wxAnyStrPtr(); return false;
if ( !wxIsdigit(*p) ) if ( !wxIsdigit(*p) )
return wxAnyStrPtr(); return false;
wxDateTime_t min = (wxDateTime_t)(*p++ - '0'); wxDateTime_t min = (wxDateTime_t)(*p++ - '0');
if ( !wxIsdigit(*p) ) if ( !wxIsdigit(*p) )
return wxAnyStrPtr(); return false;
min *= 10; min *= 10;
min += (wxDateTime_t)(*p++ - '0'); min += (wxDateTime_t)(*p++ - '0');
@@ -790,19 +790,19 @@ wxDateTime::ParseRfc822Date(const wxString& date, wxString::const_iterator *end)
{ {
p++; p++;
if ( !wxIsdigit(*p) ) if ( !wxIsdigit(*p) )
return wxAnyStrPtr(); return false;
sec = (wxDateTime_t)(*p++ - '0'); sec = (wxDateTime_t)(*p++ - '0');
if ( !wxIsdigit(*p) ) if ( !wxIsdigit(*p) )
return wxAnyStrPtr(); return false;
sec *= 10; sec *= 10;
sec += (wxDateTime_t)(*p++ - '0'); sec += (wxDateTime_t)(*p++ - '0');
} }
if ( *p++ != ' ' ) if ( *p++ != ' ' )
return wxAnyStrPtr(); return false;
// 7. now the interesting part: the timezone // 7. now the interesting part: the timezone
int offset wxDUMMY_INITIALIZE(0); int offset wxDUMMY_INITIALIZE(0);
@@ -812,7 +812,7 @@ wxDateTime::ParseRfc822Date(const wxString& date, wxString::const_iterator *end)
bool plus = *p++ == '+'; bool plus = *p++ == '+';
if ( !wxIsdigit(*p) || !wxIsdigit(*(p + 1)) ) if ( !wxIsdigit(*p) || !wxIsdigit(*(p + 1)) )
return wxAnyStrPtr(); return false;
// hours // hours
@@ -821,7 +821,7 @@ wxDateTime::ParseRfc822Date(const wxString& date, wxString::const_iterator *end)
p += 2; p += 2;
if ( !wxIsdigit(*p) || !wxIsdigit(*(p + 1)) ) if ( !wxIsdigit(*p) || !wxIsdigit(*(p + 1)) )
return wxAnyStrPtr(); return false;
// minutes // minutes
offset += 10*(*p - '0') + (*(p + 1) - '0'); offset += 10*(*p - '0') + (*(p + 1) - '0');
@@ -847,7 +847,7 @@ wxDateTime::ParseRfc822Date(const wxString& date, wxString::const_iterator *end)
}; };
if ( *p < _T('A') || *p > _T('Z') || *p == _T('J') ) if ( *p < _T('A') || *p > _T('Z') || *p == _T('J') )
return wxAnyStrPtr(); return false;
offset = offsets[*p++ - 'A']; offset = offsets[*p++ - 'A'];
} }
@@ -878,7 +878,7 @@ wxDateTime::ParseRfc822Date(const wxString& date, wxString::const_iterator *end)
else if ( tz == _T("PDT") ) else if ( tz == _T("PDT") )
offset = PDT - GMT0; offset = PDT - GMT0;
else else
return wxAnyStrPtr(); return false;
p += tz.length(); p += tz.length();
} }
@@ -895,7 +895,7 @@ wxDateTime::ParseRfc822Date(const wxString& date, wxString::const_iterator *end)
if ( end ) if ( end )
*end = p; *end = p;
return wxAnyStrPtr(date, p); return true;
} }
#ifdef __WINDOWS__ #ifdef __WINDOWS__
@@ -1058,13 +1058,14 @@ static wxString GetLocaleDateFormat()
#endif // __WINDOWS__ #endif // __WINDOWS__
wxAnyStrPtr bool
wxDateTime::ParseFormat(const wxString& date, wxDateTime::ParseFormat(const wxString& date,
const wxString& format, const wxString& format,
const wxDateTime& dateDef, const wxDateTime& dateDef,
wxString::const_iterator *end) wxString::const_iterator *end)
{ {
wxCHECK_MSG( !format.empty(), wxAnyStrPtr(), "format can't be empty" ); wxCHECK_MSG( !format.empty(), false, "format can't be empty" );
wxCHECK_MSG( end, false, "end iterator pointer must be specified" );
wxString str; wxString str;
unsigned long num; unsigned long num;
@@ -1115,7 +1116,7 @@ wxDateTime::ParseFormat(const wxString& date,
if ( *input++ != *fmt ) if ( *input++ != *fmt )
{ {
// no match // no match
return wxAnyStrPtr(); return false;
} }
} }
@@ -1172,7 +1173,7 @@ wxDateTime::ParseFormat(const wxString& date,
if ( wday == Inv_WeekDay ) if ( wday == Inv_WeekDay )
{ {
// no match // no match
return wxAnyStrPtr(); return false;
} }
} }
haveWDay = true; haveWDay = true;
@@ -1190,7 +1191,7 @@ wxDateTime::ParseFormat(const wxString& date,
if ( mon == Inv_Month ) if ( mon == Inv_Month )
{ {
// no match // no match
return wxAnyStrPtr(); return false;
} }
} }
haveMon = true; haveMon = true;
@@ -1229,7 +1230,7 @@ wxDateTime::ParseFormat(const wxString& date,
wxS("%X %x") wxS("%X %x")
); );
if ( !dt.IsValid() ) if ( !dt.IsValid() )
return wxAnyStrPtr(); return false;
Tm tm = dt.GetTm(); Tm tm = dt.GetTm();
@@ -1252,7 +1253,7 @@ wxDateTime::ParseFormat(const wxString& date,
(num > 31) || (num < 1) ) (num > 31) || (num < 1) )
{ {
// no match // no match
return wxAnyStrPtr(); return false;
} }
// we can't check whether the day range is correct yet, will // we can't check whether the day range is correct yet, will
@@ -1265,7 +1266,7 @@ wxDateTime::ParseFormat(const wxString& date,
if ( !GetNumericToken(width, input, &num) || (num > 23) ) if ( !GetNumericToken(width, input, &num) || (num > 23) )
{ {
// no match // no match
return wxAnyStrPtr(); return false;
} }
haveHour = true; haveHour = true;
@@ -1276,7 +1277,7 @@ wxDateTime::ParseFormat(const wxString& date,
if ( !GetNumericToken(width, input, &num) || !num || (num > 12) ) if ( !GetNumericToken(width, input, &num) || !num || (num > 12) )
{ {
// no match // no match
return wxAnyStrPtr(); return false;
} }
haveHour = true; haveHour = true;
@@ -1288,7 +1289,7 @@ wxDateTime::ParseFormat(const wxString& date,
if ( !GetNumericToken(width, input, &num) || !num || (num > 366) ) if ( !GetNumericToken(width, input, &num) || !num || (num > 366) )
{ {
// no match // no match
return wxAnyStrPtr(); return false;
} }
haveYDay = true; haveYDay = true;
@@ -1297,7 +1298,7 @@ wxDateTime::ParseFormat(const wxString& date,
case _T('l'): // milliseconds (0-999) case _T('l'): // milliseconds (0-999)
if ( !GetNumericToken(width, input, &num) ) if ( !GetNumericToken(width, input, &num) )
return wxAnyStrPtr(); return false;
haveMsec = true; haveMsec = true;
msec = (wxDateTime_t)num; msec = (wxDateTime_t)num;
@@ -1307,7 +1308,7 @@ wxDateTime::ParseFormat(const wxString& date,
if ( !GetNumericToken(width, input, &num) || !num || (num > 12) ) if ( !GetNumericToken(width, input, &num) || !num || (num > 12) )
{ {
// no match // no match
return wxAnyStrPtr(); return false;
} }
haveMon = true; haveMon = true;
@@ -1318,7 +1319,7 @@ wxDateTime::ParseFormat(const wxString& date,
if ( !GetNumericToken(width, input, &num) || (num > 59) ) if ( !GetNumericToken(width, input, &num) || (num > 59) )
{ {
// no match // no match
return wxAnyStrPtr(); return false;
} }
haveMin = true; haveMin = true;
@@ -1338,7 +1339,7 @@ wxDateTime::ParseFormat(const wxString& date,
GetAmPmStrings(&am, &pm); GetAmPmStrings(&am, &pm);
if (am.empty() && pm.empty()) if (am.empty() && pm.empty())
return wxAnyStrPtr(); // no am/pm strings defined return false; // no am/pm strings defined
if ( token.CmpNoCase(pm) == 0 ) if ( token.CmpNoCase(pm) == 0 )
{ {
isPM = true; isPM = true;
@@ -1346,7 +1347,7 @@ wxDateTime::ParseFormat(const wxString& date,
else if ( token.CmpNoCase(am) != 0 ) else if ( token.CmpNoCase(am) != 0 )
{ {
// no match // no match
return wxAnyStrPtr(); return false;
} }
} }
break; break;
@@ -1356,7 +1357,7 @@ wxDateTime::ParseFormat(const wxString& date,
wxDateTime dt; wxDateTime dt;
if ( !dt.ParseFormat(wxString(input, date.end()), if ( !dt.ParseFormat(wxString(input, date.end()),
wxS("%I:%M:%S %p"), &input) ) wxS("%I:%M:%S %p"), &input) )
return wxAnyStrPtr(); return false;
haveHour = haveMin = haveSec = true; haveHour = haveMin = haveSec = true;
@@ -1372,7 +1373,7 @@ wxDateTime::ParseFormat(const wxString& date,
const wxDateTime const wxDateTime
dt = ParseFormatAt(input, date.end(), wxS("%H:%M")); dt = ParseFormatAt(input, date.end(), wxS("%H:%M"));
if ( !dt.IsValid() ) if ( !dt.IsValid() )
return wxAnyStrPtr(); return false;
haveHour = haveHour =
haveMin = true; haveMin = true;
@@ -1387,7 +1388,7 @@ wxDateTime::ParseFormat(const wxString& date,
if ( !GetNumericToken(width, input, &num) || (num > 61) ) if ( !GetNumericToken(width, input, &num) || (num > 61) )
{ {
// no match // no match
return wxAnyStrPtr(); return false;
} }
haveSec = true; haveSec = true;
@@ -1399,7 +1400,7 @@ wxDateTime::ParseFormat(const wxString& date,
const wxDateTime const wxDateTime
dt = ParseFormatAt(input, date.end(), wxS("%H:%M:%S")); dt = ParseFormatAt(input, date.end(), wxS("%H:%M:%S"));
if ( !dt.IsValid() ) if ( !dt.IsValid() )
return wxAnyStrPtr(); return false;
haveHour = haveHour =
haveMin = haveMin =
@@ -1416,7 +1417,7 @@ wxDateTime::ParseFormat(const wxString& date,
if ( !GetNumericToken(width, input, &num) || (wday > 6) ) if ( !GetNumericToken(width, input, &num) || (wday > 6) )
{ {
// no match // no match
return wxAnyStrPtr(); return false;
} }
haveWDay = true; haveWDay = true;
@@ -1472,7 +1473,7 @@ wxDateTime::ParseFormat(const wxString& date,
dt = ParseFormatAt(input, date.end(), dt = ParseFormatAt(input, date.end(),
fmtDate, fmtDateAlt); fmtDate, fmtDateAlt);
if ( !dt.IsValid() ) if ( !dt.IsValid() )
return wxAnyStrPtr(); return false;
Tm tm = dt.GetTm(); Tm tm = dt.GetTm();
@@ -1493,7 +1494,7 @@ wxDateTime::ParseFormat(const wxString& date,
// use strptime() to do it for us (FIXME !Unicode friendly) // use strptime() to do it for us (FIXME !Unicode friendly)
struct tm tm; struct tm tm;
if ( !CallStrptime(date, input, "%X", &tm) ) if ( !CallStrptime(date, input, "%X", &tm) )
return wxAnyStrPtr(); return false;
haveHour = haveMin = haveSec = true; haveHour = haveMin = haveSec = true;
@@ -1512,7 +1513,7 @@ wxDateTime::ParseFormat(const wxString& date,
const wxDateTime const wxDateTime
dt = ParseFormatAt(input, date.end(), "%T", "%r"); dt = ParseFormatAt(input, date.end(), "%T", "%r");
if ( !dt.IsValid() ) if ( !dt.IsValid() )
return wxAnyStrPtr(); return false;
haveHour = haveHour =
haveMin = haveMin =
@@ -1530,7 +1531,7 @@ wxDateTime::ParseFormat(const wxString& date,
if ( !GetNumericToken(width, input, &num) || (num > 99) ) if ( !GetNumericToken(width, input, &num) || (num > 99) )
{ {
// no match // no match
return wxAnyStrPtr(); return false;
} }
haveYear = true; haveYear = true;
@@ -1544,7 +1545,7 @@ wxDateTime::ParseFormat(const wxString& date,
if ( !GetNumericToken(width, input, &num) ) if ( !GetNumericToken(width, input, &num) )
{ {
// no match // no match
return wxAnyStrPtr(); return false;
} }
haveYear = true; haveYear = true;
@@ -1559,7 +1560,7 @@ wxDateTime::ParseFormat(const wxString& date,
if ( *input++ != _T('%') ) if ( *input++ != _T('%') )
{ {
// no match // no match
return wxAnyStrPtr(); return false;
} }
break; break;
@@ -1569,7 +1570,7 @@ wxDateTime::ParseFormat(const wxString& date,
// fall through // fall through
default: // not a known format spec default: // not a known format spec
return wxAnyStrPtr(); return false;
} }
} }
@@ -1610,14 +1611,14 @@ wxDateTime::ParseFormat(const wxString& date,
if ( haveDay ) if ( haveDay )
{ {
if ( mday > GetNumberOfDays(tm.mon, tm.year) ) if ( mday > GetNumberOfDays(tm.mon, tm.year) )
return wxAnyStrPtr(); return false;
tm.mday = mday; tm.mday = mday;
} }
else if ( haveYDay ) else if ( haveYDay )
{ {
if ( yday > GetNumberOfDays(tm.year) ) if ( yday > GetNumberOfDays(tm.year) )
return wxAnyStrPtr(); return false;
Tm tm2 = wxDateTime(1, Jan, tm.year).SetToYearDay(yday).GetTm(); Tm tm2 = wxDateTime(1, Jan, tm.year).SetToYearDay(yday).GetTm();
@@ -1656,17 +1657,18 @@ wxDateTime::ParseFormat(const wxString& date,
// finally check that the week day is consistent -- if we had it // finally check that the week day is consistent -- if we had it
if ( haveWDay && GetWeekDay() != wday ) if ( haveWDay && GetWeekDay() != wday )
return wxAnyStrPtr(); return false;
if ( end ) *end = input;
*end = input;
return wxAnyStrPtr(date, input); return true;
} }
wxAnyStrPtr bool
wxDateTime::ParseDateTime(const wxString& date, wxString::const_iterator *end) wxDateTime::ParseDateTime(const wxString& date, wxString::const_iterator *end)
{ {
wxCHECK_MSG( end, false, "end iterator pointer must be specified" );
// Set to current day and hour, so strings like '14:00' becomes today at // Set to current day and hour, so strings like '14:00' becomes today at
// 14, not some other random date // 14, not some other random date
wxDateTime dtDate = wxDateTime::Today(); wxDateTime dtDate = wxDateTime::Today();
@@ -1687,7 +1689,7 @@ wxDateTime::ParseDateTime(const wxString& date, wxString::const_iterator *end)
const wxString timestr(endDate, date.end()); const wxString timestr(endDate, date.end());
if ( !dtTime.ParseTime(timestr, &endTime) ) if ( !dtTime.ParseTime(timestr, &endTime) )
return wxAnyStrPtr(); return false;
endBoth = endDate + (endTime - timestr.begin()); endBoth = endDate + (endTime - timestr.begin());
} }
@@ -1695,14 +1697,14 @@ wxDateTime::ParseDateTime(const wxString& date, wxString::const_iterator *end)
{ {
// check if we have a time followed by a date // check if we have a time followed by a date
if ( !dtTime.ParseTime(date, &endTime) ) if ( !dtTime.ParseTime(date, &endTime) )
return wxAnyStrPtr(); return false;
while ( endTime != date.end() && wxIsspace(*endTime) ) while ( endTime != date.end() && wxIsspace(*endTime) )
++endTime; ++endTime;
const wxString datestr(endTime, date.end()); const wxString datestr(endTime, date.end());
if ( !dtDate.ParseDate(datestr, &endDate) ) if ( !dtDate.ParseDate(datestr, &endDate) )
return wxAnyStrPtr(); return false;
endBoth = endTime + (endDate - datestr.begin()); endBoth = endTime + (endDate - datestr.begin());
} }
@@ -1711,16 +1713,16 @@ wxDateTime::ParseDateTime(const wxString& date, wxString::const_iterator *end)
dtTime.GetHour(), dtTime.GetMinute(), dtTime.GetSecond(), dtTime.GetHour(), dtTime.GetMinute(), dtTime.GetSecond(),
dtTime.GetMillisecond()); dtTime.GetMillisecond());
// Return endpoint of scan *end = endBoth;
if ( end )
*end = endBoth;
return wxAnyStrPtr(date, endBoth); return true;
} }
wxAnyStrPtr bool
wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end) wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end)
{ {
wxCHECK_MSG( end, false, "end iterator pointer must be specified" );
// this is a simplified version of ParseDateTime() which understands only // this is a simplified version of ParseDateTime() which understands only
// "today" (for wxDate compatibility) and digits only otherwise (and not // "today" (for wxDate compatibility) and digits only otherwise (and not
// all esoteric constructions ParseDateTime() knows about) // all esoteric constructions ParseDateTime() knows about)
@@ -1762,10 +1764,9 @@ wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end)
*this += wxDateSpan::Days(dayDiffFromToday); *this += wxDateSpan::Days(dayDiffFromToday);
} }
if ( end ) *end = pEnd;
*end = pEnd;
return wxAnyStrPtr(date, pEnd); return true;
} }
} }
@@ -1986,7 +1987,7 @@ wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end)
// either no more tokens or the scan was stopped by something we couldn't // either no more tokens or the scan was stopped by something we couldn't
// parse - in any case, see if we can construct a date from what we have // parse - in any case, see if we can construct a date from what we have
if ( !haveDay && !haveWDay ) if ( !haveDay && !haveWDay )
return wxAnyStrPtr(); return false;
if ( haveWDay && (haveMon || haveYear || haveDay) && if ( haveWDay && (haveMon || haveYear || haveDay) &&
!(haveDay && haveMon && haveYear) ) !(haveDay && haveMon && haveYear) )
@@ -1994,7 +1995,7 @@ wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end)
// without adjectives (which we don't support here) the week day only // without adjectives (which we don't support here) the week day only
// makes sense completely separately or with the full date // makes sense completely separately or with the full date
// specification (what would "Wed 1999" mean?) // specification (what would "Wed 1999" mean?)
return wxAnyStrPtr(); return false;
} }
if ( !haveWDay && haveYear && !(haveDay && haveMon) ) if ( !haveWDay && haveYear && !(haveDay && haveMon) )
@@ -2020,7 +2021,7 @@ wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end)
} }
if ( !haveMon ) if ( !haveMon )
return wxAnyStrPtr(); return false;
} }
if ( !haveMon ) if ( !haveMon )
@@ -2038,7 +2039,7 @@ wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end)
// normally we check the day above but the check is optimistic in case // normally we check the day above but the check is optimistic in case
// we find the day before its month/year so we have to redo it now // we find the day before its month/year so we have to redo it now
if ( day > GetNumberOfDays(mon, year) ) if ( day > GetNumberOfDays(mon, year) )
return wxAnyStrPtr(); return false;
Set(day, mon, year); Set(day, mon, year);
@@ -2046,7 +2047,7 @@ wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end)
{ {
// check that it is really the same // check that it is really the same
if ( GetWeekDay() != wday ) if ( GetWeekDay() != wday )
return wxAnyStrPtr(); return false;
} }
} }
else // haveWDay else // haveWDay
@@ -2065,15 +2066,16 @@ wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end)
p--; p--;
} }
if ( end ) *end = p;
*end = p;
return wxAnyStrPtr(date, p); return true;
} }
wxAnyStrPtr bool
wxDateTime::ParseTime(const wxString& time, wxString::const_iterator *end) wxDateTime::ParseTime(const wxString& time, wxString::const_iterator *end)
{ {
wxCHECK_MSG( end, false, "end iterator pointer must be specified" );
// first try some extra things // first try some extra things
static const struct static const struct
{ {
@@ -2098,7 +2100,7 @@ wxDateTime::ParseTime(const wxString& time, wxString::const_iterator *end)
if ( end ) if ( end )
*end = p; *end = p;
return wxAnyStrPtr(time, p); return true;
} }
} }
@@ -2118,12 +2120,11 @@ wxDateTime::ParseTime(const wxString& time, wxString::const_iterator *end)
for ( size_t nFmt = 0; nFmt < WXSIZEOF(timeFormats); nFmt++ ) for ( size_t nFmt = 0; nFmt < WXSIZEOF(timeFormats); nFmt++ )
{ {
const wxAnyStrPtr result = ParseFormat(time, timeFormats[nFmt], end); if ( ParseFormat(time, timeFormats[nFmt], end) )
if ( result ) return true;
return result;
} }
return wxAnyStrPtr(); return false;
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -1271,9 +1271,8 @@ bool wxVariantDataDateTime::Read(wxString& str)
return true; return true;
} }
if(! m_value.ParseDateTime(str.c_str()/*FIXME-UTF8*/)) wxString::const_iterator end;
return false; return m_value.ParseDateTime(str, &end) && end == str.end();
return true;
} }
// wxVariant // wxVariant