|
@@ -1,6 +1,6 @@
|
|
|
// -*- mode: cpp; mode: fold -*-
|
|
// -*- mode: cpp; mode: fold -*-
|
|
|
// Description /*{{{*/
|
|
// Description /*{{{*/
|
|
|
-// $Id: algorithms.cc,v 1.25 1999/10/02 04:14:53 jgg Exp $
|
|
|
|
|
|
|
+// $Id: algorithms.cc,v 1.26 1999/10/22 04:05:47 jgg Exp $
|
|
|
/* ######################################################################
|
|
/* ######################################################################
|
|
|
|
|
|
|
|
Algorithms - A set of misc algorithms
|
|
Algorithms - A set of misc algorithms
|
|
@@ -549,34 +549,38 @@ bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg)
|
|
|
if ((Flags[P->ID] & Protected) == Protected)
|
|
if ((Flags[P->ID] & Protected) == Protected)
|
|
|
{
|
|
{
|
|
|
if (Debug == true)
|
|
if (Debug == true)
|
|
|
- clog << " Reinet Failed because of protected " << P.Name() << endl;
|
|
|
|
|
|
|
+ clog << " Reinst Failed because of protected " << P.Name() << endl;
|
|
|
Fail = true;
|
|
Fail = true;
|
|
|
- break;
|
|
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
- // Upgrade the package if the candidate version will fix the problem.
|
|
|
|
|
- if ((Cache[Start] & pkgDepCache::DepCVer) == pkgDepCache::DepCVer)
|
|
|
|
|
|
|
+ else
|
|
|
{
|
|
{
|
|
|
- if (DoUpgrade(P) == false)
|
|
|
|
|
|
|
+ // Upgrade the package if the candidate version will fix the problem.
|
|
|
|
|
+ if ((Cache[Start] & pkgDepCache::DepCVer) == pkgDepCache::DepCVer)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (DoUpgrade(P) == false)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (Debug == true)
|
|
|
|
|
+ clog << " Reinst Failed because of " << P.Name() << endl;
|
|
|
|
|
+ Fail = true;
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ Fail = false;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
{
|
|
{
|
|
|
|
|
+ /* We let the algorithm deal with conflicts on its next iteration,
|
|
|
|
|
+ it is much smarter than us */
|
|
|
|
|
+ if (Start->Type == pkgCache::Dep::Conflicts)
|
|
|
|
|
+ continue;
|
|
|
|
|
+
|
|
|
if (Debug == true)
|
|
if (Debug == true)
|
|
|
- clog << " Reinst Failed because of " << P.Name() << endl;
|
|
|
|
|
|
|
+ clog << " Reinst Failed early because of " << Start.TargetPkg().Name() << endl;
|
|
|
Fail = true;
|
|
Fail = true;
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
- /* We let the algorithm deal with conflicts on its next iteration,
|
|
|
|
|
- it is much smarter than us */
|
|
|
|
|
- if (Start->Type == pkgCache::Dep::Conflicts)
|
|
|
|
|
- continue;
|
|
|
|
|
-
|
|
|
|
|
- if (Debug == true)
|
|
|
|
|
- clog << " Reinst Failed early because of " << Start.TargetPkg().Name() << endl;
|
|
|
|
|
- Fail = true;
|
|
|
|
|
- break;
|
|
|
|
|
- }
|
|
|
|
|
|
|
|
|
|
if (Start == End)
|
|
if (Start == End)
|
|
|
break;
|
|
break;
|
|
@@ -721,12 +725,29 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
|
|
|
bool InOr = false;
|
|
bool InOr = false;
|
|
|
pkgCache::DepIterator Start;
|
|
pkgCache::DepIterator Start;
|
|
|
pkgCache::DepIterator End;
|
|
pkgCache::DepIterator End;
|
|
|
|
|
+ PackageKill *OldEnd;
|
|
|
|
|
+
|
|
|
|
|
+ enum {OrRemove,OrKeep} OrOp = OrRemove;
|
|
|
for (pkgCache::DepIterator D = Cache[I].InstVerIter(Cache).DependsList();
|
|
for (pkgCache::DepIterator D = Cache[I].InstVerIter(Cache).DependsList();
|
|
|
D.end() == false || InOr == true;)
|
|
D.end() == false || InOr == true;)
|
|
|
{
|
|
{
|
|
|
// Compute a single dependency element (glob or)
|
|
// Compute a single dependency element (glob or)
|
|
|
- if (InOr == false)
|
|
|
|
|
|
|
+ if (Start == End)
|
|
|
|
|
+ {
|
|
|
|
|
+ // Decide what to do
|
|
|
|
|
+ if (InOr == true)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (OldEnd == LEnd && OrOp == OrRemove)
|
|
|
|
|
+ Cache.MarkDelete(I);
|
|
|
|
|
+ if (OldEnd == LEnd && OrOp == OrKeep)
|
|
|
|
|
+ Cache.MarkKeep(I);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ OrOp = OrRemove;
|
|
|
D.GlobOr(Start,End);
|
|
D.GlobOr(Start,End);
|
|
|
|
|
+ InOr = Start != End;
|
|
|
|
|
+ OldEnd = LEnd;
|
|
|
|
|
+ }
|
|
|
else
|
|
else
|
|
|
Start++;
|
|
Start++;
|
|
|
|
|
|
|
@@ -737,9 +758,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
|
|
|
// Dep is ok
|
|
// Dep is ok
|
|
|
if ((Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall)
|
|
if ((Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall)
|
|
|
continue;
|
|
continue;
|
|
|
-
|
|
|
|
|
- InOr = Start != End;
|
|
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
if (Debug == true)
|
|
if (Debug == true)
|
|
|
clog << "Package " << I.Name() << " has broken dep on " << Start.TargetPkg().Name() << endl;
|
|
clog << "Package " << I.Name() << " has broken dep on " << Start.TargetPkg().Name() << endl;
|
|
|
|
|
|
|
@@ -748,11 +767,18 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
|
|
|
if a package has a dep on another package that cant be found */
|
|
if a package has a dep on another package that cant be found */
|
|
|
pkgCache::Version **VList = Start.AllTargets();
|
|
pkgCache::Version **VList = Start.AllTargets();
|
|
|
if (*VList == 0 && (Flags[I->ID] & Protected) != Protected &&
|
|
if (*VList == 0 && (Flags[I->ID] & Protected) != Protected &&
|
|
|
- Start->Type != pkgCache::Dep::Conflicts &&
|
|
|
|
|
|
|
+ Start->Type != pkgCache::Dep::Conflicts &&
|
|
|
Cache[I].NowBroken() == false)
|
|
Cache[I].NowBroken() == false)
|
|
|
- {
|
|
|
|
|
|
|
+ {
|
|
|
|
|
+ if (InOr == true)
|
|
|
|
|
+ {
|
|
|
|
|
+ /* No keep choice because the keep being OK could be the
|
|
|
|
|
+ result of another element in the OR group! */
|
|
|
|
|
+ continue;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
Change = true;
|
|
Change = true;
|
|
|
- Cache.MarkKeep(I);
|
|
|
|
|
|
|
+ Cache.MarkKeep(I);
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -778,10 +804,19 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/* See if a keep will do, unless the package is protected,
|
|
/* See if a keep will do, unless the package is protected,
|
|
|
- then installing it will be necessary */
|
|
|
|
|
|
|
+ then installing it will be necessary */
|
|
|
|
|
+ bool Installed = Cache[I].Install();
|
|
|
Cache.MarkKeep(I);
|
|
Cache.MarkKeep(I);
|
|
|
if (Cache[I].InstBroken() == false)
|
|
if (Cache[I].InstBroken() == false)
|
|
|
{
|
|
{
|
|
|
|
|
+ // Unwind operation will be keep now
|
|
|
|
|
+ if (OrOp == OrRemove)
|
|
|
|
|
+ OrOp = OrKeep;
|
|
|
|
|
+
|
|
|
|
|
+ // Restore
|
|
|
|
|
+ if (InOr == true && Installed == true)
|
|
|
|
|
+ Cache.MarkInstall(I,false);
|
|
|
|
|
+
|
|
|
if (Debug == true)
|
|
if (Debug == true)
|
|
|
clog << " Holding Back " << I.Name() << " rather than change " << Start.TargetPkg().Name() << endl;
|
|
clog << " Holding Back " << I.Name() << " rather than change " << Start.TargetPkg().Name() << endl;
|
|
|
}
|
|
}
|
|
@@ -807,7 +842,7 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
|
- // Skip this if it is protected
|
|
|
|
|
|
|
+ // Skip adding to the kill list if it is protected
|
|
|
if ((Flags[Pkg->ID] & Protected) != 0)
|
|
if ((Flags[Pkg->ID] & Protected) != 0)
|
|
|
continue;
|
|
continue;
|
|
|
|
|
|
|
@@ -822,11 +857,20 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
|
|
|
|
|
|
|
|
// Hm, nothing can possibly satisify this dep. Nuke it.
|
|
// Hm, nothing can possibly satisify this dep. Nuke it.
|
|
|
if (VList[0] == 0 && Start->Type != pkgCache::Dep::Conflicts &&
|
|
if (VList[0] == 0 && Start->Type != pkgCache::Dep::Conflicts &&
|
|
|
- (Flags[I->ID] & Protected) != Protected && InOr == false)
|
|
|
|
|
|
|
+ (Flags[I->ID] & Protected) != Protected)
|
|
|
{
|
|
{
|
|
|
|
|
+ bool Installed = Cache[I].Install();
|
|
|
Cache.MarkKeep(I);
|
|
Cache.MarkKeep(I);
|
|
|
if (Cache[I].InstBroken() == false)
|
|
if (Cache[I].InstBroken() == false)
|
|
|
{
|
|
{
|
|
|
|
|
+ // Unwind operation will be keep now
|
|
|
|
|
+ if (OrOp == OrRemove)
|
|
|
|
|
+ OrOp = OrKeep;
|
|
|
|
|
+
|
|
|
|
|
+ // Restore
|
|
|
|
|
+ if (InOr == true && Installed == true)
|
|
|
|
|
+ Cache.MarkInstall(I,false);
|
|
|
|
|
+
|
|
|
if (Debug == true)
|
|
if (Debug == true)
|
|
|
clog << " Holding Back " << I.Name() << " because I can't find " << Start.TargetPkg().Name() << endl;
|
|
clog << " Holding Back " << I.Name() << " because I can't find " << Start.TargetPkg().Name() << endl;
|
|
|
}
|
|
}
|
|
@@ -834,47 +878,51 @@ bool pkgProblemResolver::Resolve(bool BrokenFix)
|
|
|
{
|
|
{
|
|
|
if (Debug == true)
|
|
if (Debug == true)
|
|
|
clog << " Removing " << I.Name() << " because I can't find " << Start.TargetPkg().Name() << endl;
|
|
clog << " Removing " << I.Name() << " because I can't find " << Start.TargetPkg().Name() << endl;
|
|
|
- Cache.MarkDelete(I);
|
|
|
|
|
|
|
+ if (InOr == false)
|
|
|
|
|
+ Cache.MarkDelete(I);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
Change = true;
|
|
Change = true;
|
|
|
Done = true;
|
|
Done = true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ delete [] VList;
|
|
|
|
|
+
|
|
|
// Try some more
|
|
// Try some more
|
|
|
if (InOr == true)
|
|
if (InOr == true)
|
|
|
continue;
|
|
continue;
|
|
|
|
|
|
|
|
- delete [] VList;
|
|
|
|
|
if (Done == true)
|
|
if (Done == true)
|
|
|
break;
|
|
break;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Apply the kill list now
|
|
// Apply the kill list now
|
|
|
if (Cache[I].InstallVer != 0)
|
|
if (Cache[I].InstallVer != 0)
|
|
|
|
|
+ {
|
|
|
for (PackageKill *J = KillList; J != LEnd; J++)
|
|
for (PackageKill *J = KillList; J != LEnd; J++)
|
|
|
- {
|
|
|
|
|
- Change = true;
|
|
|
|
|
- if ((Cache[J->Dep] & pkgDepCache::DepGNow) == 0)
|
|
|
|
|
{
|
|
{
|
|
|
- if (J->Dep->Type == pkgCache::Dep::Conflicts)
|
|
|
|
|
|
|
+ Change = true;
|
|
|
|
|
+ if ((Cache[J->Dep] & pkgDepCache::DepGNow) == 0)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (J->Dep->Type == pkgCache::Dep::Conflicts)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (Debug == true)
|
|
|
|
|
+ clog << " Fixing " << I.Name() << " via remove of " << J->Pkg.Name() << endl;
|
|
|
|
|
+ Cache.MarkDelete(J->Pkg);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
{
|
|
{
|
|
|
if (Debug == true)
|
|
if (Debug == true)
|
|
|
- clog << " Fixing " << I.Name() << " via remove of " << J->Pkg.Name() << endl;
|
|
|
|
|
- Cache.MarkDelete(J->Pkg);
|
|
|
|
|
|
|
+ clog << " Fixing " << I.Name() << " via keep of " << J->Pkg.Name() << endl;
|
|
|
|
|
+ Cache.MarkKeep(J->Pkg);
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
- else
|
|
|
|
|
- {
|
|
|
|
|
- if (Debug == true)
|
|
|
|
|
- clog << " Fixing " << I.Name() << " via keep of " << J->Pkg.Name() << endl;
|
|
|
|
|
- Cache.MarkKeep(J->Pkg);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (Counter > 1)
|
|
|
|
|
- Scores[J->Pkg->ID] = Scores[I->ID];
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+
|
|
|
|
|
+ if (Counter > 1)
|
|
|
|
|
+ Scores[J->Pkg->ID] = Scores[I->ID];
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (Debug == true)
|
|
if (Debug == true)
|