]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/version.cc
Fixed espy's bug with experimental
[apt.git] / apt-pkg / version.cc
index 9f245a9e70510e70ef48707db5f6a5b32b8ad9d9..f3ebb556e0389dae658483e935379bb9ec77e25b 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: version.cc,v 1.4 1998/07/12 23:58:42 jgg Exp $
+// $Id: version.cc,v 1.8 1998/12/05 01:44:57 jgg Exp $
 /* ######################################################################
 
    Version - Version string 
 #include <stdlib.h>
                                                                        /*}}}*/
 
-// Version::pkgVersion - Default Constructor                           /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-pkgVersion::pkgVersion()
-{
-}
-                                                                       /*}}}*/
-// Version::operator == - Checks if two versions are equal             /*{{{*/
-// ---------------------------------------------------------------------
-/* We can't simply perform a string compare because of epochs. */
-bool pkgVersion::operator ==(const pkgVersion &Vrhs) const
-{
-   if (pkgVersionCompare(Value.begin(),Value.end(),
-                    Vrhs.Value.begin(),Vrhs.Value.end()) == 0)
-      return true;
-   return false;
-}
-                                                                       /*}}}*/
-// Version::operator < - Checks if this is less than another version   /*{{{*/
-// ---------------------------------------------------------------------
-/* All other forms of comparision can be built up from this single function.
-    a > b -> b < a
-    a <= b -> !(a > b) -> !(b < a)
-    a >= b -> !(a < b) 
- */
-bool pkgVersion::operator <(const pkgVersion &Vrhs) const
-{
-   if (pkgVersionCompare(Value.begin(),Value.end(),
-                    Vrhs.Value.begin(),Vrhs.Value.end()) == -1)
-      return true;
-   return false;
-}
-                                                                       /*}}}*/
 // StrToLong - Convert the string between two iterators to a long      /*{{{*/
 // ---------------------------------------------------------------------
 /* */
@@ -86,36 +53,18 @@ int pkgVersionCompare(string A,string B)
 }
 
                                                                        /*}}}*/
-// VersionCompare - Greater than comparison for versions               /*{{{*/
+// iVersionCompare - Compare versions                                  /*{{{*/
 // ---------------------------------------------------------------------
-/* */
-int pkgVersionCompare(const char *A, const char *AEnd, const char *B,
-                      const char *BEnd)
+/* This compares a fragment of the version. */
+static int iVersionCompare(const char *A, const char *AEnd, const char *B,
+                          const char *BEnd)
 {
-   // lhs = left hand side, rhs = right hand side
-   const char *lhs = A;
-   const char *rhs = B;
-
-   /* Consider epochs. They need special handling because an epoch 
-      must not be compared against the first element of the real version.
-      This works okay when both sides have an epoch but when only one
-      does it must compare the missing epoch to 0 */
-   for (;lhs != AEnd && *lhs != ':'; lhs++);
-   for (;rhs != BEnd && *rhs != ':'; rhs++);
-
-   // Parse the epoch out
-   unsigned long lhsEpoch = 0;
-   unsigned long rhsEpoch = 0;
-   if (lhs != AEnd && *lhs == ':')
-      lhsEpoch = StrToLong(A,lhs);
-   if (rhs != BEnd && *rhs == ':')
-      rhsEpoch = StrToLong(B,rhs);
-   if (lhsEpoch != rhsEpoch)
-   {
-      if (lhsEpoch > rhsEpoch)
-        return 1;
+   if (A >= AEnd && B >= BEnd)
+      return 0;
+   if (A >= AEnd)
       return -1;
-   }
+   if (B >= BEnd)
+      return 1;
    
    /* Iterate over the whole string
       What this does is to spilt the whole string into groups of 
@@ -124,8 +73,8 @@ int pkgVersionCompare(const char *A, const char *AEnd, const char *B,
       Has 4 portions 'a', '67', 'bhgs', '89'. A more normal:
          2.7.2-linux-1
       Has '2', '.', '7', '.' ,'-linux-','1' */
-   lhs = A;
-   rhs = B;
+   const char *lhs = A;
+   const char *rhs = B;
    while (lhs != AEnd && rhs != BEnd)
    {
       // Starting points
@@ -139,10 +88,10 @@ int pkgVersionCompare(const char *A, const char *AEnd, const char *B,
       
       if (Digit == true)
       {
-        // If the lhs has a digit and the rhs does not then true
+        // If the lhs has a digit and the rhs does not then <
         if (rhs - Srhs == 0)
            return -1;
-
+        
         // Generate integers from the strings.
         unsigned long Ilhs = StrToLong(Slhs,lhs);
         unsigned long Irhs = StrToLong(Srhs,rhs);
@@ -161,20 +110,17 @@ int pkgVersionCompare(const char *A, const char *AEnd, const char *B,
            if (*Slhs != *Srhs)
            {
               /* We need to compare non alpha chars as higher than alpha
-                 chars (a < !) This is so things like  7.6p2-4 and 7.6-0 
-                 compare higher as well as . and -. I am not sure how
-                 the dpkg code manages to achive the != '-' test, but it
-                 is necessary. */
+                 chars (a < !) */
               int lc = *Slhs;
               int rc = *Srhs;
-              if (isalpha(lc) == 0 && lc != '-') lc += 256;
-              if (isalpha(rc) == 0 && rc != '-') rc += 256;
+              if (isalpha(lc) == 0) lc += 256;
+              if (isalpha(rc) == 0) rc += 256;
               if (lc > rc)
                  return 1;
               return -1;
            }
         }
-        
+
         // If the lhs is shorter than the right it is 'less'
         if (lhs - Slhs < rhs - Srhs)
            return -1;
@@ -201,6 +147,58 @@ int pkgVersionCompare(const char *A, const char *AEnd, const char *B,
    return 1;
 }
                                                                        /*}}}*/
+// VersionCompare - Comparison for versions                            /*{{{*/
+// ---------------------------------------------------------------------
+/* This fragments the version into E:V-R triples and compares each 
+   portion seperately. */
+int pkgVersionCompare(const char *A, const char *AEnd, const char *B,
+                     const char *BEnd)
+{
+   // Strip off the epoch and compare it 
+   const char *lhs = A;
+   const char *rhs = B;
+   for (;lhs != AEnd && *lhs != ':'; lhs++);
+   for (;rhs != BEnd && *rhs != ':'; rhs++);
+   if (lhs == AEnd)
+      lhs = A;
+   if (rhs == BEnd)
+      rhs = B;
+   
+   // Compare the epoch
+   int Res = iVersionCompare(A,lhs,B,rhs);
+   if (Res != 0)
+      return Res;
+
+   // Skip the :
+   if (lhs != A)
+      lhs++;
+   if (rhs != B)
+      rhs++;
+   
+   // Find the last - 
+   const char *dlhs = AEnd-1;
+   const char *drhs = BEnd-1;
+   for (;dlhs > lhs && *dlhs != '-'; dlhs--);
+   for (;drhs > rhs && *drhs != '-'; drhs--);
+
+   if (dlhs == lhs)
+      dlhs = AEnd;
+   if (drhs == rhs)
+      drhs = BEnd;
+   
+   // Compare the main version
+   Res = iVersionCompare(lhs,dlhs,rhs,drhs);
+   if (Res != 0)
+      return Res;
+   
+   // Skip the -
+   if (dlhs != lhs)
+      dlhs++;
+   if (drhs != rhs)
+      drhs++;
+   return iVersionCompare(dlhs,AEnd,drhs,BEnd);
+}
+                                                                       /*}}}*/
 // CheckDep - Check a single dependency                                        /*{{{*/
 // ---------------------------------------------------------------------
 /* This simply preforms the version comparison and switch based on 
@@ -250,4 +248,3 @@ bool pkgCheckDep(const char *DepVer,const char *PkgVer,int Op)
    return false;
 }
                                                                        /*}}}*/
-