From 254696bb8f2b10e2231475c4c8334e6f0129503f Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Tue, 24 Mar 2009 23:21:29 +0000 Subject: [PATCH] return a wxAnyStrPtr covnertible to either narrow or wide char pointer from wxDateTime::ParseXXX() methods to improve compatibility with wx 2.8 and also simplify the code (closes #9560) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@59822 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- Makefile.in | 2 + build/bakefiles/files.bkl | 1 + build/msw/wx_base.dsp | 4 + build/msw/wx_vc7_base.vcproj | 3 + build/msw/wx_vc8_base.vcproj | 4 + build/msw/wx_vc9_base.vcproj | 4 + include/wx/anystr.h | 136 ++++++++++ include/wx/datetime.h | 158 ++---------- interface/wx/datetime.h | 122 +++++---- src/common/datetimefmt.cpp | 471 ++++++++++++++++------------------- wxGTK.spec | 1 + wxMotif.spec | 1 + wxX11.spec | 1 + 13 files changed, 442 insertions(+), 466 deletions(-) create mode 100644 include/wx/anystr.h diff --git a/Makefile.in b/Makefile.in index 351aef9cba..e62d62561c 100644 --- a/Makefile.in +++ b/Makefile.in @@ -309,6 +309,7 @@ WXSCINTILLA_OBJECTS = \ 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 \ @@ -467,6 +468,7 @@ ALL_HEADERS = \ $(ALL_GUI_HEADERS) ALL_PORTS_BASE_HEADERS = \ wx/afterstd.h \ + wx/anystr.h \ wx/app.h \ wx/apptrait.h \ wx/archive.h \ diff --git a/build/bakefiles/files.bkl b/build/bakefiles/files.bkl index 26618cd7b7..b60fdaf5a5 100644 --- a/build/bakefiles/files.bkl +++ b/build/bakefiles/files.bkl @@ -390,6 +390,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file! wx/afterstd.h + wx/anystr.h wx/app.h wx/apptrait.h wx/archive.h diff --git a/build/msw/wx_base.dsp b/build/msw/wx_base.dsp index 80bc56c80e..d33ad49d4b 100644 --- a/build/msw/wx_base.dsp +++ b/build/msw/wx_base.dsp @@ -1035,6 +1035,10 @@ SOURCE=..\..\include\wx\afterstd.h # End Source File # Begin Source File +SOURCE=..\..\include\wx\anystr.h +# End Source File +# Begin Source File + SOURCE=..\..\include\wx\app.h # End Source File # Begin Source File diff --git a/build/msw/wx_vc7_base.vcproj b/build/msw/wx_vc7_base.vcproj index 07635cef86..1ff4efc7c5 100644 --- a/build/msw/wx_vc7_base.vcproj +++ b/build/msw/wx_vc7_base.vcproj @@ -1194,6 +1194,9 @@ + + diff --git a/build/msw/wx_vc8_base.vcproj b/build/msw/wx_vc8_base.vcproj index b2eb486494..1572da419f 100644 --- a/build/msw/wx_vc8_base.vcproj +++ b/build/msw/wx_vc8_base.vcproj @@ -1615,6 +1615,10 @@ RelativePath="..\..\include\wx\afterstd.h" > + + diff --git a/build/msw/wx_vc9_base.vcproj b/build/msw/wx_vc9_base.vcproj index 622ba7bd69..68a24b3277 100644 --- a/build/msw/wx_vc9_base.vcproj +++ b/build/msw/wx_vc9_base.vcproj @@ -1611,6 +1611,10 @@ RelativePath="..\..\include\wx\afterstd.h" > + + diff --git a/include/wx/anystr.h b/include/wx/anystr.h new file mode 100644 index 0000000000..f816745625 --- /dev/null +++ b/include/wx/anystr.h @@ -0,0 +1,136 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/anystr.h +// Purpose: wxAnyStrPtr class declaration +// Author: Vadim Zeitlin +// Created: 2009-03-23 +// RCS-ID: $Id$ +// Copyright: (c) 2008 Vadim Zeitlin +// 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_ + diff --git a/include/wx/datetime.h b/include/wx/datetime.h index bf1b58444c..b7df66ae9b 100644 --- a/include/wx/datetime.h +++ b/include/wx/datetime.h @@ -26,6 +26,7 @@ #include // for INT_MIN #include "wx/longlong.h" +#include "wx/anystr.h" class WXDLLIMPEXP_FWD_BASE wxDateTime; class WXDLLIMPEXP_FWD_BASE wxTimeSpan; @@ -1098,103 +1099,36 @@ public: 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 // @@ -1221,65 +1155,18 @@ public: // 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 @@ -1326,23 +1213,6 @@ public: 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() diff --git a/interface/wx/datetime.h b/interface/wx/datetime.h index 02f28dc731..f075107937 100644 --- a/interface/wx/datetime.h +++ b/interface/wx/datetime.h @@ -802,50 +802,34 @@ public: /** 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 @@ -865,8 +849,38 @@ public: @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() */ @@ -878,16 +892,9 @@ public: /** @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 @@ -933,39 +940,22 @@ public: 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); //@} diff --git a/src/common/datetimefmt.cpp b/src/common/datetimefmt.cpp index d7218ac999..29edeab302 100644 --- a/src/common/datetimefmt.cpp +++ b/src/common/datetimefmt.cpp @@ -128,8 +128,20 @@ CallStrptime(const wxString& str, #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) ) @@ -138,19 +150,35 @@ wxDateTime::Month GetMonthFromName(const wxString& name, int flags) // 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; } } } @@ -159,28 +187,46 @@ wxDateTime::Month GetMonthFromName(const wxString& name, int flags) } // 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; } } } @@ -636,226 +682,156 @@ wxString wxDateTime::Format(const wxString& format, const TimeZone& tz) const // // 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 @@ -871,18 +847,14 @@ wxDateTime::ParseRfc822Date(const wxString& date, wxString::const_iterator *end) }; 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") ) @@ -906,11 +878,7 @@ wxDateTime::ParseRfc822Date(const wxString& date, wxString::const_iterator *end) else if ( tz == _T("PDT") ) offset = PDT - GMT0; else - { - wxLogDebug(_T("Unknown RFC 822 timezone '%s'"), p); - - return NULL; - } + return wxAnyStrPtr(); p += tz.length(); } @@ -919,15 +887,15 @@ wxDateTime::ParseRfc822Date(const wxString& date, wxString::const_iterator *end) 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__ @@ -1090,13 +1058,13 @@ static wxString GetLocaleDateFormat() #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; @@ -1147,7 +1115,7 @@ wxDateTime::ParseFormat(const wxString& date, if ( *input++ != *fmt ) { // no match - return NULL; + return wxAnyStrPtr(); } } @@ -1162,7 +1130,7 @@ wxDateTime::ParseFormat(const wxString& date, while ( wxIsdigit(*++fmt) ) { width *= 10; - width += *fmt - _T('0'); + width += *fmt - '0'; } // the default widths for the various fields @@ -1195,12 +1163,16 @@ wxDateTime::ParseFormat(const wxString& date, 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; @@ -1209,12 +1181,16 @@ wxDateTime::ParseFormat(const wxString& date, 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; @@ -1253,7 +1229,7 @@ wxDateTime::ParseFormat(const wxString& date, wxS("%X %x") ); if ( !dt.IsValid() ) - return NULL; + return wxAnyStrPtr(); Tm tm = dt.GetTm(); @@ -1276,7 +1252,7 @@ wxDateTime::ParseFormat(const wxString& date, (num > 31) || (num < 1) ) { // no match - return NULL; + return wxAnyStrPtr(); } // we can't check whether the day range is correct yet, will @@ -1289,7 +1265,7 @@ wxDateTime::ParseFormat(const wxString& date, if ( !GetNumericToken(width, input, &num) || (num > 23) ) { // no match - return NULL; + return wxAnyStrPtr(); } haveHour = true; @@ -1300,7 +1276,7 @@ wxDateTime::ParseFormat(const wxString& date, if ( !GetNumericToken(width, input, &num) || !num || (num > 12) ) { // no match - return NULL; + return wxAnyStrPtr(); } haveHour = true; @@ -1312,7 +1288,7 @@ wxDateTime::ParseFormat(const wxString& date, if ( !GetNumericToken(width, input, &num) || !num || (num > 366) ) { // no match - return NULL; + return wxAnyStrPtr(); } haveYDay = true; @@ -1321,7 +1297,7 @@ wxDateTime::ParseFormat(const wxString& date, case _T('l'): // milliseconds (0-999) if ( !GetNumericToken(width, input, &num) ) - return NULL; + return wxAnyStrPtr(); haveMsec = true; msec = (wxDateTime_t)num; @@ -1331,7 +1307,7 @@ wxDateTime::ParseFormat(const wxString& date, if ( !GetNumericToken(width, input, &num) || !num || (num > 12) ) { // no match - return NULL; + return wxAnyStrPtr(); } haveMon = true; @@ -1342,7 +1318,7 @@ wxDateTime::ParseFormat(const wxString& date, if ( !GetNumericToken(width, input, &num) || (num > 59) ) { // no match - return NULL; + return wxAnyStrPtr(); } haveMin = true; @@ -1362,7 +1338,7 @@ wxDateTime::ParseFormat(const wxString& date, 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; @@ -1370,7 +1346,7 @@ wxDateTime::ParseFormat(const wxString& date, else if ( token.CmpNoCase(am) != 0 ) { // no match - return NULL; + return wxAnyStrPtr(); } } break; @@ -1380,7 +1356,7 @@ wxDateTime::ParseFormat(const wxString& date, wxDateTime dt; if ( !dt.ParseFormat(wxString(input, date.end()), wxS("%I:%M:%S %p"), &input) ) - return NULL; + return wxAnyStrPtr(); haveHour = haveMin = haveSec = true; @@ -1396,7 +1372,7 @@ wxDateTime::ParseFormat(const wxString& date, const wxDateTime dt = ParseFormatAt(input, date.end(), wxS("%H:%M")); if ( !dt.IsValid() ) - return NULL; + return wxAnyStrPtr(); haveHour = haveMin = true; @@ -1411,7 +1387,7 @@ wxDateTime::ParseFormat(const wxString& date, if ( !GetNumericToken(width, input, &num) || (num > 61) ) { // no match - return NULL; + return wxAnyStrPtr(); } haveSec = true; @@ -1423,7 +1399,7 @@ wxDateTime::ParseFormat(const wxString& date, const wxDateTime dt = ParseFormatAt(input, date.end(), wxS("%H:%M:%S")); if ( !dt.IsValid() ) - return NULL; + return wxAnyStrPtr(); haveHour = haveMin = @@ -1440,7 +1416,7 @@ wxDateTime::ParseFormat(const wxString& date, if ( !GetNumericToken(width, input, &num) || (wday > 6) ) { // no match - return NULL; + return wxAnyStrPtr(); } haveWDay = true; @@ -1496,7 +1472,7 @@ wxDateTime::ParseFormat(const wxString& date, dt = ParseFormatAt(input, date.end(), fmtDate, fmtDateAlt); if ( !dt.IsValid() ) - return NULL; + return wxAnyStrPtr(); Tm tm = dt.GetTm(); @@ -1517,7 +1493,7 @@ wxDateTime::ParseFormat(const wxString& date, // 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; @@ -1536,7 +1512,7 @@ wxDateTime::ParseFormat(const wxString& date, const wxDateTime dt = ParseFormatAt(input, date.end(), "%T", "%r"); if ( !dt.IsValid() ) - return NULL; + return wxAnyStrPtr(); haveHour = haveMin = @@ -1554,7 +1530,7 @@ wxDateTime::ParseFormat(const wxString& date, if ( !GetNumericToken(width, input, &num) || (num > 99) ) { // no match - return NULL; + return wxAnyStrPtr(); } haveYear = true; @@ -1568,7 +1544,7 @@ wxDateTime::ParseFormat(const wxString& date, if ( !GetNumericToken(width, input, &num) ) { // no match - return NULL; + return wxAnyStrPtr(); } haveYear = true; @@ -1583,7 +1559,7 @@ wxDateTime::ParseFormat(const wxString& date, if ( *input++ != _T('%') ) { // no match - return NULL; + return wxAnyStrPtr(); } break; @@ -1593,7 +1569,7 @@ wxDateTime::ParseFormat(const wxString& date, // fall through default: // not a known format spec - return NULL; + return wxAnyStrPtr(); } } @@ -1634,22 +1610,14 @@ wxDateTime::ParseFormat(const wxString& date, 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(); @@ -1688,19 +1656,15 @@ wxDateTime::ParseFormat(const wxString& date, // 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 @@ -1723,7 +1687,7 @@ wxDateTime::ParseDateTime(const wxString& date, wxString::const_iterator *end) const wxString timestr(endDate, date.end()); if ( !dtTime.ParseTime(timestr, &endTime) ) - return NULL; + return wxAnyStrPtr(); endBoth = endDate + (endTime - timestr.begin()); } @@ -1731,14 +1695,14 @@ wxDateTime::ParseDateTime(const wxString& date, wxString::const_iterator *end) { // 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()); } @@ -1751,10 +1715,10 @@ wxDateTime::ParseDateTime(const wxString& date, wxString::const_iterator *end) 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 @@ -1801,8 +1765,7 @@ wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end) if ( end ) *end = pEnd; - return wxStringOperations::AddToIter(date.c_str().AsChar(), - pEnd - pBegin); + return wxAnyStrPtr(date, pEnd); } } @@ -1906,7 +1869,12 @@ wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end) 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 @@ -1934,7 +1902,12 @@ wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end) } 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 @@ -2013,11 +1986,7 @@ wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end) // 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) ) @@ -2025,7 +1994,7 @@ wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end) // 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) ) @@ -2051,12 +2020,7 @@ wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end) } 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 ) @@ -2074,7 +2038,7 @@ wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end) // 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); @@ -2082,12 +2046,7 @@ wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end) { // check that it is really the same if ( GetWeekDay() != wday ) - { - // inconsistency detected - wxLogDebug(_T("ParseDate: inconsistent day/weekday.")); - - return NULL; - } + return wxAnyStrPtr(); } } else // haveWDay @@ -2109,17 +2068,17 @@ wxDateTime::ParseDate(const wxString& date, wxString::const_iterator *end) 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 }, @@ -2129,17 +2088,17 @@ wxDateTime::ParseTime(const wxString& time, wxString::const_iterator *end) 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); } } @@ -2159,12 +2118,12 @@ wxDateTime::ParseTime(const wxString& time, wxString::const_iterator *end) 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(); } // ---------------------------------------------------------------------------- diff --git a/wxGTK.spec b/wxGTK.spec index aa3ca9669b..d6e259093f 100644 --- a/wxGTK.spec +++ b/wxGTK.spec @@ -206,6 +206,7 @@ rm -rf $RPM_BUILD_ROOT # --- wxBase headers list begins here --- cat <wxbase-headers.files wx/afterstd.h +wx/anystr.h wx/app.h wx/apptrait.h wx/archive.h diff --git a/wxMotif.spec b/wxMotif.spec index 03ac42fe17..4f29e8dc2c 100644 --- a/wxMotif.spec +++ b/wxMotif.spec @@ -111,6 +111,7 @@ rm -rf $RPM_BUILD_ROOT # --- wxBase headers list begins here --- cat <wxbase-headers.files wx/afterstd.h +wx/anystr.h wx/app.h wx/apptrait.h wx/archive.h diff --git a/wxX11.spec b/wxX11.spec index 657ae14529..2a4504e07e 100644 --- a/wxX11.spec +++ b/wxX11.spec @@ -135,6 +135,7 @@ rm -rf $RPM_BUILD_ROOT # --- wxBase headers list begins here --- cat <wxbase-headers.files wx/afterstd.h +wx/anystr.h wx/app.h wx/apptrait.h wx/archive.h -- 2.47.2