]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/depcache.cc
more explicit MarkRequired algorithm code
[apt.git] / apt-pkg / depcache.cc
index 02f61bf13ba28d6528795caf55a11200c47e15d4..ee40b879c04328110262d4ef7d04b24f9b8abc9f 100644 (file)
@@ -13,7 +13,6 @@
 #include <apt-pkg/depcache.h>
 #include <apt-pkg/versionmatch.h>
 #include <apt-pkg/error.h>
-#include <apt-pkg/sptr.h>
 #include <apt-pkg/fileutl.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/configuration.h>
@@ -23,6 +22,7 @@
 #include <apt-pkg/cacheset.h>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/cacheiterators.h>
+#include <apt-pkg/prettyprinters.h>
 #include <apt-pkg/cachefile.h>
 #include <apt-pkg/macros.h>
 
@@ -154,7 +154,7 @@ bool pkgDepCache::Init(OpProgress * const Prog)
       State.iFlags = 0;
 
       // Figure out the install version
-      State.CandidateVer = GetCandidateVer(I);
+      State.CandidateVer = LocalPolicy->GetCandidateVer(I);
       State.InstallVer = I.CurrentVer();
       State.Mode = ModeKeep;
 
@@ -327,6 +327,11 @@ bool pkgDepCache::writeStateFile(OpProgress * const /*prog*/, bool const Install
            return false;
       }
    }
+   if (StateFile.Failed())
+   {
+      OutFile.OpFail();
+      return false;
+   }
    if (OutFile.Close() == false)
       return false;
    chmod(state.c_str(), 0644);
@@ -792,7 +797,7 @@ bool pkgDepCache::MarkKeep(PkgIterator const &Pkg, bool Soft, bool FromUser,
 #endif
 
    if (DebugMarker == true)
-      std::clog << OutputInDepth(Depth) << "MarkKeep " << Pkg << " FU=" << FromUser << std::endl;
+      std::clog << OutputInDepth(Depth) << "MarkKeep " << APT::PrettyPkg(this, Pkg) << " FU=" << FromUser << std::endl;
 
    RemoveSizes(Pkg);
    RemoveStates(Pkg);
@@ -872,7 +877,7 @@ bool pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool rPurge,
    }
 
    if (DebugMarker == true)
-      std::clog << OutputInDepth(Depth) << (rPurge ? "MarkPurge " : "MarkDelete ") << Pkg << " FU=" << FromUser << std::endl;
+      std::clog << OutputInDepth(Depth) << (rPurge ? "MarkPurge " : "MarkDelete ") << APT::PrettyPkg(this, Pkg) << " FU=" << FromUser << std::endl;
 
    RemoveSizes(Pkg);
    RemoveStates(Pkg);
@@ -908,7 +913,7 @@ bool pkgDepCache::IsDeleteOkProtectInstallRequests(PkgIterator const &Pkg,
       if (P.InstallVer != 0 && P.Status == 2 && (P.Flags & Flag::Auto) != Flag::Auto)
       {
         if (DebugMarker == true)
-           std::clog << OutputInDepth(Depth) << "Manual install request prevents MarkDelete of " << Pkg << std::endl;
+           std::clog << OutputInDepth(Depth) << "Manual install request prevents MarkDelete of " << APT::PrettyPkg(this, Pkg) << std::endl;
         return false;
       }
    }
@@ -958,7 +963,7 @@ bool pkgDepCache::IsModeChangeOk(ModeList const mode, PkgIterator const &Pkg,
    {
       if (unlikely(DebugMarker == true))
         std::clog << OutputInDepth(Depth) << "Ignore Mark" << PrintMode(mode)
-                  << " of " << Pkg << " as its mode (" << PrintMode(P.Mode)
+                  << " of " << APT::PrettyPkg(this, Pkg) << " as its mode (" << PrintMode(P.Mode)
                   << ") is protected" << std::endl;
       return false;
    }
@@ -968,7 +973,7 @@ bool pkgDepCache::IsModeChangeOk(ModeList const mode, PkgIterator const &Pkg,
    {
       if (unlikely(DebugMarker == true))
         std::clog << OutputInDepth(Depth) << "Hold prevents Mark" << PrintMode(mode)
-                  << " of " << Pkg << std::endl;
+                  << " of " << APT::PrettyPkg(this, Pkg) << std::endl;
       return false;
    }
 
@@ -1017,6 +1022,8 @@ struct CompareProviders {
         if (instA != instB)
            return instA == false;
       }
+      if ((A->CurrentVer == 0 || B->CurrentVer == 0) && A->CurrentVer != B->CurrentVer)
+        return A->CurrentVer == 0;
       // Prefer packages in the same group as the target; e.g. foo:i386, foo:amd64
       if (A->Group != B->Group)
       {
@@ -1126,7 +1133,7 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
       return true;
 
    if (DebugMarker == true)
-      std::clog << OutputInDepth(Depth) << "MarkInstall " << Pkg << " FU=" << FromUser << std::endl;
+      std::clog << OutputInDepth(Depth) << "MarkInstall " << APT::PrettyPkg(this, Pkg) << " FU=" << FromUser << std::endl;
 
    bool MoveAutoBitToDependencies = false;
    VerIterator const PV = P.InstVerIter(*this);
@@ -1182,7 +1189,7 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
 
       /* unsatisfiable dependency: IsInstallOkDependenciesSatisfiableByCandidates
          would have prevented us to get here if not overridden, so just skip
-        over the problem here as the frontend will know what it is doing */
+        over the problem here as the front-end will know what it is doing */
       if (Ors == 1 && (DepState[Start->ID] &DepCVer) != DepCVer && Start.IsNegative() == false)
         continue;
 
@@ -1281,9 +1288,9 @@ bool pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst,
         Otherwise we remove the offender if needed */
       else if (Start.IsNegative() == true && Start->Type != pkgCache::Dep::Obsoletes)
       {
-        SPtrArray<Version *> List = Start.AllTargets();
+        std::unique_ptr<Version *[]> List(Start.AllTargets());
         pkgCache::PkgIterator TrgPkg = Start.TargetPkg();
-        for (Version **I = List; *I != 0; I++)
+        for (Version **I = List.get(); *I != 0; I++)
         {
            VerIterator Ver(*this,*I);
            PkgIterator Pkg = Ver.ParentPkg();
@@ -1359,7 +1366,7 @@ bool pkgDepCache::IsInstallOkMultiArchSameVersionSynced(PkgIterator const &Pkg,
       // not having a candidate or being in sync
       // (simple string-compare as stuff like '1' == '0:1-0' can't happen here)
       VerIterator CV = PkgState[P->ID].CandidateVerIter(*this);
-      if (CV.end() == true || strcmp(Pkg.CandVersion(), CV.VerStr()) == 0)
+      if (CV.end() == true || strcmp(CandVer.VerStr(), CV.VerStr()) == 0)
         continue;
 
       // packages losing M-A:same can be out-of-sync
@@ -1372,9 +1379,9 @@ bool pkgDepCache::IsInstallOkMultiArchSameVersionSynced(PkgIterator const &Pkg,
 
       PkgState[Pkg->ID].iFlags |= AutoKept;
       if (unlikely(DebugMarker == true))
-        std::clog << OutputInDepth(Depth) << "Ignore MarkInstall of " << Pkg
-           << " as it is not in sync with its M-A:same sibling " << P
-           << " (" << Pkg.CandVersion() << " != " << CV.VerStr() << ")" << std::endl;
+        std::clog << OutputInDepth(Depth) << "Ignore MarkInstall of " << APT::PrettyPkg(this, Pkg)
+           << " as it is not in sync with its M-A:same sibling " << APT::PrettyPkg(this, P)
+           << " (" << CandVer.VerStr() << " != " << CV.VerStr() << ")" << std::endl;
       return false;
    }
 
@@ -1415,12 +1422,20 @@ bool pkgDepCache::IsInstallOkDependenciesSatisfiableByCandidates(PkgIterator con
       if (Ors == 1 && (DepState[Start->ID] &DepCVer) != DepCVer)
       {
         if (DebugAutoInstall == true)
-           std::clog << OutputInDepth(Depth) << Start << " can't be satisfied!" << std::endl;
+           std::clog << OutputInDepth(Depth) << APT::PrettyDep(this, Start) << " can't be satisfied!" << std::endl;
 
         // the dependency is critical, but can't be installed, so discard the candidate
         // as the problemresolver will trip over it otherwise trying to install it (#735967)
         if (Pkg->CurrentVer != 0 && (PkgState[Pkg->ID].iFlags & Protected) != Protected)
+         {
            SetCandidateVersion(Pkg.CurrentVer());
+            StateCache &State = PkgState[Pkg->ID];
+           if (State.Mode != ModeDelete)
+           {
+              State.Mode = ModeKeep;
+              State.Update(Pkg, *this);
+           }
+         }
         return false;
       }
    }
@@ -1468,6 +1483,11 @@ void pkgDepCache::SetReInstall(PkgIterator const &Pkg,bool To)
    }
 }
                                                                        /*}}}*/
+pkgCache::VerIterator pkgDepCache::GetCandidateVersion(PkgIterator const &Pkg)/*{{{*/
+{
+   return PkgState[Pkg->ID].CandidateVerIter(*this);
+}
+                                                                       /*}}}*/
 // DepCache::SetCandidateVersion - Change the candidate version                /*{{{*/
 // ---------------------------------------------------------------------
 /* */
@@ -1689,11 +1709,7 @@ void pkgDepCache::StateCache::Update(PkgIterator Pkg,pkgCache &Cache)
    CurVersion = "";
    if (Pkg->CurrentVer != 0)
       CurVersion = Pkg.CurrentVer().VerStr();
-   
-   // Strip off the epochs for display
-   CurVersion = StripEpoch(CurVersion);
-   CandVersion = StripEpoch(CandVersion);
-   
+
    // Figure out if its up or down or equal
    Status = Ver.CompareVer(Pkg.CurrentVer());
    if (Pkg->CurrentVer == 0 || Pkg->VersionList == 0 || CandidateVer == 0)
@@ -1780,6 +1796,8 @@ bool pkgDepCache::Policy::IsImportantDep(DepIterator const &Dep) const
 // Policy::GetPriority - Get the priority of the package pin           /*{{{*/
 APT_CONST signed short pkgDepCache::Policy::GetPriority(pkgCache::PkgIterator const &/*Pkg*/)
 { return 0; }
+APT_CONST signed short pkgDepCache::Policy::GetPriority(pkgCache::VerIterator const &/*Ver*/, bool /*ConsiderFiles*/)
+{ return 0; }
 APT_CONST signed short pkgDepCache::Policy::GetPriority(pkgCache::PkgFileIterator const &/*File*/)
 { return 0; }
                                                                        /*}}}*/
@@ -1829,28 +1847,41 @@ bool pkgDepCache::MarkRequired(InRootSetFunc &userFunc)
    bool const follow_suggests   = MarkFollowsSuggests();
 
    // do the mark part, this is the core bit of the algorithm
-   for(PkgIterator p = PkgBegin(); !p.end(); ++p)
+   for (PkgIterator P = PkgBegin(); !P.end(); ++P)
    {
-      if(!(PkgState[p->ID].Flags & Flag::Auto) ||
-         (p->Flags & Flag::Essential) ||
-         (p->Flags & Flag::Important) ||
-         userFunc.InRootSet(p) ||
-         // be nice even then a required package violates the policy (#583517)
-         // and do the full mark process also for required packages
-         (p.CurrentVer().end() != true &&
-          p.CurrentVer()->Priority == pkgCache::State::Required) ||
-         // packages which can't be changed (like holds) can't be garbage
-         (IsModeChangeOk(ModeGarbage, p, 0, false) == false))
+      if (P->CurrentVer == 0)
+      {
+        if (PkgState[P->ID].Keep())
+           continue;
+      }
+      else
       {
-        // the package is installed (and set to keep)
-        if(PkgState[p->ID].Keep() && !p.CurrentVer().end())
-           MarkPackage(p, p.CurrentVer(),
-                       follow_recommends, follow_suggests);
-        // the package is to be installed 
-        else if(PkgState[p->ID].Install())
-           MarkPackage(p, PkgState[p->ID].InstVerIter(*this),
-                       follow_recommends, follow_suggests);
+        if (PkgState[P->ID].Delete())
+           continue;
       }
+
+      if ((PkgState[P->ID].Flags & Flag::Auto) == 0)
+        ;
+      else if ((P->Flags & Flag::Essential) || (P->Flags & Flag::Important))
+        ;
+      // be nice even then a required package violates the policy (#583517)
+      // and do the full mark process also for required packages
+      else if (P->CurrentVer != 0 && P.CurrentVer()->Priority == pkgCache::State::Required)
+        ;
+      else if (userFunc.InRootSet(P))
+        ;
+      // packages which can't be changed (like holds) can't be garbage
+      else if (IsModeChangeOk(ModeGarbage, P, 0, false) == false)
+        ;
+      else
+        continue;
+
+      if (PkgState[P->ID].Install())
+        MarkPackage(P, PkgState[P->ID].InstVerIter(*this),
+              follow_recommends, follow_suggests);
+      else
+        MarkPackage(P, P.CurrentVer(),
+              follow_recommends, follow_suggests);
    }
 
    return true;
@@ -2010,7 +2041,7 @@ bool pkgDepCache::MarkAndSweep(InRootSetFunc &rootFunc)
 }
 bool pkgDepCache::MarkAndSweep()
 {
-   std::auto_ptr<InRootSetFunc> f(GetRootSetFunc());
+   std::unique_ptr<InRootSetFunc> f(GetRootSetFunc());
    if(f.get() != NULL)
       return MarkAndSweep(*f.get());
    else