+ if (Debug) {
+ VerIterator InstallVer = VerIterator(Cache,Cache[Pkg].InstallVer);
+ clog << OutputInDepth(Depth) << "SmartConfigure " << Pkg.FullName() << " (" << InstallVer.VerStr() << ")";
+ if (PkgLoop)
+ clog << " (Only Correct Dependencies)";
+ clog << endl;
+ }
+
+ VerIterator const instVer = Cache[Pkg].InstVerIter(Cache);
+
+ /* Because of the ordered list, most dependencies should be unpacked,
+ however if there is a loop (A depends on B, B depends on A) this will not
+ be the case, so check for dependencies before configuring. */
+ bool Bad = false, Changed = false;
+ const unsigned int max_loops = _config->FindI("APT::pkgPackageManager::MaxLoopCount", 5000);
+ unsigned int i=0;
+ std::list<DepIterator> needConfigure;
+ do
+ {
+ Changed = false;
+ for (DepIterator D = instVer.DependsList(); D.end() == false; )
+ {
+ // Compute a single dependency element (glob or)
+ pkgCache::DepIterator Start, End;
+ D.GlobOr(Start,End);
+
+ if (End->Type != pkgCache::Dep::Depends)
+ continue;
+ Bad = true;
+
+ // Check for dependencies that have not been unpacked, probably due to loops.
+ for (DepIterator Cur = Start; true; ++Cur)
+ {
+ SPtrArray<Version *> VList = Cur.AllTargets();
+
+ for (Version **I = VList; *I != 0; ++I)
+ {
+ VerIterator Ver(Cache,*I);
+ PkgIterator DepPkg = Ver.ParentPkg();
+
+ // Check if the current version of the package is available and will satisfy this dependency
+ if (DepPkg.CurrentVer() == Ver && List->IsNow(DepPkg) == true &&
+ List->IsFlag(DepPkg,pkgOrderList::Removed) == false &&
+ DepPkg.State() == PkgIterator::NeedsNothing)
+ {
+ Bad = false;
+ break;
+ }
+
+ // Check if the version that is going to be installed will satisfy the dependency
+ if (Cache[DepPkg].InstallVer != *I || List->IsNow(DepPkg) == false)
+ continue;
+
+ if (PkgLoop == true)
+ {
+ if (Debug)
+ std::clog << OutputInDepth(Depth) << "Package " << Pkg << " loops in SmartConfigure" << std::endl;
+ Bad = false;
+ break;
+ }
+ else
+ {
+ if (Debug)
+ clog << OutputInDepth(Depth) << "Unpacking " << DepPkg.FullName() << " to avoid loop " << Cur << endl;
+ if (PkgLoop == false)
+ List->Flag(Pkg,pkgOrderList::Loop);
+ if (SmartUnPack(DepPkg, true, Depth + 1) == true)
+ {
+ Bad = false;
+ if (List->IsFlag(DepPkg,pkgOrderList::Loop) == false)
+ Changed = true;
+ }
+ if (PkgLoop == false)
+ List->RmFlag(Pkg,pkgOrderList::Loop);
+ if (Bad == false)
+ break;
+ }
+ }
+
+ if (Cur == End || Bad == false)
+ break;
+ }
+
+ if (Bad == false)
+ continue;
+
+ needConfigure.push_back(Start);
+ }
+ if (i++ > max_loops)
+ return _error->Error("Internal error: MaxLoopCount reached in SmartUnPack (1) for %s, aborting", Pkg.FullName().c_str());
+ } while (Changed == true);
+
+ Bad = false, Changed = false, i = 0;
+ do
+ {
+ Changed = false;
+ for (std::list<DepIterator>::const_iterator D = needConfigure.begin(); D != needConfigure.end(); ++D)
+ {
+ // Compute a single dependency element (glob or) without modifying D
+ pkgCache::DepIterator Start, End;
+ {
+ pkgCache::DepIterator Discard = *D;
+ Discard.GlobOr(Start,End);
+ }
+
+ if (End->Type != pkgCache::Dep::Depends)
+ continue;
+ Bad = true;
+
+ // Search for dependencies which are unpacked but aren't configured yet (maybe loops)
+ for (DepIterator Cur = Start; true; ++Cur)
+ {
+ SPtrArray<Version *> VList = Cur.AllTargets();