summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt-pkg/cacheset.h99
-rw-r--r--apt-private/private-cachefile.cc61
-rw-r--r--apt-private/private-cachefile.h59
-rw-r--r--apt-private/private-cacheset.h16
-rw-r--r--apt-private/private-install.cc69
-rw-r--r--apt-private/private-output.cc263
-rw-r--r--apt-private/private-output.h67
-rw-r--r--po/apt-all.pot2
-rw-r--r--po/ar.po4
-rw-r--r--po/ast.po4
-rw-r--r--po/bg.po4
-rw-r--r--po/bs.po2
-rw-r--r--po/ca.po4
-rw-r--r--po/cs.po4
-rw-r--r--po/cy.po4
-rw-r--r--po/da.po4
-rw-r--r--po/de.po4
-rw-r--r--po/dz.po2
-rw-r--r--po/el.po4
-rw-r--r--po/es.po4
-rw-r--r--po/eu.po4
-rw-r--r--po/fi.po4
-rw-r--r--po/fr.po4
-rw-r--r--po/gl.po4
-rw-r--r--po/he.po4
-rw-r--r--po/hu.po4
-rw-r--r--po/it.po4
-rw-r--r--po/ja.po4
-rw-r--r--po/km.po4
-rw-r--r--po/ko.po4
-rw-r--r--po/ku.po2
-rw-r--r--po/lt.po4
-rw-r--r--po/mr.po2
-rw-r--r--po/nb.po4
-rw-r--r--po/ne.po4
-rw-r--r--po/nl.po4
-rw-r--r--po/nn.po4
-rw-r--r--po/pl.po4
-rw-r--r--po/pt.po4
-rw-r--r--po/pt_BR.po4
-rw-r--r--po/ro.po4
-rw-r--r--po/ru.po4
-rw-r--r--po/sk.po4
-rw-r--r--po/sl.po4
-rw-r--r--po/sv.po4
-rw-r--r--po/th.po4
-rw-r--r--po/tl.po4
-rw-r--r--po/tr.po4
-rw-r--r--po/uk.po4
-rw-r--r--po/vi.po4
-rw-r--r--po/zh_CN.po4
-rw-r--r--po/zh_TW.po4
-rwxr-xr-xtest/integration/test-apt-get-autoremove26
-rwxr-xr-xtest/integration/test-bug-596498-trusted-unsigned-repo9
-rwxr-xr-xtest/integration/test-bug-604222-new-and-autoremove26
-rwxr-xr-xtest/integration/test-bug-613420-new-garbage-dependency16
-rwxr-xr-xtest/integration/test-bug-675449-essential-are-protected14
-rwxr-xr-xtest/integration/test-kernel-helper-autoremove16
58 files changed, 570 insertions, 341 deletions
diff --git a/apt-pkg/cacheset.h b/apt-pkg/cacheset.h
index 03f3605a1..0b9b9441c 100644
--- a/apt-pkg/cacheset.h
+++ b/apt-pkg/cacheset.h
@@ -17,6 +17,7 @@
#include <forward_list>
#endif
#include <list>
+#include <deque>
#include <vector>
#include <string>
#include <iterator>
@@ -210,16 +211,15 @@ private:
void * const d;
}; /*}}}*/
// Iterator templates for our Containers /*{{{*/
-template<typename Interface, typename Container, typename Master, typename iterator_type, typename container_iterator> class Container_iterator_base :
+template<typename Interface, typename Master, typename iterator_type, typename container_iterator, typename container_value> class Container_iterator_base :
public std::iterator<typename std::iterator_traits<container_iterator>::iterator_category, container_iterator>,
public Interface::iterator_base
{
protected:
container_iterator _iter;
- inline virtual typename Container::value_type getType(void) const APT_OVERRIDE { return *_iter; }
public:
explicit Container_iterator_base(container_iterator i) : _iter(i) {}
- inline typename Container::value_type operator*(void) const { return *_iter; }
+ inline container_value operator*(void) const { return this->getType(); }
operator container_iterator(void) const { return _iter; }
inline iterator_type& operator++() { ++_iter; return static_cast<iterator_type&>(*this); }
inline iterator_type operator++(int) { iterator_type tmp(*this); operator++(); return tmp; }
@@ -241,48 +241,56 @@ public:
friend Master;
};
template<class Interface, class Container, class Master> class Container_const_iterator :
- public Container_iterator_base<Interface, Container, Master, Container_const_iterator<Interface, Container, Master>, typename Container::const_iterator>
+ public Container_iterator_base<Interface, Master, Container_const_iterator<Interface, Container, Master>, typename Container::const_iterator, typename Container::value_type>
{
typedef Container_const_iterator<Interface, Container, Master> iterator_type;
typedef typename Container::const_iterator container_iterator;
public:
explicit Container_const_iterator(container_iterator i) :
- Container_iterator_base<Interface, Container, Master, iterator_type, container_iterator>(i) {}
+ Container_iterator_base<Interface, Master, iterator_type, container_iterator, typename Container::value_type>(i) {}
+
+ inline virtual typename Container::value_type getType(void) const APT_OVERRIDE { return *this->_iter; }
};
template<class Interface, class Container, class Master> class Container_iterator :
- public Container_iterator_base<Interface, Container, Master, Container_iterator<Interface, Container, Master>, typename Container::iterator>
+ public Container_iterator_base<Interface, Master, Container_iterator<Interface, Container, Master>, typename Container::iterator, typename Container::value_type>
{
typedef Container_iterator<Interface, Container, Master> iterator_type;
typedef typename Container::iterator container_iterator;
public:
explicit Container_iterator(container_iterator i) :
- Container_iterator_base<Interface, Container, Master, iterator_type, container_iterator>(i) {}
+ Container_iterator_base<Interface, Master, iterator_type, container_iterator, typename Container::value_type>(i) {}
operator typename Master::const_iterator() { return typename Master::const_iterator(this->_iter); }
inline iterator_type& operator=(iterator_type const &i) { this->_iter = i._iter; return static_cast<iterator_type&>(*this); }
inline iterator_type& operator=(container_iterator const &i) { this->_iter = i; return static_cast<iterator_type&>(*this); }
+
+ inline virtual typename Container::value_type getType(void) const APT_OVERRIDE { return *this->_iter; }
};
template<class Interface, class Container, class Master> class Container_const_reverse_iterator :
- public Container_iterator_base<Interface, Container, Master, Container_const_reverse_iterator<Interface, Container, Master>, typename Container::const_reverse_iterator>
+ public Container_iterator_base<Interface, Master, Container_const_reverse_iterator<Interface, Container, Master>, typename Container::const_reverse_iterator, typename Container::value_type>
{
typedef Container_const_reverse_iterator<Interface, Container, Master> iterator_type;
typedef typename Container::const_reverse_iterator container_iterator;
public:
explicit Container_const_reverse_iterator(container_iterator i) :
- Container_iterator_base<Interface, Container, Master, iterator_type, container_iterator>(i) {}
+ Container_iterator_base<Interface, Master, iterator_type, container_iterator, typename Container::value_type>(i) {}
+
+ inline virtual typename Container::value_type getType(void) const APT_OVERRIDE { return *this->_iter; }
};
template<class Interface, class Container, class Master> class Container_reverse_iterator :
- public Container_iterator_base<Interface, Container, Master, Container_reverse_iterator<Interface, Container, Master>, typename Container::reverse_iterator>
+ public Container_iterator_base<Interface, Master, Container_reverse_iterator<Interface, Container, Master>, typename Container::reverse_iterator, typename Container::value_type>
{
typedef Container_reverse_iterator<Interface, Container, Master> iterator_type;
typedef typename Container::reverse_iterator container_iterator;
public:
explicit Container_reverse_iterator(container_iterator i) :
- Container_iterator_base<Interface, Container, Master, iterator_type, container_iterator>(i) {}
+ Container_iterator_base<Interface, Master, iterator_type, container_iterator, typename Container::value_type>(i) {}
operator typename Master::const_iterator() { return typename Master::const_iterator(this->_iter); }
inline iterator_type& operator=(iterator_type const &i) { this->_iter = i._iter; return static_cast<iterator_type&>(*this); }
inline iterator_type& operator=(container_iterator const &i) { this->_iter = i; return static_cast<iterator_type&>(*this); }
+
+ inline virtual typename Container::value_type getType(void) const APT_OVERRIDE { return *this->_iter; }
};
/*}}}*/
class PackageContainerInterface { /*{{{*/
@@ -583,6 +591,10 @@ template<> template<class Cont> void PackageContainer<std::forward_list<pkgCache
_cont.push_front(*p);
}
#endif
+template<> template<class Cont> void PackageContainer<std::deque<pkgCache::PkgIterator> >::insert(PackageContainer<Cont> const &pkgcont) {
+ for (typename PackageContainer<Cont>::const_iterator p = pkgcont.begin(); p != pkgcont.end(); ++p)
+ _cont.push_back(*p);
+}
template<> template<class Cont> void PackageContainer<std::vector<pkgCache::PkgIterator> >::insert(PackageContainer<Cont> const &pkgcont) {
for (typename PackageContainer<Cont>::const_iterator p = pkgcont.begin(); p != pkgcont.end(); ++p)
_cont.push_back(*p);
@@ -603,6 +615,12 @@ template<> inline bool PackageContainer<std::forward_list<pkgCache::PkgIterator>
return true;
}
#endif
+template<> inline bool PackageContainer<std::deque<pkgCache::PkgIterator> >::insert(pkgCache::PkgIterator const &P) {
+ if (P.end() == true)
+ return false;
+ _cont.push_back(P);
+ return true;
+}
template<> inline bool PackageContainer<std::vector<pkgCache::PkgIterator> >::insert(pkgCache::PkgIterator const &P) {
if (P.end() == true)
return false;
@@ -619,6 +637,10 @@ template<> inline void PackageContainer<std::forward_list<pkgCache::PkgIterator>
_cont.push_front(*p);
}
#endif
+template<> inline void PackageContainer<std::deque<pkgCache::PkgIterator> >::insert(const_iterator begin, const_iterator end) {
+ for (const_iterator p = begin; p != end; ++p)
+ _cont.push_back(*p);
+}
template<> inline void PackageContainer<std::vector<pkgCache::PkgIterator> >::insert(const_iterator begin, const_iterator end) {
for (const_iterator p = begin; p != end; ++p)
_cont.push_back(*p);
@@ -647,6 +669,10 @@ template<> template<class Compare> inline bool PackageContainer<std::forward_lis
return true;
}
#endif
+template<> template<class Compare> inline bool PackageContainer<std::deque<pkgCache::PkgIterator> >::sort(Compare Comp) {
+ std::sort(_cont.begin(), _cont.end(), Comp);
+ return true;
+}
/*}}}*/
// class PackageUniverse - pkgCache as PackageContainerInterface /*{{{*/
@@ -657,22 +683,35 @@ template<> template<class Compare> inline bool PackageContainer<std::forward_lis
The wrapping is read-only in practice modeled by making erase and co
private methods. */
-class APT_HIDDEN PackageUniverse : public PackageContainerInterface {
+class APT_PUBLIC PackageUniverse : public PackageContainerInterface {
pkgCache * const _cont;
void * const d;
public:
- typedef pkgCache::PkgIterator iterator;
- typedef pkgCache::PkgIterator const_iterator;
+ class const_iterator : public APT::Container_iterator_base<APT::PackageContainerInterface, PackageUniverse, PackageUniverse::const_iterator, pkgCache::PkgIterator, pkgCache::PkgIterator>
+ {
+ protected:
+ inline virtual pkgCache::PkgIterator getType(void) const APT_OVERRIDE
+ {
+ return _iter;
+ }
+ public:
+ explicit const_iterator(pkgCache::PkgIterator i):
+ Container_iterator_base<APT::PackageContainerInterface, PackageUniverse, PackageUniverse::const_iterator, pkgCache::PkgIterator, pkgCache::PkgIterator>(i) {}
+
+ };
+ typedef const_iterator iterator;
APT_PUBLIC bool empty() const APT_OVERRIDE { return false; }
APT_PUBLIC size_t size() const APT_OVERRIDE { return _cont->Head().PackageCount; }
- APT_PUBLIC const_iterator begin() const { return _cont->PkgBegin(); }
- APT_PUBLIC const_iterator end() const { return _cont->PkgEnd(); }
- APT_PUBLIC const_iterator cbegin() const { return _cont->PkgBegin(); }
- APT_PUBLIC const_iterator cend() const { return _cont->PkgEnd(); }
- APT_PUBLIC iterator begin() { return _cont->PkgBegin(); }
- APT_PUBLIC iterator end() { return _cont->PkgEnd(); }
+ APT_PUBLIC const_iterator begin() const { return const_iterator(_cont->PkgBegin()); }
+ APT_PUBLIC const_iterator end() const { return const_iterator(_cont->PkgEnd()); }
+ APT_PUBLIC const_iterator cbegin() const { return const_iterator(_cont->PkgBegin()); }
+ APT_PUBLIC const_iterator cend() const { return const_iterator(_cont->PkgEnd()); }
+ APT_PUBLIC iterator begin() { return iterator(_cont->PkgBegin()); }
+ APT_PUBLIC iterator end() { return iterator(_cont->PkgEnd()); }
+
+ APT_PUBLIC pkgCache * data() const { return _cont; }
explicit APT_PUBLIC PackageUniverse(pkgCache * const Owner);
APT_PUBLIC virtual ~PackageUniverse();
@@ -693,6 +732,7 @@ typedef PackageContainer<std::unordered_set<pkgCache::PkgIterator> > PackageUnor
typedef PackageContainer<std::forward_list<pkgCache::PkgIterator> > PackageForwardList;
#endif
typedef PackageContainer<std::list<pkgCache::PkgIterator> > PackageList;
+typedef PackageContainer<std::deque<pkgCache::PkgIterator> > PackageDeque;
typedef PackageContainer<std::vector<pkgCache::PkgIterator> > PackageVector;
class VersionContainerInterface { /*{{{*/
@@ -1059,6 +1099,10 @@ template<> template<class Cont> void VersionContainer<std::forward_list<pkgCache
_cont.push_front(*v);
}
#endif
+template<> template<class Cont> void VersionContainer<std::deque<pkgCache::VerIterator> >::insert(VersionContainer<Cont> const &vercont) {
+ for (typename VersionContainer<Cont>::const_iterator v = vercont.begin(); v != vercont.end(); ++v)
+ _cont.push_back(*v);
+}
template<> template<class Cont> void VersionContainer<std::vector<pkgCache::VerIterator> >::insert(VersionContainer<Cont> const &vercont) {
for (typename VersionContainer<Cont>::const_iterator v = vercont.begin(); v != vercont.end(); ++v)
_cont.push_back(*v);
@@ -1079,6 +1123,12 @@ template<> inline bool VersionContainer<std::forward_list<pkgCache::VerIterator>
return true;
}
#endif
+template<> inline bool VersionContainer<std::deque<pkgCache::VerIterator> >::insert(pkgCache::VerIterator const &V) {
+ if (V.end() == true)
+ return false;
+ _cont.push_back(V);
+ return true;
+}
template<> inline bool VersionContainer<std::vector<pkgCache::VerIterator> >::insert(pkgCache::VerIterator const &V) {
if (V.end() == true)
return false;
@@ -1095,6 +1145,10 @@ template<> inline void VersionContainer<std::forward_list<pkgCache::VerIterator>
_cont.push_front(*v);
}
#endif
+template<> inline void VersionContainer<std::deque<pkgCache::VerIterator> >::insert(const_iterator begin, const_iterator end) {
+ for (const_iterator v = begin; v != end; ++v)
+ _cont.push_back(*v);
+}
template<> inline void VersionContainer<std::vector<pkgCache::VerIterator> >::insert(const_iterator begin, const_iterator end) {
for (const_iterator v = begin; v != end; ++v)
_cont.push_back(*v);
@@ -1123,6 +1177,10 @@ template<> template<class Compare> inline bool VersionContainer<std::forward_lis
return true;
}
#endif
+template<> template<class Compare> inline bool VersionContainer<std::deque<pkgCache::VerIterator> >::sort(Compare Comp) {
+ std::sort(_cont.begin(), _cont.end(), Comp);
+ return true;
+}
/*}}}*/
typedef VersionContainer<std::set<pkgCache::VerIterator> > VersionSet;
@@ -1131,6 +1189,7 @@ typedef VersionContainer<std::unordered_set<pkgCache::VerIterator> > VersionUnor
typedef VersionContainer<std::forward_list<pkgCache::VerIterator> > VersionForwardList;
#endif
typedef VersionContainer<std::list<pkgCache::VerIterator> > VersionList;
+typedef VersionContainer<std::deque<pkgCache::VerIterator> > VersionDeque;
typedef VersionContainer<std::vector<pkgCache::VerIterator> > VersionVector;
}
#endif
diff --git a/apt-private/private-cachefile.cc b/apt-private/private-cachefile.cc
index 29e665245..2b2050684 100644
--- a/apt-private/private-cachefile.cc
+++ b/apt-private/private-cachefile.cc
@@ -7,7 +7,7 @@
#include <apt-pkg/configuration.h>
#include <apt-pkg/depcache.h>
#include <apt-pkg/pkgcache.h>
-#include <apt-pkg/cacheiterators.h>
+#include <apt-pkg/cacheset.h>
#include <apt-private/private-output.h>
#include <apt-private/private-cachefile.h>
@@ -21,39 +21,40 @@
using namespace std;
-// CacheFile::NameComp - QSort compare by name /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-pkgCache *CacheFile::SortCache = 0;
-int CacheFile::NameComp(const void *a,const void *b)
+static bool SortPackagesByName(pkgCache * const Owner,
+ map_pointer_t const A, map_pointer_t const B)
{
- if (*(pkgCache::Package **)a == 0 || *(pkgCache::Package **)b == 0)
- return *(pkgCache::Package **)a - *(pkgCache::Package **)b;
-
- const pkgCache::Package &A = **(pkgCache::Package **)a;
- const pkgCache::Package &B = **(pkgCache::Package **)b;
- const pkgCache::Group * const GA = SortCache->GrpP + A.Group;
- const pkgCache::Group * const GB = SortCache->GrpP + B.Group;
-
- return strcmp(SortCache->StrP + GA->Name,SortCache->StrP + GB->Name);
+ if (A == 0)
+ return false;
+ if (B == 0 || A == B)
+ return true;
+ pkgCache::Group const * const GA = Owner->GrpP + A;
+ pkgCache::Group const * const GB = Owner->GrpP + B;
+ return strcmp(Owner->StrP + GA->Name, Owner->StrP + GB->Name) <= 0;
}
- /*}}}*/
-// CacheFile::Sort - Sort by name /*{{{*/
-// ---------------------------------------------------------------------
-/* */
-void CacheFile::Sort()
+SortedPackageUniverse::SortedPackageUniverse(CacheFile &Cache) :
+ PackageUniverse{Cache}, List{Cache.UniverseList}
{
- delete [] List;
- List = new pkgCache::Package *[Cache->Head().PackageCount];
- memset(List,0,sizeof(*List)*Cache->Head().PackageCount);
- pkgCache::PkgIterator I = Cache->PkgBegin();
- for (;I.end() != true; ++I)
- List[I->ID] = I;
-
- SortCache = *this;
- qsort(List,Cache->Head().PackageCount,sizeof(*List),NameComp);
}
- /*}}}*/
+void SortedPackageUniverse::LazyInit() const
+{
+ if (List.empty() == false)
+ return;
+ pkgCache * const Owner = data();
+ // In Multi-Arch systems Grps are easier to sort than Pkgs
+ std::vector<map_pointer_t> GrpList;
+ List.reserve(Owner->Head().GroupCount);
+ for (pkgCache::GrpIterator I{Owner->GrpBegin()}; I.end() != true; ++I)
+ GrpList.emplace_back(I - Owner->GrpP);
+ std::stable_sort(GrpList.begin(), GrpList.end(), std::bind( &SortPackagesByName, Owner, std::placeholders::_1, std::placeholders::_2 ));
+ List.reserve(Owner->Head().PackageCount);
+ for (auto G : GrpList)
+ {
+ pkgCache::GrpIterator const Grp(*Owner, Owner->GrpP + G);
+ for (pkgCache::PkgIterator P = Grp.PackageList(); P.end() != true; P = Grp.NextPkg(P))
+ List.emplace_back(P - Owner->PkgP);
+ }
+}
// CacheFile::CheckDeps - Open the cache file /*{{{*/
// ---------------------------------------------------------------------
/* This routine generates the caches and then opens the dependency cache
diff --git a/apt-private/private-cachefile.h b/apt-private/private-cachefile.h
index 1fddabfbd..4a68d9733 100644
--- a/apt-private/private-cachefile.h
+++ b/apt-private/private-cachefile.h
@@ -7,12 +7,13 @@
#include <apt-pkg/pkgcache.h>
#include <apt-pkg/macros.h>
#include <apt-pkg/sourcelist.h>
+#include <apt-pkg/cacheset.h>
+
#include <apti18n.h>
-// FIXME: we need to find a way to export this
+// FIXME: we need to find a way to export this
class APT_PUBLIC SourceList : public pkgSourceList
{
-
public:
// Add custom metaIndex (e.g. local files)
void AddMetaIndex(metaIndex *mi) {
@@ -22,17 +23,11 @@ class APT_PUBLIC SourceList : public pkgSourceList
};
// class CacheFile - Cover class for some dependency cache functions /*{{{*/
-// ---------------------------------------------------------------------
-/* */
class APT_PUBLIC CacheFile : public pkgCacheFile
{
- static pkgCache *SortCache;
- APT_HIDDEN static int NameComp(const void *a,const void *b) APT_PURE;
-
public:
- pkgCache::Package **List;
-
- void Sort();
+ std::vector<map_pointer_t> UniverseList;
+
bool CheckDeps(bool AllowBroken = false);
bool BuildCaches(bool WithLock = true)
{
@@ -51,14 +46,10 @@ class APT_PUBLIC CacheFile : public pkgCacheFile
return _error->Error(_("The list of sources could not be read."));
return true;
}
- bool Open(bool WithLock = true)
+ bool Open(bool WithLock = true)
{
OpTextProgress Prog(*_config);
- if (pkgCacheFile::Open(&Prog,WithLock) == false)
- return false;
- Sort();
-
- return true;
+ return pkgCacheFile::Open(&Prog,WithLock);
};
bool OpenForInstall()
{
@@ -67,11 +58,39 @@ class APT_PUBLIC CacheFile : public pkgCacheFile
else
return Open(true);
}
- CacheFile() : List(0) {};
- ~CacheFile() {
- delete[] List;
- }
};
/*}}}*/
+class APT_PUBLIC SortedPackageUniverse : public APT::PackageUniverse
+{
+ std::vector<map_pointer_t> &List;
+ void LazyInit() const;
+
+public:
+ SortedPackageUniverse(CacheFile &Cache);
+
+ class const_iterator : public APT::Container_iterator_base<APT::PackageContainerInterface, SortedPackageUniverse, SortedPackageUniverse::const_iterator, std::vector<map_pointer_t>::const_iterator, pkgCache::PkgIterator>
+ {
+ pkgCache * const Cache;
+ protected:
+ inline virtual pkgCache::PkgIterator getType(void) const APT_OVERRIDE
+ {
+ if (*_iter == 0) return pkgCache::PkgIterator(*Cache);
+ return pkgCache::PkgIterator(*Cache, Cache->PkgP + *_iter);
+ }
+ public:
+ explicit const_iterator(pkgCache * const Owner, std::vector<map_pointer_t>::const_iterator i):
+ Container_iterator_base<APT::PackageContainerInterface, SortedPackageUniverse, SortedPackageUniverse::const_iterator, std::vector<map_pointer_t>::const_iterator, pkgCache::PkgIterator>(i), Cache(Owner) {}
+
+ };
+ typedef const_iterator iterator;
+
+ APT_PUBLIC const_iterator begin() const { LazyInit(); return const_iterator(data(), List.begin()); }
+ APT_PUBLIC const_iterator end() const { LazyInit(); return const_iterator(data(), List.end()); }
+ APT_PUBLIC const_iterator cbegin() const { LazyInit(); return const_iterator(data(), List.begin()); }
+ APT_PUBLIC const_iterator cend() const { LazyInit(); return const_iterator(data(), List.end()); }
+ APT_PUBLIC iterator begin() { LazyInit(); return iterator(data(), List.begin()); }
+ APT_PUBLIC iterator end() { LazyInit(); return iterator(data(), List.end()); }
+};
+
#endif
diff --git a/apt-private/private-cacheset.h b/apt-private/private-cacheset.h
index 518f179f3..7cafe4fdd 100644
--- a/apt-private/private-cacheset.h
+++ b/apt-private/private-cacheset.h
@@ -12,6 +12,8 @@
#include <apt-pkg/cacheiterators.h>
#include <apt-pkg/macros.h>
+#include <apt-private/private-output.h>
+
#include <algorithm>
#include <vector>
#include <string.h>
@@ -21,8 +23,6 @@
#include <string>
#include <utility>
-#include "private-output.h"
-
#include <apti18n.h>
class OpProgress;
@@ -174,17 +174,19 @@ public:
std::string VersionsList;
SPtrArray<bool> Seen = new bool[Cache.GetPkgCache()->Head().PackageCount];
memset(Seen,0,Cache.GetPkgCache()->Head().PackageCount*sizeof(*Seen));
+ APT::PackageList pkglist;
for (pkgCache::DepIterator Dep = Pkg.RevDependsList();
Dep.end() == false; ++Dep) {
if (Dep->Type != pkgCache::Dep::Replaces)
continue;
- if (Seen[Dep.ParentPkg()->ID] == true)
+ pkgCache::PkgIterator const DP = Dep.ParentPkg();
+ if (Seen[DP->ID] == true)
continue;
- Seen[Dep.ParentPkg()->ID] = true;
- List += Dep.ParentPkg().FullName(true) + " ";
- //VersionsList += std::string(Dep.ParentPkg().CurVersion) + "\n"; ???
+ Seen[DP->ID] = true;
+ pkglist.insert(DP);
}
- ShowList(c1out,_("However the following packages replace it:"),List,VersionsList);
+ ShowList(c1out, _("However the following packages replace it:"), pkglist,
+ &AlwaysTrue, &PrettyFullName, &EmptyString);
}
c1out << std::endl;
}
diff --git a/apt-private/private-install.cc b/apt-private/private-install.cc
index 3474d262a..cdca45755 100644
--- a/apt-private/private-install.cc
+++ b/apt-private/private-install.cc
@@ -374,11 +374,10 @@ static bool DoAutomaticRemove(CacheFile &Cache)
unsigned long autoRemoveCount = 0;
APT::PackageSet tooMuch;
- APT::PackageList autoRemoveList;
+ SortedPackageUniverse Universe(Cache);
// look over the cache to see what can be removed
- for (unsigned J = 0; J < Cache->Head().PackageCount; ++J)
+ for (auto const &Pkg: Universe)
{
- pkgCache::PkgIterator Pkg(Cache,Cache.List[J]);
if (Cache[Pkg].Garbage)
{
if(Pkg.CurrentVer() != 0 || Cache[Pkg].Install())
@@ -395,8 +394,6 @@ static bool DoAutomaticRemove(CacheFile &Cache)
}
else
{
- if (hideAutoRemove == false && Cache[Pkg].Delete() == false)
- autoRemoveList.insert(Pkg);
// if the package is a new install and already garbage we don't need to
// install it in the first place, so nuke it instead of show it
if (Cache[Pkg].Install() == true && Pkg.CurrentVer() == 0)
@@ -456,18 +453,6 @@ static bool DoAutomaticRemove(CacheFile &Cache)
} while (Changed == true);
}
- std::string autoremovelist, autoremoveversions;
- if (smallList == false && autoRemoveCount != 0)
- {
- for (APT::PackageList::const_iterator Pkg = autoRemoveList.begin(); Pkg != autoRemoveList.end(); ++Pkg)
- {
- if (Cache[Pkg].Garbage == false)
- continue;
- autoremovelist += Pkg.FullName(true) + " ";
- autoremoveversions += std::string(Cache[Pkg].CandVersion) + "\n";
- }
- }
-
// Now see if we had destroyed anything (if we had done anything)
if (Cache->BrokenCount() != 0)
{
@@ -482,12 +467,17 @@ static bool DoAutomaticRemove(CacheFile &Cache)
}
// if we don't remove them, we should show them!
- if (doAutoRemove == false && (autoremovelist.empty() == false || autoRemoveCount != 0))
+ if (doAutoRemove == false && autoRemoveCount != 0)
{
if (smallList == false)
+ {
+ SortedPackageUniverse Universe(Cache);
ShowList(c1out, P_("The following package was automatically installed and is no longer required:",
"The following packages were automatically installed and are no longer required:",
- autoRemoveCount), autoremovelist, autoremoveversions);
+ autoRemoveCount), Universe,
+ [&Cache](pkgCache::PkgIterator const &Pkg) { return (*Cache)[Pkg].Garbage == true && (*Cache)[Pkg].Delete() == false; },
+ &PrettyFullName, CandidateVersion(&Cache));
+ }
else
ioprintf(c1out, P_("%lu package was automatically installed and is no longer required.\n",
"%lu packages were automatically installed and are no longer required.\n", autoRemoveCount), autoRemoveCount);
@@ -651,6 +641,18 @@ bool DoCacheManipulationFromCommandLine(CommandLine &CmdL, CacheFile &Cache,
// DoInstall - Install packages from the command line /*{{{*/
// ---------------------------------------------------------------------
/* Install named packages */
+struct PkgIsExtraInstalled {
+ pkgCacheFile * const Cache;
+ APT::VersionSet const * const verset;
+ PkgIsExtraInstalled(pkgCacheFile * const Cache, APT::VersionSet const * const Container) : Cache(Cache), verset(Container) {}
+ bool operator() (pkgCache::PkgIterator const Pkg)
+ {
+ if ((*Cache)[Pkg].Install() == false)
+ return false;
+ pkgCache::VerIterator const Cand = (*Cache)[Pkg].CandidateVerIter(*Cache);
+ return verset->find(Cand) == verset->end();
+ }
+};
bool DoInstall(CommandLine &CmdL)
{
CacheFile Cache;
@@ -689,35 +691,18 @@ bool DoInstall(CommandLine &CmdL)
/* Print out a list of packages that are going to be installed extra
to what the user asked */
+ SortedPackageUniverse Universe(Cache);
if (Cache->InstCount() != verset[MOD_INSTALL].size())
- {
- std::string List;
- std::string VersionsList;
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
- {
- pkgCache::PkgIterator I(Cache,Cache.List[J]);
- if ((*Cache)[I].Install() == false)
- continue;
- pkgCache::VerIterator Cand = Cache[I].CandidateVerIter(Cache);
-
- if (verset[MOD_INSTALL].find(Cand) != verset[MOD_INSTALL].end())
- continue;
-
- List += I.FullName(true) + " ";
- VersionsList += std::string(Cache[I].CandVersion) + "\n";
- }
-
- ShowList(c1out,_("The following extra packages will be installed:"),List,VersionsList);
- }
+ ShowList(c1out, _("The following extra packages will be installed:"), Universe,
+ PkgIsExtraInstalled(&Cache, &verset[MOD_INSTALL]),
+ &PrettyFullName, CandidateVersion(&Cache));
/* Print out a list of suggested and recommended packages */
{
std::string SuggestsList, RecommendsList;
std::string SuggestsVersions, RecommendsVersions;
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+ for (auto const &Pkg: Universe)
{
- pkgCache::PkgIterator Pkg(Cache,Cache.List[J]);
-
/* Just look at the ones we want to install */
if ((*Cache)[Pkg].Install() == false)
continue;
@@ -738,7 +723,6 @@ bool DoInstall(CommandLine &CmdL)
for(;;)
{
/* Skip if package is installed already, or is about to be */
- std::string target = Start.TargetPkg().FullName(true) + " ";
pkgCache::PkgIterator const TarPkg = Start.TargetPkg();
if (TarPkg->SelectedState == pkgCache::State::Install ||
TarPkg->SelectedState == pkgCache::State::Hold ||
@@ -749,6 +733,7 @@ bool DoInstall(CommandLine &CmdL)
}
/* Skip if we already saw it */
+ std::string target = Start.TargetPkg().FullName(true) + " ";
if (int(SuggestsList.find(target)) != -1 || int(RecommendsList.find(target)) != -1)
{
foundInstalledInOrGroup=true;
diff --git a/apt-private/private-output.cc b/apt-private/private-output.cc
index 9944ab002..b77efff86 100644
--- a/apt-private/private-output.cc
+++ b/apt-private/private-output.cc
@@ -25,6 +25,8 @@
#include <signal.h>
#include <sys/ioctl.h>
+#include <sstream>
+
#include <apti18n.h>
/*}}}*/
@@ -491,11 +493,9 @@ void ShowBroken(ostream &out, CacheFile &Cache, bool const Now)
return;
out << _("The following packages have unmet dependencies:") << endl;
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
- {
- pkgCache::PkgIterator const I(Cache,Cache.List[J]);
- ShowBrokenPackage(out, &Cache, I, Now);
- }
+ SortedPackageUniverse Universe(Cache);
+ for (auto const &Pkg: Universe)
+ ShowBrokenPackage(out, &Cache, Pkg, Now);
}
void ShowBroken(ostream &out, pkgCacheFile &Cache, bool const Now)
{
@@ -503,98 +503,64 @@ void ShowBroken(ostream &out, pkgCacheFile &Cache, bool const Now)
return;
out << _("The following packages have unmet dependencies:") << endl;
- for (pkgCache::PkgIterator Pkg = Cache->PkgBegin(); Pkg.end() == false; ++Pkg)
+ APT::PackageUniverse Universe(Cache);
+ for (auto const &Pkg: Universe)
ShowBrokenPackage(out, &Cache, Pkg, Now);
}
/*}}}*/
// ShowNew - Show packages to newly install /*{{{*/
-// ---------------------------------------------------------------------
-/* */
void ShowNew(ostream &out,CacheFile &Cache)
{
- /* Print out a list of packages that are going to be installed extra
- to what the user asked */
- string List;
- string VersionsList;
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
- {
- pkgCache::PkgIterator I(Cache,Cache.List[J]);
- if (Cache[I].NewInstall() == true) {
- List += I.FullName(true) + " ";
- VersionsList += string(Cache[I].CandVersion) + "\n";
- }
- }
-
- ShowList(out,_("The following NEW packages will be installed:"),List,VersionsList);
+ SortedPackageUniverse Universe(Cache);
+ ShowList(out,_("The following NEW packages will be installed:"), Universe,
+ [&Cache](pkgCache::PkgIterator const &Pkg) { return Cache[Pkg].NewInstall(); },
+ &PrettyFullName,
+ CandidateVersion(&Cache));
}
/*}}}*/
// ShowDel - Show packages to delete /*{{{*/
-// ---------------------------------------------------------------------
-/* */
void ShowDel(ostream &out,CacheFile &Cache)
{
- /* Print out a list of packages that are going to be removed extra
- to what the user asked */
- string List;
- string VersionsList;
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
- {
- pkgCache::PkgIterator I(Cache,Cache.List[J]);
- if (Cache[I].Delete() == true)
- {
- if ((Cache[I].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge)
- List += I.FullName(true) + "* ";
- else
- List += I.FullName(true) + " ";
-
- VersionsList += string(Cache[I].CandVersion)+ "\n";
- }
- }
-
- ShowList(out,_("The following packages will be REMOVED:"),List,VersionsList);
+ SortedPackageUniverse Universe(Cache);
+ ShowList(out,_("The following packages will be REMOVED:"), Universe,
+ [&Cache](pkgCache::PkgIterator const &Pkg) { return Cache[Pkg].Delete(); },
+ [&Cache](pkgCache::PkgIterator const &Pkg)
+ {
+ std::string str = PrettyFullName(Pkg);
+ if (((*Cache)[Pkg].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge)
+ str.append("*");
+ return str;
+ },
+ CandidateVersion(&Cache));
}
/*}}}*/
// ShowKept - Show kept packages /*{{{*/
-// ---------------------------------------------------------------------
-/* */
void ShowKept(ostream &out,CacheFile &Cache)
{
- string List;
- string VersionsList;
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
- {
- pkgCache::PkgIterator I(Cache,Cache.List[J]);
-
- // Not interesting
- if (Cache[I].Upgrade() == true || Cache[I].Upgradable() == false ||
- I->CurrentVer == 0 || Cache[I].Delete() == true)
- continue;
-
- List += I.FullName(true) + " ";
- VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
- }
- ShowList(out,_("The following packages have been kept back:"),List,VersionsList);
+ SortedPackageUniverse Universe(Cache);
+ ShowList(out,_("The following packages have been kept back:"), Universe,
+ [&Cache](pkgCache::PkgIterator const &Pkg)
+ {
+ return Cache[Pkg].Upgrade() == false &&
+ Cache[Pkg].Upgradable() == true &&
+ Pkg->CurrentVer != 0 &&
+ Cache[Pkg].Delete() == false;
+ },
+ &PrettyFullName,
+ CurrentToCandidateVersion(&Cache));
}
/*}}}*/
// ShowUpgraded - Show upgraded packages /*{{{*/
-// ---------------------------------------------------------------------
-/* */
void ShowUpgraded(ostream &out,CacheFile &Cache)
{
- string List;
- string VersionsList;
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
- {
- pkgCache::PkgIterator I(Cache,Cache.List[J]);
-
- // Not interesting
- if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true)
- continue;
-
- List += I.FullName(true) + " ";
- VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
- }
- ShowList(out,_("The following packages will be upgraded:"),List,VersionsList);
+ SortedPackageUniverse Universe(Cache);
+ ShowList(out,_("The following packages will be upgraded:"), Universe,
+ [&Cache](pkgCache::PkgIterator const &Pkg)
+ {
+ return Cache[Pkg].Upgrade() == true && Cache[Pkg].NewInstall() == false;
+ },
+ &PrettyFullName,
+ CurrentToCandidateVersion(&Cache));
}
/*}}}*/
// ShowDowngraded - Show downgraded packages /*{{{*/
@@ -602,74 +568,73 @@ void ShowUpgraded(ostream &out,CacheFile &Cache)
/* */
bool ShowDowngraded(ostream &out,CacheFile &Cache)
{
- string List;
- string VersionsList;
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
- {
- pkgCache::PkgIterator I(Cache,Cache.List[J]);
-
- // Not interesting
- if (Cache[I].Downgrade() == false || Cache[I].NewInstall() == true)
- continue;
-
- List += I.FullName(true) + " ";
- VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
- }
- return ShowList(out,_("The following packages will be DOWNGRADED:"),List,VersionsList);
+ SortedPackageUniverse Universe(Cache);
+ return ShowList(out,_("The following packages will be DOWNGRADED:"), Universe,
+ [&Cache](pkgCache::PkgIterator const &Pkg)
+ {
+ return Cache[Pkg].Downgrade() == true && Cache[Pkg].NewInstall() == false;
+ },
+ &PrettyFullName,
+ CurrentToCandidateVersion(&Cache));
}
/*}}}*/
// ShowHold - Show held but changed packages /*{{{*/
-// ---------------------------------------------------------------------
-/* */
bool ShowHold(ostream &out,CacheFile &Cache)
{
- string List;
- string VersionsList;
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
- {
- pkgCache::PkgIterator I(Cache,Cache.List[J]);
- if (Cache[I].InstallVer != (pkgCache::Version *)I.CurrentVer() &&
- I->SelectedState == pkgCache::State::Hold) {
- List += I.FullName(true) + " ";
- VersionsList += string(Cache[I].CurVersion) + " => " + Cache[I].CandVersion + "\n";
- }
- }
-
- return ShowList(out,_("The following held packages will be changed:"),List,VersionsList);
+ SortedPackageUniverse Universe(Cache);
+ return ShowList(out,_("The following held packages will be changed:"), Universe,
+ [&Cache](pkgCache::PkgIterator const &Pkg)
+ {
+ return Pkg->SelectedState == pkgCache::State::Hold &&
+ Cache[Pkg].InstallVer != (pkgCache::Version *)Pkg.CurrentVer();
+ },
+ &PrettyFullName,
+ CurrentToCandidateVersion(&Cache));
}
/*}}}*/
// ShowEssential - Show an essential package warning /*{{{*/
// ---------------------------------------------------------------------
/* This prints out a warning message that is not to be ignored. It shows
- all essential packages and their dependents that are to be removed.
+ all essential packages and their dependents that are to be removed.
It is insanely risky to remove the dependents of an essential package! */
+struct APT_HIDDEN PrettyFullNameWithDue {
+ std::map<unsigned long long, pkgCache::PkgIterator> due;
+ PrettyFullNameWithDue() {}
+ std::string operator() (pkgCache::PkgIterator const &Pkg)
+ {
+ std::string const A = PrettyFullName(Pkg);
+ std::map<unsigned long long, pkgCache::PkgIterator>::const_iterator d = due.find(Pkg->ID);
+ if (d == due.end())
+ return A;
+
+ std::string const B = PrettyFullName(d->second);
+ std::ostringstream outstr;
+ ioprintf(outstr, _("%s (due to %s)"), A.c_str(), B.c_str());
+ return outstr.str();
+ }
+};
bool ShowEssential(ostream &out,CacheFile &Cache)
{
- string List;
- string VersionsList;
- bool *Added = new bool[Cache->Head().PackageCount];
- for (unsigned int I = 0; I != Cache->Head().PackageCount; I++)
- Added[I] = false;
-
- for (unsigned J = 0; J < Cache->Head().PackageCount; J++)
+ std::vector<bool> Added(Cache->Head().PackageCount, false);
+ APT::PackageDeque pkglist;
+ PrettyFullNameWithDue withdue;
+
+ SortedPackageUniverse Universe(Cache);
+ for (pkgCache::PkgIterator const &I: Universe)
{
- pkgCache::PkgIterator I(Cache,Cache.List[J]);
if ((I->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential &&
(I->Flags & pkgCache::Flag::Important) != pkgCache::Flag::Important)
continue;
-
+
// The essential package is being removed
- if (Cache[I].Delete() == true)
+ if (Cache[I].Delete() == false)
+ continue;
+
+ if (Added[I->ID] == false)
{
- if (Added[I->ID] == false)
- {
- Added[I->ID] = true;
- List += I.FullName(true) + " ";
- //VersionsList += string(Cache[I].CurVersion) + "\n"; ???
- }
+ Added[I->ID] = true;
+ pkglist.insert(I);
}
- else
- continue;
if (I->CurrentVer == 0)
continue;
@@ -681,27 +646,23 @@ bool ShowEssential(ostream &out,CacheFile &Cache)
if (D->Type != pkgCache::Dep::PreDepends &&
D->Type != pkgCache::Dep::Depends)
continue;
-
+
pkgCache::PkgIterator P = D.SmartTargetPkg();
if (Cache[P].Delete() == true)
{
if (Added[P->ID] == true)
continue;
Added[P->ID] = true;
-
- char S[300];
- snprintf(S,sizeof(S),_("%s (due to %s) "),P.FullName(true).c_str(),I.FullName(true).c_str());
- List += S;
- //VersionsList += "\n"; ???
- }
- }
+
+ pkglist.insert(P);
+ withdue.due[P->ID] = I;
+ }
+ }
}
-
- delete [] Added;
return ShowList(out,_("WARNING: The following essential packages will be removed.\n"
- "This should NOT be done unless you know exactly what you are doing!"),List,VersionsList);
+ "This should NOT be done unless you know exactly what you are doing!"),
+ pkglist, &AlwaysTrue, withdue, &EmptyString);
}
-
/*}}}*/
// Stats - Show some statistics /*{{{*/
// ---------------------------------------------------------------------
@@ -829,3 +790,33 @@ bool AnalPrompt(const char *Text)
return false;
}
/*}}}*/
+
+std::string PrettyFullName(pkgCache::PkgIterator const &Pkg)
+{
+ return Pkg.FullName(true);
+}
+std::string CandidateVersion(pkgCacheFile * const Cache, pkgCache::PkgIterator const &Pkg)
+{
+ return (*Cache)[Pkg].CandVersion;
+}
+std::function<std::string(pkgCache::PkgIterator const &)> CandidateVersion(pkgCacheFile * const Cache)
+{
+ return std::bind(static_cast<std::string(*)(pkgCacheFile * const, pkgCache::PkgIterator const&)>(&CandidateVersion), Cache, std::placeholders::_1);
+}
+std::string CurrentToCandidateVersion(pkgCacheFile * const Cache, pkgCache::PkgIterator const &Pkg)
+{
+ return std::string((*Cache)[Pkg].CurVersion) + " => " + (*Cache)[Pkg].CandVersion;
+}
+std::function<std::string(pkgCache::PkgIterator const &)> CurrentToCandidateVersion(pkgCacheFile * const Cache)
+{
+ return std::bind(static_cast<std::string(*)(pkgCacheFile * const, pkgCache::PkgIterator const&)>(&CurrentToCandidateVersion), Cache, std::placeholders::_1);
+}
+bool AlwaysTrue(pkgCache::PkgIterator const &)
+{
+ return true;
+}
+std::string EmptyString(pkgCache::PkgIterator const &)
+{
+ return std::string();
+}
+
diff --git a/apt-private/private-output.h b/apt-private/private-output.h
index d5b57adec..b9151b245 100644
--- a/apt-private/private-output.h
+++ b/apt-private/private-output.h
@@ -1,9 +1,11 @@
#ifndef APT_PRIVATE_OUTPUT_H
#define APT_PRIVATE_OUTPUT_H
+#include <apt-pkg/configuration.h>
#include <apt-pkg/pkgcache.h>
#include <apt-pkg/macros.h>
+#include <functional>
#include <fstream>
#include <string>
#include <iostream>
@@ -32,8 +34,63 @@ void ListSingleVersion(pkgCacheFile &CacheFile, pkgRecords &records,
APT_PUBLIC void ShowBroken(std::ostream &out, CacheFile &Cache, bool const Now);
APT_PUBLIC void ShowBroken(std::ostream &out, pkgCacheFile &Cache, bool const Now);
-APT_PUBLIC bool ShowList(std::ostream &out, std::string Title, std::string List,
+template<class Container> APT_PUBLIC bool ShowList(std::ostream &out, std::string const &Title,
+ Container const &cont,
+ std::function<bool(pkgCache::PkgIterator const &)> Predicate,
+ std::function<std::string(pkgCache::PkgIterator const &)> PkgDisplay,
+ std::function<std::string(pkgCache::PkgIterator const &)> VerboseDisplay)
+{
+ size_t const ScreenWidth = (::ScreenWidth > 3) ? ::ScreenWidth - 3 : 0;
+ int ScreenUsed = 0;
+ bool const ShowVersions = _config->FindB("APT::Get::Show-Versions", false);
+ bool printedTitle = false;
+
+ for (auto const &Pkg: cont)
+ {
+ if (Predicate(Pkg) == false)
+ continue;
+
+ if (printedTitle == false)
+ {
+ out << Title;
+ printedTitle = true;
+ }
+
+ if (ShowVersions == true)
+ {
+ out << std::endl << " " << PkgDisplay(Pkg);
+ std::string const verbose = VerboseDisplay(Pkg);
+ if (verbose.empty() == false)
+ out << " (" << verbose << ")";
+ }
+ else
+ {
+ std::string const PkgName = PkgDisplay(Pkg);
+ if (ScreenUsed == 0 || (ScreenUsed + PkgName.length()) >= ScreenWidth)
+ {
+ out << std::endl << " ";
+ ScreenUsed = 0;
+ }
+ else if (ScreenUsed != 0)
+ {
+ out << " ";
+ ++ScreenUsed;
+ }
+ out << PkgName;
+ ScreenUsed += PkgName.length();
+ }
+ }
+
+ if (printedTitle == true)
+ {
+ out << std::endl;
+ return false;
+ }
+ return true;
+}
+APT_DEPRECATED APT_PUBLIC bool ShowList(std::ostream &out, std::string Title, std::string List,
std::string VersionsList);
+
void ShowNew(std::ostream &out,CacheFile &Cache);
void ShowDel(std::ostream &out,CacheFile &Cache);
void ShowKept(std::ostream &out,CacheFile &Cache);
@@ -49,4 +106,12 @@ void Stats(std::ostream &out, pkgDepCache &Dep);
bool YnPrompt(bool Default=true);
bool AnalPrompt(const char *Text);
+APT_PUBLIC std::string PrettyFullName(pkgCache::PkgIterator const &Pkg);
+APT_PUBLIC std::string CandidateVersion(pkgCacheFile * const Cache, pkgCache::PkgIterator const &Pkg);
+APT_PUBLIC std::function<std::string(pkgCache::PkgIterator const &)> CandidateVersion(pkgCacheFile * const Cache);
+APT_PUBLIC std::string CurrentToCandidateVersion(pkgCacheFile * const Cache, pkgCache::PkgIterator const &Pkg);
+APT_PUBLIC std::function<std::string(pkgCache::PkgIterator const &)> CurrentToCandidateVersion(pkgCacheFile * const Cache);
+APT_PUBLIC std::string EmptyString(pkgCache::PkgIterator const &);
+APT_PUBLIC bool AlwaysTrue(pkgCache::PkgIterator const &);
+
#endif
diff --git a/po/apt-all.pot b/po/apt-all.pot
index 73b033876..e2d09401b 100644
--- a/po/apt-all.pot
+++ b/po/apt-all.pot
@@ -1135,7 +1135,7 @@ msgstr ""
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
+msgid "%s (due to %s)"
msgstr ""
#: apt-private/private-output.cc:696
diff --git a/po/ar.po b/po/ar.po
index 3e71fef80..8c1622d91 100644
--- a/po/ar.po
+++ b/po/ar.po
@@ -1151,8 +1151,8 @@ msgstr "سيتم تغيير الحزم المبقاة التالية:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (بسبب %s) "
+msgid "%s (due to %s)"
+msgstr "%s (بسبب %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/ast.po b/po/ast.po
index 1995c12f6..07888ebe2 100644
--- a/po/ast.po
+++ b/po/ast.po
@@ -1261,8 +1261,8 @@ msgstr "Van camudase los siguientes paquetes reteníos:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (por %s) "
+msgid "%s (due to %s)"
+msgstr "%s (por %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/bg.po b/po/bg.po
index 7dff005e6..6dc47f5bb 100644
--- a/po/bg.po
+++ b/po/bg.po
@@ -1294,8 +1294,8 @@ msgstr "Следните задържани пакети ще бъдат про
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (поради %s) "
+msgid "%s (due to %s)"
+msgstr "%s (поради %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/bs.po b/po/bs.po
index abb9a570a..e68cee981 100644
--- a/po/bs.po
+++ b/po/bs.po
@@ -1159,7 +1159,7 @@ msgstr ""
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
+msgid "%s (due to %s)"
msgstr ""
#: apt-private/private-output.cc:696
diff --git a/po/ca.po b/po/ca.po
index 065ad0ea7..3f111875d 100644
--- a/po/ca.po
+++ b/po/ca.po
@@ -1276,8 +1276,8 @@ msgstr "Es canviaran els paquets retinguts següents:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (per %s) "
+msgid "%s (due to %s)"
+msgstr "%s (per %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/cs.po b/po/cs.po
index 3f6bcb4a7..4de2b7006 100644
--- a/po/cs.po
+++ b/po/cs.po
@@ -1301,8 +1301,8 @@ msgstr "Následující podržené balíky budou změněny:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (kvůli %s) "
+msgid "%s (due to %s)"
+msgstr "%s (kvůli %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/cy.po b/po/cy.po
index b05bc7c59..db9ec0bbc 100644
--- a/po/cy.po
+++ b/po/cy.po
@@ -1288,8 +1288,8 @@ msgstr "Caiff y pecynnau wedi eu dal canlynol eu newid:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (oherwydd %s) "
+msgid "%s (due to %s)"
+msgstr "%s (oherwydd %s)"
#: apt-private/private-output.cc:696
#, fuzzy
diff --git a/po/da.po b/po/da.po
index d6b8e07a1..f337879f6 100644
--- a/po/da.po
+++ b/po/da.po
@@ -1319,8 +1319,8 @@ msgstr "Følgende tilbageholdte pakker vil blive ændret:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (grundet %s) "
+msgid "%s (due to %s)"
+msgstr "%s (grundet %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/de.po b/po/de.po
index d4ca0d5a0..0b363c8de 100644
--- a/po/de.po
+++ b/po/de.po
@@ -1364,8 +1364,8 @@ msgstr "Die folgenden zurückgehaltenen Pakete werden verändert:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (wegen %s) "
+msgid "%s (due to %s)"
+msgstr "%s (wegen %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/dz.po b/po/dz.po
index a4c50d245..e27ea6a90 100644
--- a/po/dz.po
+++ b/po/dz.po
@@ -1256,7 +1256,7 @@ msgstr "འོག་གི་འཆང་ཡོད་པའི་ཐུམ་ས
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
+msgid "%s (due to %s)"
msgstr "%s( %s་གིས་སྦེ)"
#: apt-private/private-output.cc:696
diff --git a/po/el.po b/po/el.po
index 98e1f31c9..b2370c6ad 100644
--- a/po/el.po
+++ b/po/el.po
@@ -1272,8 +1272,8 @@ msgstr "Τα ακόλουθα κρατημένα πακέτα θα αλλαχθ
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (λόγω του %s) "
+msgid "%s (due to %s)"
+msgstr "%s (λόγω του %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/es.po b/po/es.po
index a2a9a71e9..c071ffb4a 100644
--- a/po/es.po
+++ b/po/es.po
@@ -1388,8 +1388,8 @@ msgstr "Se cambiarán los siguientes paquetes retenidos:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (por %s) "
+msgid "%s (due to %s)"
+msgstr "%s (por %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/eu.po b/po/eu.po
index f1e90411a..528c6cc51 100644
--- a/po/eu.po
+++ b/po/eu.po
@@ -1257,8 +1257,8 @@ msgstr "Ondorengo pakete atxikiak aldatu egingo dira:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (arrazoia: %s) "
+msgid "%s (due to %s)"
+msgstr "%s (arrazoia: %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/fi.po b/po/fi.po
index c40ed8e9e..5a5299255 100644
--- a/po/fi.po
+++ b/po/fi.po
@@ -1248,8 +1248,8 @@ msgstr "Seuraavat pysytetyt paketit muutetaan:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (syynä %s) "
+msgid "%s (due to %s)"
+msgstr "%s (syynä %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/fr.po b/po/fr.po
index ecb752f5e..0a437907f 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -1328,8 +1328,8 @@ msgstr "Les paquets retenus suivants seront changés :"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (en raison de %s) "
+msgid "%s (due to %s)"
+msgstr "%s (en raison de %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/gl.po b/po/gl.po
index 2adaa302a..9ec10122b 100644
--- a/po/gl.po
+++ b/po/gl.po
@@ -1275,8 +1275,8 @@ msgstr "Vanse modificar os paquetes retidos seguintes:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (por mor de %s) "
+msgid "%s (due to %s)"
+msgstr "%s (por mor de %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/he.po b/po/he.po
index ab7b50745..2c355f863 100644
--- a/po/he.po
+++ b/po/he.po
@@ -610,8 +610,8 @@ msgstr "החבילות המחוזקות הבאות ישונו:"
#: cmdline/apt-get.cc:545
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (בגלל %s) "
+msgid "%s (due to %s)"
+msgstr "%s (בגלל %s)"
#: cmdline/apt-get.cc:553
#, fuzzy
diff --git a/po/hu.po b/po/hu.po
index 635184c75..fcf53f727 100644
--- a/po/hu.po
+++ b/po/hu.po
@@ -1291,8 +1291,8 @@ msgstr "Az alábbi visszafogott csomagokat cserélem:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (%s miatt) "
+msgid "%s (due to %s)"
+msgstr "%s (%s miatt)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/it.po b/po/it.po
index 178754c52..6d9793c55 100644
--- a/po/it.po
+++ b/po/it.po
@@ -1323,8 +1323,8 @@ msgstr "I seguenti pacchetti bloccati saranno cambiati:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (a causa di %s) "
+msgid "%s (due to %s)"
+msgstr "%s (a causa di %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/ja.po b/po/ja.po
index f8f55f8aa..6e0e21418 100644
--- a/po/ja.po
+++ b/po/ja.po
@@ -1324,8 +1324,8 @@ msgstr "以下の変更禁止パッケージは変更されます:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (%s のため) "
+msgid "%s (due to %s)"
+msgstr "%s (%s のため)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/km.po b/po/km.po
index 8c72865f8..8ae605510 100644
--- a/po/km.po
+++ b/po/km.po
@@ -1242,8 +1242,8 @@ msgstr "កញ្ចប់​រង់ចាំ​ខាងក្រោម​ន
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (ដោយ​សារតែ​ %s) "
+msgid "%s (due to %s)"
+msgstr "%s (ដោយ​សារតែ​ %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/ko.po b/po/ko.po
index 51cc27d61..e5b08fdec 100644
--- a/po/ko.po
+++ b/po/ko.po
@@ -1250,8 +1250,8 @@ msgstr "고정되었던 다음 패키지를 바꿀 것입니다:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (%s때문에) "
+msgid "%s (due to %s)"
+msgstr "%s (%s때문에)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/ku.po b/po/ku.po
index 540307937..3b2d6ed12 100644
--- a/po/ku.po
+++ b/po/ku.po
@@ -1162,7 +1162,7 @@ msgstr ""
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
+msgid "%s (due to %s)"
msgstr "%s (ji ber %s)"
#: apt-private/private-output.cc:696
diff --git a/po/lt.po b/po/lt.po
index 1f485b28d..6d0365183 100644
--- a/po/lt.po
+++ b/po/lt.po
@@ -1166,8 +1166,8 @@ msgstr "Bus pakeisti šie sulaikyti paketai:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (dėl %s) "
+msgid "%s (due to %s)"
+msgstr "%s (dėl %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/mr.po b/po/mr.po
index 24e470cef..31bdb63c9 100644
--- a/po/mr.po
+++ b/po/mr.po
@@ -1240,7 +1240,7 @@ msgstr "पुढिल ठेवलेली पॅकेजेस बदलत
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
+msgid "%s (due to %s)"
msgstr "%s (च्या मुळे %s)"
#: apt-private/private-output.cc:696
diff --git a/po/nb.po b/po/nb.po
index 433e33909..41563cecd 100644
--- a/po/nb.po
+++ b/po/nb.po
@@ -1258,8 +1258,8 @@ msgstr "Følgende pakker vil bli endret:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (pga. %s) "
+msgid "%s (due to %s)"
+msgstr "%s (pga. %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/ne.po b/po/ne.po
index 4c6f2d098..b5fb2c6fc 100644
--- a/po/ne.po
+++ b/po/ne.po
@@ -1240,8 +1240,8 @@ msgstr "निम्न भइरहेको प्याकेजहरू प
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (%s कारणले) "
+msgid "%s (due to %s)"
+msgstr "%s (%s कारणले)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/nl.po b/po/nl.po
index 5c774fe8d..2214ac65c 100644
--- a/po/nl.po
+++ b/po/nl.po
@@ -1337,8 +1337,8 @@ msgstr "De volgende vastgehouden pakketten zullen gewijzigd worden:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (vanwege %s) "
+msgid "%s (due to %s)"
+msgstr "%s (vanwege %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/nn.po b/po/nn.po
index 0886c266a..5c8c39967 100644
--- a/po/nn.po
+++ b/po/nn.po
@@ -1251,8 +1251,8 @@ msgstr "Dei flgjande pakkane som er haldne tilbake vil verta endra:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (fordi %s) "
+msgid "%s (due to %s)"
+msgstr "%s (fordi %s)"
#: apt-private/private-output.cc:696
#, fuzzy
diff --git a/po/pl.po b/po/pl.po
index 1851fa805..f248841c9 100644
--- a/po/pl.po
+++ b/po/pl.po
@@ -1302,8 +1302,8 @@ msgstr "Zostaną zmienione następujące zatrzymane pakiety:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (z powodu %s) "
+msgid "%s (due to %s)"
+msgstr "%s (z powodu %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/pt.po b/po/pt.po
index 4f05ada82..0e106a7d1 100644
--- a/po/pt.po
+++ b/po/pt.po
@@ -1291,8 +1291,8 @@ msgstr "Os seguintes pacotes mantidos serão mudados:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (devido a %s) "
+msgid "%s (due to %s)"
+msgstr "%s (devido a %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/pt_BR.po b/po/pt_BR.po
index 5e2abd988..c50792b79 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -1264,8 +1264,8 @@ msgstr "Os seguintes pacotes mantidos serão mudados:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (por causa de %s) "
+msgid "%s (due to %s)"
+msgstr "%s (por causa de %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/ro.po b/po/ro.po
index 9b0a1494a..7b94bd3d8 100644
--- a/po/ro.po
+++ b/po/ro.po
@@ -1267,8 +1267,8 @@ msgstr "Următoarele pachete ținute vor fi schimbate:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (datorită %s) "
+msgid "%s (due to %s)"
+msgstr "%s (datorită %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/ru.po b/po/ru.po
index 7d30cb696..5e52b9234 100644
--- a/po/ru.po
+++ b/po/ru.po
@@ -1614,8 +1614,8 @@ msgstr ""
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (вследствие %s) "
+msgid "%s (due to %s)"
+msgstr "%s (вследствие %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/sk.po b/po/sk.po
index 631ddd826..0aeb167ea 100644
--- a/po/sk.po
+++ b/po/sk.po
@@ -1280,8 +1280,8 @@ msgstr "Nasledovné pridržané balíky sa zmenia:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (kvôli %s) "
+msgid "%s (due to %s)"
+msgstr "%s (kvôli %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/sl.po b/po/sl.po
index 845fe3c5f..496919956 100644
--- a/po/sl.po
+++ b/po/sl.po
@@ -1277,8 +1277,8 @@ msgstr "Naslednji zadržani paketi bodo spremenjeni:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (zaradi %s) "
+msgid "%s (due to %s)"
+msgstr "%s (zaradi %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/sv.po b/po/sv.po
index 52f65b598..bdf00ff65 100644
--- a/po/sv.po
+++ b/po/sv.po
@@ -1266,8 +1266,8 @@ msgstr "Följande tillbakahållna paket kommer att ändras:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (på grund av %s) "
+msgid "%s (due to %s)"
+msgstr "%s (på grund av %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/th.po b/po/th.po
index 60a468ea4..c016205c5 100644
--- a/po/th.po
+++ b/po/th.po
@@ -1287,8 +1287,8 @@ msgstr "จะเปลี่ยนแปลงรายการคงรุ่
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (เนื่องจาก %s) "
+msgid "%s (due to %s)"
+msgstr "%s (เนื่องจาก %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/tl.po b/po/tl.po
index 970b0b387..be3371704 100644
--- a/po/tl.po
+++ b/po/tl.po
@@ -1258,8 +1258,8 @@ msgstr "Ang susunod na mga hinawakang mga pakete ay babaguhin:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (dahil sa %s) "
+msgid "%s (due to %s)"
+msgstr "%s (dahil sa %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/tr.po b/po/tr.po
index 79945ebd3..8b8691a55 100644
--- a/po/tr.po
+++ b/po/tr.po
@@ -1315,8 +1315,8 @@ msgstr "Aşağıdaki eski sürümlerinde tutulan paketler değiştirilecek:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (%s nedeniyle) "
+msgid "%s (due to %s)"
+msgstr "%s (%s nedeniyle)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/uk.po b/po/uk.po
index 47976d39c..514403641 100644
--- a/po/uk.po
+++ b/po/uk.po
@@ -1298,8 +1298,8 @@ msgstr "Пакунки, які мали б залишитися без змін,
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (внаслідок %s) "
+msgid "%s (due to %s)"
+msgstr "%s (внаслідок %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/vi.po b/po/vi.po
index 2edb52f22..73770ce74 100644
--- a/po/vi.po
+++ b/po/vi.po
@@ -1334,8 +1334,8 @@ msgstr "Những gói giữ lại sau đây sẽ bị THAY ĐỔI:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (bởi vì %s) "
+msgid "%s (due to %s)"
+msgstr "%s (bởi vì %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/zh_CN.po b/po/zh_CN.po
index 6e9610ac9..1f92d6269 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -1289,8 +1289,8 @@ msgstr "下列被要求保持版本不变的软件包将被改变:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s (是由于 %s) "
+msgid "%s (due to %s)"
+msgstr "%s (是由于 %s)"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/po/zh_TW.po b/po/zh_TW.po
index 201d9d675..f37e5e0ed 100644
--- a/po/zh_TW.po
+++ b/po/zh_TW.po
@@ -1236,8 +1236,8 @@ msgstr "下列被保留 (hold) 的套件將會被更改:"
#: apt-private/private-output.cc:688
#, c-format
-msgid "%s (due to %s) "
-msgstr "%s(因為 %s)"
+msgid "%s (due to %s)"
+msgstr "%s(因為 %s"
#: apt-private/private-output.cc:696
msgid ""
diff --git a/test/integration/test-apt-get-autoremove b/test/integration/test-apt-get-autoremove
index a0e4d3c24..454b47976 100755
--- a/test/integration/test-apt-get-autoremove
+++ b/test/integration/test-apt-get-autoremove
@@ -27,6 +27,19 @@ The following packages will be REMOVED:
po-debconf
0 upgraded, 0 newly installed, 1 to remove and 0 not upgraded.
Remv po-debconf [1.0.16]' aptget autoremove -s
+testequal "Reading package lists...
+Building dependency tree...
+Reading state information...
+The following package was automatically installed and is no longer required:
+ po-debconf
+Use 'apt-get autoremove' to remove it.
+0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." aptget install -s
+testequal "Reading package lists...
+Building dependency tree...
+Reading state information...
+1 package was automatically installed and is no longer required.
+Use 'apt-get autoremove' to remove it.
+0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." aptget install -s -o APT::Get::HideAutoRemove=small
testdpkginstalled 'po-debconf'
echo 'APT::NeverAutoRemove { "^po-debconf$"; };' > rootdir/etc/apt/apt.conf.d/00autoremove
@@ -63,6 +76,19 @@ The following packages will be REMOVED:
0 upgraded, 0 newly installed, 2 to remove and 0 not upgraded.
Remv debhelper [8.0.0]
Remv po-debconf [1.0.16]' aptget autoremove -s
+testequal "Reading package lists...
+Building dependency tree...
+Reading state information...
+The following packages were automatically installed and are no longer required:
+ debhelper po-debconf
+Use 'apt-get autoremove' to remove them.
+0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." aptget install -s
+testequal "Reading package lists...
+Building dependency tree...
+Reading state information...
+2 packages were automatically installed and are no longer required.
+Use 'apt-get autoremove' to remove them.
+0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." aptget install -s -o APT::Get::HideAutoRemove=small
testsuccess aptmark hold debhelper
testsuccessequal 'Reading package lists...
diff --git a/test/integration/test-bug-596498-trusted-unsigned-repo b/test/integration/test-bug-596498-trusted-unsigned-repo
index c515837a3..94f280b81 100755
--- a/test/integration/test-bug-596498-trusted-unsigned-repo
+++ b/test/integration/test-bug-596498-trusted-unsigned-repo
@@ -37,6 +37,15 @@ WARNING: The following packages cannot be authenticated!
Install these packages without verification? [y/N] N
E: Some packages could not be authenticated" aptget install cool --assume-no -d
+configarchitecture 'amd64' 'i386'
+testequal "$(echo "$PKGTEXT" | sed 's#cool$#cool:i386#g')
+WARNING: The following packages cannot be authenticated!
+ cool:i386
+Authentication warning overridden.
+$DOWNLOG
+Download complete and in download only mode" aptget install cool:i386 --assume-no -d --allow-unauthenticated
+configarchitecture 'i386'
+
find aptarchive/ \( -name 'Release.gpg' -o -name 'InRelease' \) -delete
sed -i -e 's#\(deb\(-src\)\?\) \[trusted=no\] #\1 #' $DEBFILE
aptgetupdate
diff --git a/test/integration/test-bug-604222-new-and-autoremove b/test/integration/test-bug-604222-new-and-autoremove
index 52992680b..3b5fa20c4 100755
--- a/test/integration/test-bug-604222-new-and-autoremove
+++ b/test/integration/test-bug-604222-new-and-autoremove
@@ -23,6 +23,17 @@ The following NEW packages will be installed:
Inst libavcodec52 (4:0.5.2-6 localhost [i386])
Conf libavcodec52 (4:0.5.2-6 localhost [i386])" aptget install libavcodec52 -s
+testsuccessequal "Reading package lists...
+Building dependency tree...
+Reading state information...
+1 package was automatically installed and is no longer required.
+Use 'apt-get autoremove' to remove it.
+The following NEW packages will be installed:
+ libavcodec52
+0 upgraded, 1 newly installed, 0 to remove and 1 not upgraded.
+Inst libavcodec52 (4:0.5.2-6 localhost [i386])
+Conf libavcodec52 (4:0.5.2-6 localhost [i386])" aptget install libavcodec52 -s -o APT::Get::HideAutoRemove=small
+
testfailureequal "Reading package lists...
Building dependency tree...
Reading state information...
@@ -39,6 +50,21 @@ The following packages will be upgraded:
Need to get 0 B/19.4 MB of archives.
After this operation, 17.3 MB of additional disk space will be used.
E: Trivial Only specified but this is not a trivial operation." aptget install dummy-archive --trivial-only
+testequal "Reading package lists...
+Building dependency tree...
+Reading state information...
+1 package was automatically installed and is no longer required.
+Use 'apt-get autoremove' to remove it.
+The following extra packages will be installed:
+ libavcodec52 libopenal-dev libvtk5.4
+The following NEW packages will be installed:
+ dummy-archive libavcodec52 libopenal-dev
+The following packages will be upgraded:
+ libvtk5.4
+1 upgraded, 3 newly installed, 0 to remove and 0 not upgraded.
+Need to get 0 B/19.4 MB of archives.
+After this operation, 17.3 MB of additional disk space will be used.
+E: Trivial Only specified but this is not a trivial operation." aptget install dummy-archive --trivial-only -o APT::Get::HideAutoRemove=small
echo -n > rootdir/var/lib/dpkg/status
rm rootdir/var/lib/apt/extended_states
diff --git a/test/integration/test-bug-613420-new-garbage-dependency b/test/integration/test-bug-613420-new-garbage-dependency
index 5839f8798..18eab79c2 100755
--- a/test/integration/test-bug-613420-new-garbage-dependency
+++ b/test/integration/test-bug-613420-new-garbage-dependency
@@ -35,3 +35,19 @@ The following packages will be upgraded:
1 upgraded, 3 newly installed, 1 to remove and 0 not upgraded.
After this operation, 126 MB disk space will be freed.
E: Trivial Only specified but this is not a trivial operation." aptget install libreoffice --trivial-only
+testequal "Reading package lists...
+Building dependency tree...
+Reading state information...
+2 packages were automatically installed and are no longer required.
+Use 'apt-get autoremove' to remove them.
+The following extra packages will be installed:
+ libreoffice-core libreoffice-officebean openoffice.org-officebean
+The following packages will be REMOVED:
+ openoffice.org-core
+The following NEW packages will be installed:
+ libreoffice libreoffice-core libreoffice-officebean
+The following packages will be upgraded:
+ openoffice.org-officebean
+1 upgraded, 3 newly installed, 1 to remove and 0 not upgraded.
+After this operation, 126 MB disk space will be freed.
+E: Trivial Only specified but this is not a trivial operation." aptget install libreoffice --trivial-only -o APT::Get::HideAutoRemove=small
diff --git a/test/integration/test-bug-675449-essential-are-protected b/test/integration/test-bug-675449-essential-are-protected
index f50507532..e62add938 100755
--- a/test/integration/test-bug-675449-essential-are-protected
+++ b/test/integration/test-bug-675449-essential-are-protected
@@ -87,3 +87,17 @@ Inst pkg-none-native [1] (2 unstable [amd64])
Conf pkg-none-native (2 unstable [amd64])
Inst pkg-none-new (2 unstable [amd64])
Conf pkg-none-new (2 unstable [amd64])' aptget dist-upgrade -s
+
+insertinstalledpackage 'foo' 'amd64' '1' 'Depends: libfoo
+Essential: yes'
+insertinstalledpackage 'libfoo' 'amd64' '1'
+testequal 'Reading package lists...
+Building dependency tree...
+The following packages will be REMOVED:
+ foo* libfoo*
+WARNING: The following essential packages will be removed.
+This should NOT be done unless you know exactly what you are doing!
+ foo libfoo (due to foo)
+0 upgraded, 0 newly installed, 2 to remove and 4 not upgraded.
+Purg foo [1]
+Purg libfoo [1]' aptget purge libfoo -s
diff --git a/test/integration/test-kernel-helper-autoremove b/test/integration/test-kernel-helper-autoremove
index c2fc37ee7..2b020ceca 100755
--- a/test/integration/test-kernel-helper-autoremove
+++ b/test/integration/test-kernel-helper-autoremove
@@ -58,6 +58,22 @@ testprotected() {
testsuccessequal "Reading package lists...
Building dependency tree...
Reading state information...
+The following packages were automatically installed and are no longer required:
+ linux-headers-1000000-1-generic (100.0.0-1)
+ linux-image-1.0.0-2-generic (1.0.0-2)
+ linux-image-100.0.0-1-generic (100.0.0-1)
+ $CURRENTKERNEL (1)
+Use 'apt-get autoremove' to remove them.
+0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." aptget install -sV
+testequal "Reading package lists...
+Building dependency tree...
+Reading state information...
+4 packages were automatically installed and are no longer required.
+Use 'apt-get autoremove' to remove them.
+0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded." aptget install -s -o APT::Get::HideAutoRemove=small
+testequal "Reading package lists...
+Building dependency tree...
+Reading state information...
The following packages will be REMOVED:
linux-headers-1000000-1-generic (100.0.0-1)
linux-image-1.0.0-2-generic (1.0.0-2)