// -*- 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.
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.
##################################################################### */
/*}}}*/
// Include Files /*{{{*/
-#ifdef __GNUG__
-#pragma implementation "apt-pkg/orderlist.h"
-#endif
#include <apt-pkg/orderlist.h>
#include <apt-pkg/depcache.h>
#include <apt-pkg/error.h>
#include <apt-pkg/version.h>
#include <apt-pkg/sptr.h>
#include <apt-pkg/configuration.h>
+
+#include <iostream>
/*}}}*/
+using namespace std;
+
pkgOrderList *pkgOrderList::Me = 0;
// OrderList::pkgOrderList - Constructor /*{{{*/
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;
+
+ // Missing Pseudo packages are missing if the real package is missing
+ if (pkgCache::VerIterator(Cache, Cache[Pkg].CandidateVer).Pseudo() == true)
+ return IsMissing(Pkg.Group().FindPkg("all"));
+
return true;
}
/*}}}*/
-
// OrderList::DoRun - Does an order run /*{{{*/
// ---------------------------------------------------------------------
/* The caller is expeted to have setup the desired probe state */
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.FullName() << ' ' << IsMissing(P) << ',' << IsFlag(P,After) << endl;
+ }
+ }
+
return true;
}
/*}}}*/
if (FileList != 0)
{
WipeFlags(After);
-
+
// Set the inlist flag
for (iterator I = List; I != End; I++)
{
Flag(*I,After);
}
}
-
+
Primary = &pkgOrderList::DepUnPackCrit;
Secondary = &pkgOrderList::DepConfigure;
RevDepends = &pkgOrderList::DepUnPackDep;
clog << "** Pass A" << endl;
if (DoRun() == false)
return false;
-
+
if (Debug == true)
clog << "** Pass B" << endl;
Secondary = 0;
Remove = 0; // Otherwise the libreadline remove problem occures
if (DoRun() == false)
return false;
-
+
if (Debug == true)
clog << "** Pass D" << endl;
LoopCount = 0;
{
PkgIterator P(Cache,*I);
if (IsNow(P) == true)
- clog << P.Name() << ' ' << IsMissing(P) << ',' << IsFlag(P,After) << endl;
+ clog << " " << P.FullName() << ' ' << IsMissing(P) << ',' << IsFlag(P,After) << endl;
}
- }
+ }
return true;
}
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)
int ScoreA = Me->Score(A);
int ScoreB = Me->Score(B);
+
if (ScoreA > ScoreB)
return -1;
int ScoreA = Me->Score(A);
int ScoreB = Me->Score(B);
+
if (ScoreA > ScoreB)
return -1;
return strcmp(A.Name(),B.Name());
}
/*}}}*/
-
// OrderList::VisitDeps - Visit forward install dependencies /*{{{*/
// ---------------------------------------------------------------------
/* This calls the dependency function for the normal forwards dependencies
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;
if (Debug == true)
{
for (int j = 0; j != Depth; j++) clog << ' ';
- clog << "Visit " << Pkg.Name() << endl;
+ clog << "Visit " << Pkg.FullName() << endl;
}
Depth++;
if (Debug == true)
{
for (int j = 0; j != Depth; j++) clog << ' ';
- clog << "Leave " << Pkg.Name() << ' ' << IsFlag(Pkg,Added) << ',' << IsFlag(Pkg,AddPending) << endl;
+ clog << "Leave " << Pkg.FullName() << ' ' << IsFlag(Pkg,Added) << ',' << IsFlag(Pkg,AddPending) << endl;
}
return true;
}
/*}}}*/
-
// OrderList::DepUnPackCrit - Critical UnPacking ordering /*{{{*/
// ---------------------------------------------------------------------
/* Critical unpacking ordering strives to satisfy Conflicts: and
/* 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;
// ---------------------------------------------------------------------
/* 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)
{
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;
}
return true;
}
/*}}}*/
-
// OrderList::AddLoop - Add a loop to the loop list /*{{{*/
// ---------------------------------------------------------------------
/* We record the loops. This is a relic since loop breaking is done
/* 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