Browse Source

factor out Pkg/DepIterator prettyprinters into own header

The old prettyprinters have only access to the struct they pretty print,
which isn't enough usually as we want to know for a package also a bit
of state information like which version is the candidate.

We therefore need to pull the DepCache into context and hence use a
temporary struct which is printed instead of the iterator itself.
David Kalnischkies 8 years ago
parent
commit
84573326f4

+ 9 - 8
apt-pkg/algorithms.cc

@@ -24,6 +24,7 @@
 #include <apt-pkg/packagemanager.h>
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/cacheiterators.h>
+#include <apt-pkg/prettyprinters.h>
 
 #include <string.h>
 #include <string>
@@ -710,7 +711,7 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix)
          if (Scores[(*K)->ID] != 0)
          {
            pkgCache::PkgIterator Pkg(Cache,*K);
-           clog << Scores[(*K)->ID] << ' ' << Pkg << std::endl;
+           clog << Scores[(*K)->ID] << ' ' << APT::PrettyPkg(&Cache, Pkg) << std::endl;
          }
    }
 
@@ -765,7 +766,7 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix)
 	    continue;
 	 
 	 if (Debug == true)
-	    clog << "Investigating (" << Counter << ") " << I << endl;
+	    clog << "Investigating (" << Counter << ") " << APT::PrettyPkg(&Cache, I) << endl;
 	 
 	 // Isolate the problem dependency
 	 bool InOr = false;
@@ -835,7 +836,7 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix)
 	    }
 	    
 	    if (Debug == true)
-	       clog << "Broken " << Start << endl;
+	       clog << "Broken " << APT::PrettyDep(&Cache, Start) << endl;
 
 	    /* Look across the version list. If there are no possible
 	       targets then we keep the package and bail. This is necessary
@@ -942,7 +943,7 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix)
 			      is removed by the resolver because of a conflict or alike but it is
 			      dangerous as it could trigger new breaks/conflicts… */
 			   if (Debug == true)
-			      clog << "  Try Installing " << Start.TargetPkg() << " before changing " << I.FullName(false) << std::endl;
+			      clog << "  Try Installing " << APT::PrettyPkg(&Cache, Start.TargetPkg()) << " before changing " << I.FullName(false) << std::endl;
 			   unsigned long const OldBroken = Cache.BrokenCount();
 			   Cache.MarkInstall(Start.TargetPkg(), true, 1, false);
 			   // FIXME: we should undo the complete MarkInstall process here
@@ -1108,7 +1109,7 @@ bool pkgProblemResolver::InstOrNewPolicyBroken(pkgCache::PkgIterator I)
    if (Cache[I].InstBroken() == true)
    {
       if (Debug == true)
-	 std::clog << "  Dependencies are not satisfied for " << I << std::endl;
+	 std::clog << "  Dependencies are not satisfied for " << APT::PrettyPkg(&Cache, I) << std::endl;
       return true;
    }
 
@@ -1117,7 +1118,7 @@ bool pkgProblemResolver::InstOrNewPolicyBroken(pkgCache::PkgIterator I)
        Cache[I].InstPolicyBroken() == true)
    {
       if (Debug == true)
-	 std::clog << "  Policy breaks with upgrade of " << I << std::endl;
+	 std::clog << "  Policy breaks with upgrade of " << APT::PrettyPkg(&Cache, I) << std::endl;
       return true;
    }
 
@@ -1169,7 +1170,7 @@ bool pkgProblemResolver::ResolveByKeepInternal()
          if (Scores[(*K)->ID] != 0)
          {
            pkgCache::PkgIterator Pkg(Cache,*K);
-           clog << Scores[(*K)->ID] << ' ' << Pkg << std::endl;
+           clog << Scores[(*K)->ID] << ' ' << APT::PrettyPkg(&Cache, Pkg) << std::endl;
          }
    }
 
@@ -1224,7 +1225,7 @@ bool pkgProblemResolver::ResolveByKeepInternal()
 	 while (true)
 	 {
 	    if (Debug == true)
-	       clog << "Package " << I.FullName(false) << " " << Start << endl;
+	       clog << "Package " << I.FullName(false) << " " << APT::PrettyDep(&Cache, Start) << endl;
 
 	    // Look at all the possible provides on this package
 	    std::unique_ptr<pkgCache::Version *[]> VList(Start.AllTargets());

+ 2 - 2
apt-pkg/cacheiterators.h

@@ -179,7 +179,7 @@ class pkgCache::PkgIterator: public Iterator<Package, PkgIterator> {
 	const char *CurVersion() const APT_PURE;
 
 	//Nice printable representation
-	friend std::ostream& operator <<(std::ostream& out, PkgIterator i);
+	APT_DEPRECATED_MSG("Use APT::PrettyPkg instead") friend std::ostream& operator <<(std::ostream& out, PkgIterator i);
 	std::string FullName(bool const &Pretty = false) const;
 
 	// Constructors
@@ -343,7 +343,7 @@ class pkgCache::DepIterator : public Iterator<Dependency, DepIterator> {
 	}
 
 	//Nice printable representation
-	friend std::ostream& operator <<(std::ostream& out, DepIterator D);
+	APT_DEPRECATED_MSG("Use APT::PrettyDep instead") friend std::ostream& operator <<(std::ostream& out, DepIterator D);
 
 	inline DepIterator(pkgCache &Owner, Dependency *Trg, Version* = 0) :
 		Iterator<Dependency, DepIterator>(Owner, Trg), Type(DepVer), S2(Trg == 0 ? Owner.DepDataP : (Owner.DepDataP + Trg->DependencyData)) {

+ 10 - 9
apt-pkg/depcache.cc

@@ -22,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>
 
@@ -791,7 +792,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);
@@ -871,7 +872,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);
@@ -907,7 +908,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;
       }
    }
@@ -957,7 +958,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;
    }
@@ -967,7 +968,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;
    }
 
@@ -1127,7 +1128,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);
@@ -1373,8 +1374,8 @@ 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
+	 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;
    }
@@ -1416,7 +1417,7 @@ 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)

+ 1 - 0
apt-pkg/depcache.h

@@ -369,6 +369,7 @@ class pkgDepCache : protected pkgCache::Namespace
    
    // Accessors
    inline StateCache &operator [](PkgIterator const &I) {return PkgState[I->ID];};
+   inline StateCache &operator [](PkgIterator const &I) const {return PkgState[I->ID];};
    inline unsigned char &operator [](DepIterator const &I) {return DepState[I->ID];};
 
    /** \return A function identifying packages in the root set other

+ 19 - 18
apt-pkg/packagemanager.cc

@@ -28,6 +28,7 @@
 #include <apt-pkg/cacheiterators.h>
 #include <apt-pkg/strutl.h>
 #include <apt-pkg/install-progress.h>
+#include <apt-pkg/prettyprinters.h>
 
 #include <stddef.h>
 #include <list>
@@ -159,7 +160,7 @@ void pkgPackageManager::ImmediateAdd(PkgIterator I, bool UseInstallVer, unsigned
 	 if(!List->IsFlag(D.TargetPkg(), pkgOrderList::Immediate))
 	 {
 	    if(Debug)
-	       clog << OutputInDepth(Depth) << "ImmediateAdd(): Adding Immediate flag to " << D.TargetPkg() << " cause of " << D.DepType() << " " << I.FullName() << endl;
+	       clog << OutputInDepth(Depth) << "ImmediateAdd(): Adding Immediate flag to " << APT::PrettyPkg(&Cache, D.TargetPkg()) << " cause of " << D.DepType() << " " << I.FullName() << endl;
 	    List->Flag(D.TargetPkg(),pkgOrderList::Immediate);
 	    ImmediateAdd(D.TargetPkg(), UseInstallVer, Depth + 1);
 	 }
@@ -440,7 +441,7 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth)
 	       if (PkgLoop == true)
 	       {
 		  if (Debug)
-		     std::clog << OutputInDepth(Depth) << "Package " << Pkg << " loops in SmartConfigure";
+		     std::clog << OutputInDepth(Depth) << "Package " << APT::PrettyPkg(&Cache, Pkg) << " loops in SmartConfigure";
 		  if (List->IsFlag(DepPkg,pkgOrderList::UnPacked))
 		     Bad = false;
 		  else if (Debug)
@@ -458,7 +459,7 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth)
          if (Bad == false)
          {
             if (Debug)
-               std::clog << OutputInDepth(Depth) << "Found ok dep " << Start.TargetPkg() << std::endl;
+               std::clog << OutputInDepth(Depth) << "Found ok dep " << APT::PrettyPkg(&Cache, Start.TargetPkg()) << std::endl;
             continue;
          }
 
@@ -487,7 +488,7 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth)
 	       if (PkgLoop == true)
 	       {
 		  if (Debug)
-		     std::clog << OutputInDepth(Depth) << "Package " << Pkg << " loops in SmartConfigure";
+		     std::clog << OutputInDepth(Depth) << "Package " << APT::PrettyPkg(&Cache, Pkg) << " loops in SmartConfigure";
 		  if (List->IsFlag(DepPkg,pkgOrderList::UnPacked))
 		     Bad = false;
 		  else if (Debug)
@@ -498,7 +499,7 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth)
 	       else
 	       {
 		  if (Debug)
-		     clog << OutputInDepth(Depth) << "Unpacking " << DepPkg.FullName() << " to avoid loop " << Cur << endl;
+		     clog << OutputInDepth(Depth) << "Unpacking " << DepPkg.FullName() << " to avoid loop " << APT::PrettyDep(&Cache, Cur) << endl;
 		  if (NonLoopingSmart(UNPACK_IMMEDIATE, Pkg, DepPkg, Depth, PkgLoop, &Bad, &Changed) == false)
 		     return false;
 	       }
@@ -561,7 +562,7 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth)
 		    break;
 		  }
 		  if (Debug)
-		     std::clog << OutputInDepth(Depth) << "Configure already unpacked " << DepPkg << std::endl;
+		     std::clog << OutputInDepth(Depth) << "Configure already unpacked " << APT::PrettyPkg(&Cache, DepPkg) << std::endl;
 		  if (NonLoopingSmart(CONFIGURE, Pkg, DepPkg, Depth, PkgLoop, &Bad, &Changed) == false)
 		     return false;
 		  break;
@@ -579,7 +580,7 @@ bool pkgPackageManager::SmartConfigure(PkgIterator Pkg, int const Depth)
 
 
 	 if (Bad == true && Changed == false && Debug == true)
-	    std::clog << OutputInDepth(Depth) << "Could not satisfy " << *D << std::endl;
+	    std::clog << OutputInDepth(Depth) << "Could not satisfy " << APT::PrettyDep(&Cache, *D) << std::endl;
       }
       if (i++ > max_loops)
          return _error->Error("Internal error: MaxLoopCount reached in SmartUnPack (2) for %s, aborting", Pkg.FullName().c_str());
@@ -848,21 +849,21 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate, int c
 	       if (ConflictPkg.CurrentVer() != Ver)
 	       {
 		  if (Debug)
-		     std::clog << OutputInDepth(Depth) << "Ignore not-installed version " << Ver.VerStr() << " of " << ConflictPkg.FullName() << " for " << End << std::endl;
+		     std::clog << OutputInDepth(Depth) << "Ignore not-installed version " << Ver.VerStr() << " of " << ConflictPkg.FullName() << " for " << APT::PrettyDep(&Cache, End) << std::endl;
 		  continue;
 	       }
 
 	       if (List->IsNow(ConflictPkg) == false)
 	       {
 		  if (Debug)
-		     std::clog << OutputInDepth(Depth) << "Ignore already dealt-with version " << Ver.VerStr() << " of " << ConflictPkg.FullName() << " for " << End << std::endl;
+		     std::clog << OutputInDepth(Depth) << "Ignore already dealt-with version " << Ver.VerStr() << " of " << ConflictPkg.FullName() << " for " << APT::PrettyDep(&Cache, End) << std::endl;
 		  continue;
 	       }
 
 	       if (List->IsFlag(ConflictPkg,pkgOrderList::Removed) == true)
 	       {
 		  if (Debug)
-		     clog << OutputInDepth(Depth) << "Ignoring " << End << " as " << ConflictPkg.FullName() << "was temporarily removed" << endl;
+		     clog << OutputInDepth(Depth) << "Ignoring " << APT::PrettyDep(&Cache, End) << " as " << ConflictPkg.FullName() << "was temporarily removed" << endl;
 		  continue;
 	       }
 
@@ -871,7 +872,7 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate, int c
 		  if (End->Type == pkgCache::Dep::DpkgBreaks && End.IsMultiArchImplicit() == true)
 		  {
 		     if (Debug)
-			clog << OutputInDepth(Depth) << "Because dependency is MultiArchImplicit we ignored looping on: " << ConflictPkg << endl;
+			clog << OutputInDepth(Depth) << "Because dependency is MultiArchImplicit we ignored looping on: " << APT::PrettyPkg(&Cache, ConflictPkg) << endl;
 		     continue;
 		  }
 		  if (Debug)
@@ -891,7 +892,7 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate, int c
 	       {
 		  if (Debug)
 		  {
-		     clog << OutputInDepth(Depth) << "Unpacking " << ConflictPkg.FullName() << " to avoid " << End;
+		     clog << OutputInDepth(Depth) << "Unpacking " << ConflictPkg.FullName() << " to avoid " << APT::PrettyDep(&Cache, End);
 		     if (PkgLoop == true)
 			clog << " (Looping)";
 		     clog << std::endl;
@@ -903,7 +904,7 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate, int c
 		     // but if it fails ignore this failure and look for alternative ways of solving
 		     if (Debug)
 		     {
-			clog << OutputInDepth(Depth) << "Avoidance unpack of " << ConflictPkg.FullName() << " failed for " << End << " ignoring:" << std::endl;
+			clog << OutputInDepth(Depth) << "Avoidance unpack of " << ConflictPkg.FullName() << " failed for " << APT::PrettyDep(&Cache, End) << " ignoring:" << std::endl;
 			_error->DumpErrors(std::clog, GlobalError::DEBUG, false);
 		     }
 		     _error->RevertToStack();
@@ -911,18 +912,18 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate, int c
 		     if (List->IsFlag(ConflictPkg,pkgOrderList::Removed) == true)
 		     {
 			if (Debug)
-			   clog << OutputInDepth(Depth) << "But " << ConflictPkg.FullName() << " was temporarily removed in the meantime to satisfy " << End << endl;
+			   clog << OutputInDepth(Depth) << "But " << ConflictPkg.FullName() << " was temporarily removed in the meantime to satisfy " << APT::PrettyDep(&Cache, End) << endl;
 		     }
 		     else if (List->IsFlag(Pkg,pkgOrderList::Removed) == true)
 		     {
 			if (Debug)
-			   clog << OutputInDepth(Depth) << "But " << Pkg.FullName() << " was temporarily removed in the meantime to satisfy " << End << endl;
+			   clog << OutputInDepth(Depth) << "But " << Pkg.FullName() << " was temporarily removed in the meantime to satisfy " <<  APT::PrettyDep(&Cache, End) << endl;
 		     }
 		     // or b) we can make one go (removal or dpkg auto-deconfigure)
 		     else
 		     {
 			if (Debug)
-			   clog << OutputInDepth(Depth) << "So temprorary remove/deconfigure " << ConflictPkg.FullName() << " to satisfy " << End << endl;
+			   clog << OutputInDepth(Depth) << "So temprorary remove/deconfigure " << ConflictPkg.FullName() << " to satisfy " <<  APT::PrettyDep(&Cache, End) << endl;
 			if (EarlyRemove(ConflictPkg, &End) == false)
 			   return _error->Error("Internal Error, Could not early remove %s (%d)",ConflictPkg.FullName().c_str(), 2);
 		     }
@@ -933,7 +934,7 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate, int c
 	       else
 	       {
 		  if (Debug)
-		     clog << OutputInDepth(Depth) << "Removing " << ConflictPkg.FullName() << " now to avoid " << End << endl;
+		     clog << OutputInDepth(Depth) << "Removing " << ConflictPkg.FullName() << " now to avoid " << APT::PrettyDep(&Cache, End) << endl;
 		  // no earlyremove() here as user has already agreed to the permanent removal
 		  if (SmartRemove(Pkg) == false)
 		     return _error->Error("Internal Error, Could not early remove %s (%d)",ConflictPkg.FullName().c_str(), 1);
@@ -951,7 +952,7 @@ bool pkgPackageManager::SmartUnPack(PkgIterator Pkg, bool const Immediate, int c
    if (couldBeTemporaryRemoved == true && List->IsFlag(Pkg,pkgOrderList::Removed) == true)
    {
       if (Debug)
-	 std::clog << OutputInDepth(Depth) << "Prevent unpack as " << Pkg << " is currently temporarily removed" << std::endl;
+	 std::clog << OutputInDepth(Depth) << "Prevent unpack as " << APT::PrettyPkg(&Cache, Pkg) << " is currently temporarily removed" << std::endl;
       return true;
    }
 

+ 4 - 0
apt-pkg/pkgcache.cc

@@ -553,7 +553,9 @@ operator<<(std::ostream& out, pkgCache::PkgIterator Pkg)
       return out << "invalid package";
 
    string current = string(Pkg.CurVersion() == 0 ? "none" : Pkg.CurVersion());
+APT_IGNORE_DEPRECATED_PUSH
    string candidate = string(Pkg.CandVersion() == 0 ? "none" : Pkg.CandVersion());
+APT_IGNORE_DEPRECATED_POP
    string newest = string(Pkg.VersionList().end() ? "none" : Pkg.VersionList().VerStr());
 
    out << Pkg.Name() << " [ " << Pkg.Arch() << " ] < " << current;
@@ -815,10 +817,12 @@ std::ostream& operator<<(std::ostream& out, pkgCache::DepIterator D)
 
    out << (P.end() ? "invalid pkg" : P.FullName(false)) << " " << D.DepType()
 	<< " on ";
+APT_IGNORE_DEPRECATED_PUSH
    if (T.end() == true)
       out << "invalid pkg";
    else
       out << T;
+APT_IGNORE_DEPRECATED_POP
 
    if (D->Version != 0)
       out << " (" << D.CompType() << " " << D.TargetVer() << ")";

+ 56 - 0
apt-pkg/prettyprinters.cc

@@ -0,0 +1,56 @@
+// Description								/*{{{*/
+/* ######################################################################
+
+   Provide pretty printers for pkgCache structs like PkgIterator
+
+   ##################################################################### */
+									/*}}}*/
+// Include Files							/*{{{*/
+#include <config.h>
+
+#include <apt-pkg/depcache.h>
+#include <apt-pkg/prettyprinters.h>
+
+#include <ostream>
+#include <string>
+
+									/*}}}*/
+
+std::ostream& operator<<(std::ostream& os, const APT::PrettyPkg& pp)	/*{{{*/
+{
+   if (pp.Pkg.end() == true)
+      return os << "invalid package";
+
+   std::string current = (pp.Pkg.CurVersion() == 0 ? "none" : pp.Pkg.CurVersion());
+   std::string candidate = (*pp.DepCache)[pp.Pkg].CandVersion;
+   std::string newest = (pp.Pkg.VersionList().end() ? "none" : pp.Pkg.VersionList().VerStr());
+
+   os << pp.Pkg.Name() << " [ " << pp.Pkg.Arch() << " ] < " << current;
+   if (current != candidate)
+      os << " -> " << candidate;
+   if ( newest != "none" && candidate != newest)
+      os << " | " << newest;
+   if (pp.Pkg->VersionList == 0)
+      os << " > ( none )";
+   else
+      os << " > ( " << (pp.Pkg.VersionList().Section()==0?"unknown":pp.Pkg.VersionList().Section()) << " )";
+   return os;
+}
+									/*}}}*/
+std::ostream& operator<<(std::ostream& os, const APT::PrettyDep& pd)	/*{{{*/
+{
+   if (unlikely(pd.Dep.end() == true))
+      return os << "invalid dependency";
+
+   pkgCache::PkgIterator P = pd.Dep.ParentPkg();
+   pkgCache::PkgIterator T = pd.Dep.TargetPkg();
+
+   os << (P.end() ? "invalid pkg" : P.FullName(false)) << " " << pd.Dep.DepType()
+	<< " on " << APT::PrettyPkg(pd.DepCache, T);
+
+   if (pd.Dep->Version != 0)
+      os << " (" << pd.Dep.CompType() << " " << pd.Dep.TargetVer() << ")";
+
+   return os;
+}
+									/*}}}*/

+ 37 - 0
apt-pkg/prettyprinters.h

@@ -0,0 +1,37 @@
+#ifndef APT_PRETTYPRINTERS_H
+#define APT_PRETTYPRINTERS_H
+#include <apt-pkg/pkgcache.h>
+#include <apt-pkg/macros.h>
+
+class pkgDepCache;
+
+namespace APT {
+
+/** helper to format PkgIterator for easier printing in debug messages.
+ *
+ * The actual text generated is subject to change without prior notice
+ * and should NOT be used as part of a general user interface.
+ */
+struct PrettyPkg
+{
+   pkgDepCache const * const DepCache;
+   pkgCache::PkgIterator const Pkg;
+   PrettyPkg(pkgDepCache const * const depcache, pkgCache::PkgIterator const &pkg) APT_NONNULL(2) : DepCache(depcache), Pkg(pkg) {}
+};
+/** helper to format DepIterator for easier printing in debug messages.
+ *
+ * The actual text generated is subject to change without prior notice
+ * and should NOT be used as part of a general user interface.
+ */
+struct PrettyDep
+{
+   pkgDepCache const * const DepCache;
+   pkgCache::DepIterator const Dep;
+   PrettyDep(pkgDepCache const * const depcache, pkgCache::DepIterator const &dep) APT_NONNULL(2) : DepCache(depcache), Dep(dep) {}
+};
+
+}
+std::ostream& operator<<(std::ostream& os, const APT::PrettyPkg& pp);
+std::ostream& operator<<(std::ostream& os, const APT::PrettyDep& pd);
+
+#endif

+ 3 - 3
apt-private/private-install.cc

@@ -21,6 +21,7 @@
 #include <apt-pkg/pkgcache.h>
 #include <apt-pkg/upgrade.h>
 #include <apt-pkg/install-progress.h>
+#include <apt-pkg/prettyprinters.h>
 
 #include <stdlib.h>
 #include <string.h>
@@ -443,8 +444,7 @@ bool DoAutomaticRemove(CacheFile &Cache)
 	    // install it in the first place, so nuke it instead of show it
 	    if (Cache[Pkg].Install() == true && Pkg.CurrentVer() == 0)
 	    {
-	       if (Pkg.CandVersion() != 0)
-	          tooMuch.insert(Pkg);
+	       tooMuch.insert(Pkg);
 	       Cache->MarkDelete(Pkg, false, 0, false);
 	    }
 	    // only show stuff in the list that is not yet marked for removal
@@ -481,7 +481,7 @@ bool DoAutomaticRemove(CacheFile &Cache)
 		 if (N.end() == true || (N->CurrentVer == 0 && (*Cache)[N].Install() == false))
 		    continue;
 		 if (Debug == true)
-		    std::clog << "Save " << Pkg << " as another installed garbage package depends on it" << std::endl;
+		    std::clog << "Save " << APT::PrettyPkg(Cache, Pkg) << " as another installed garbage package depends on it" << std::endl;
 		 Cache->MarkInstall(Pkg, false, 0, false);
 		 if (hideAutoRemove == false)
 		    ++autoRemoveCount;