X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/b2e465d6d32d2dc884f58b94acb7e35f671a87fe..c5dac10c3dd6d8f54d97d3105803d07fa891fcd4:/apt-pkg/orderlist.cc?ds=sidebyside diff --git a/apt-pkg/orderlist.cc b/apt-pkg/orderlist.cc index 4bd603726..0ee2e2bc8 100644 --- a/apt-pkg/orderlist.cc +++ b/apt-pkg/orderlist.cc @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: orderlist.cc,v 1.12 2001/02/20 07:03:17 jgg Exp $ +// $Id: orderlist.cc,v 1.14 2001/05/07 05:49:43 jgg Exp $ /* ###################################################################### Order List - Represents and Manipulates an ordered list of packages. @@ -39,7 +39,7 @@ ordering. Each of the features can be enabled in the sorting routine at an - arbitary priority to give quite abit of control over the final unpacking + arbitrary priority to give quite abit of control over the final unpacking order. The rules listed above may never be violated and are called Critical. @@ -63,17 +63,18 @@ ##################################################################### */ /*}}}*/ // Include Files /*{{{*/ -#ifdef __GNUG__ -#pragma implementation "apt-pkg/orderlist.h" -#endif #include #include #include #include #include #include + +#include /*}}}*/ +using namespace std; + pkgOrderList *pkgOrderList::Me = 0; // OrderList::pkgOrderList - Constructor /*{{{*/ @@ -119,13 +120,15 @@ bool pkgOrderList::IsMissing(PkgIterator Pkg) if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure && Cache[Pkg].Keep() == true) return false; + + if (FileList == 0) + return false; - if (FileList != 0 && FileList[Pkg->ID].empty() == false) + if (FileList[Pkg->ID].empty() == false) return false; return true; } /*}}}*/ - // OrderList::DoRun - Does an order run /*{{{*/ // --------------------------------------------------------------------- /* The caller is expeted to have setup the desired probe state */ @@ -171,22 +174,35 @@ bool pkgOrderList::DoRun() bool pkgOrderList::OrderCritical() { FileList = 0; - - Primary = &pkgOrderList::DepUnPackPre; + + Primary = &pkgOrderList::DepUnPackPreD; Secondary = 0; RevDepends = 0; Remove = 0; LoopCount = 0; - + // Sort Me = this; - qsort(List,End - List,sizeof(*List),&OrderCompareB); - + qsort(List,End - List,sizeof(*List),&OrderCompareB); + if (DoRun() == false) return false; - + if (LoopCount != 0) return _error->Error("Fatal, predepends looping detected"); + + if (Debug == true) + { + clog << "** Critical Unpack ordering done" << endl; + + for (iterator I = List; I != End; I++) + { + PkgIterator P(Cache,*I); + if (IsNow(P) == true) + clog << " " << P.Name() << ' ' << IsMissing(P) << ',' << IsFlag(P,After) << endl; + } + } + return true; } /*}}}*/ @@ -202,7 +218,7 @@ bool pkgOrderList::OrderUnpack(string *FileList) if (FileList != 0) { WipeFlags(After); - + // Set the inlist flag for (iterator I = List; I != End; I++) { @@ -211,7 +227,7 @@ bool pkgOrderList::OrderUnpack(string *FileList) Flag(*I,After); } } - + Primary = &pkgOrderList::DepUnPackCrit; Secondary = &pkgOrderList::DepConfigure; RevDepends = &pkgOrderList::DepUnPackDep; @@ -226,7 +242,7 @@ bool pkgOrderList::OrderUnpack(string *FileList) clog << "** Pass A" << endl; if (DoRun() == false) return false; - + if (Debug == true) clog << "** Pass B" << endl; Secondary = 0; @@ -240,7 +256,7 @@ bool pkgOrderList::OrderUnpack(string *FileList) Remove = 0; // Otherwise the libreadline remove problem occures if (DoRun() == false) return false; - + if (Debug == true) clog << "** Pass D" << endl; LoopCount = 0; @@ -256,9 +272,9 @@ bool pkgOrderList::OrderUnpack(string *FileList) { PkgIterator P(Cache,*I); if (IsNow(P) == true) - clog << P.Name() << ' ' << IsMissing(P) << ',' << IsFlag(P,After) << endl; + clog << " " << P.Name() << ' ' << IsMissing(P) << ',' << IsFlag(P,After) << endl; } - } + } return true; } @@ -278,35 +294,40 @@ bool pkgOrderList::OrderConfigure() return DoRun(); } /*}}}*/ - // OrderList::Score - Score the package for sorting /*{{{*/ // --------------------------------------------------------------------- /* Higher scores order earlier */ int pkgOrderList::Score(PkgIterator Pkg) { + static int const ScoreDelete = _config->FindI("OrderList::Score::Delete", 500); + // Removal is always done first if (Cache[Pkg].Delete() == true) - return 200; - + return ScoreDelete; + // This should never happen.. if (Cache[Pkg].InstVerIter(Cache).end() == true) return -1; - + + static int const ScoreEssential = _config->FindI("OrderList::Score::Essential", 200); + static int const ScoreImmediate = _config->FindI("OrderList::Score::Immediate", 10); + static int const ScorePreDepends = _config->FindI("OrderList::Score::PreDepends", 50); + int Score = 0; if ((Pkg->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) - Score += 100; + Score += ScoreEssential; if (IsFlag(Pkg,Immediate) == true) - Score += 10; - - for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList(); + Score += ScoreImmediate; + + for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList(); D.end() == false; D++) if (D->Type == pkgCache::Dep::PreDepends) { - Score += 50; + Score += ScorePreDepends; break; } - + // Important Required Standard Optional Extra signed short PrioMap[] = {0,5,4,3,1,0}; if (Cache[Pkg].InstVerIter(Cache)->Priority <= 5) @@ -384,6 +405,7 @@ int pkgOrderList::OrderCompareA(const void *a, const void *b) int ScoreA = Me->Score(A); int ScoreB = Me->Score(B); + if (ScoreA > ScoreB) return -1; @@ -420,6 +442,7 @@ int pkgOrderList::OrderCompareB(const void *a, const void *b) int ScoreA = Me->Score(A); int ScoreB = Me->Score(B); + if (ScoreA > ScoreB) return -1; @@ -429,7 +452,6 @@ int pkgOrderList::OrderCompareB(const void *a, const void *b) return strcmp(A.Name(),B.Name()); } /*}}}*/ - // OrderList::VisitDeps - Visit forward install dependencies /*{{{*/ // --------------------------------------------------------------------- /* This calls the dependency function for the normal forwards dependencies @@ -484,11 +506,13 @@ bool pkgOrderList::VisitProvides(DepIterator D,bool Critical) continue; if (D->Type != pkgCache::Dep::Conflicts && + D->Type != pkgCache::Dep::DpkgBreaks && D->Type != pkgCache::Dep::Obsoletes && Cache[Pkg].InstallVer != *I) continue; if ((D->Type == pkgCache::Dep::Conflicts || + D->Type == pkgCache::Dep::DpkgBreaks || D->Type == pkgCache::Dep::Obsoletes) && (Version *)Pkg.CurrentVer() != *I) continue; @@ -584,7 +608,6 @@ bool pkgOrderList::VisitNode(PkgIterator Pkg) return true; } /*}}}*/ - // OrderList::DepUnPackCrit - Critical UnPacking ordering /*{{{*/ // --------------------------------------------------------------------- /* Critical unpacking ordering strives to satisfy Conflicts: and @@ -623,6 +646,7 @@ bool pkgOrderList::DepUnPackCrit(DepIterator D) /* Forward critical dependencies MUST be correct before the package can be unpacked. */ if (D->Type != pkgCache::Dep::Conflicts && + D->Type != pkgCache::Dep::DpkgBreaks && D->Type != pkgCache::Dep::Obsoletes && D->Type != pkgCache::Dep::PreDepends) continue; @@ -666,8 +690,7 @@ bool pkgOrderList::DepUnPackCrit(DepIterator D) // --------------------------------------------------------------------- /* Critical PreDepends (also configure immediate and essential) strives to ensure not only that all conflicts+predepends are met but that this - package will be immediately configurable when it is unpacked. - + package will be immediately configurable when it is unpacked. Loops are preprocessed and logged. */ bool pkgOrderList::DepUnPackPreD(DepIterator D) { @@ -796,9 +819,20 @@ bool pkgOrderList::DepUnPackDep(DepIterator D) return false; } else + { if (D->Type == pkgCache::Dep::Depends) if (VisitProvides(D,false) == false) return false; + + if (D->Type == pkgCache::Dep::DpkgBreaks) + { + if (CheckDep(D) == true) + continue; + + if (VisitNode(D.TargetPkg()) == false) + return false; + } + } } return true; } @@ -874,7 +908,6 @@ bool pkgOrderList::DepRemove(DepIterator D) return true; } /*}}}*/ - // OrderList::AddLoop - Add a loop to the loop list /*{{{*/ // --------------------------------------------------------------------- /* We record the loops. This is a relic since loop breaking is done @@ -946,6 +979,7 @@ bool pkgOrderList::CheckDep(DepIterator D) /* Conflicts requires that all versions are not present, depends just needs one */ if (D->Type != pkgCache::Dep::Conflicts && + D->Type != pkgCache::Dep::DpkgBreaks && D->Type != pkgCache::Dep::Obsoletes) { /* Try to find something that does not have the after flag set