version.cpp

00001 
00002 // Name:        version.cpp
00003 // Purpose:     wxVersion, wxVersionRange
00004 // Author:      Francesco Montorsi
00005 // Modified by:
00006 // Created:     2006-06-29
00007 // RCS-ID:      $Id: version.cpp,v 1.1.1.1 2006/12/12 09:39:34 frm Exp $
00008 // Copyright:   (c) Francesco Montorsi
00009 // Licence:     wxWidgets licence
00011 
00012 
00013 // For compilers that support precompilation, includes "wx/wx.h".
00014 #include "wx/wxprec.h"
00015 
00016 #ifdef __BORLANDC__
00017 #pragma hdrstop
00018 #endif
00019 
00020 #ifndef WX_PRECOMP
00021     #include "wx/wx.h"
00022 #endif
00023 
00024 // includes
00025 #include "wxp/version.h"
00026 
00027 
00028 // RTTI
00029 IMPLEMENT_DYNAMIC_CLASS(wxVersion, wxObject)
00030 IMPLEMENT_DYNAMIC_CLASS(wxVersionRange, wxObject)
00031 
00032 
00033 // wx array implementations
00034 #include <wx/arrimpl.cpp> // this is a magic incantation which must be done!
00035 WX_DEFINE_OBJARRAY(wxVersionRangeArray);
00036 
00037 // static
00038 wxVersion wxEmptyVersion;
00039 wxVersionRange wxEmptyVersionRange;
00040 
00041 
00042 
00043 // ----------------------------------------------------------------------------
00044 // wxVersion
00045 // ----------------------------------------------------------------------------
00046 
00047 bool wxVersion::operator >(const wxVersion &v) const
00048 {
00049     if (m_nMajor > v.m_nMajor)
00050         return true;
00051     if (m_nMajor == v.m_nMajor && m_nMinor > v.m_nMinor)
00052         return true;
00053     if (m_nMajor == v.m_nMajor && m_nMinor == v.m_nMinor && m_nRelease > v.m_nRelease)
00054         return true;
00055     return false;
00056 }
00057 
00058 bool wxVersion::operator <(const wxVersion &v) const
00059 {
00060     if (m_nMajor < v.m_nMajor)
00061         return true;
00062     if (m_nMajor == v.m_nMajor && m_nMinor < v.m_nMinor)
00063         return true;
00064     if (m_nMajor == v.m_nMajor && m_nMinor == v.m_nMinor && m_nRelease < v.m_nRelease)
00065         return true;
00066     return false;
00067 }
00068 
00069 bool wxVersion::operator ==(const wxVersion &ver) const
00070 {
00071     return m_nMajor==ver.m_nMajor &&
00072            m_nMinor==ver.m_nMinor &&
00073            m_nRelease==ver.m_nRelease;
00074 }
00075 
00076 bool wxVersion::Set(const wxString &str)
00077 {
00078     // reset to initial state so that IsOk() will fail
00079     // on invalid strings
00080     m_nMajor = m_nMinor = m_nRelease = 0;
00081 
00082     // extract the single version numbers in string format
00083     wxString major = str.BeforeFirst(wxT('.'));
00084     wxString minor = str.AfterFirst(wxT('.')).BeforeFirst(wxT('.'));
00085     wxString release = str.AfterFirst(wxT('.')).AfterFirst(wxT('.'));
00086 
00087     if (major.IsEmpty() || !major.IsNumber() ||
00088         (!minor.IsEmpty() && !minor.IsNumber()) ||
00089         (!release.IsEmpty() && !release.IsNumber()))
00090         return false;           // invalid version format !
00091     if (minor.IsEmpty())
00092         minor = wxT("0");               // allow version formats of the type "1" = "1.0.0"
00093     if (release.IsEmpty())
00094         release = wxT("0");             // allow version formats of the type "1.2" = "1.2.0"
00095 
00096     // then convert them in numbers
00097     major.ToULong((unsigned long *)&m_nMajor);
00098     minor.ToULong((unsigned long *)&m_nMinor);
00099     release.ToULong((unsigned long *)&m_nRelease);
00100 
00101     return IsOk();
00102 }
00103 
00104 
00105 
00106 // ----------------------------------------------------------------------------
00107 // wxVersionRange
00108 // ----------------------------------------------------------------------------
00109 
00110 bool wxVersionRange::Set(const wxString &str)
00111 {
00112     // reset to initial state so that IsOk() will fail
00113     // on invalid strings
00114     m_start.Set(0, 0, 0);
00115     m_end.Set(0, 0, 0);
00116 
00117     if (str.IsEmpty())
00118         return false;
00119 
00120     // the key characters are the wildcard 'x', range separator '-'
00121     // comparison operators lt,le,eq,ge,gt
00122     if (str.Contains(wxT('-')))
00123     {
00124         // if using start-end syntax, the wildcard 'x' is not allowed!
00125         if (str.Contains(wxT('x')))
00126             return false;
00127 
00128         // it's allowed to specify less than three digits per version:
00129         // 1.2-3.4  ==>  1.2.0-3.4.9
00130         wxString start(str.BeforeFirst(wxT('-'))),
00131                  end(str.AfterFirst(wxT('-')));
00132         if (start.Freq(wxT('.')) < 2)
00133             start += wxT(".0");
00134         if (end.Freq(wxT('.')) < 2)
00135             end += wxT(".9");
00136 
00137         m_start.Set(start);
00138         m_end.Set(end);
00139     }
00140     else if (str.Contains(wxT('x')))
00141     {
00142         // if using wildcard 'x', the start-end syntax is not allowed!
00143         if (str.Contains(wxT('-')))
00144             return false;
00145 
00146         // it's allowed to specify less than three digits per version:
00147         // 1.x  ==>  1.x.x
00148         wxString ver(str);
00149         if (ver.Freq(wxT('.')) < 2)
00150             ver += wxT(".x");
00151 
00152         wxString start(ver), end(ver);
00153         start.Replace(wxT("x"), wxT("0"));
00154         end.Replace(wxT("x"), wxT("9"));
00155 
00156         m_start.Set(start);
00157         m_end.Set(end);
00158     }
00159     else
00160     {
00161         wxString op(str), ver(str);
00162 
00163         op = op.Remove(2).MakeLower().Trim();       // keep only first two chars
00164         ver = ver.Mid(2).Trim(false);                // remove first two chars
00165 
00166         if (op == wxT("lt"))
00167         {
00168             // lt 2.3.4 ==> 0.0.1-2.3.3
00169             m_start.Set(0,0,1);
00170             m_end.Set(ver);
00171             m_end.Set(m_end.GetMajor(), m_end.GetMinor(), m_end.GetRelease()-1);
00172         }
00173         else if (op == wxT("le"))
00174         {
00175             // le 2.3.4 ==> 0.0.1-2.3.4
00176             m_start.Set(0,0,1);
00177             m_end.Set(ver);
00178         }
00179         else if (op == wxT("eq"))
00180         {
00181             // eq 2.3.4 ==> 2.3.4-2.3.4
00182             m_start.Set(ver);
00183             m_end.Set(ver);
00184         }
00185         else if (op == wxT("ge"))
00186         {
00187             // ge 2.3.4 ==> 2.3.4-9.9.9
00188             m_start.Set(ver);
00189             m_end.Set(9,9,9);
00190         }
00191         else if (op == wxT("gt"))
00192         {
00193             // gt 2.3.4 ==> 2.3.5-9.9.9
00194             m_start.Set(ver);
00195             m_start.Set(m_start.GetMajor(), m_start.GetMinor(), m_start.GetRelease()+1);
00196             m_end.Set(9,9,9);
00197         }
00198         else
00199         {
00200             // a simple version, not a range ?
00201             m_start.Set(str);
00202             m_end.Set(str);
00203         }
00204     }
00205 
00206     return IsOk();
00207 }
00208 
00209 wxString wxVersionRange::GetAsString() const
00210 {
00211     if (m_start == m_end)
00212         return m_start.GetAsString();
00213 
00214     // can we use the 'x' wildcard to represent this range ?
00215     bool canUseXforRelease = m_start.GetRelease() == 0 && m_end.GetRelease() == 9;
00216     bool canUseXforMinor = m_start.GetMinor() == 0 && m_end.GetMinor() == 9;
00217     bool canUseXforMajor = m_start.GetMajor() == 0 && m_end.GetMajor() == 9;
00218     bool eqRelease = m_start.GetRelease() == m_end.GetRelease();
00219     bool eqMinor = m_start.GetMinor() == m_end.GetMinor();
00220     bool eqMajor = m_start.GetMajor() == m_end.GetMajor();
00221 
00222     // to be able to use the 'x' wildcard, either one of the canUseX or eq
00223     // conditions defined above must be true for all the three digits
00224     if (!(canUseXforRelease || eqRelease) ||
00225         !(canUseXforMinor || eqMinor) ||
00226         !(canUseXforMajor || eqMajor))
00227     {
00228         // cannot use the 'x' wildcard!
00229         return wxString::Format(wxT("%s-%s"),
00230                                 m_start.GetAsString().c_str(),
00231                                 m_end.GetAsString().c_str());
00232     }
00233 
00234 #define APPEND_DIGIT(n)     \
00235     if (canUseXfor##n)      \
00236         str += wxT("x.");   \
00237     else                    \
00238         str += wxString::Format(wxT("%d."), m_start.Get##n());
00239 
00240     wxString str;
00241     APPEND_DIGIT(Major);
00242     APPEND_DIGIT(Minor);
00243     APPEND_DIGIT(Release);
00244     return str.RemoveLast();
00245 }
00246 
00247 bool wxVersionRange::Contains(const wxVersion &ver) const
00248 {
00249     if (m_start <= ver && m_end >= ver)
00250         return true;
00251     return false;
00252 }
00253 
00254 bool wxVersionRange::OverlapsWith(const wxVersionRange &ver) const
00255 {
00256     if (ver.Contains(m_start) || ver.Contains(m_end))
00257         return true;
00258     return false;
00259 }
00260 
00261 
00262 

Generated on Thu Feb 1 22:14:31 2007 for wxWidgets Package Manager by  doxygen 1.5.1-p1