1 // -*- mode: cpp; mode: fold -*-
3 // $Id: debversion.cc,v 1.8 2003/09/10 23:39:49 mdz Exp $
4 /* ######################################################################
6 Debian Version - Versioning system for Debian
8 This implements the standard Debian versioning system.
10 ##################################################################### */
12 // Include Files /*{{{*/
15 #include <apt-pkg/debversion.h>
16 #include <apt-pkg/pkgcache.h>
23 debVersioningSystem debVS
;
25 // debVS::debVersioningSystem - Constructor /*{{{*/
26 // ---------------------------------------------------------------------
28 debVersioningSystem::debVersioningSystem()
30 Label
= "Standard .deb";
34 // debVS::CmpFragment - Compare versions /*{{{*/
35 // ---------------------------------------------------------------------
36 /* This compares a fragment of the version. This is a slightly adapted
37 version of what dpkg uses in dpkg/lib/dpkg/version.c.
38 In particular, the a | b = NULL check is removed as we check this in the
39 caller, we use an explicit end for a | b strings and we check ~ explicit. */
40 static int order(char c
)
53 int debVersioningSystem::CmpFragment(const char *A
,const char *AEnd
,
54 const char *B
,const char *BEnd
)
56 /* Iterate over the whole string
57 What this does is to split the whole string into groups of
58 numeric and non numeric portions. For instance:
60 Has 4 portions 'a', '67', 'bhgs', '89'. A more normal:
62 Has '2', '.', '7', '.' ,'-linux-','1' */
65 while (lhs
!= AEnd
&& rhs
!= BEnd
)
69 while (lhs
!= AEnd
&& rhs
!= BEnd
&&
70 (!isdigit(*lhs
) || !isdigit(*rhs
)))
83 while (isdigit(*lhs
) && isdigit(*rhs
))
86 first_diff
= *lhs
- *rhs
;
99 // The strings must be equal
100 if (lhs
== AEnd
&& rhs
== BEnd
)
106 if (*rhs
== '~') return 1;
113 if (*lhs
== '~') return -1;
121 // debVS::CmpVersion - Comparison for versions /*{{{*/
122 // ---------------------------------------------------------------------
123 /* This fragments the version into E:V-R triples and compares each
124 portion separately. */
125 int debVersioningSystem::DoCmpVersion(const char *A
,const char *AEnd
,
126 const char *B
,const char *BEnd
)
128 // Strip off the epoch and compare it
129 const char *lhs
= (const char*) memchr(A
, ':', AEnd
- A
);
130 const char *rhs
= (const char*) memchr(B
, ':', BEnd
- B
);
136 // Special case: a zero epoch is the same as no epoch,
140 for (; *A
== '0'; ++A
);
149 for (; *B
== '0'; ++B
);
158 int Res
= CmpFragment(A
,lhs
,B
,rhs
);
169 const char *dlhs
= (const char*) memrchr(lhs
, '-', AEnd
- lhs
);
170 const char *drhs
= (const char*) memrchr(rhs
, '-', BEnd
- rhs
);
176 // Compare the main version
177 Res
= CmpFragment(lhs
,dlhs
,rhs
,drhs
);
187 // no debian revision need to be treated like -0
188 if (*(dlhs
-1) == '-' && *(drhs
-1) == '-')
189 return CmpFragment(dlhs
,AEnd
,drhs
,BEnd
);
190 else if (*(dlhs
-1) == '-')
192 const char* null
= "0";
193 return CmpFragment(dlhs
,AEnd
,null
, null
+1);
195 else if (*(drhs
-1) == '-')
197 const char* null
= "0";
198 return CmpFragment(null
, null
+1, drhs
, BEnd
);
204 // debVS::CheckDep - Check a single dependency /*{{{*/
205 // ---------------------------------------------------------------------
206 /* This simply preforms the version comparison and switch based on
207 operator. If DepVer is 0 then we are comparing against a provides
209 bool debVersioningSystem::CheckDep(const char *PkgVer
,
210 int Op
,const char *DepVer
)
212 if (DepVer
== 0 || DepVer
[0] == 0)
214 if (PkgVer
== 0 || PkgVer
[0] == 0)
218 // fast track for (equal) strings [by location] which are by definition equal versions
219 if (PkgVer
== DepVer
)
220 return Op
== pkgCache::Dep::Equals
|| Op
== pkgCache::Dep::LessEq
|| Op
== pkgCache::Dep::GreaterEq
;
222 // Perform the actual comparison.
223 int const Res
= CmpVersion(PkgVer
, DepVer
);
226 case pkgCache::Dep::LessEq
:
231 case pkgCache::Dep::GreaterEq
:
236 case pkgCache::Dep::Less
:
241 case pkgCache::Dep::Greater
:
246 case pkgCache::Dep::Equals
:
251 case pkgCache::Dep::NotEquals
:
260 // debVS::UpstreamVersion - Return the upstream version string /*{{{*/
261 // ---------------------------------------------------------------------
262 /* This strips all the debian specific information from the version number */
263 std::string
debVersioningSystem::UpstreamVersion(const char *Ver
)
265 // Strip off the bit before the first colon
267 for (; *I
!= 0 && *I
!= ':'; I
++);
271 // Chop off the trailing -
273 unsigned Last
= strlen(Ver
);
278 return std::string(Ver
,Last
);