#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 <apt-pkg/cacheiterators.h>
+#include <apt-pkg/pkgcache.h>
+#include <stdlib.h>
+#include <string.h>
+#include <algorithm>
#include <iostream>
/*}}}*/
using namespace std;
-pkgOrderList *pkgOrderList::Me = 0;
-
// OrderList::pkgOrderList - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* */
-pkgOrderList::pkgOrderList(pkgDepCache *pCache) : Cache(*pCache),
+pkgOrderList::pkgOrderList(pkgDepCache *pCache) : d(NULL), Cache(*pCache),
Primary(NULL), Secondary(NULL),
RevDepends(NULL), Remove(NULL),
AfterEnd(NULL), FileList(NULL),
{
// Temp list
unsigned long Size = Cache.Head().PackageCount;
- SPtrArray<Package *> NList = new Package *[Size];
- SPtrArray<Package *> AfterList = new Package *[Size];
- AfterEnd = AfterList;
+ std::unique_ptr<Package *[]> NList(new Package *[Size]);
+ std::unique_ptr<Package *[]> AfterList(new Package *[Size]);
+ AfterEnd = AfterList.get();
Depth = 0;
WipeFlags(Added | AddPending | Loop | InList);
// Rebuild the main list into the temp list.
iterator OldEnd = End;
- End = NList;
+ End = NList.get();
for (iterator I = List; I != OldEnd; ++I)
if (VisitNode(PkgIterator(Cache,*I), "DoRun") == false)
{
}
// Copy the after list to the end of the main list
- for (Package **I = AfterList; I != AfterEnd; I++)
+ for (Package **I = AfterList.get(); I != AfterEnd; I++)
*End++ = *I;
// Swap the main list to the new list
delete [] List;
- List = NList.UnGuard();
+ List = NList.release();
return true;
}
/*}}}*/
LoopCount = 0;
// Sort
- Me = this;
- qsort(List,End - List,sizeof(*List),&OrderCompareB);
+ std::sort(List,End, [this](Package *a, Package *b) { return OrderCompareB(a, b) < 0; } );
if (DoRun() == false)
return false;
LoopCount = -1;
// Sort
- Me = this;
- qsort(List,End - List,sizeof(*List),&OrderCompareA);
+ std::sort(List,End, [this](Package *a, Package *b) { return OrderCompareA(a, b) < 0; });
if (Debug == true)
clog << "** Pass A" << endl;
clog << "** Pass C" << endl;
LoopCount = 0;
RevDepends = 0;
- Remove = 0; // Otherwise the libreadline remove problem occures
+ Remove = 0; // Otherwise the libreadline remove problem occurs
if (DoRun() == false)
return false;
/* Higher scores order earlier */
int pkgOrderList::Score(PkgIterator Pkg)
{
- static int const ScoreDelete = _config->FindI("OrderList::Score::Delete", 500);
-
- // Removal is always done first
+ // Removals should be done after we dealt with essentials
+ static int const ScoreDelete = _config->FindI("OrderList::Score::Delete", 100);
if (Cache[Pkg].Delete() == true)
return ScoreDelete;
break;
}
- // Important Required Standard Optional Extra
+ // Required Important Standard Optional Extra
if (Cache[Pkg].InstVerIter(Cache)->Priority <= 5)
{
signed short PrioMap[] = {0,5,4,3,1,0};
// ---------------------------------------------------------------------
/* This provides a first-pass sort of the list and gives a decent starting
point for further complete ordering. It is used by OrderUnpack only */
-int pkgOrderList::OrderCompareA(const void *a, const void *b)
+int pkgOrderList::OrderCompareA(Package *a, Package *b)
{
- PkgIterator A(Me->Cache,*(Package **)a);
- PkgIterator B(Me->Cache,*(Package **)b);
+ PkgIterator A(Cache,a);
+ PkgIterator B(Cache,b);
// We order packages with a set state toward the front
int Res;
- if ((Res = BoolCompare(Me->IsNow(A),Me->IsNow(B))) != 0)
+ if ((Res = BoolCompare(IsNow(A),IsNow(B))) != 0)
return -1*Res;
// We order missing files to toward the end
-/* if (Me->FileList != 0)
+/* if (FileList != 0)
{
- if ((Res = BoolCompare(Me->IsMissing(A),
- Me->IsMissing(B))) != 0)
+ if ((Res = BoolCompare(IsMissing(A),
+ IsMissing(B))) != 0)
return Res;
}*/
B.State() != pkgCache::PkgIterator::NeedsNothing)
return 1;
- int ScoreA = Me->Score(A);
- int ScoreB = Me->Score(B);
+ int ScoreA = Score(A);
+ int ScoreB = Score(B);
if (ScoreA > ScoreB)
return -1;
// ---------------------------------------------------------------------
/* This orders by installation source. This is useful to handle
inter-source breaks */
-int pkgOrderList::OrderCompareB(const void *a, const void *b)
+int pkgOrderList::OrderCompareB(Package *a, Package *b)
{
- PkgIterator A(Me->Cache,*(Package **)a);
- PkgIterator B(Me->Cache,*(Package **)b);
+ PkgIterator A(Cache,a);
+ PkgIterator B(Cache,b);
if (A.State() != pkgCache::PkgIterator::NeedsNothing &&
B.State() == pkgCache::PkgIterator::NeedsNothing)
B.State() != pkgCache::PkgIterator::NeedsNothing)
return 1;
- int F = Me->FileCmp(A,B);
+ int F = FileCmp(A,B);
if (F != 0)
{
if (F > 0)
return 1;
}
- int ScoreA = Me->Score(A);
- int ScoreB = Me->Score(B);
+ int ScoreA = Score(A);
+ int ScoreB = Score(B);
if (ScoreA > ScoreB)
return -1;
against it! */
bool pkgOrderList::VisitProvides(DepIterator D,bool Critical)
{
- SPtrArray<Version *> List = D.AllTargets();
- for (Version **I = List; *I != 0; ++I)
+ std::unique_ptr<Version *[]> List(D.AllTargets());
+ for (Version **I = List.get(); *I != 0; ++I)
{
VerIterator Ver(Cache,*I);
PkgIterator Pkg = Ver.ParentPkg();
}
if (D.IsNegative() == false)
return true;
- for (Version **I = List; *I != 0; ++I)
+ for (Version **I = List.get(); *I != 0; ++I)
{
VerIterator Ver(Cache,*I);
PkgIterator Pkg = Ver.ParentPkg();
// ---------------------------------------------------------------------
/* This is the core ordering routine. It calls the set dependency
consideration functions which then potentialy call this again. Finite
- depth is achived through the colouring mechinism. */
+ depth is achieved through the colouring mechinism. */
bool pkgOrderList::VisitNode(PkgIterator Pkg, char const* from)
{
- // Looping or irrelevent.
+ // Looping or irrelevant.
// This should probably trancend not installed packages
if (Pkg.end() == true || IsFlag(Pkg,Added) == true ||
IsFlag(Pkg,AddPending) == true || IsFlag(Pkg,InList) == false)
The forwards depends loop is designed to bring the packages dependents
close to the package. This helps reduce deconfigure time.
- Loops are irrelevent to this. */
+ Loops are irrelevant to this. */
bool pkgOrderList::DepUnPackDep(DepIterator D)
{
D.ParentPkg().CurrentVer() != D.ParentVer())
continue;
- // The dep will not break so it is irrelevent.
+ // The dep will not break so it is irrelevant.
if (CheckDep(D) == true)
continue;
this fails to produce a suitable result. */
bool pkgOrderList::CheckDep(DepIterator D)
{
- SPtrArray<Version *> List = D.AllTargets();
+ std::unique_ptr<Version *[]> List(D.AllTargets());
bool Hit = false;
- for (Version **I = List; *I != 0; I++)
+ for (Version **I = List.get(); *I != 0; I++)
{
VerIterator Ver(Cache,*I);
PkgIterator Pkg = Ver.ParentPkg();