X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/be615841e27068522c467899c96c541b74e4c349..dabe757a0a6d91e07ba30e3d580e49fe56eb4737:/apt-pkg/algorithms.cc

diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc
index ac9d3be0b..158f9c258 100644
--- a/apt-pkg/algorithms.cc
+++ b/apt-pkg/algorithms.cc
@@ -14,9 +14,6 @@
    ##################################################################### */
 									/*}}}*/
 // Include Files							/*{{{*/
-#ifdef __GNUG__
-#pragma implementation "apt-pkg/algorithms.h"
-#endif 
 #include <apt-pkg/algorithms.h>
 #include <apt-pkg/error.h>
 #include <apt-pkg/configuration.h>
@@ -26,6 +23,8 @@
     
 #include <apti18n.h>
 #include <sys/types.h>
+#include <cstdlib>
+#include <algorithm>
 #include <iostream>
 									/*}}}*/
 using namespace std;
@@ -102,6 +101,7 @@ bool pkgSimulate::Install(PkgIterator iPkg,string /*File*/)
 	 DepIterator End;
 	 D.GlobOr(Start,End);
 	 if (Start->Type == pkgCache::Dep::Conflicts ||
+	     Start->Type == pkgCache::Dep::DpkgBreaks ||
 	     Start->Type == pkgCache::Dep::Obsoletes ||
 	     End->Type == pkgCache::Dep::PreDepends)
          {
@@ -151,6 +151,8 @@ bool pkgSimulate::Configure(PkgIterator iPkg)
 	    cout << " Obsoletes:" << D.TargetPkg().Name();
 	 else if (D->Type == pkgCache::Dep::Conflicts)
 	    cout << " Conflicts:" << D.TargetPkg().Name();
+	 else if (D->Type == pkgCache::Dep::DpkgBreaks)
+	    cout << " Breaks:" << D.TargetPkg().Name();
 	 else
 	    cout << " Depends:" << D.TargetPkg().Name();
       }	    
@@ -255,6 +257,8 @@ bool pkgApplyStatus(pkgDepCache &Cache)
 	    re-unpacked (probably) */
 	 case pkgCache::State::UnPacked:
 	 case pkgCache::State::HalfConfigured:
+	 case pkgCache::State::TriggersAwaited:
+	 case pkgCache::State::TriggersPending:
 	 if ((I->CurrentVer != 0 && I.CurrentVer().Downloadable() == true) ||
 	     I.State() != pkgCache::PkgIterator::NeedsUnpack)
 	    Cache.MarkKeep(I, false, false);
@@ -506,8 +510,10 @@ void pkgProblemResolver::MakeScores()
 	 Score += PrioMap[Cache[I].InstVerIter(Cache)->Priority];
       
       /* This helps to fix oddball problems with conflicting packages
-         on the same level. We enhance the score of installed packages */
-      if (I->CurrentVer != 0)
+         on the same level. We enhance the score of installed packages 
+	 if those are not obsolete
+      */
+      if (I->CurrentVer != 0 && Cache[I].CandidateVer != 0 && Cache[I].CandidateVerIter(Cache).Downloadable())
 	 Score += 1;
    }
 
@@ -651,6 +657,7 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg)
 	       /* We let the algorithm deal with conflicts on its next iteration,
 		it is much smarter than us */
 	       if (Start->Type == pkgCache::Dep::Conflicts || 
+		   Start->Type == pkgCache::Dep::DpkgBreaks || 
 		   Start->Type == pkgCache::Dep::Obsoletes)
 		   break;
 	       
@@ -800,7 +807,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
 	    continue;
 	 
 	 if (Debug == true)
-	    cout << "Investigating " << I.Name() << endl;
+	    clog << "Investigating " << I.Name() << endl;
 	 
 	 // Isolate the problem dependency
 	 PackageKill KillList[100];
@@ -855,7 +862,12 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
 	       OldEnd = LEnd;
 	    }
 	    else
+            {
 	       Start++;
+	       // We only worry about critical deps.
+	       if (Start.IsCritical() != true)
+                  continue;
+            }
 
 	    // Dep is ok
 	    if ((Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall)
@@ -873,6 +885,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
 	    SPtrArray<pkgCache::Version *> VList = Start.AllTargets();
 	    if (*VList == 0 && (Flags[I->ID] & Protected) != Protected &&
 		Start->Type != pkgCache::Dep::Conflicts &&
+		Start->Type != pkgCache::Dep::DpkgBreaks &&
 		Start->Type != pkgCache::Dep::Obsoletes &&
 		Cache[I].NowBroken() == false)
 	    {	       
@@ -903,6 +916,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
 	       if (Scores[I->ID] <= Scores[Pkg->ID] ||
 		   ((Cache[Start] & pkgDepCache::DepNow) == 0 &&
 		    End->Type != pkgCache::Dep::Conflicts &&
+		    End->Type != pkgCache::Dep::DpkgBreaks &&
 		    End->Type != pkgCache::Dep::Obsoletes))
 	       {
 		  // Try a little harder to fix protected packages..
@@ -968,7 +982,22 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
 		      (Start->Type == pkgCache::Dep::Conflicts ||
 		       Start->Type == pkgCache::Dep::Obsoletes))
 		     continue;
-		  
+
+		  if (Start->Type == pkgCache::Dep::DpkgBreaks)
+		  {
+		     /* Would it help if we upgraded? */
+		     if (Cache[End] & pkgDepCache::DepGCVer) {
+			if (Debug)
+			   clog << "  Upgrading " << Pkg.Name() << " due to Breaks field in " << I.Name() << endl;
+			Cache.MarkInstall(Pkg, false, 0, false);
+			continue;
+		     }
+		     if (Debug)
+			clog << "  Will not break " << Pkg.Name() << " as stated in Breaks field in " << I.Name() <<endl;
+		     Cache.MarkKeep(I, false, false);
+		     continue;
+		  }
+
 		  // Skip adding to the kill list if it is protected
 		  if ((Flags[Pkg->ID] & Protected) != 0)
 		     continue;
@@ -989,6 +1018,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
 	    // Hm, nothing can possibly satisify this dep. Nuke it.
 	    if (VList[0] == 0 && 
 		Start->Type != pkgCache::Dep::Conflicts &&
+		Start->Type != pkgCache::Dep::DpkgBreaks &&
 		Start->Type != pkgCache::Dep::Obsoletes &&
 		(Flags[I->ID] & Protected) != Protected)
 	    {
@@ -1229,8 +1259,13 @@ void pkgProblemResolver::InstallProtect()
       {
 	 if ((Flags[I->ID] & ToRemove) == ToRemove)
 	    Cache.MarkDelete(I);
-	 else
-	    Cache.MarkInstall(I, false, 0, false);
+	 else 
+	 {
+	    // preserve the information whether the package was auto
+	    // or manually installed
+	    bool autoInst = (Cache[I].Flags & pkgCache::Flag::Auto);
+	    Cache.MarkInstall(I, false, 0, !autoInst);
+	 }
       }
    }   
 }