+ if (crossgraded.empty() == false)
+ {
+ auto const oldsize = List.size();
+ List.erase(std::remove_if(List.begin(), PlanedEnd,
+ [&crossgraded](Item const &i){
+ return (i.Op == Item::Remove || i.Op == Item::Purge) &&
+ crossgraded.find(i.Pkg->ID) != crossgraded.end();
+ }), PlanedEnd);
+ explicitIdx -= (oldsize - List.size());
+ }
+ }
+
+ APT::StateChanges currentStates;
+ if (_config->FindB("dpkg::selection::current::saveandrestore", true))
+ {
+ for (auto Pkg = Cache.PkgBegin(); Pkg.end() == false; ++Pkg)
+ if (Pkg->CurrentVer == 0)
+ continue;
+ else if (Pkg->SelectedState == pkgCache::State::Purge)
+ currentStates.Purge(FindToBeRemovedVersion(Pkg));
+ else if (Pkg->SelectedState == pkgCache::State::DeInstall)
+ currentStates.Remove(FindToBeRemovedVersion(Pkg));
+ if (currentStates.empty() == false)
+ {
+ APT::StateChanges cleanStates;
+ for (auto && P: currentStates.Remove())
+ cleanStates.Install(P);
+ for (auto && P: currentStates.Purge())
+ cleanStates.Install(P);
+ if (cleanStates.Save(false) == false)
+ return _error->Error("Couldn't clean the currently selected dpkg states");
+ }
+ }
+
+ if (_config->FindB("dpkg::selection::remove::approved", true))
+ {
+ if (approvedStates.Save(false) == false)
+ {
+ _error->Error("Couldn't record the approved state changes as dpkg selection states");
+ if (currentStates.Save(false) == false)
+ _error->Error("Couldn't restore dpkg selection states which were present before this interaction!");
+ return false;
+ }
+
+ List.erase(std::next(List.begin(), explicitIdx), List.end());
+
+ std::vector<bool> toBeRemoved(Cache.Head().PackageCount, false);
+ for (auto && I: approvedStates.Remove())
+ toBeRemoved[I.ParentPkg()->ID] = true;
+ for (auto && I: approvedStates.Purge())
+ toBeRemoved[I.ParentPkg()->ID] = true;
+
+ for (auto && I: List)
+ if (I.Op == Item::Remove || I.Op == Item::Purge)
+ toBeRemoved[I.Pkg->ID] = false;
+
+ bool const RemovePending = std::find(toBeRemoved.begin(), toBeRemoved.end(), true) != toBeRemoved.end();
+ bool const PurgePending = approvedStates.Purge().empty() == false;
+ if (RemovePending != false || PurgePending != false)
+ List.emplace_back(Item::ConfigurePending, pkgCache::PkgIterator());
+ if (RemovePending)
+ List.emplace_back(Item::RemovePending, pkgCache::PkgIterator());
+ if (PurgePending)
+ List.emplace_back(Item::PurgePending, pkgCache::PkgIterator());
+
+ // support subpressing of triggers processing for special
+ // cases like d-i that runs the triggers handling manually
+ if (_config->FindB("DPkg::ConfigurePending", true))
+ List.emplace_back(Item::ConfigurePending, pkgCache::PkgIterator());