Needs Unpack fixes
[ntk/apt.git] / apt-pkg / algorithms.cc
index 2e4ca5c..6328a20 100644 (file)
@@ -1,6 +1,6 @@
 // -*- mode: cpp; mode: fold -*-
 // Description                                                         /*{{{*/
-// $Id: algorithms.cc,v 1.4 1998/10/02 04:39:42 jgg Exp $
+// $Id: algorithms.cc,v 1.12 1998/11/23 07:02:58 jgg Exp $
 /* ######################################################################
 
    Algorithms - A set of misc algorithms
@@ -165,6 +165,14 @@ bool pkgApplyStatus(pkgDepCache &Cache)
 {
    for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
    {
+      // Only choice for a ReInstReq package is to reinstall
+      if (I->InstState == pkgCache::State::ReInstReq ||
+         I->InstState == pkgCache::State::HoldReInstReq)
+      {
+        Cache.MarkKeep(I);
+        continue;
+      }
+      
       switch (I->CurrentState)
       {
         // This means installation failed somehow
@@ -197,7 +205,7 @@ bool pkgFixBroken(pkgDepCache &Cache)
    for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
       if (Cache[I].NowBroken() == true)
         Cache.MarkInstall(I,true);
-
+   
    /* Fix packages that are in a NeedArchive state but don't have a
       downloadable install version */
    for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
@@ -209,7 +217,7 @@ bool pkgFixBroken(pkgDepCache &Cache)
       if (Cache[I].InstVerIter(Cache).Downloadable() == false)
         continue;
 
-      Cache.MarkInstall(I,true);
+      Cache.MarkInstall(I,true);      
    }
    
    pkgProblemResolver Fix(Cache);
@@ -245,14 +253,17 @@ bool pkgDistUpgrade(pkgDepCache &Cache)
         Cache.MarkInstall(I,false);
 
    pkgProblemResolver Fix(Cache);
-   
+
    // Hold back held packages.
-   for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
+   if (_config->FindB("APT::Ingore-Hold",false) == false)
    {
-      if (I->SelectedState == pkgCache::State::Hold)
+      for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
       {
-        Fix.Protect(I);
-        Cache.MarkKeep(I);
+        if (I->SelectedState == pkgCache::State::Hold)
+        {
+           Fix.Protect(I);
+           Cache.MarkKeep(I);
+        }
       }
    }
    
@@ -277,8 +288,9 @@ bool pkgAllUpgrade(pkgDepCache &Cache)
       if (Cache[I].Install() == true)
         Fix.Protect(I);
          
-      if (I->SelectedState == pkgCache::State::Hold)
-        continue;
+      if (_config->FindB("APT::Ingore-Hold",false) == false)
+        if (I->SelectedState == pkgCache::State::Hold)
+           continue;
       
       if (I->CurrentVer != 0 && Cache[I].InstallVer != 0)
         Cache.MarkInstall(I,false);
@@ -287,6 +299,43 @@ bool pkgAllUpgrade(pkgDepCache &Cache)
    return Fix.ResolveByKeep();
 }
                                                                        /*}}}*/
+// MinimizeUpgrade - Minimizes the set of packages to be upgraded      /*{{{*/
+// ---------------------------------------------------------------------
+/* This simply goes over the entire set of packages and tries to keep 
+   each package marked for upgrade. If a conflict is generated then 
+   the package is restored. */
+bool pkgMinimizeUpgrade(pkgDepCache &Cache)
+{   
+   if (Cache.BrokenCount() != 0)
+      return false;
+   
+   // We loop indefinately to get the minimal set size.
+   bool Change = false;
+   do
+   {
+      Change = false;
+      for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
+      {
+        // Not interesting
+        if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true)
+           continue;
+        
+        // Keep it and see if that is OK
+        Cache.MarkKeep(I);
+        if (Cache.BrokenCount() != 0)
+           Cache.MarkInstall(I,false);
+        else
+           Change = true;
+      }      
+   }
+   while (Change == true);
+
+   if (Cache.BrokenCount() != 0)
+      return _error->Error("Internal Error in pkgMinimizeUpgrade");
+   
+   return true;
+}
+                                                                       /*}}}*/
 
 // ProblemResolver::pkgProblemResolver - Constructor                   /*{{{*/
 // ---------------------------------------------------------------------
@@ -603,7 +652,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
         {
            if (Debug == true)
               clog << " Try to Re-Instate " << I.Name() << endl;
-           int OldBreaks = Cache.BrokenCount();
+           unsigned long OldBreaks = Cache.BrokenCount();
            pkgCache::Version *OldVer = Cache[I].InstallVer;
            Flags[I->ID] &= ReInstateTried;
            
@@ -630,16 +679,9 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
         for (pkgCache::DepIterator D = Cache[I].InstVerIter(Cache).DependsList(); D.end() == false;)
         {
            // Compute a single dependency element (glob or)
-           pkgCache::DepIterator Start = D;
-           pkgCache::DepIterator End = D;
-           unsigned char State = 0;
-           for (bool LastOR = true; D.end() == false && LastOR == true; D++)
-           {
-              State |= Cache[D];
-              LastOR = (D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or;
-              if (LastOR == true)
-                 End = D;
-           }
+           pkgCache::DepIterator Start;
+           pkgCache::DepIterator End;
+           D.GlobOr(Start,End);
            
            // We only worry about critical deps.
            if (End.IsCritical() != true)
@@ -659,10 +701,20 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
                    
            if (Debug == true)
               clog << "Package " << I.Name() << " has broken dep on " << End.TargetPkg().Name() << endl;
-           
-           /* Conflicts is simple, decide if we should remove this package
-              or the conflicted one */
+
+           /* Look across the version list. If there are no possible
+              targets then we keep the package and bail. This is necessary
+              if a package has a dep on another package that cant be found */
            pkgCache::Version **VList = End.AllTargets();
+           if (*VList == 0 && (Flags[I->ID] & Protected) != Protected &&
+               End->Type != pkgCache::Dep::Conflicts && 
+               Cache[I].NowBroken() == false)
+           {
+              Change = true;
+              Cache.MarkKeep(I);
+              break;
+           }
+           
            bool Done = false;
            for (pkgCache::Version **V = VList; *V != 0; V++)
            {
@@ -676,7 +728,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
                   ((Cache[End] & pkgDepCache::DepGNow) == 0 &&
                    End->Type != pkgCache::Dep::Conflicts))
               {
-                 if ((Flags[I->ID] & Protected) != 0)
+                 if ((Flags[I->ID] & Protected) == Protected)
                     continue;
 
                  // See if a keep will do
@@ -718,7 +770,8 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
            }
 
            // Hm, nothing can possibly satisify this dep. Nuke it.
-           if (VList[0] == 0 && End->Type != pkgCache::Dep::Conflicts)
+           if (VList[0] == 0 && End->Type != pkgCache::Dep::Conflicts &&
+               (Flags[I->ID] & Protected) != Protected)
            {
               Cache.MarkKeep(I);
               if (Cache[I].InstBroken() == false)
@@ -866,7 +919,6 @@ bool pkgProblemResolver::ResolveByKeep()
         
         // Look at all the possible provides on this package
         pkgCache::Version **VList = End.AllTargets();
-        bool Done = false;
         for (pkgCache::Version **V = VList; *V != 0; V++)
         {
            pkgCache::VerIterator Ver(Cache,*V);
@@ -905,3 +957,20 @@ bool pkgProblemResolver::ResolveByKeep()
    return true;
 }
                                                                        /*}}}*/
+// ProblemResolver::InstallProtect - Install all protected packages    /*{{{*/
+// ---------------------------------------------------------------------
+/* This is used to make sure protected packages are installed */
+void pkgProblemResolver::InstallProtect()
+{
+   for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
+   {
+      if ((Flags[I->ID] & Protected) == Protected)
+      {
+        if ((Flags[I->ID] & ToRemove) == ToRemove)
+           Cache.MarkDelete(I);
+        else
+           Cache.MarkInstall(I,false);
+      }
+   }   
+}
+                                                                       /*}}}*/