X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/e1b74f61dfb6980d643cb7c666c761ff3bda2f1e..10bb1f5f242d8a475b0c4395d71214353355f304:/apt-pkg/orderlist.cc diff --git a/apt-pkg/orderlist.cc b/apt-pkg/orderlist.cc index 04d8c4c7e..bfe91507e 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.3 1998/09/26 05:34:21 jgg Exp $ +// $Id: orderlist.cc,v 1.9 1999/11/04 06:05:02 jgg Exp $ /* ###################################################################### Order List - Represents and Manipulates an ordered list of packages. @@ -42,7 +42,7 @@ arbitary priority to give quite abit of control over the final unpacking order. - The rules listed above my never be violated and are called Critical. + The rules listed above may never be violated and are called Critical. When a critical rule is violated then a loop condition is recorded and will have to be delt with in the caller. @@ -65,6 +65,7 @@ pkgOrderList *pkgOrderList::Me = 0; /* */ pkgOrderList::pkgOrderList(pkgDepCache &Cache) : Cache(Cache) { + FileList = 0; Primary = 0; Secondary = 0; RevDepends = 0; @@ -88,12 +89,31 @@ pkgOrderList::~pkgOrderList() delete [] Flags; } /*}}}*/ +// OrderList::IsMissing - Check if a file is missing /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgOrderList::IsMissing(PkgIterator Pkg) +{ + // Skip packages to erase + if (Cache[Pkg].Delete() == true) + return false; + + // Skip Packages that need configure only. + if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure && + Cache[Pkg].Keep() == true) + return false; + + if (FileList != 0 && 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 */ bool pkgOrderList::DoRun() -{ +{ // Temp list unsigned long Size = Cache.HeaderP->PackageCount; Package **NList = new Package *[Size]; @@ -128,7 +148,9 @@ bool pkgOrderList::DoRun() fatal and indicate that the packages cannot be installed. */ bool pkgOrderList::OrderCritical() { - Primary = &DepUnPackPre; + FileList = 0; + + Primary = &pkgOrderList::DepUnPackPre; Secondary = 0; RevDepends = 0; Remove = 0; @@ -150,18 +172,20 @@ bool pkgOrderList::OrderCritical() // --------------------------------------------------------------------- /* This performs complete unpacking ordering and creates an order that is suitable for unpacking */ -bool pkgOrderList::OrderUnpack() +bool pkgOrderList::OrderUnpack(string *FileList) { - Primary = &DepUnPackCrit; - Secondary = &DepConfigure; - RevDepends = &DepUnPackDep; - Remove = &DepRemove; + this->FileList = FileList; + + Primary = &pkgOrderList::DepUnPackCrit; + Secondary = &pkgOrderList::DepConfigure; + RevDepends = &pkgOrderList::DepUnPackDep; + Remove = &pkgOrderList::DepRemove; LoopCount = -1; // Sort Me = this; qsort(List,End - List,sizeof(*List),&OrderCompareA); - + if (DoRun() == false) return false; @@ -176,7 +200,7 @@ bool pkgOrderList::OrderUnpack() return false; LoopCount = 0; - Primary = &DepUnPackPre; + Primary = &pkgOrderList::DepUnPackPre; if (DoRun() == false) return false; @@ -197,7 +221,8 @@ bool pkgOrderList::OrderUnpack() for configuration */ bool pkgOrderList::OrderConfigure() { - Primary = &DepConfigure; + FileList = 0; + Primary = &pkgOrderList::DepConfigure; Secondary = 0; RevDepends = 0; Remove = 0; @@ -214,7 +239,11 @@ int pkgOrderList::Score(PkgIterator Pkg) // Removal is always done first if (Cache[Pkg].Delete() == true) return 200; - + + // This should never happen.. + if (Cache[Pkg].InstVerIter(Cache).end() == true) + return -1; + int Score = 0; if ((Pkg->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) Score += 100; @@ -248,7 +277,7 @@ int pkgOrderList::FileCmp(PkgIterator A,PkgIterator B) if (Cache[A].InstVerIter(Cache).FileList().end() == true) return -1; - if (Cache[A].InstVerIter(Cache).FileList().end() == true) + if (Cache[B].InstVerIter(Cache).FileList().end() == true) return 1; pkgCache::PackageFile *FA = Cache[A].InstVerIter(Cache).FileList().File(); @@ -260,6 +289,18 @@ int pkgOrderList::FileCmp(PkgIterator A,PkgIterator B) return 0; } /*}}}*/ +// BoolCompare - Comparison function for two booleans /*{{{*/ +// --------------------------------------------------------------------- +/* */ +static int BoolCompare(bool A,bool B) +{ + if (A == B) + return 0; + if (A == false) + return -1; + return 1; +} + /*}}}*/ // OrderList::OrderCompareA - Order the installation by op /*{{{*/ // --------------------------------------------------------------------- /* This provides a first-pass sort of the list and gives a decent starting @@ -269,6 +310,19 @@ int pkgOrderList::OrderCompareA(const void *a, const void *b) PkgIterator A(Me->Cache,*(Package **)a); PkgIterator B(Me->Cache,*(Package **)b); + // We order packages with a set state toward the front + int Res; + if ((Res = BoolCompare(Me->IsNow(A),Me->IsNow(B))) == 0) + return -1*Res; + + // We order missing files to toward the end + if (Me->FileList != 0) + { + if ((Res = BoolCompare(Me->IsMissing(A), + Me->IsMissing(B))) == 0) + return Res; + } + if (A.State() != pkgCache::PkgIterator::NeedsNothing && B.State() == pkgCache::PkgIterator::NeedsNothing) return -1; @@ -367,15 +421,15 @@ bool pkgOrderList::VisitRProvides(DepFunc F,VerIterator Ver) // OrderList::VisitProvides - Visit all of the providing packages /*{{{*/ // --------------------------------------------------------------------- /* This routine calls visit on all providing packages. */ -bool pkgOrderList::VisitProvides(DepIterator D) -{ +bool pkgOrderList::VisitProvides(DepIterator D,bool Critical) +{ Version **List = D.AllTargets(); for (Version **I = List; *I != 0; I++) { VerIterator Ver(Cache,*I); PkgIterator Pkg = Ver.ParentPkg(); - - if (Cache[Pkg].Keep() == true) + + if (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing) continue; if (D->Type != pkgCache::Dep::Conflicts && Cache[Pkg].InstallVer != *I) @@ -384,6 +438,10 @@ bool pkgOrderList::VisitProvides(DepIterator D) if (D->Type == pkgCache::Dep::Conflicts && (Version *)Pkg.CurrentVer() != *I) continue; + // Skip over missing files + if (Critical == false && IsMissing(D.ParentPkg()) == true) + continue; + if (VisitNode(Pkg) == false) { delete [] List; @@ -417,36 +475,39 @@ bool pkgOrderList::VisitNode(PkgIterator Pkg) DepFunc Old = Primary; // Perform immedate configuration of the package if so flagged. - if (IsFlag(Pkg,Immediate) == true && Primary != &DepUnPackPre) - Primary = &DepUnPackPreD; - - bool Res = true; - if (Cache[Pkg].Delete() == false) + if (IsFlag(Pkg,Immediate) == true && Primary != &pkgOrderList::DepUnPackPre) + Primary = &pkgOrderList::DepUnPackPreD; + + if (IsNow(Pkg) == true) { - // Primary - Res &= Res && VisitDeps(Primary,Pkg); - Res &= Res && VisitRDeps(Primary,Pkg); - Res &= Res && VisitRProvides(Primary,Pkg.CurrentVer()); - Res &= Res && VisitRProvides(Primary,Cache[Pkg].InstVerIter(Cache)); - - // RevDep - Res &= Res && VisitRDeps(RevDepends,Pkg); - Res &= Res && VisitRProvides(RevDepends,Pkg.CurrentVer()); - Res &= Res && VisitRProvides(RevDepends,Cache[Pkg].InstVerIter(Cache)); - - // Secondary - Res &= Res && VisitDeps(Secondary,Pkg); - Res &= Res && VisitRDeps(Secondary,Pkg); - Res &= Res && VisitRProvides(Secondary,Pkg.CurrentVer()); - Res &= Res && VisitRProvides(Secondary,Cache[Pkg].InstVerIter(Cache)); - } - else - { - // RevDep - Res &= Res && VisitRDeps(Remove,Pkg); - Res &= Res && VisitRProvides(Remove,Pkg.CurrentVer()); + bool Res = true; + if (Cache[Pkg].Delete() == false) + { + // Primary + Res &= Res && VisitDeps(Primary,Pkg); + Res &= Res && VisitRDeps(Primary,Pkg); + Res &= Res && VisitRProvides(Primary,Pkg.CurrentVer()); + Res &= Res && VisitRProvides(Primary,Cache[Pkg].InstVerIter(Cache)); + + // RevDep + Res &= Res && VisitRDeps(RevDepends,Pkg); + Res &= Res && VisitRProvides(RevDepends,Pkg.CurrentVer()); + Res &= Res && VisitRProvides(RevDepends,Cache[Pkg].InstVerIter(Cache)); + + // Secondary + Res &= Res && VisitDeps(Secondary,Pkg); + Res &= Res && VisitRDeps(Secondary,Pkg); + Res &= Res && VisitRProvides(Secondary,Pkg.CurrentVer()); + Res &= Res && VisitRProvides(Secondary,Cache[Pkg].InstVerIter(Cache)); + } + else + { + // RevDep + Res &= Res && VisitRDeps(Remove,Pkg); + Res &= Res && VisitRProvides(Remove,Pkg.CurrentVer()); + } } - + if (IsFlag(Pkg,Added) == false) { Flag(Pkg,Added,Added | AddPending); @@ -528,8 +589,8 @@ bool pkgOrderList::DepUnPackCrit(DepIterator D) DepFunc Old = Primary; bool Res = false; if (D->Type == pkgCache::Dep::PreDepends) - Primary = &DepUnPackPreD; - Res = VisitProvides(D); + Primary = &pkgOrderList::DepUnPackPreD; + Res = VisitProvides(D,true); Primary = Old; if (Res == false) return false; @@ -575,7 +636,7 @@ bool pkgOrderList::DepUnPackPreD(DepIterator D) continue; } - if (VisitProvides(D) == false) + if (VisitProvides(D,true) == false) return false; } return true; @@ -628,7 +689,7 @@ bool pkgOrderList::DepUnPackPre(DepIterator D) continue; } - if (VisitProvides(D) == false) + if (VisitProvides(D,true) == false) return false; } return true; @@ -664,12 +725,16 @@ bool pkgOrderList::DepUnPackDep(DepIterator D) if (CheckDep(D) == true) continue; + // Skip over missing files + if (IsMissing(D.ParentPkg()) == true) + continue; + if (VisitNode(D.ParentPkg()) == false) return false; } else if (D->Type == pkgCache::Dep::Depends) - if (VisitProvides(D) == false) + if (VisitProvides(D,false) == false) return false; } return true; @@ -690,7 +755,7 @@ bool pkgOrderList::DepConfigure(DepIterator D) for (; D.end() == false; D++) if (D->Type == pkgCache::Dep::Depends) - if (VisitProvides(D) == false) + if (VisitProvides(D,false) == false) return false; return true; } @@ -735,6 +800,10 @@ bool pkgOrderList::DepRemove(DepIterator D) continue; } + // Skip over missing files + if (IsMissing(D.ParentPkg()) == true) + continue; + if (VisitNode(D.ParentPkg()) == false) return false; }