PLUGINS_INST_DIR = $(libdir)/wx/$(PLUGIN_VERSION0)
ALL_BASE_HEADERS = \
wx/afterstd.h \
+ wx/anystr.h \
wx/app.h \
wx/apptrait.h \
wx/archive.h \
$(ALL_GUI_HEADERS)
ALL_PORTS_BASE_HEADERS = \
wx/afterstd.h \
+ wx/anystr.h \
wx/app.h \
wx/apptrait.h \
wx/archive.h \
</set>
<set var="BASE_CMN_HDR" hints="files">
wx/afterstd.h
+ wx/anystr.h
wx/app.h
wx/apptrait.h
wx/archive.h
# End Source File\r
# Begin Source File\r
\r
+SOURCE=..\..\include\wx\anystr.h\r
+# End Source File\r
+# Begin Source File\r
+\r
SOURCE=..\..\include\wx\app.h\r
# End Source File\r
# Begin Source File\r
<File\r
RelativePath="..\..\include\wx\afterstd.h">\r
</File>\r
+ <File\r
+ RelativePath="..\..\include\wx\anystr.h">\r
+ </File>\r
<File\r
RelativePath="..\..\include\wx\app.h">\r
</File>\r
RelativePath="..\..\include\wx\afterstd.h"\r
>\r
</File>\r
+ <File\r
+ RelativePath="..\..\include\wx\anystr.h"\r
+ >\r
+ </File>\r
<File\r
RelativePath="..\..\include\wx\app.h"\r
>\r
RelativePath="..\..\include\wx\afterstd.h"\r
>\r
</File>\r
+ <File\r
+ RelativePath="..\..\include\wx\anystr.h"\r
+ >\r
+ </File>\r
<File\r
RelativePath="..\..\include\wx\app.h"\r
>\r
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Name: wx/anystr.h
+// Purpose: wxAnyStrPtr class declaration
+// Author: Vadim Zeitlin
+// Created: 2009-03-23
+// RCS-ID: $Id$
+// Copyright: (c) 2008 Vadim Zeitlin <vadim@wxwidgets.org>
+// Licence: wxWindows licence
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_ANYSTR_H_
+#define _WX_ANYSTR_H_
+
+#include "wx/string.h"
+
+// ----------------------------------------------------------------------------
+// wxAnyStrPtr
+//
+// Notice that this is an internal and intentionally not documented class. It
+// is only used by wxWidgets itself to ensure compatibility with previous
+// versions and shouldn't be used by user code. When you see a function
+// returning it you should just know that you can treat it as a string pointer.
+// ----------------------------------------------------------------------------
+
+// This is a helper class convertible to either narrow or wide string pointer.
+// It is similar to wxCStrData but, unlike it, can be NULL which is required to
+// represent the return value of wxDateTime::ParseXXX() methods for example.
+//
+// NB: this class is fully inline and so doesn't need to be DLL-exported
+class wxAnyStrPtr
+{
+public:
+ // ctors: this class must be created from the associated string or using
+ // its default ctor for an invalid NULL-like object; notice that it is
+ // immutable after creation.
+
+ // ctor for invalid pointer
+ wxAnyStrPtr()
+ : m_str(NULL)
+ {
+ }
+
+ // ctor for valid pointer into the given string (whose lifetime must be
+ // greater than ours and which should remain constant while we're used)
+ wxAnyStrPtr(const wxString& str, const wxString::const_iterator& iter)
+ : m_str(&str),
+ m_iter(iter)
+ {
+ }
+
+ // default copy ctor is ok and so is default dtor, in particular we do not
+ // free the string
+
+
+ // various operators meant to make this class look like a superposition of
+ // char* and wchar_t*
+
+ // this one is needed to allow boolean expressions involving these objects,
+ // e.g. "if ( FuncReturningAnyStrPtr() && ... )" (unfortunately using
+ // unspecified_bool_type here wouldn't help with ambiguity between all the
+ // different conversions to pointers)
+ operator bool() const { return m_str != NULL; }
+
+
+ // and these are the conversions operator which allow to assign the result
+ // of FuncReturningAnyStrPtr() to either char* or wxChar* (i.e. wchar_t*)
+ operator const char *() const
+ {
+ if ( !m_str )
+ return NULL;
+
+ // check if the string is convertible to char at all
+ //
+ // notice that this pointer points into wxString internal buffer
+ // containing its char* representation and so it can be kept for as
+ // long as wxString is not modified -- which is long enough for our
+ // needs
+ const char *p = m_str->c_str().AsChar();
+ if ( *p )
+ {
+ // find the offset of the character corresponding to this iterator
+ // position in bytes: we don't have any direct way to do it so we
+ // need to redo the conversion again for the part of the string
+ // before the iterator to find its length in bytes in current
+ // locale
+ //
+ // NB: conversion won't fail as it succeeded for the entire string
+ p += strlen(wxString(m_str->begin(), m_iter).mb_str());
+ }
+ //else: conversion failed, return "" as we can't do anything else
+
+ return p;
+ }
+
+ operator const wchar_t *() const
+ {
+ if ( !m_str )
+ return NULL;
+
+ // no complications with wide strings (as long as we discount
+ // surrogates as we do for now)
+ //
+ // just remember that this works as long as wxString keeps an internal
+ // buffer with its wide wide char representation, just as with AsChar()
+ // above
+ return m_str->c_str().AsWChar() + (m_iter - m_str->begin());
+ }
+
+ // Because the objects of this class are only used as return type for
+ // functions which can return NULL we can skip providing dereferencing
+ // operators: the code using this class must test it for NULL first and if
+ // it does anything else with it it has to assign it to either char* or
+ // wchar_t* itself, before dereferencing.
+ //
+ // IOW this
+ //
+ // if ( *FuncReturningAnyStrPtr() )
+ //
+ // is invalid because it could crash. And this
+ //
+ // const char *p = FuncReturningAnyStrPtr();
+ // if ( p && *p )
+ //
+ // already works fine.
+
+private:
+ // the original string and the offset in it we correspond to, if the string
+ // is NULL this object is NULL pointer-like
+ const wxString * const m_str;
+ const wxString::const_iterator m_iter;
+
+ wxDECLARE_NO_ASSIGN_CLASS(wxAnyStrPtr);
+};
+
+#endif // _WX_ANYSTR_H_
+
#include <limits.h> // for INT_MIN
#include "wx/longlong.h"
+#include "wx/anystr.h"
class WXDLLIMPEXP_FWD_BASE wxDateTime;
class WXDLLIMPEXP_FWD_BASE wxTimeSpan;
inline wxTimeSpan Subtract(const wxDateTime& dt) const;
inline wxTimeSpan operator-(const wxDateTime& dt2) const;
- // conversion to/from text: all conversions from text return the pointer to
- // the next character following the date specification (i.e. the one where
- // the scan had to stop) or NULL on failure; for the versions taking
- // wxString or wxCStrData, we don't know if the user code needs char* or
- // wchar_t* pointer and so we return char* one for compatibility with the
- // existing ANSI code and also return iterator in another output parameter
- // (it will be equal to end if the entire string was parsed)
+ // conversion to/from text: all conversions from text 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 -- 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)
// ------------------------------------------------------------------------
// 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")
- const char *ParseRfc822Date(const wxString& date,
+ wxAnyStrPtr ParseRfc822Date(const wxString& date,
wxString::const_iterator *end = NULL);
- const char *ParseRfc822Date(const wxCStrData& date,
- wxString::const_iterator *end = NULL)
- {
- return ParseRfc822Date(date.AsString(), end);
- }
-
- const wchar_t *ParseRfc822Date(const wchar_t* date)
- {
- return ReturnEndAsWidePtr(&wxDateTime::ParseRfc822Date, date);
- }
-
- const char *ParseRfc822Date(const char* date)
- {
- return ParseRfc822Date(wxString(date));
- }
// 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
// default, they will not change if they had valid values or will
// default to Today() otherwise)
-
- // notice that we unfortunately need all those overloads because we use
- // the type of the date string to select the return value of the
- // function: it's wchar_t if a wide string is passed for compatibility
- // with the code doing "const wxChar *p = dt.ParseFormat(_T("..."))",
- // but char* in all other cases for compatibility with ANSI build which
- // allowed code like "const char *p = dt.ParseFormat("...")"
- //
- // so we need wchar_t overload and now passing s.c_str() as first
- // argument is ambiguous because it's convertible to both wxString and
- // wchar_t* and now it's passing char* which becomes ambiguous as it is
- // convertible to both wxString and wxCStrData hence we need char*
- // overload too
- //
- // and to make our life more miserable we also pay for having the
- // optional dateDef parameter: as it's almost never used, we want to
- // allow people to omit it when specifying the end iterator output
- // parameter but we still have to allow specifying dateDef too, so we
- // need another overload for this
- //
- // FIXME: all this mess could be avoided by using some class similar to
- // wxFormatString, i.e. remembering string [pointer] of any type
- // and convertible to either char* or wchar_t* as wxCStrData and
- // having only 1 (or 2, because of the last paragraph above)
- // overload taking it, see #9560
- const char *ParseFormat(const wxString& date,
+ wxAnyStrPtr ParseFormat(const wxString& date,
const wxString& format = wxDefaultDateTimeFormat,
const wxDateTime& dateDef = wxDefaultDateTime,
wxString::const_iterator *end = NULL);
- const char *ParseFormat(const wxString& date,
+ wxAnyStrPtr ParseFormat(const wxString& date,
const wxString& format,
wxString::const_iterator *end)
{
return ParseFormat(date, format, wxDefaultDateTime, end);
}
- const char *ParseFormat(const wxCStrData& date,
- const wxString& format = wxDefaultDateTimeFormat,
- const wxDateTime& dateDef = wxDefaultDateTime,
- wxString::const_iterator *end = NULL)
- {
- return ParseFormat(date.AsString(), format, dateDef, end);
- }
-
- const wchar_t *ParseFormat(const wchar_t *date,
- const wxString& format = wxDefaultDateTimeFormat,
- const wxDateTime& dateDef = wxDefaultDateTime)
- {
- const wxString datestr(date);
- wxString::const_iterator end;
- if ( !ParseFormat(datestr, format, dateDef, &end) )
- return NULL;
-
- return date + (end - datestr.begin());
- }
-
- const char *ParseFormat(const char *date,
- const wxString& format = "%c",
- const wxDateTime& dateDef = wxDefaultDateTime)
- {
- return ParseFormat(wxString(date), format, dateDef);
- }
-
// parse a string containing date, time or both in ISO 8601 format
//
// parse a string containing the date/time in "free" format, this
// function will try to make an educated guess at the string contents
- const char *ParseDateTime(const wxString& datetime,
+ wxAnyStrPtr ParseDateTime(const wxString& datetime,
wxString::const_iterator *end = NULL);
- const char *ParseDateTime(const wxCStrData& datetime,
- wxString::const_iterator *end = NULL)
- {
- return ParseDateTime(datetime.AsString(), end);
- }
-
- const wchar_t *ParseDateTime(const wchar_t *datetime)
- {
- return ReturnEndAsWidePtr(&wxDateTime::ParseDateTime, datetime);
- }
-
- const char *ParseDateTime(const char *datetime)
- {
- return ParseDateTime(wxString(datetime));
- }
-
// parse a string containing the date only in "free" format (less
// flexible than ParseDateTime)
- const char *ParseDate(const wxString& date,
+ wxAnyStrPtr ParseDate(const wxString& date,
wxString::const_iterator *end = NULL);
- const char *ParseDate(const wxCStrData& date,
- wxString::const_iterator *end = NULL)
- {
- return ParseDate(date.AsString(), end);
- }
-
- const wchar_t *ParseDate(const wchar_t *date)
- {
- return ReturnEndAsWidePtr(&wxDateTime::ParseDate, date);
- }
-
- const char *ParseDate(const char *date)
- {
- return ParseDate(wxString(date));
- }
-
// parse a string containing the time only in "free" format
- const char *ParseTime(const wxString& time,
+ wxAnyStrPtr ParseTime(const wxString& time,
wxString::const_iterator *end = NULL);
- const char *ParseTime(const wxCStrData& time,
- wxString::const_iterator *end = NULL)
- {
- return ParseTime(time.AsString(), end);
- }
-
- const wchar_t *ParseTime(const wchar_t *time)
- {
- return ReturnEndAsWidePtr(&wxDateTime::ParseTime, time);
- }
-
- const char *ParseTime(const char *time)
- {
- return ParseTime(wxString(time));
- }
// this function accepts strftime()-like format string (default
// argument corresponds to the preferred date and time representation
static struct tm *GetTmNow(struct tm *tmstruct);
private:
- // helper function for defining backward-compatible wrappers for code
- // using wchar_t* pointer instead of wxString iterators
- typedef
- const char *(wxDateTime::*StringMethod)(const wxString& s,
- wxString::const_iterator *end);
-
- const wchar_t *ReturnEndAsWidePtr(StringMethod func, const wchar_t *p)
- {
- const wxString s(p);
- wxString::const_iterator end;
- if ( !(this->*func)(s, &end) )
- return NULL;
-
- return p + (end - s.begin());
- }
-
-
// the current country - as it's the same for all program objects (unless
// it runs on a _really_ big cluster system :-), this is a static member:
// see SetCountry() and GetCountry()
/**
This function is like ParseDateTime(), but it only allows the date to
- be specified. It is thus less flexible then ParseDateTime(), but also
- has less chances to misinterpret the user input.
+ be specified.
- @return @NULL if the conversion failed, otherwise return the pointer
- to the character which stopped the scan.
+ It is thus less flexible then ParseDateTime(), but also has less
+ chances to misinterpret the user input.
+
+ See ParseFormat() for the description of function parameters and return
+ value.
@see Format()
*/
const char* ParseDate(const wxString& date,
- wxString::const_iterator* end = NULL);
-
- /**
- @overload
- */
- const char* ParseDate(const char* date);
-
- /**
- @overload
- */
- const wchar_t* ParseDate(const wchar_t* date);
+ wxString::const_iterator* end = NULL);
/**
Parses the string @a datetime containing the date and time in free
- format. This function tries as hard as it can to interpret the given
- string as date and time. Unlike ParseRfc822Date(), it will accept
- anything that may be accepted and will only reject strings which can
- not be parsed in any way at all.
+ format.
- @return @NULL if the conversion failed, otherwise return the pointer
- to the character which stopped the scan.
+ This function tries as hard as it can to interpret the given string as
+ date and time. Unlike ParseRfc822Date(), it will accept anything that
+ may be accepted and will only reject strings which can not be parsed in
+ any way at all.
+
+ See ParseFormat() for the description of function parameters and return
+ value.
*/
const char* ParseDateTime(const wxString& datetime,
wxString::const_iterator* end = NULL);
- /**
- @overload
- */
- const char* ParseDateTime(const char* datetime);
-
- /**
- @overload
- */
- const wchar_t* ParseDateTime(const wchar_t* datetime);
-
/**
This function parses the string @a date according to the given
@e format. The system @c strptime(3) function is used whenever
@a dateDef. If it is not specified, Today() is used as the default
date.
- @return @NULL if the conversion failed, otherwise return the pointer
- to the character which stopped the scan.
+ Notice that the return value of this method is not actually a pointer
+ 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
+ wxDateTime dt;
+ wxString str = "...";
+ wxString::const_iterator end;
+ if ( !dt.ParseFormat(str, "%Y-%m-%d", &end) )
+ ... parsing failed ...
+ else if ( end == str.end() )
+ ... entire string parsed ...
+ else
+ ... wxString(end, str.end()) left over ...
+ @endcode
+
+ @param date
+ The string to be parsed.
+ @param format
+ strptime()-like format string.
+ @param dateDef
+ Used to fill in the date components not specified in the @a date
+ string.
+ @param end
+ If non-@NULL, will be filled with the iterator pointing to the
+ location where the parsing stopped. If the entire string was
+ consumed, it is set to @c date.end().
+ @return
+ Pointer-like object indicating the location where the scan stopped
+ if parsing was successful or @NULL-like otherwise.
@see Format()
*/
/**
@overload
*/
- const char* ParseFormat(const char* date,
+ const char* ParseFormat(const wxString& date,
const wxString& format = wxDefaultDateTimeFormat,
- const wxDateTime& dateDef = wxDefaultDateTime);
-
- /**
- @overload
- */
- const wchar_t* ParseFormat(const wchar_t* date,
- const wxString& format = wxDefaultDateTimeFormat,
- const wxDateTime& dateDef = wxDefaultDateTime);
+ wxString::const_iterator* end = NULL);
/**
This function parses the string containing the date and time in ISO
string which is not RFC 822 compliant. If you need to parse date
formatted in more free ways, you should use ParseDateTime() or
ParseDate() instead.
- */
- const char* ParseRfc822Date(const wxString& date,
- wxString::const_iterator* end = NULL);
-
- /**
- @overload
- */
- const char* ParseRfc822Date(const char* date);
- /**
- @overload
+ See ParseFormat() for the description of function parameters and return
+ value.
*/
- const wchar_t* ParseRfc822Date(const wchar_t* date);
+ const char* ParseRfc822Date(const wxString& date,
+ wxString::const_iterator* end = NULL);
/**
This functions is like ParseDateTime(), but only allows the time to be
specified in the input string.
- @return @NULL if the conversion failed, otherwise return the pointer
- to the character which stopped the scan.
+ See ParseFormat() for the description of function parameters and return
+ value.
*/
const char* ParseTime(const wxString& time,
- wxString::const_iterator* end = NULL);
-
- /**
- @overload
- */
- const char* ParseTime(const char* time);
-
- /**
- @overload
- */
- const wchar_t* ParseTime(const wchar_t* time);
+ wxString::const_iterator* end = NULL);
//@}
#endif // HAVE_STRPTIME
+enum
+{
+ DateLang_English = 1,
+ DateLang_Local = 2
+};
+
// return the month if the string is a month name or Inv_Month otherwise
-wxDateTime::Month GetMonthFromName(const wxString& name, int flags)
+//
+// flags can contain wxDateTime::Name_Abbr/Name_Full or both of them and lang
+// can be either DateLang_Local (default) to interpret string as a localized
+// month name or DateLang_English to parse it as a standard English name or
+// their combination to interpret it in any way
+wxDateTime::Month
+GetMonthFromName(const wxString& name, int flags, int lang)
{
wxDateTime::Month mon;
for ( mon = wxDateTime::Jan; mon < wxDateTime::Inv_Month; wxNextMonth(mon) )
// and not versions
if ( flags & wxDateTime::Name_Full )
{
- if ( name.CmpNoCase(wxDateTime::
- GetMonthName(mon, wxDateTime::Name_Full)) == 0 )
+ if ( lang & DateLang_English )
{
- break;
+ if ( name.CmpNoCase(wxDateTime::GetEnglishMonthName(mon,
+ wxDateTime::Name_Full)) == 0 )
+ break;
+ }
+
+ if ( lang & DateLang_Local )
+ {
+ if ( name.CmpNoCase(wxDateTime::GetMonthName(mon,
+ wxDateTime::Name_Full)) == 0 )
+ break;
}
}
if ( flags & wxDateTime::Name_Abbr )
{
- if ( name.CmpNoCase(wxDateTime::
- GetMonthName(mon, wxDateTime::Name_Abbr)) == 0 )
+ if ( lang & DateLang_English )
{
- break;
+ if ( name.CmpNoCase(wxDateTime::GetEnglishMonthName(mon,
+ wxDateTime::Name_Abbr)) == 0 )
+ break;
+ }
+
+ if ( lang & DateLang_Local )
+ {
+ if ( name.CmpNoCase(wxDateTime::GetMonthName(mon,
+ wxDateTime::Name_Abbr)) == 0 )
+ break;
}
}
}
}
// return the weekday if the string is a weekday name or Inv_WeekDay otherwise
-wxDateTime::WeekDay GetWeekDayFromName(const wxString& name, int flags)
+//
+// flags and lang parameters have the same meaning as for GetMonthFromName()
+// above
+wxDateTime::WeekDay
+GetWeekDayFromName(const wxString& name, int flags, int lang)
{
wxDateTime::WeekDay wd;
for ( wd = wxDateTime::Sun; wd < wxDateTime::Inv_WeekDay; wxNextWDay(wd) )
{
- // case-insensitive comparison either one of or with both abbreviated
- // and not versions
if ( flags & wxDateTime::Name_Full )
{
- if ( name.CmpNoCase(wxDateTime::
- GetWeekDayName(wd, wxDateTime::Name_Full)) == 0 )
+ if ( lang & DateLang_English )
{
- break;
+ if ( name.CmpNoCase(wxDateTime::GetEnglishWeekDayName(wd,
+ wxDateTime::Name_Full)) == 0 )
+ break;
+ }
+
+ if ( lang & DateLang_Local )
+ {
+ if ( name.CmpNoCase(wxDateTime::GetWeekDayName(wd,
+ wxDateTime::Name_Full)) == 0 )
+ break;
}
}
if ( flags & wxDateTime::Name_Abbr )
{
- if ( name.CmpNoCase(wxDateTime::
- GetWeekDayName(wd, wxDateTime::Name_Abbr)) == 0 )
+ if ( lang & DateLang_English )
{
- break;
+ if ( name.CmpNoCase(wxDateTime::GetEnglishWeekDayName(wd,
+ wxDateTime::Name_Abbr)) == 0 )
+ break;
+ }
+
+ if ( lang & DateLang_Local )
+ {
+ if ( name.CmpNoCase(wxDateTime::GetWeekDayName(wd,
+ wxDateTime::Name_Abbr)) == 0 )
+ break;
}
}
}
//
// this function is "strict" by design - it must reject anything except true
// RFC822 time specs.
-//
-// TODO a great candidate for using reg exps
-const char *
+wxAnyStrPtr
wxDateTime::ParseRfc822Date(const wxString& date, wxString::const_iterator *end)
{
- // TODO: rewrite using iterators instead of wxChar pointers
- const wxStringCharType *p = date.wx_str();
- const wxStringCharType *comma = wxStrchr(p, wxS(','));
- if ( comma )
- {
- // the part before comma is the weekday
+ wxString::const_iterator p = date.begin();
- // skip it for now - we don't use but might check that it really
- // corresponds to the specfied date
- p = comma + 1;
+ // 1. week day
+ static const int WDAY_LEN = 3;
+ const wxString::const_iterator endWday = p + WDAY_LEN;
+ const wxString wday(p, endWday);
+ if ( GetWeekDayFromName(wday, Name_Abbr, DateLang_English) == Inv_WeekDay )
+ return wxAnyStrPtr();
+ //else: ignore week day for now, we could also check that it really
+ // corresponds to the specified date
- if ( *p != _T(' ') )
- {
- wxLogDebug(_T("no space after weekday in RFC822 time spec"));
+ p = endWday;
- return NULL;
- }
-
- p++; // skip space
- }
+ // 2. separating comma
+ if ( *p++ != ',' || *p++ != ' ' )
+ return wxAnyStrPtr();
- // the following 1 or 2 digits are the day number
+ // 3. day number
if ( !wxIsdigit(*p) )
- {
- wxLogDebug(_T("day number expected in RFC822 time spec, none found"));
-
- return NULL;
- }
+ return wxAnyStrPtr();
- wxDateTime_t day = (wxDateTime_t)(*p++ - _T('0'));
+ wxDateTime_t day = (wxDateTime_t)(*p++ - '0');
if ( wxIsdigit(*p) )
{
day *= 10;
- day = (wxDateTime_t)(day + (*p++ - _T('0')));
+ day = (wxDateTime_t)(day + (*p++ - '0'));
}
- if ( *p++ != _T(' ') )
- {
- return NULL;
- }
+ if ( *p++ != ' ' )
+ return wxAnyStrPtr();
- // the following 3 letters specify the month
- wxString monName(p, 3);
- Month mon;
- if ( monName == _T("Jan") )
- mon = Jan;
- else if ( monName == _T("Feb") )
- mon = Feb;
- else if ( monName == _T("Mar") )
- mon = Mar;
- else if ( monName == _T("Apr") )
- mon = Apr;
- else if ( monName == _T("May") )
- mon = May;
- else if ( monName == _T("Jun") )
- mon = Jun;
- else if ( monName == _T("Jul") )
- mon = Jul;
- else if ( monName == _T("Aug") )
- mon = Aug;
- else if ( monName == _T("Sep") )
- mon = Sep;
- else if ( monName == _T("Oct") )
- mon = Oct;
- else if ( monName == _T("Nov") )
- mon = Nov;
- else if ( monName == _T("Dec") )
- mon = Dec;
- else
- {
- wxLogDebug(_T("Invalid RFC 822 month name '%s'"), monName.c_str());
+ // 4. month name
+ static const int MONTH_LEN = 3;
+ const wxString::const_iterator endMonth = p + MONTH_LEN;
+ const wxString monName(p, endMonth);
+ Month mon = GetMonthFromName(monName, Name_Abbr, DateLang_English);
+ if ( mon == Inv_Month )
+ return wxAnyStrPtr();
- return NULL;
- }
+ p = endMonth;
- p += 3;
+ if ( *p++ != ' ' )
+ return wxAnyStrPtr();
- if ( *p++ != _T(' ') )
- {
- return NULL;
- }
-
- // next is the year
+ // 5. year
if ( !wxIsdigit(*p) )
- {
- // no year?
- return NULL;
- }
+ return wxAnyStrPtr();
- int year = *p++ - _T('0');
-
- if ( !wxIsdigit(*p) )
- {
- // should have at least 2 digits in the year
- return NULL;
- }
+ int year = *p++ - '0';
+ if ( !wxIsdigit(*p) ) // should have at least 2 digits in the year
+ return wxAnyStrPtr();
year *= 10;
- year += *p++ - _T('0');
+ year += *p++ - '0';
// is it a 2 digit year (as per original RFC 822) or a 4 digit one?
if ( wxIsdigit(*p) )
{
year *= 10;
- year += *p++ - _T('0');
+ year += *p++ - '0';
if ( !wxIsdigit(*p) )
{
// no 3 digit years please
- return NULL;
+ return wxAnyStrPtr();
}
year *= 10;
- year += *p++ - _T('0');
+ year += *p++ - '0';
}
- if ( *p++ != _T(' ') )
- {
- return NULL;
- }
+ if ( *p++ != ' ' )
+ return wxAnyStrPtr();
- // time is in the format hh:mm:ss and seconds are optional
+ // 6. time in hh:mm:ss format with seconds being optional
if ( !wxIsdigit(*p) )
- {
- return NULL;
- }
+ return wxAnyStrPtr();
- wxDateTime_t hour = (wxDateTime_t)(*p++ - _T('0'));
+ wxDateTime_t hour = (wxDateTime_t)(*p++ - '0');
if ( !wxIsdigit(*p) )
- {
- return NULL;
- }
+ return wxAnyStrPtr();
hour *= 10;
- hour = (wxDateTime_t)(hour + (*p++ - _T('0')));
+ hour = (wxDateTime_t)(hour + (*p++ - '0'));
- if ( *p++ != _T(':') )
- {
- return NULL;
- }
+ if ( *p++ != ':' )
+ return wxAnyStrPtr();
if ( !wxIsdigit(*p) )
- {
- return NULL;
- }
+ return wxAnyStrPtr();
- wxDateTime_t min = (wxDateTime_t)(*p++ - _T('0'));
+ wxDateTime_t min = (wxDateTime_t)(*p++ - '0');
if ( !wxIsdigit(*p) )
- {
- return NULL;
- }
+ return wxAnyStrPtr();
min *= 10;
- min = (wxDateTime_t)(min + *p++ - _T('0'));
+ min += (wxDateTime_t)(*p++ - '0');
wxDateTime_t sec = 0;
- if ( *p == _T(':') )
+ if ( *p == ':' )
{
p++;
if ( !wxIsdigit(*p) )
- {
- return NULL;
- }
+ return wxAnyStrPtr();
- sec = (wxDateTime_t)(*p++ - _T('0'));
+ sec = (wxDateTime_t)(*p++ - '0');
if ( !wxIsdigit(*p) )
- {
- return NULL;
- }
+ return wxAnyStrPtr();
sec *= 10;
- sec = (wxDateTime_t)(sec + *p++ - _T('0'));
+ sec += (wxDateTime_t)(*p++ - '0');
}
- if ( *p++ != _T(' ') )
- {
- return NULL;
- }
+ if ( *p++ != ' ' )
+ return wxAnyStrPtr();
- // and now the interesting part: the timezone
+ // 7. now the interesting part: the timezone
int offset wxDUMMY_INITIALIZE(0);
- if ( *p == _T('-') || *p == _T('+') )
+ if ( *p == '-' || *p == '+' )
{
// the explicit offset given: it has the form of hhmm
- bool plus = *p++ == _T('+');
+ bool plus = *p++ == '+';
if ( !wxIsdigit(*p) || !wxIsdigit(*(p + 1)) )
- {
- return NULL;
- }
+ return wxAnyStrPtr();
+
// hours
- offset = MIN_PER_HOUR*(10*(*p - _T('0')) + (*(p + 1) - _T('0')));
+ offset = MIN_PER_HOUR*(10*(*p - '0') + (*(p + 1) - '0'));
p += 2;
if ( !wxIsdigit(*p) || !wxIsdigit(*(p + 1)) )
- {
- return NULL;
- }
+ return wxAnyStrPtr();
// minutes
- offset += 10*(*p - _T('0')) + (*(p + 1) - _T('0'));
+ offset += 10*(*p - '0') + (*(p + 1) - '0');
if ( !plus )
- {
offset = -offset;
- }
p += 2;
}
- else
+ else // not numeric
{
// the symbolic timezone given: may be either military timezone or one
// of standard abbreviations
};
if ( *p < _T('A') || *p > _T('Z') || *p == _T('J') )
- {
- wxLogDebug(_T("Invalid militaty timezone '%c'"), *p);
-
- return NULL;
- }
+ return wxAnyStrPtr();
- offset = offsets[*p++ - _T('A')];
+ offset = offsets[*p++ - 'A'];
}
else
{
// abbreviation
- wxString tz = p;
+ const wxString tz(p, date.end());
if ( tz == _T("UT") || tz == _T("UTC") || tz == _T("GMT") )
offset = 0;
else if ( tz == _T("AST") )
else if ( tz == _T("PDT") )
offset = PDT - GMT0;
else
- {
- wxLogDebug(_T("Unknown RFC 822 timezone '%s'"), p);
-
- return NULL;
- }
+ return wxAnyStrPtr();
p += tz.length();
}
offset *= MIN_PER_HOUR;
}
+
// the spec was correct, construct the date from the values we found
Set(day, mon, year, hour, min, sec);
MakeFromTimezone(TimeZone::Make(offset*SEC_PER_MIN));
- const size_t endpos = p - date.wx_str();
if ( end )
- *end = date.begin() + endpos;
+ *end = p;
- return date.c_str() + endpos;
+ return wxAnyStrPtr(date, p);
}
#ifdef __WINDOWS__
#endif // __WINDOWS__
-const char *
+wxAnyStrPtr
wxDateTime::ParseFormat(const wxString& date,
const wxString& format,
const wxDateTime& dateDef,
wxString::const_iterator *end)
{
- wxCHECK_MSG( !format.empty(), NULL, "format can't be empty" );
+ wxCHECK_MSG( !format.empty(), wxAnyStrPtr(), "format can't be empty" );
wxString str;
unsigned long num;
if ( *input++ != *fmt )
{
// no match
- return NULL;
+ return wxAnyStrPtr();
}
}
while ( wxIsdigit(*++fmt) )
{
width *= 10;
- width += *fmt - _T('0');
+ width += *fmt - '0';
}
// the default widths for the various fields
case _T('a'): // a weekday name
case _T('A'):
{
- int flag = *fmt == _T('a') ? Name_Abbr : Name_Full;
- wday = GetWeekDayFromName(GetAlphaToken(input), flag);
+ wday = GetWeekDayFromName
+ (
+ GetAlphaToken(input),
+ *fmt == 'a' ? Name_Abbr : Name_Full,
+ DateLang_Local
+ );
if ( wday == Inv_WeekDay )
{
// no match
- return NULL;
+ return wxAnyStrPtr();
}
}
haveWDay = true;
case _T('b'): // a month name
case _T('B'):
{
- int flag = *fmt == _T('b') ? Name_Abbr : Name_Full;
- mon = GetMonthFromName(GetAlphaToken(input), flag);
+ mon = GetMonthFromName
+ (
+ GetAlphaToken(input),
+ *fmt == 'b' ? Name_Abbr : Name_Full,
+ DateLang_Local
+ );
if ( mon == Inv_Month )
{
// no match
- return NULL;
+ return wxAnyStrPtr();
}
}
haveMon = true;
wxS("%X %x")
);
if ( !dt.IsValid() )
- return NULL;
+ return wxAnyStrPtr();
Tm tm = dt.GetTm();
(num > 31) || (num < 1) )
{
// no match
- return NULL;
+ return wxAnyStrPtr();
}
// we can't check whether the day range is correct yet, will
if ( !GetNumericToken(width, input, &num) || (num > 23) )
{
// no match
- return NULL;
+ return wxAnyStrPtr();
}
haveHour = true;
if ( !GetNumericToken(width, input, &num) || !num || (num > 12) )
{
// no match
- return NULL;
+ return wxAnyStrPtr();
}
haveHour = true;
if ( !GetNumericToken(width, input, &num) || !num || (num > 366) )
{
// no match
- return NULL;
+ return wxAnyStrPtr();
}
haveYDay = true;
case _T('l'): // milliseconds (0-999)
if ( !GetNumericToken(width, input, &num) )
- return NULL;
+ return wxAnyStrPtr();
haveMsec = true;
msec = (wxDateTime_t)num;
if ( !GetNumericToken(width, input, &num) || !num || (num > 12) )
{
// no match
- return NULL;
+ return wxAnyStrPtr();
}
haveMon = true;
if ( !GetNumericToken(width, input, &num) || (num > 59) )
{
// no match
- return NULL;
+ return wxAnyStrPtr();
}
haveMin = true;
GetAmPmStrings(&am, &pm);
if (am.empty() && pm.empty())
- return NULL; // no am/pm strings defined
+ return wxAnyStrPtr(); // no am/pm strings defined
if ( token.CmpNoCase(pm) == 0 )
{
isPM = true;
else if ( token.CmpNoCase(am) != 0 )
{
// no match
- return NULL;
+ return wxAnyStrPtr();
}
}
break;
wxDateTime dt;
if ( !dt.ParseFormat(wxString(input, date.end()),
wxS("%I:%M:%S %p"), &input) )
- return NULL;
+ return wxAnyStrPtr();
haveHour = haveMin = haveSec = true;
const wxDateTime
dt = ParseFormatAt(input, date.end(), wxS("%H:%M"));
if ( !dt.IsValid() )
- return NULL;
+ return wxAnyStrPtr();
haveHour =
haveMin = true;
if ( !GetNumericToken(width, input, &num) || (num > 61) )
{
// no match
- return NULL;
+ return wxAnyStrPtr();
}
haveSec = true;
const wxDateTime
dt = ParseFormatAt(input, date.end(), wxS("%H:%M:%S"));
if ( !dt.IsValid() )
- return NULL;
+ return wxAnyStrPtr();
haveHour =
haveMin =
if ( !GetNumericToken(width, input, &num) || (wday > 6) )
{
// no match
- return NULL;
+ return wxAnyStrPtr();
}
haveWDay = true;
dt = ParseFormatAt(input, date.end(),
fmtDate, fmtDateAlt);
if ( !dt.IsValid() )
- return NULL;
+ return wxAnyStrPtr();
Tm tm = dt.GetTm();
// use strptime() to do it for us (FIXME !Unicode friendly)
struct tm tm;
if ( !CallStrptime(date, input, "%X", &tm) )
- return NULL;
+ return wxAnyStrPtr();
haveHour = haveMin = haveSec = true;
const wxDateTime
dt = ParseFormatAt(input, date.end(), "%T", "%r");
if ( !dt.IsValid() )
- return NULL;
+ return wxAnyStrPtr();
haveHour =
haveMin =
if ( !GetNumericToken(width, input, &num) || (num > 99) )
{
// no match
- return NULL;
+ return wxAnyStrPtr();
}
haveYear = true;
if ( !GetNumericToken(width, input, &num) )
{
// no match
- return NULL;
+ return wxAnyStrPtr();
}
haveYear = true;
if ( *input++ != _T('%') )
{
// no match
- return NULL;
+ return wxAnyStrPtr();
}
break;
// fall through
default: // not a known format spec
- return NULL;
+ return wxAnyStrPtr();
}
}
if ( haveDay )
{
if ( mday > GetNumberOfDays(tm.mon, tm.year) )
- {
- wxLogDebug(_T("bad month day in wxDateTime::ParseFormat"));
-
- return NULL;
- }
+ return wxAnyStrPtr();
tm.mday = mday;
}
else if ( haveYDay )
{
if ( yday > GetNumberOfDays(tm.year) )
- {
- wxLogDebug(_T("bad year day in wxDateTime::ParseFormat"));
-
- return NULL;
- }
+ return wxAnyStrPtr();
Tm tm2 = wxDateTime(1, Jan, tm.year).SetToYearDay(yday).GetTm();
// finally check that the week day is consistent -- if we had it
if ( haveWDay && GetWeekDay() != wday )
- {
- wxLogDebug(_T("inconsistsnet week day in wxDateTime::ParseFormat()"));
-
- return NULL;
- }
+ return wxAnyStrPtr();
if ( end )
*end = input;
- return date.c_str() + (input - date.begin());
+ return wxAnyStrPtr(date, input);
}
-const char *
+wxAnyStrPtr
wxDateTime::ParseDateTime(const wxString& date, wxString::const_iterator *end)
{
// Set to current day and hour, so strings like '14:00' becomes today at
const wxString timestr(endDate, date.end());
if ( !dtTime.ParseTime(timestr, &endTime) )
- return NULL;
+ return wxAnyStrPtr();
endBoth = endDate + (endTime - timestr.begin());
}
{
// check if we have a time followed by a date
if ( !dtTime.ParseTime(date, &endTime) )
- return NULL;
+ return wxAnyStrPtr();
while ( endTime != date.end() && wxIsspace(*endTime) )
++endTime;
const wxString datestr(endTime, date.end());
if ( !dtDate.ParseDate(datestr, &endDate) )
- return NULL;
+ return wxAnyStrPtr();
endBoth = endTime + (endDate - datestr.begin());
}
if ( end )
*end = endBoth;
- return date.c_str() + (endBoth - date.begin());
+ return wxAnyStrPtr(date, endBoth);
}
-const char *
+wxAnyStrPtr
wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end)
{
// this is a simplified version of ParseDateTime() which understands only
if ( end )
*end = pEnd;
- return wxStringOperations::AddToIter(date.c_str().AsChar(),
- pEnd - pBegin);
+ return wxAnyStrPtr(date, pEnd);
}
}
else // not a number
{
// be careful not to overwrite the current mon value
- Month mon2 = GetMonthFromName(token, Name_Full | Name_Abbr);
+ Month mon2 = GetMonthFromName
+ (
+ token,
+ Name_Full | Name_Abbr,
+ DateLang_Local | DateLang_English
+ );
if ( mon2 != Inv_Month )
{
// it's a month
}
else // not a valid month name
{
- WeekDay wday2 = GetWeekDayFromName(token, Name_Full | Name_Abbr);
+ WeekDay wday2 = GetWeekDayFromName
+ (
+ token,
+ Name_Full | Name_Abbr,
+ DateLang_Local | DateLang_English
+ );
if ( wday2 != Inv_WeekDay )
{
// a week day
// 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
if ( !haveDay && !haveWDay )
- {
- wxLogDebug(_T("ParseDate: no day, no weekday hence no date."));
-
- return NULL;
- }
+ return wxAnyStrPtr();
if ( haveWDay && (haveMon || haveYear || haveDay) &&
!(haveDay && haveMon && haveYear) )
// without adjectives (which we don't support here) the week day only
// makes sense completely separately or with the full date
// specification (what would "Wed 1999" mean?)
- return NULL;
+ return wxAnyStrPtr();
}
if ( !haveWDay && haveYear && !(haveDay && haveMon) )
}
if ( !haveMon )
- {
- // if we give the year, month and day must be given too
- wxLogDebug(_T("ParseDate: day and month should be specified if year is."));
-
- return NULL;
- }
+ return wxAnyStrPtr();
}
if ( !haveMon )
// 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
if ( day > GetNumberOfDays(mon, year) )
- return NULL;
+ return wxAnyStrPtr();
Set(day, mon, year);
{
// check that it is really the same
if ( GetWeekDay() != wday )
- {
- // inconsistency detected
- wxLogDebug(_T("ParseDate: inconsistent day/weekday."));
-
- return NULL;
- }
+ return wxAnyStrPtr();
}
}
else // haveWDay
if ( end )
*end = p;
- return wxStringOperations::AddToIter(date.c_str().AsChar(), p - pBegin);
+ return wxAnyStrPtr(date, p);
}
-const char *
+wxAnyStrPtr
wxDateTime::ParseTime(const wxString& time, wxString::const_iterator *end)
{
// first try some extra things
static const struct
{
const char *name;
- wxDateTime_t hour;
+ wxDateTime_t hour;
} stdTimes[] =
{
{ wxTRANSLATE("noon"), 12 },
for ( size_t n = 0; n < WXSIZEOF(stdTimes); n++ )
{
- wxString timeString = wxGetTranslation(stdTimes[n].name);
- size_t len = timeString.length();
- if ( timeString.CmpNoCase(wxString(time, len)) == 0 )
+ const wxString timeString = wxGetTranslation(stdTimes[n].name);
+ const wxString::const_iterator p = time.begin() + timeString.length();
+ if ( timeString.CmpNoCase(wxString(time.begin(), p)) == 0 )
{
// casts required by DigitalMars
Set(stdTimes[n].hour, wxDateTime_t(0), wxDateTime_t(0));
if ( end )
- *end = time.begin() + len;
+ *end = p;
- return time.c_str() + len;
+ return wxAnyStrPtr(time, p);
}
}
for ( size_t nFmt = 0; nFmt < WXSIZEOF(timeFormats); nFmt++ )
{
- const char *result = ParseFormat(time, timeFormats[nFmt], end);
+ const wxAnyStrPtr result = ParseFormat(time, timeFormats[nFmt], end);
if ( result )
return result;
}
- return NULL;
+ return wxAnyStrPtr();
}
// ----------------------------------------------------------------------------
# --- wxBase headers list begins here ---
cat <<EOF >wxbase-headers.files
wx/afterstd.h
+wx/anystr.h
wx/app.h
wx/apptrait.h
wx/archive.h
# --- wxBase headers list begins here ---
cat <<EOF >wxbase-headers.files
wx/afterstd.h
+wx/anystr.h
wx/app.h
wx/apptrait.h
wx/archive.h
# --- wxBase headers list begins here ---
cat <<EOF >wxbase-headers.files
wx/afterstd.h
+wx/anystr.h
wx/app.h
wx/apptrait.h
wx/archive.h