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 /*{{{*/
13 #define APT_COMPATIBILITY 986
16 #include <apt-pkg/debversion.h>
17 #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. */
38 #define order(x) ((x) == '~' ? -1 \
41 : isalpha((x)) ? (x) \
43 int debVersioningSystem::CmpFragment(const char *A
,const char *AEnd
,
44 const char *B
,const char *BEnd
)
46 if (A
>= AEnd
&& B
>= BEnd
)
50 if (*B
== '~') return 1;
55 if (*A
== '~') return -1;
59 /* Iterate over the whole string
60 What this does is to split the whole string into groups of
61 numeric and non numeric portions. For instance:
63 Has 4 portions 'a', '67', 'bhgs', '89'. A more normal:
65 Has '2', '.', '7', '.' ,'-linux-','1' */
68 while (lhs
!= AEnd
&& rhs
!= BEnd
)
72 while (lhs
!= AEnd
&& rhs
!= BEnd
&&
73 (!isdigit(*lhs
) || !isdigit(*rhs
)))
86 while (isdigit(*lhs
) && isdigit(*rhs
))
89 first_diff
= *lhs
- *rhs
;
102 // The strings must be equal
103 if (lhs
== AEnd
&& rhs
== BEnd
)
109 if (*rhs
== '~') return 1;
116 if (*lhs
== '~') return -1;
124 // debVS::CmpVersion - Comparison for versions /*{{{*/
125 // ---------------------------------------------------------------------
126 /* This fragments the version into E:V-R triples and compares each
127 portion separately. */
128 int debVersioningSystem::DoCmpVersion(const char *A
,const char *AEnd
,
129 const char *B
,const char *BEnd
)
131 // Strip off the epoch and compare it
134 for (;lhs
!= AEnd
&& *lhs
!= ':'; lhs
++);
135 for (;rhs
!= BEnd
&& *rhs
!= ':'; rhs
++);
141 // Special case: a zero epoch is the same as no epoch,
145 for (; *A
== '0'; ++A
);
154 for (; *B
== '0'; ++B
);
163 int Res
= CmpFragment(A
,lhs
,B
,rhs
);
174 const char *dlhs
= AEnd
-1;
175 const char *drhs
= BEnd
-1;
176 for (;dlhs
> lhs
&& *dlhs
!= '-'; dlhs
--);
177 for (;drhs
> rhs
&& *drhs
!= '-'; drhs
--);
184 // Compare the main version
185 Res
= CmpFragment(lhs
,dlhs
,rhs
,drhs
);
195 // no debian revision need to be treated like -0
196 if (*(dlhs
-1) == '-' && *(drhs
-1) == '-')
197 return CmpFragment(dlhs
,AEnd
,drhs
,BEnd
);
198 else if (*(dlhs
-1) == '-')
200 const char* null
= "0";
201 return CmpFragment(dlhs
,AEnd
,null
, null
+1);
203 else if (*(drhs
-1) == '-')
205 const char* null
= "0";
206 return CmpFragment(null
, null
+1, drhs
, BEnd
);
212 // debVS::CheckDep - Check a single dependency /*{{{*/
213 // ---------------------------------------------------------------------
214 /* This simply preforms the version comparison and switch based on
215 operator. If DepVer is 0 then we are comparing against a provides
217 bool debVersioningSystem::CheckDep(const char *PkgVer
,
218 int Op
,const char *DepVer
)
220 if (DepVer
== 0 || DepVer
[0] == 0)
222 if (PkgVer
== 0 || PkgVer
[0] == 0)
225 // Perform the actual comparision.
226 int Res
= CmpVersion(PkgVer
,DepVer
);
229 case pkgCache::Dep::LessEq
:
234 case pkgCache::Dep::GreaterEq
:
239 case pkgCache::Dep::Less
:
244 case pkgCache::Dep::Greater
:
249 case pkgCache::Dep::Equals
:
254 case pkgCache::Dep::NotEquals
:
263 // debVS::UpstreamVersion - Return the upstream version string /*{{{*/
264 // ---------------------------------------------------------------------
265 /* This strips all the debian specific information from the version number */
266 string
debVersioningSystem::UpstreamVersion(const char *Ver
)
268 // Strip off the bit before the first colon
270 for (; *I
!= 0 && *I
!= ':'; I
++);
274 // Chop off the trailing -
276 unsigned Last
= strlen(Ver
);
281 return string(Ver
,Last
);