1 // -*- mode: cpp; mode: fold -*-
3 // $Id: debversion.cc,v 1.4 2002/11/22 06:59:35 doogie 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 #define order(x) ((x) == '~' ? -1 \
51 : isalpha((x)) ? (x) \
54 // debVS::CmpFragment - Compare versions /*{{{*/
55 // ---------------------------------------------------------------------
56 /* This compares a fragment of the version. Dpkg has a really short
57 version of this, but it is uh.. interesting to grok. */
58 int debVersioningSystem::CmpFragment(const char *A
,const char *AEnd
,
59 const char *B
,const char *BEnd
)
61 if (A
>= AEnd
&& B
>= BEnd
)
68 /* Iterate over the whole string
69 What this does is to spilt the whole string into groups of
70 numeric and non numeric portions. For instance:
72 Has 4 portions 'a', '67', 'bhgs', '89'. A more normal:
74 Has '2', '.', '7', '.' ,'-linux-','1' */
77 while (lhs
!= AEnd
&& rhs
!= BEnd
)
80 const char *Slhs
= lhs
;
81 const char *Srhs
= rhs
;
84 while ( (lhs
!= AEnd
&& !isdigit(*lhs
)) || (rhs
!= BEnd
&& !isdigit(*rhs
)) ) {
85 int vc
= order(*lhs
), rc
= order(*rhs
);
86 if (vc
!= rc
) return vc
- rc
;
90 while ( *lhs
== '0' ) lhs
++;
91 while ( *rhs
== '0' ) rhs
++;
92 while (isdigit(*lhs
) && isdigit(*rhs
)) {
93 if (!first_diff
) first_diff
= *lhs
- *rhs
;
96 if (isdigit(*lhs
)) return 1;
97 if (isdigit(*rhs
)) return -1;
98 if (first_diff
) return first_diff
;
101 // The strings must be equal
102 if (lhs
== AEnd
&& rhs
== BEnd
)
117 // debVS::CmpVersion - Comparison for versions /*{{{*/
118 // ---------------------------------------------------------------------
119 /* This fragments the version into E:V-R triples and compares each
120 portion separately. */
121 int debVersioningSystem::DoCmpVersion(const char *A
,const char *AEnd
,
122 const char *B
,const char *BEnd
)
124 // Strip off the epoch and compare it
127 for (;lhs
!= AEnd
&& *lhs
!= ':'; lhs
++);
128 for (;rhs
!= BEnd
&& *rhs
!= ':'; rhs
++);
135 int Res
= CmpFragment(A
,lhs
,B
,rhs
);
146 const char *dlhs
= AEnd
-1;
147 const char *drhs
= BEnd
-1;
148 for (;dlhs
> lhs
&& *dlhs
!= '-'; dlhs
--);
149 for (;drhs
> rhs
&& *drhs
!= '-'; drhs
--);
156 // Compare the main version
157 Res
= CmpFragment(lhs
,dlhs
,rhs
,drhs
);
167 return CmpFragment(dlhs
,AEnd
,drhs
,BEnd
);
170 // debVS::CheckDep - Check a single dependency /*{{{*/
171 // ---------------------------------------------------------------------
172 /* This simply preforms the version comparison and switch based on
173 operator. If DepVer is 0 then we are comparing against a provides
175 bool debVersioningSystem::CheckDep(const char *PkgVer
,
176 int Op
,const char *DepVer
)
178 if (DepVer
== 0 || DepVer
[0] == 0)
180 if (PkgVer
== 0 || PkgVer
[0] == 0)
183 // Perform the actual comparision.
184 int Res
= CmpVersion(PkgVer
,DepVer
);
187 case pkgCache::Dep::LessEq
:
192 case pkgCache::Dep::GreaterEq
:
197 case pkgCache::Dep::Less
:
202 case pkgCache::Dep::Greater
:
207 case pkgCache::Dep::Equals
:
212 case pkgCache::Dep::NotEquals
:
221 // debVS::UpstreamVersion - Return the upstream version string /*{{{*/
222 // ---------------------------------------------------------------------
223 /* This strips all the debian specific information from the version number */
224 string
debVersioningSystem::UpstreamVersion(const char *Ver
)
226 // Strip off the bit before the first colon
228 for (; *I
!= 0 && *I
!= ':'; I
++);
232 // Chop off the trailing -
234 unsigned Last
= strlen(Ver
);
239 return string(Ver
,Last
);