]>
git.saurik.com Git - apt.git/blob - apt-pkg/version.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: version.cc,v 1.2 1998/07/04 05:57:40 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 /*{{{*/
20 #include <pkglib/version.h>
21 #include <pkglib/pkgcache.h>
26 // Version::pkgVersion - Default Constructor /*{{{*/
27 // ---------------------------------------------------------------------
29 pkgVersion::pkgVersion()
33 // Version::operator == - Checks if two versions are equal /*{{{*/
34 // ---------------------------------------------------------------------
35 /* We can't simply perform a string compare because of epochs. */
36 bool pkgVersion::operator ==(const pkgVersion
&Vrhs
) const
38 if (pkgVersionCompare(Value
.begin(),Value
.end(),
39 Vrhs
.Value
.begin(),Vrhs
.Value
.end()) == 0)
44 // Version::operator < - Checks if this is less than another version /*{{{*/
45 // ---------------------------------------------------------------------
46 /* All other forms of comparision can be built up from this single function.
48 a <= b -> !(a > b) -> !(b < a)
51 bool pkgVersion::operator <(const pkgVersion
&Vrhs
) const
53 if (pkgVersionCompare(Value
.begin(),Value
.end(),
54 Vrhs
.Value
.begin(),Vrhs
.Value
.end()) == -1)
59 // StrToLong - Convert the string between two iterators to a long /*{{{*/
60 // ---------------------------------------------------------------------
62 static unsigned long StrToLong(const char *begin
,const char *end
)
66 for (; begin
!= end
&& I
< S
+ 40;)
69 return strtoul(S
,0,10);
72 // VersionCompare (op) - Greater than comparison for versions /*{{{*/
73 // ---------------------------------------------------------------------
75 int pkgVersionCompare(const char *A
, const char *B
)
77 return pkgVersionCompare(A
,A
+ strlen(A
),B
,B
+ strlen(B
));
79 int pkgVersionCompare(string A
,string B
)
81 return pkgVersionCompare(A
.begin(),A
.end(),B
.begin(),B
.end());
85 // VersionCompare - Greater than comparison for versions /*{{{*/
86 // ---------------------------------------------------------------------
88 int pkgVersionCompare(const char *A
, const char *AEnd
, const char *B
,
91 // lhs = left hand side, rhs = right hand side
95 /* Consider epochs. They need special handling because an epoch
96 must not be compared against the first element of the real version.
97 This works okay when both sides have an epoch but when only one
98 does it must compare the missing epoch to 0 */
99 for (;lhs
!= AEnd
&& *lhs
!= ':'; lhs
++);
100 for (;rhs
!= BEnd
&& *rhs
!= ':'; rhs
++);
102 // Parse the epoch out
103 unsigned long lhsEpoch
= 0;
104 unsigned long rhsEpoch
= 0;
105 if (lhs
!= AEnd
&& *lhs
== ':')
106 lhsEpoch
= StrToLong(A
,lhs
);
107 if (rhs
!= BEnd
&& *rhs
== ':')
108 rhsEpoch
= StrToLong(B
,rhs
);
109 if (lhsEpoch
!= rhsEpoch
)
111 if (lhsEpoch
> rhsEpoch
)
116 /* Iterate over the whole string
117 What this does is to spilt the whole string into groups of
118 numeric and non numeric portions. For instance:
120 Has 4 portions 'a', '67', 'bhgs', '89'. A more normal:
122 Has '2', '.', '7', '.' ,'-linux-','1' */
125 while (lhs
!= AEnd
&& rhs
!= BEnd
)
128 const char *Slhs
= lhs
;
129 const char *Srhs
= rhs
;
131 // Compute ending points were we have passed over the portion
132 bool Digit
= (isdigit(*lhs
) > 0?true:false);
133 for (;lhs
!= AEnd
&& (isdigit(*lhs
) > 0?true:false) == Digit
; lhs
++);
134 for (;rhs
!= BEnd
&& (isdigit(*rhs
) > 0?true:false) == Digit
; rhs
++);
138 // If the lhs has a digit and the rhs does not then true
142 // Generate integers from the strings.
143 unsigned long Ilhs
= StrToLong(Slhs
,lhs
);
144 unsigned long Irhs
= StrToLong(Srhs
,rhs
);
154 // They are equal length so do a straight text compare
155 for (;Slhs
!= lhs
&& Srhs
!= rhs
; Slhs
++, Srhs
++)
159 /* We need to compare non alpha chars as higher than alpha
160 chars (a < !) This is so things like 7.6p2-4 and 7.6-0
161 compare higher as well as . and -. I am not sure how
162 the dpkg code manages to achive the != '-' test, but it
166 if (isalpha(lc
) == 0 && lc
!= '-') lc
+= 256;
167 if (isalpha(rc
) == 0 && rc
!= '-') rc
+= 256;
174 // If the lhs is shorter than the right it is 'less'
175 if (lhs
- Slhs
< rhs
- Srhs
)
178 // If the lhs is longer than the right it is 'more'
179 if (lhs
- Slhs
> rhs
- Srhs
)
184 // The strings must be equal
185 if (lhs
== AEnd
&& rhs
== BEnd
)
200 // CheckDep - Check a single dependency /*{{{*/
201 // ---------------------------------------------------------------------
202 /* This simply preforms the version comparison and switch based on
204 bool pkgCheckDep(const char *DepVer
,const char *PkgVer
,int Op
)
211 // Perform the actuall comparision.
212 int Res
= pkgVersionCompare(PkgVer
,DepVer
);
215 case pkgCache::LessEq
:
220 case pkgCache::GreaterEq
:
230 case pkgCache::Greater
:
235 case pkgCache::Equals
:
240 case pkgCache::NotEquals
: