X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/98cc7fd2c1d397623960baf69ae3cec04a87a23e..7303e11ff28f920a6277c159aa46f80c007350bb:/apt-pkg/algorithms.cc diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 446afa08d..b173979c3 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -19,13 +19,12 @@ #include #include #include -#include #include -#include #include #include #include #include +#include #include #include @@ -36,8 +35,6 @@ /*}}}*/ using namespace std; -pkgProblemResolver *pkgProblemResolver::This = 0; - // Simulate::Simulate - Constructor /*{{{*/ // --------------------------------------------------------------------- /* The legacy translations here of input Pkg iterators is obsolete, @@ -362,13 +359,11 @@ pkgProblemResolver::~pkgProblemResolver() // ProblemResolver::ScoreSort - Sort the list by score /*{{{*/ // --------------------------------------------------------------------- /* */ -int pkgProblemResolver::ScoreSort(const void *a,const void *b) +int pkgProblemResolver::ScoreSort(Package const *A,Package const *B) { - Package const **A = (Package const **)a; - Package const **B = (Package const **)b; - if (This->Scores[(*A)->ID] > This->Scores[(*B)->ID]) + if (Scores[A->ID] > Scores[B->ID]) return -1; - if (This->Scores[(*A)->ID] < This->Scores[(*B)->ID]) + if (Scores[A->ID] < Scores[B->ID]) return 1; return 0; } @@ -641,8 +636,9 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg) bool pkgProblemResolver::Resolve(bool BrokenFix, OpProgress * const Progress) { std::string const solver = _config->Find("APT::Solver", "internal"); + auto const ret = EDSP::ResolveExternal(solver.c_str(), Cache, 0, Progress); if (solver != "internal") - return EDSP::ResolveExternal(solver.c_str(), Cache, false, false, false, Progress); + return ret; return ResolveInternal(BrokenFix); } /*}}}*/ @@ -706,8 +702,8 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix) pkgCache::Package **PEnd = PList.get(); for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) *PEnd++ = I; - This = this; - qsort(PList.get(),PEnd - PList.get(),sizeof(PList[0]),&ScoreSort); + + std::sort(PList.get(), PEnd, [this](Package *a, Package *b) { return ScoreSort(a, b) < 0; }); if (_config->FindB("Debug::pkgProblemResolver::ShowScores",false) == true) { @@ -716,7 +712,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; } } @@ -731,6 +727,7 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix) changing a breaks c) */ bool Change = true; bool const TryFixByInstall = _config->FindB("pkgProblemResolver::FixByInstall", true); + std::vector KillList; for (int Counter = 0; Counter != 10 && Change == true; Counter++) { Change = false; @@ -770,15 +767,15 @@ 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 - PackageKill KillList[100]; - PackageKill *LEnd = KillList; bool InOr = false; pkgCache::DepIterator Start; pkgCache::DepIterator End; - PackageKill *OldEnd = LEnd; + size_t OldSize = 0; + + KillList.resize(0); enum {OrRemove,OrKeep} OrOp = OrRemove; for (pkgCache::DepIterator D = Cache[I].InstVerIter(Cache).DependsList(); @@ -788,7 +785,7 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix) if (Start == End) { // Decide what to do - if (InOr == true && OldEnd == LEnd) + if (InOr == true && OldSize == KillList.size()) { if (OrOp == OrRemove) { @@ -822,7 +819,7 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix) continue; InOr = Start != End; - OldEnd = LEnd; + OldSize = KillList.size(); } else { @@ -840,7 +837,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 @@ -939,7 +936,7 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix) Start.TargetPkg()->CurrentVer == 0 && Cache[Start.TargetPkg()].Delete() == false && (Flags[Start.TargetPkg()->ID] & ToRemove) != ToRemove && - Cache.GetCandidateVer(Start.TargetPkg()).end() == false) + Cache.GetCandidateVersion(Start.TargetPkg()).end() == false) { /* Before removing or keeping the package with the broken dependency try instead to install the first not previously installed package @@ -947,7 +944,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 @@ -985,10 +982,8 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix) if (Debug == true) clog << " Added " << Pkg.FullName(false) << " to the remove list" << endl; - - LEnd->Pkg = Pkg; - LEnd->Dep = End; - LEnd++; + + KillList.push_back({Pkg, End}); if (Start.IsNegative() == false) break; @@ -1038,7 +1033,7 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix) // Apply the kill list now if (Cache[I].InstallVer != 0) { - for (PackageKill *J = KillList; J != LEnd; J++) + for (auto J = KillList.begin(); J != KillList.end(); J++) { Change = true; if ((Cache[J->Dep] & pkgDepCache::DepGNow) == 0) @@ -1115,7 +1110,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; } @@ -1124,7 +1119,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; } @@ -1139,8 +1134,10 @@ bool pkgProblemResolver::InstOrNewPolicyBroken(pkgCache::PkgIterator I) bool pkgProblemResolver::ResolveByKeep(OpProgress * const Progress) { std::string const solver = _config->Find("APT::Solver", "internal"); + constexpr auto flags = EDSP::Request::UPGRADE_ALL | EDSP::Request::FORBID_NEW_INSTALL | EDSP::Request::FORBID_REMOVE; + auto const ret = EDSP::ResolveExternal(solver.c_str(), Cache, flags, Progress); if (solver != "internal") - return EDSP::ResolveExternal(solver.c_str(), Cache, true, false, false, Progress); + return ret; return ResolveByKeepInternal(); } /*}}}*/ @@ -1165,8 +1162,9 @@ bool pkgProblemResolver::ResolveByKeepInternal() pkgCache::Package **PEnd = PList; for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; ++I) *PEnd++ = I; - This = this; - qsort(PList,PEnd - PList,sizeof(*PList),&ScoreSort); + + std::sort(PList,PEnd,[this](Package *a, Package *b) { return ScoreSort(a, b) < 0; }); + if (_config->FindB("Debug::pkgProblemResolver::ShowScores",false) == true) { @@ -1175,7 +1173,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; } } @@ -1230,7 +1228,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 VList(Start.AllTargets()); @@ -1316,36 +1314,46 @@ void pkgProblemResolver::InstallProtect() // --------------------------------------------------------------------- /* This is ment to be used in conjunction with AllTargets to get a list of versions ordered by preference. */ -static pkgCache *PrioCache; -static int PrioComp(const void *A,const void *B) -{ - pkgCache::VerIterator L(*PrioCache,*(pkgCache::Version **)A); - pkgCache::VerIterator R(*PrioCache,*(pkgCache::Version **)B); - - if ((L.ParentPkg()->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential && - (R.ParentPkg()->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential) - return 1; - if ((L.ParentPkg()->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential && - (R.ParentPkg()->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) - return -1; - - if ((L.ParentPkg()->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important && - (R.ParentPkg()->Flags & pkgCache::Flag::Important) != pkgCache::Flag::Important) - return 1; - if ((L.ParentPkg()->Flags & pkgCache::Flag::Important) != pkgCache::Flag::Important && - (R.ParentPkg()->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important) - return -1; - - if (L->Priority != R->Priority) - return R->Priority - L->Priority; - return strcmp(L.ParentPkg().Name(),R.ParentPkg().Name()); -} + +struct PrioComp { + pkgCache &PrioCache; + + explicit PrioComp(pkgCache &PrioCache) : PrioCache(PrioCache) { + } + + bool operator() (pkgCache::Version * const &A, pkgCache::Version * const &B) { + return compare(A, B) < 0; + } + + int compare(pkgCache::Version * const &A, pkgCache::Version * const &B) { + pkgCache::VerIterator L(PrioCache,A); + pkgCache::VerIterator R(PrioCache,B); + + if ((L.ParentPkg()->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential && + (R.ParentPkg()->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential) + return 1; + if ((L.ParentPkg()->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential && + (R.ParentPkg()->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) + return -1; + + if ((L.ParentPkg()->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important && + (R.ParentPkg()->Flags & pkgCache::Flag::Important) != pkgCache::Flag::Important) + return 1; + if ((L.ParentPkg()->Flags & pkgCache::Flag::Important) != pkgCache::Flag::Important && + (R.ParentPkg()->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important) + return -1; + + if (L->Priority != R->Priority) + return R->Priority - L->Priority; + return strcmp(L.ParentPkg().Name(),R.ParentPkg().Name()); + } +}; + void pkgPrioSortList(pkgCache &Cache,pkgCache::Version **List) { unsigned long Count = 0; - PrioCache = &Cache; for (pkgCache::Version **I = List; *I != 0; I++) Count++; - qsort(List,Count,sizeof(*List),PrioComp); + std::sort(List,List+Count,PrioComp(Cache)); } /*}}}*/