// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: algorithms.cc,v 1.4 1998/10/02 04:39:42 jgg Exp $
+// $Id: algorithms.cc,v 1.15 1999/01/30 02:12:53 jgg Exp $
/* ######################################################################
Algorithms - A set of misc algorithms
// ---------------------------------------------------------------------
/* */
pkgSimulate::pkgSimulate(pkgDepCache &Cache) : pkgPackageManager(Cache),
- Sim(Cache)
+ Sim(Cache.GetMap())
{
Flags = new unsigned char[Cache.HeaderP->PackageCount];
memset(Flags,0,sizeof(*Flags)*Cache.HeaderP->PackageCount);
PkgIterator Pkg = Sim.FindPkg(iPkg.Name());
Flags[Pkg->ID] = 1;
- clog << "Inst " << Pkg.Name();
+ cout << "Inst " << Pkg.Name();
Sim.MarkInstall(Pkg,false);
// Look for broken conflicts+predepends.
{
if ((Sim[D] & pkgDepCache::DepInstall) == 0)
{
- clog << " [" << I.Name() << " on " << D.TargetPkg().Name() << ']';
+ cout << " [" << I.Name() << " on " << D.TargetPkg().Name() << ']';
if (D->Type == pkgCache::Dep::Conflicts)
_error->Error("Fatal, conflicts violated %s",I.Name());
}
if (Sim.BrokenCount() != 0)
ShortBreaks();
else
- clog << endl;
+ cout << endl;
return true;
}
/*}}}*/
// Sim.MarkInstall(Pkg,false);
if (Sim[Pkg].InstBroken() == true)
{
- clog << "Conf " << Pkg.Name() << " broken" << endl;
+ cout << "Conf " << Pkg.Name() << " broken" << endl;
Sim.Update();
continue;
if (D->Type == pkgCache::Dep::Conflicts)
- clog << " Conflicts:" << D.TargetPkg().Name();
+ cout << " Conflicts:" << D.TargetPkg().Name();
else
- clog << " Depends:" << D.TargetPkg().Name();
+ cout << " Depends:" << D.TargetPkg().Name();
}
- clog << endl;
+ cout << endl;
_error->Error("Conf Broken %s",Pkg.Name());
}
else
- clog << "Conf " << Pkg.Name();
+ cout << "Conf " << Pkg.Name();
if (Sim.BrokenCount() != 0)
ShortBreaks();
else
- clog << endl;
+ cout << endl;
return true;
}
Flags[Pkg->ID] = 3;
Sim.MarkDelete(Pkg);
- clog << "Remv " << Pkg.Name();
+ cout << "Remv " << Pkg.Name();
if (Sim.BrokenCount() != 0)
ShortBreaks();
else
- clog << endl;
+ cout << endl;
return true;
}
/* */
void pkgSimulate::ShortBreaks()
{
- clog << " [";
+ cout << " [";
for (PkgIterator I = Sim.PkgBegin(); I.end() == false; I++)
{
if (Sim[I].InstBroken() == true)
{
if (Flags[I->ID] == 0)
- clog << I.Name() << ' ';
+ cout << I.Name() << ' ';
/* else
- clog << I.Name() << "! ";*/
+ cout << I.Name() << "! ";*/
}
}
- clog << ']' << endl;
+ cout << ']' << endl;
}
/*}}}*/
// ApplyStatus - Adjust for non-ok packages /*{{{*/
{
for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
{
+ // Only choice for a ReInstReq package is to reinstall
+ if (I->InstState == pkgCache::State::ReInstReq ||
+ I->InstState == pkgCache::State::HoldReInstReq)
+ {
+ Cache.MarkKeep(I);
+ continue;
+ }
+
switch (I->CurrentState)
{
// This means installation failed somehow
for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
if (Cache[I].NowBroken() == true)
Cache.MarkInstall(I,true);
-
+
/* Fix packages that are in a NeedArchive state but don't have a
downloadable install version */
for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
if (Cache[I].InstVerIter(Cache).Downloadable() == false)
continue;
- Cache.MarkInstall(I,true);
+ Cache.MarkInstall(I,true);
}
pkgProblemResolver Fix(Cache);
Cache.MarkInstall(I,false);
pkgProblemResolver Fix(Cache);
-
+
// Hold back held packages.
- for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
+ if (_config->FindB("APT::Ingore-Hold",false) == false)
{
- if (I->SelectedState == pkgCache::State::Hold)
+ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
{
- Fix.Protect(I);
- Cache.MarkKeep(I);
+ if (I->SelectedState == pkgCache::State::Hold)
+ {
+ Fix.Protect(I);
+ Cache.MarkKeep(I);
+ }
}
}
if (Cache[I].Install() == true)
Fix.Protect(I);
- if (I->SelectedState == pkgCache::State::Hold)
- continue;
+ if (_config->FindB("APT::Ingore-Hold",false) == false)
+ if (I->SelectedState == pkgCache::State::Hold)
+ continue;
if (I->CurrentVer != 0 && Cache[I].InstallVer != 0)
Cache.MarkInstall(I,false);
return Fix.ResolveByKeep();
}
/*}}}*/
+// MinimizeUpgrade - Minimizes the set of packages to be upgraded /*{{{*/
+// ---------------------------------------------------------------------
+/* This simply goes over the entire set of packages and tries to keep
+ each package marked for upgrade. If a conflict is generated then
+ the package is restored. */
+bool pkgMinimizeUpgrade(pkgDepCache &Cache)
+{
+ if (Cache.BrokenCount() != 0)
+ return false;
+
+ // We loop indefinately to get the minimal set size.
+ bool Change = false;
+ do
+ {
+ Change = false;
+ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
+ {
+ // Not interesting
+ if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true)
+ continue;
+
+ // Keep it and see if that is OK
+ Cache.MarkKeep(I);
+ if (Cache.BrokenCount() != 0)
+ Cache.MarkInstall(I,false);
+ else
+ Change = true;
+ }
+ }
+ while (Change == true);
+
+ if (Cache.BrokenCount() != 0)
+ return _error->Error("Internal Error in pkgMinimizeUpgrade");
+
+ return true;
+}
+ /*}}}*/
// ProblemResolver::pkgProblemResolver - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* Protected things are pushed really high up. This number should put them
ahead of everything */
for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
+ {
if ((Flags[I->ID] & Protected) != 0)
Scores[I->ID] += 10000;
+ if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential)
+ Scores[I->ID] += 5000;
+ }
delete [] OldScores;
}
{
if (Debug == true)
clog << " Try to Re-Instate " << I.Name() << endl;
- int OldBreaks = Cache.BrokenCount();
+ unsigned long OldBreaks = Cache.BrokenCount();
pkgCache::Version *OldVer = Cache[I].InstallVer;
Flags[I->ID] &= ReInstateTried;
for (pkgCache::DepIterator D = Cache[I].InstVerIter(Cache).DependsList(); D.end() == false;)
{
// Compute a single dependency element (glob or)
- pkgCache::DepIterator Start = D;
- pkgCache::DepIterator End = D;
- unsigned char State = 0;
- for (bool LastOR = true; D.end() == false && LastOR == true; D++)
- {
- State |= Cache[D];
- LastOR = (D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or;
- if (LastOR == true)
- End = D;
- }
+ pkgCache::DepIterator Start;
+ pkgCache::DepIterator End;
+ D.GlobOr(Start,End);
// We only worry about critical deps.
if (End.IsCritical() != true)
// Hm, the group is broken.. I have no idea how to handle this
if (Start != End)
{
- clog << "Note, a broken or group was found in " << I.Name() << "." << endl;
+ if (Debug == true)
+ clog << "Note, a broken or group was found in " << I.Name() << "." << endl;
Cache.MarkDelete(I);
break;
}
if (Debug == true)
clog << "Package " << I.Name() << " has broken dep on " << End.TargetPkg().Name() << endl;
-
- /* Conflicts is simple, decide if we should remove this package
- or the conflicted one */
+
+ /* Look across the version list. If there are no possible
+ targets then we keep the package and bail. This is necessary
+ if a package has a dep on another package that cant be found */
pkgCache::Version **VList = End.AllTargets();
+ if (*VList == 0 && (Flags[I->ID] & Protected) != Protected &&
+ End->Type != pkgCache::Dep::Conflicts &&
+ Cache[I].NowBroken() == false)
+ {
+ Change = true;
+ Cache.MarkKeep(I);
+ break;
+ }
+
bool Done = false;
for (pkgCache::Version **V = VList; *V != 0; V++)
{
((Cache[End] & pkgDepCache::DepGNow) == 0 &&
End->Type != pkgCache::Dep::Conflicts))
{
- if ((Flags[I->ID] & Protected) != 0)
+ if ((Flags[I->ID] & Protected) == Protected)
continue;
// See if a keep will do
}
// Hm, nothing can possibly satisify this dep. Nuke it.
- if (VList[0] == 0 && End->Type != pkgCache::Dep::Conflicts)
+ if (VList[0] == 0 && End->Type != pkgCache::Dep::Conflicts &&
+ (Flags[I->ID] & Protected) != Protected)
{
Cache.MarkKeep(I);
if (Cache[I].InstBroken() == false)
// Look at all the possible provides on this package
pkgCache::Version **VList = End.AllTargets();
- bool Done = false;
for (pkgCache::Version **V = VList; *V != 0; V++)
{
pkgCache::VerIterator Ver(Cache,*V);
return true;
}
/*}}}*/
+// ProblemResolver::InstallProtect - Install all protected packages /*{{{*/
+// ---------------------------------------------------------------------
+/* This is used to make sure protected packages are installed */
+void pkgProblemResolver::InstallProtect()
+{
+ for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++)
+ {
+ if ((Flags[I->ID] & Protected) == Protected)
+ {
+ if ((Flags[I->ID] & ToRemove) == ToRemove)
+ Cache.MarkDelete(I);
+ else
+ Cache.MarkInstall(I,false);
+ }
+ }
+}
+ /*}}}*/