]>
git.saurik.com Git - apt.git/blob - apt-pkg/version.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: version.cc,v 1.3 1998/07/07 04:17:08 jgg Exp $
4 /* ######################################################################
6 Version - Version string
8 Version comparing is done using the == and < operators. STL's
9 function.h provides the remaining set of comparitors. A directly
10 callable non-string class version is provided for functions manipulating
11 the cache file (esp the sort function).
13 A version is defined to be equal if a case sensitive compare returns
14 that the two strings are the same. For compatibility with the QSort
15 function this version returns -1,0,1.
17 ##################################################################### */
19 // Include Files /*{{{*/
21 #pragma implementation "pkglib/version.h"
24 #include <pkglib/version.h>
25 #include <pkglib/pkgcache.h>
30 // Version::pkgVersion - Default Constructor /*{{{*/
31 // ---------------------------------------------------------------------
33 pkgVersion::pkgVersion()
37 // Version::operator == - Checks if two versions are equal /*{{{*/
38 // ---------------------------------------------------------------------
39 /* We can't simply perform a string compare because of epochs. */
40 bool pkgVersion::operator ==(const pkgVersion
&Vrhs
) const
42 if (pkgVersionCompare(Value
.begin(),Value
.end(),
43 Vrhs
.Value
.begin(),Vrhs
.Value
.end()) == 0)
48 // Version::operator < - Checks if this is less than another version /*{{{*/
49 // ---------------------------------------------------------------------
50 /* All other forms of comparision can be built up from this single function.
52 a <= b -> !(a > b) -> !(b < a)
55 bool pkgVersion::operator <(const pkgVersion
&Vrhs
) const
57 if (pkgVersionCompare(Value
.begin(),Value
.end(),
58 Vrhs
.Value
.begin(),Vrhs
.Value
.end()) == -1)
63 // StrToLong - Convert the string between two iterators to a long /*{{{*/
64 // ---------------------------------------------------------------------
66 static unsigned long StrToLong(const char *begin
,const char *end
)
70 for (; begin
!= end
&& I
< S
+ 40;)
73 return strtoul(S
,0,10);
76 // VersionCompare (op) - Greater than comparison for versions /*{{{*/
77 // ---------------------------------------------------------------------
79 int pkgVersionCompare(const char *A
, const char *B
)
81 return pkgVersionCompare(A
,A
+ strlen(A
),B
,B
+ strlen(B
));
83 int pkgVersionCompare(string A
,string B
)
85 return pkgVersionCompare(A
.begin(),A
.end(),B
.begin(),B
.end());
89 // VersionCompare - Greater than comparison for versions /*{{{*/
90 // ---------------------------------------------------------------------
92 int pkgVersionCompare(const char *A
, const char *AEnd
, const char *B
,
95 // lhs = left hand side, rhs = right hand side
99 /* Consider epochs. They need special handling because an epoch
100 must not be compared against the first element of the real version.
101 This works okay when both sides have an epoch but when only one
102 does it must compare the missing epoch to 0 */
103 for (;lhs
!= AEnd
&& *lhs
!= ':'; lhs
++);
104 for (;rhs
!= BEnd
&& *rhs
!= ':'; rhs
++);
106 // Parse the epoch out
107 unsigned long lhsEpoch
= 0;
108 unsigned long rhsEpoch
= 0;
109 if (lhs
!= AEnd
&& *lhs
== ':')
110 lhsEpoch
= StrToLong(A
,lhs
);
111 if (rhs
!= BEnd
&& *rhs
== ':')
112 rhsEpoch
= StrToLong(B
,rhs
);
113 if (lhsEpoch
!= rhsEpoch
)
115 if (lhsEpoch
> rhsEpoch
)
120 /* Iterate over the whole string
121 What this does is to spilt the whole string into groups of
122 numeric and non numeric portions. For instance:
124 Has 4 portions 'a', '67', 'bhgs', '89'. A more normal:
126 Has '2', '.', '7', '.' ,'-linux-','1' */
129 while (lhs
!= AEnd
&& rhs
!= BEnd
)
132 const char *Slhs
= lhs
;
133 const char *Srhs
= rhs
;
135 // Compute ending points were we have passed over the portion
136 bool Digit
= (isdigit(*lhs
) > 0?true:false);
137 for (;lhs
!= AEnd
&& (isdigit(*lhs
) > 0?true:false) == Digit
; lhs
++);
138 for (;rhs
!= BEnd
&& (isdigit(*rhs
) > 0?true:false) == Digit
; rhs
++);
142 // If the lhs has a digit and the rhs does not then true
146 // Generate integers from the strings.
147 unsigned long Ilhs
= StrToLong(Slhs
,lhs
);
148 unsigned long Irhs
= StrToLong(Srhs
,rhs
);
158 // They are equal length so do a straight text compare
159 for (;Slhs
!= lhs
&& Srhs
!= rhs
; Slhs
++, Srhs
++)
163 /* We need to compare non alpha chars as higher than alpha
164 chars (a < !) This is so things like 7.6p2-4 and 7.6-0
165 compare higher as well as . and -. I am not sure how
166 the dpkg code manages to achive the != '-' test, but it
170 if (isalpha(lc
) == 0 && lc
!= '-') lc
+= 256;
171 if (isalpha(rc
) == 0 && rc
!= '-') rc
+= 256;
178 // If the lhs is shorter than the right it is 'less'
179 if (lhs
- Slhs
< rhs
- Srhs
)
182 // If the lhs is longer than the right it is 'more'
183 if (lhs
- Slhs
> rhs
- Srhs
)
188 // The strings must be equal
189 if (lhs
== AEnd
&& rhs
== BEnd
)
204 // CheckDep - Check a single dependency /*{{{*/
205 // ---------------------------------------------------------------------
206 /* This simply preforms the version comparison and switch based on
208 bool pkgCheckDep(const char *DepVer
,const char *PkgVer
,int Op
)
215 // Perform the actuall comparision.
216 int Res
= pkgVersionCompare(PkgVer
,DepVer
);
219 case pkgCache::Dep::LessEq
:
224 case pkgCache::Dep::GreaterEq
:
229 case pkgCache::Dep::Less
:
234 case pkgCache::Dep::Greater
:
239 case pkgCache::Dep::Equals
:
244 case pkgCache::Dep::NotEquals
: