1 // -*- mode: cpp; mode: fold -*-
3 // $Id: debversion.cc,v 1.3 2001/05/07 05:14:53 jgg Exp $
4 /* ######################################################################
6 Debian Version - Versioning system for Debian
8 This implements the standard Debian versioning system.
10 ##################################################################### */
12 // Include Files /*{{{*/
13 #define APT_COMPATIBILITY 986
15 #pragma implementation "apt-pkg/debversion.h"
18 #include <apt-pkg/debversion.h>
19 #include <apt-pkg/pkgcache.h>
25 debVersioningSystem debVS
;
27 // debVS::debVersioningSystem - Constructor /*{{{*/
28 // ---------------------------------------------------------------------
30 debVersioningSystem::debVersioningSystem()
32 Label
= "Standard .deb";
35 // StrToLong - Convert the string between two iterators to a long /*{{{*/
36 // ---------------------------------------------------------------------
38 static unsigned long StrToLong(const char *begin
,const char *end
)
42 for (; begin
!= end
&& I
< S
+ 40;)
45 return strtoul(S
,0,10);
48 // debVS::CmpFragment - Compare versions /*{{{*/
49 // ---------------------------------------------------------------------
50 /* This compares a fragment of the version. Dpkg has a really short
51 version of this, but it is uh.. interesting to grok. */
52 int debVersioningSystem::CmpFragment(const char *A
,const char *AEnd
,
53 const char *B
,const char *BEnd
)
55 if (A
>= AEnd
&& B
>= BEnd
)
62 /* Iterate over the whole string
63 What this does is to spilt the whole string into groups of
64 numeric and non numeric portions. For instance:
66 Has 4 portions 'a', '67', 'bhgs', '89'. A more normal:
68 Has '2', '.', '7', '.' ,'-linux-','1' */
71 while (lhs
!= AEnd
&& rhs
!= BEnd
)
74 const char *Slhs
= lhs
;
75 const char *Srhs
= rhs
;
77 // Compute ending points were we have passed over the portion
78 bool Digit
= (isdigit(*lhs
) > 0?true:false);
79 for (;lhs
!= AEnd
&& (isdigit(*lhs
) > 0?true:false) == Digit
; lhs
++);
80 for (;rhs
!= BEnd
&& (isdigit(*rhs
) > 0?true:false) == Digit
; rhs
++);
84 // If the lhs has a digit and the rhs does not then <
88 // Generate integers from the strings.
89 unsigned long Ilhs
= StrToLong(Slhs
,lhs
);
90 unsigned long Irhs
= StrToLong(Srhs
,rhs
);
100 // They are equal length so do a straight text compare
101 for (;Slhs
!= lhs
&& Srhs
!= rhs
; Slhs
++, Srhs
++)
105 /* We need to compare non alpha chars as higher than alpha
109 if (isalpha(lc
) == 0) lc
+= 256;
110 if (isalpha(rc
) == 0) rc
+= 256;
117 // If the lhs is shorter than the right it is 'less'
118 if (lhs
- Slhs
< rhs
- Srhs
)
121 // If the lhs is longer than the right it is 'more'
122 if (lhs
- Slhs
> rhs
- Srhs
)
127 // The strings must be equal
128 if (lhs
== AEnd
&& rhs
== BEnd
)
143 // debVS::CmpVersion - Comparison for versions /*{{{*/
144 // ---------------------------------------------------------------------
145 /* This fragments the version into E:V-R triples and compares each
146 portion separately. */
147 int debVersioningSystem::DoCmpVersion(const char *A
,const char *AEnd
,
148 const char *B
,const char *BEnd
)
150 // Strip off the epoch and compare it
153 for (;lhs
!= AEnd
&& *lhs
!= ':'; lhs
++);
154 for (;rhs
!= BEnd
&& *rhs
!= ':'; rhs
++);
161 int Res
= CmpFragment(A
,lhs
,B
,rhs
);
172 const char *dlhs
= AEnd
-1;
173 const char *drhs
= BEnd
-1;
174 for (;dlhs
> lhs
&& *dlhs
!= '-'; dlhs
--);
175 for (;drhs
> rhs
&& *drhs
!= '-'; drhs
--);
182 // Compare the main version
183 Res
= CmpFragment(lhs
,dlhs
,rhs
,drhs
);
193 return CmpFragment(dlhs
,AEnd
,drhs
,BEnd
);
196 // debVS::CheckDep - Check a single dependency /*{{{*/
197 // ---------------------------------------------------------------------
198 /* This simply preforms the version comparison and switch based on
199 operator. If DepVer is 0 then we are comparing against a provides
201 bool debVersioningSystem::CheckDep(const char *PkgVer
,
202 int Op
,const char *DepVer
)
204 if (DepVer
== 0 || DepVer
[0] == 0)
206 if (PkgVer
== 0 || PkgVer
[0] == 0)
209 // Perform the actual comparision.
210 int Res
= CmpVersion(PkgVer
,DepVer
);
213 case pkgCache::Dep::LessEq
:
218 case pkgCache::Dep::GreaterEq
:
223 case pkgCache::Dep::Less
:
228 case pkgCache::Dep::Greater
:
233 case pkgCache::Dep::Equals
:
238 case pkgCache::Dep::NotEquals
:
247 // debVS::UpstreamVersion - Return the upstream version string /*{{{*/
248 // ---------------------------------------------------------------------
249 /* This strips all the debian specific information from the version number */
250 string
debVersioningSystem::UpstreamVersion(const char *Ver
)
252 // Strip off the bit before the first colon
254 for (; *I
!= 0 && *I
!= ':'; I
++);
258 // Chop off the trailing -
260 unsigned Last
= strlen(Ver
);
265 return string(Ver
,Last
);