]>
git.saurik.com Git - apt.git/blob - apt-pkg/orderlist.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: orderlist.cc,v 1.14 2001/05/07 05:49:43 jgg Exp $
4 /* ######################################################################
6 Order List - Represents and Manipulates an ordered list of packages.
8 A list of packages can be ordered by a number of conflicting criteria
9 each given a specific priority. Each package also has a set of flags
10 indicating some useful things about it that are derived in the
11 course of sorting. The pkgPackageManager class uses this class for
12 all of it's installation ordering needs.
14 This is a modified version of Manoj's Routine B. It consists of four
15 independent ordering algorithms that can be applied at for different
16 points in the ordering. By appling progressivly fewer ordering
17 operations it is possible to give each consideration it's own
18 priority and create an order that satisfies the lowest applicable
21 The rules for unpacking ordering are:
22 1) Unpacking ignores Depends: on all packages
23 2) Unpacking requires Conflicts: on -ALL- packages to be satisfied
24 3) Unpacking requires PreDepends: on this package only to be satisfied
25 4) Removing requires that no packages depend on the package to be
28 And the rule for configuration ordering is:
29 1) Configuring requires that the Depends: of the package be satisfied
30 Conflicts+PreDepends are ignored because unpacking says they are
31 already correct [exageration, it does check but we need not be
34 And some features that are valuable for unpacking ordering.
35 f1) Unpacking a new package should advoid breaking dependencies of
37 f2) Removal should not require a force, corrolory of f1
38 f3) Unpacking should order by depends rather than fall back to random
41 Each of the features can be enabled in the sorting routine at an
42 arbitrary priority to give quite abit of control over the final unpacking
45 The rules listed above may never be violated and are called Critical.
46 When a critical rule is violated then a loop condition is recorded
47 and will have to be delt with in the caller.
49 The ordering keeps two lists, the main list and the 'After List'. The
50 purpose of the after list is to allow packages to be delayed. This is done
51 by setting the after flag on the package. Any package which requires this
52 package to be ordered before will inherit the after flag and so on. This
53 is used for CD swap ordering where all packages on a second CD have the
54 after flag set. This forces them and all their dependents to be ordered
57 There are complications in this algorithm when presented with cycles.
58 For all known practical cases it works, all cases where it doesn't work
59 is fixable by tweaking the package descriptions. However, it should be
60 possible to impove this further to make some better choices when
61 presented with cycles.
63 ##################################################################### */
65 // Include Files /*{{{*/
68 #include <apt-pkg/orderlist.h>
69 #include <apt-pkg/depcache.h>
70 #include <apt-pkg/error.h>
71 #include <apt-pkg/version.h>
72 #include <apt-pkg/sptr.h>
73 #include <apt-pkg/configuration.h>
80 pkgOrderList
*pkgOrderList::Me
= 0;
82 // OrderList::pkgOrderList - Constructor /*{{{*/
83 // ---------------------------------------------------------------------
85 pkgOrderList::pkgOrderList(pkgDepCache
*pCache
) : Cache(*pCache
),
86 Primary(NULL
), Secondary(NULL
),
87 RevDepends(NULL
), Remove(NULL
),
88 AfterEnd(NULL
), FileList(NULL
),
89 LoopCount(-1), Depth(0)
91 Debug
= _config
->FindB("Debug::pkgOrderList",false);
93 /* Construct the arrays, egcs 1.0.1 bug requires the package count
95 unsigned long Size
= Cache
.Head().PackageCount
;
96 Flags
= new unsigned short[Size
];
97 End
= List
= new Package
*[Size
];
98 memset(Flags
,0,sizeof(*Flags
)*Size
);
101 // OrderList::~pkgOrderList - Destructor /*{{{*/
102 // ---------------------------------------------------------------------
104 pkgOrderList::~pkgOrderList()
110 // OrderList::IsMissing - Check if a file is missing /*{{{*/
111 // ---------------------------------------------------------------------
113 bool pkgOrderList::IsMissing(PkgIterator Pkg
)
115 // Skip packages to erase
116 if (Cache
[Pkg
].Delete() == true)
119 // Skip Packages that need configure only.
120 if ((Pkg
.State() == pkgCache::PkgIterator::NeedsConfigure
||
121 Pkg
.State() == pkgCache::PkgIterator::NeedsNothing
) &&
122 Cache
[Pkg
].Keep() == true)
128 if (FileList
[Pkg
->ID
].empty() == false)
134 // OrderList::DoRun - Does an order run /*{{{*/
135 // ---------------------------------------------------------------------
136 /* The caller is expeted to have setup the desired probe state */
137 bool pkgOrderList::DoRun()
140 unsigned long Size
= Cache
.Head().PackageCount
;
141 SPtrArray
<Package
*> NList
= new Package
*[Size
];
142 SPtrArray
<Package
*> AfterList
= new Package
*[Size
];
143 AfterEnd
= AfterList
;
146 WipeFlags(Added
| AddPending
| Loop
| InList
);
148 for (iterator I
= List
; I
!= End
; ++I
)
151 // Rebuild the main list into the temp list.
152 iterator OldEnd
= End
;
154 for (iterator I
= List
; I
!= OldEnd
; ++I
)
155 if (VisitNode(PkgIterator(Cache
,*I
), "DoRun") == false)
161 // Copy the after list to the end of the main list
162 for (Package
**I
= AfterList
; I
!= AfterEnd
; I
++)
165 // Swap the main list to the new list
167 List
= NList
.UnGuard();
171 // OrderList::OrderCritical - Perform critical unpacking ordering /*{{{*/
172 // ---------------------------------------------------------------------
173 /* This performs predepends and immediate configuration ordering only.
174 This is termed critical unpacking ordering. Any loops that form are
175 fatal and indicate that the packages cannot be installed. */
176 bool pkgOrderList::OrderCritical()
180 Primary
= &pkgOrderList::DepUnPackPreD
;
188 qsort(List
,End
- List
,sizeof(*List
),&OrderCompareB
);
190 if (DoRun() == false)
194 return _error
->Error("Fatal, predepends looping detected");
198 clog
<< "** Critical Unpack ordering done" << endl
;
200 for (iterator I
= List
; I
!= End
; ++I
)
202 PkgIterator
P(Cache
,*I
);
203 if (IsNow(P
) == true)
204 clog
<< " " << P
.FullName() << ' ' << IsMissing(P
) << ',' << IsFlag(P
,After
) << endl
;
211 // OrderList::OrderUnpack - Perform complete unpacking ordering /*{{{*/
212 // ---------------------------------------------------------------------
213 /* This performs complete unpacking ordering and creates an order that is
214 suitable for unpacking */
215 bool pkgOrderList::OrderUnpack(string
*FileList
)
217 this->FileList
= FileList
;
219 // Setup the after flags
224 // Set the inlist flag
225 for (iterator I
= List
; I
!= End
; ++I
)
227 PkgIterator
P(Cache
,*I
);
228 if (IsMissing(P
) == true && IsNow(P
) == true)
233 Primary
= &pkgOrderList::DepUnPackCrit
;
234 Secondary
= &pkgOrderList::DepConfigure
;
235 RevDepends
= &pkgOrderList::DepUnPackDep
;
236 Remove
= &pkgOrderList::DepRemove
;
241 qsort(List
,End
- List
,sizeof(*List
),&OrderCompareA
);
244 clog
<< "** Pass A" << endl
;
245 if (DoRun() == false)
249 clog
<< "** Pass B" << endl
;
251 if (DoRun() == false)
255 clog
<< "** Pass C" << endl
;
258 Remove
= 0; // Otherwise the libreadline remove problem occures
259 if (DoRun() == false)
263 clog
<< "** Pass D" << endl
;
265 Primary
= &pkgOrderList::DepUnPackPre
;
266 if (DoRun() == false)
271 clog
<< "** Unpack ordering done" << endl
;
273 for (iterator I
= List
; I
!= End
; ++I
)
275 PkgIterator
P(Cache
,*I
);
276 if (IsNow(P
) == true)
277 clog
<< " " << P
.FullName() << ' ' << IsMissing(P
) << ',' << IsFlag(P
,After
) << endl
;
284 // OrderList::OrderConfigure - Perform configuration ordering /*{{{*/
285 // ---------------------------------------------------------------------
286 /* This orders by depends only and produces an order which is suitable
288 bool pkgOrderList::OrderConfigure()
291 Primary
= &pkgOrderList::DepConfigure
;
299 // OrderList::Score - Score the package for sorting /*{{{*/
300 // ---------------------------------------------------------------------
301 /* Higher scores order earlier */
302 int pkgOrderList::Score(PkgIterator Pkg
)
304 static int const ScoreDelete
= _config
->FindI("OrderList::Score::Delete", 500);
306 // Removal is always done first
307 if (Cache
[Pkg
].Delete() == true)
310 // This should never happen..
311 if (Cache
[Pkg
].InstVerIter(Cache
).end() == true)
314 static int const ScoreEssential
= _config
->FindI("OrderList::Score::Essential", 200);
315 static int const ScoreImmediate
= _config
->FindI("OrderList::Score::Immediate", 10);
316 static int const ScorePreDepends
= _config
->FindI("OrderList::Score::PreDepends", 50);
319 if ((Pkg
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
320 Score
+= ScoreEssential
;
322 if (IsFlag(Pkg
,Immediate
) == true)
323 Score
+= ScoreImmediate
;
325 for (DepIterator D
= Cache
[Pkg
].InstVerIter(Cache
).DependsList();
326 D
.end() == false; ++D
)
327 if (D
->Type
== pkgCache::Dep::PreDepends
)
329 Score
+= ScorePreDepends
;
333 // Important Required Standard Optional Extra
334 if (Cache
[Pkg
].InstVerIter(Cache
)->Priority
<= 5)
336 signed short PrioMap
[] = {0,5,4,3,1,0};
337 Score
+= PrioMap
[Cache
[Pkg
].InstVerIter(Cache
)->Priority
];
342 // OrderList::FileCmp - Compare by package file /*{{{*/
343 // ---------------------------------------------------------------------
344 /* This compares by the package file that the install version is in. */
345 int pkgOrderList::FileCmp(PkgIterator A
,PkgIterator B
)
347 if (Cache
[A
].Delete() == true && Cache
[B
].Delete() == true)
349 if (Cache
[A
].Delete() == true)
351 if (Cache
[B
].Delete() == true)
354 if (Cache
[A
].InstVerIter(Cache
).FileList().end() == true)
356 if (Cache
[B
].InstVerIter(Cache
).FileList().end() == true)
359 pkgCache::PackageFile
*FA
= Cache
[A
].InstVerIter(Cache
).FileList().File();
360 pkgCache::PackageFile
*FB
= Cache
[B
].InstVerIter(Cache
).FileList().File();
368 // BoolCompare - Comparison function for two booleans /*{{{*/
369 // ---------------------------------------------------------------------
371 static int BoolCompare(bool A
,bool B
)
380 // OrderList::OrderCompareA - Order the installation by op /*{{{*/
381 // ---------------------------------------------------------------------
382 /* This provides a first-pass sort of the list and gives a decent starting
383 point for further complete ordering. It is used by OrderUnpack only */
384 int pkgOrderList::OrderCompareA(const void *a
, const void *b
)
386 PkgIterator
A(Me
->Cache
,*(Package
**)a
);
387 PkgIterator
B(Me
->Cache
,*(Package
**)b
);
389 // We order packages with a set state toward the front
391 if ((Res
= BoolCompare(Me
->IsNow(A
),Me
->IsNow(B
))) != 0)
394 // We order missing files to toward the end
395 /* if (Me->FileList != 0)
397 if ((Res = BoolCompare(Me->IsMissing(A),
398 Me->IsMissing(B))) != 0)
402 if (A
.State() != pkgCache::PkgIterator::NeedsNothing
&&
403 B
.State() == pkgCache::PkgIterator::NeedsNothing
)
406 if (A
.State() == pkgCache::PkgIterator::NeedsNothing
&&
407 B
.State() != pkgCache::PkgIterator::NeedsNothing
)
410 int ScoreA
= Me
->Score(A
);
411 int ScoreB
= Me
->Score(B
);
419 return strcmp(A
.Name(),B
.Name());
422 // OrderList::OrderCompareB - Order the installation by source /*{{{*/
423 // ---------------------------------------------------------------------
424 /* This orders by installation source. This is useful to handle
425 inter-source breaks */
426 int pkgOrderList::OrderCompareB(const void *a
, const void *b
)
428 PkgIterator
A(Me
->Cache
,*(Package
**)a
);
429 PkgIterator
B(Me
->Cache
,*(Package
**)b
);
431 if (A
.State() != pkgCache::PkgIterator::NeedsNothing
&&
432 B
.State() == pkgCache::PkgIterator::NeedsNothing
)
435 if (A
.State() == pkgCache::PkgIterator::NeedsNothing
&&
436 B
.State() != pkgCache::PkgIterator::NeedsNothing
)
439 int F
= Me
->FileCmp(A
,B
);
447 int ScoreA
= Me
->Score(A
);
448 int ScoreB
= Me
->Score(B
);
456 return strcmp(A
.Name(),B
.Name());
459 // OrderList::VisitDeps - Visit forward install dependencies /*{{{*/
460 // ---------------------------------------------------------------------
461 /* This calls the dependency function for the normal forwards dependencies
463 bool pkgOrderList::VisitDeps(DepFunc F
,PkgIterator Pkg
)
465 if (F
== 0 || Pkg
.end() == true || Cache
[Pkg
].InstallVer
== 0)
468 return (this->*F
)(Cache
[Pkg
].InstVerIter(Cache
).DependsList());
471 // OrderList::VisitRDeps - Visit reverse dependencies /*{{{*/
472 // ---------------------------------------------------------------------
473 /* This calls the dependency function for all of the normal reverse depends
475 bool pkgOrderList::VisitRDeps(DepFunc F
,PkgIterator Pkg
)
477 if (F
== 0 || Pkg
.end() == true)
480 return (this->*F
)(Pkg
.RevDependsList());
483 // OrderList::VisitRProvides - Visit provides reverse dependencies /*{{{*/
484 // ---------------------------------------------------------------------
485 /* This calls the dependency function for all reverse dependencies
486 generated by the provides line on the package. */
487 bool pkgOrderList::VisitRProvides(DepFunc F
,VerIterator Ver
)
489 if (F
== 0 || Ver
.end() == true)
493 for (PrvIterator P
= Ver
.ProvidesList(); P
.end() == false; ++P
)
494 Res
&= (this->*F
)(P
.ParentPkg().RevDependsList());
498 // OrderList::VisitProvides - Visit all of the providing packages /*{{{*/
499 // ---------------------------------------------------------------------
500 /* This routine calls visit on all providing packages.
502 If the dependency is negative it first visits packages which are
503 intended to be removed and after that all other packages.
504 It does so to avoid situations in which this package is used to
505 satisfy a (or-group/provides) dependency of another package which
506 could have been satisfied also by upgrading another package -
507 otherwise we have more broken packages dpkg needs to auto-
508 deconfigure and in very complicated situations it even decides
510 bool pkgOrderList::VisitProvides(DepIterator D
,bool Critical
)
512 SPtrArray
<Version
*> List
= D
.AllTargets();
513 for (Version
**I
= List
; *I
!= 0; ++I
)
515 VerIterator
Ver(Cache
,*I
);
516 PkgIterator Pkg
= Ver
.ParentPkg();
518 if (D
.IsNegative() == true && Cache
[Pkg
].Delete() == false)
521 if (Cache
[Pkg
].Keep() == true && Pkg
.State() == PkgIterator::NeedsNothing
)
524 if (D
.IsNegative() == false &&
525 Cache
[Pkg
].InstallVer
!= *I
)
528 if (D
.IsNegative() == true &&
529 (Version
*)Pkg
.CurrentVer() != *I
)
532 // Skip over missing files
533 if (Critical
== false && IsMissing(D
.ParentPkg()) == true)
536 if (VisitNode(Pkg
, "Provides-1") == false)
539 if (D
.IsNegative() == false)
541 for (Version
**I
= List
; *I
!= 0; ++I
)
543 VerIterator
Ver(Cache
,*I
);
544 PkgIterator Pkg
= Ver
.ParentPkg();
546 if (Cache
[Pkg
].Delete() == true)
549 if (Cache
[Pkg
].Keep() == true && Pkg
.State() == PkgIterator::NeedsNothing
)
552 if ((Version
*)Pkg
.CurrentVer() != *I
)
555 // Skip over missing files
556 if (Critical
== false && IsMissing(D
.ParentPkg()) == true)
559 if (VisitNode(Pkg
, "Provides-2") == false)
566 // OrderList::VisitNode - Recursive ordering director /*{{{*/
567 // ---------------------------------------------------------------------
568 /* This is the core ordering routine. It calls the set dependency
569 consideration functions which then potentialy call this again. Finite
570 depth is achived through the colouring mechinism. */
571 bool pkgOrderList::VisitNode(PkgIterator Pkg
, char const* from
)
573 // Looping or irrelevent.
574 // This should probably trancend not installed packages
575 if (Pkg
.end() == true || IsFlag(Pkg
,Added
) == true ||
576 IsFlag(Pkg
,AddPending
) == true || IsFlag(Pkg
,InList
) == false)
581 for (int j
= 0; j
!= Depth
; j
++) clog
<< ' ';
582 clog
<< "Visit " << Pkg
.FullName() << " from " << from
<< endl
;
588 Flag(Pkg
,AddPending
);
590 DepFunc Old
= Primary
;
592 // Perform immedate configuration of the package if so flagged.
593 if (IsFlag(Pkg
,Immediate
) == true && Primary
!= &pkgOrderList::DepUnPackPre
)
594 Primary
= &pkgOrderList::DepUnPackPreD
;
596 if (IsNow(Pkg
) == true)
599 if (Cache
[Pkg
].Delete() == false)
602 Res
&= Res
&& VisitDeps(Primary
,Pkg
);
603 Res
&= Res
&& VisitRDeps(Primary
,Pkg
);
604 Res
&= Res
&& VisitRProvides(Primary
,Pkg
.CurrentVer());
605 Res
&= Res
&& VisitRProvides(Primary
,Cache
[Pkg
].InstVerIter(Cache
));
608 Res
&= Res
&& VisitRDeps(RevDepends
,Pkg
);
609 Res
&= Res
&& VisitRProvides(RevDepends
,Pkg
.CurrentVer());
610 Res
&= Res
&& VisitRProvides(RevDepends
,Cache
[Pkg
].InstVerIter(Cache
));
613 Res
&= Res
&& VisitDeps(Secondary
,Pkg
);
614 Res
&= Res
&& VisitRDeps(Secondary
,Pkg
);
615 Res
&= Res
&& VisitRProvides(Secondary
,Pkg
.CurrentVer());
616 Res
&= Res
&& VisitRProvides(Secondary
,Cache
[Pkg
].InstVerIter(Cache
));
621 Res
&= Res
&& VisitRDeps(Remove
,Pkg
);
622 Res
&= Res
&& VisitRProvides(Remove
,Pkg
.CurrentVer());
626 if (IsFlag(Pkg
,Added
) == false)
628 Flag(Pkg
,Added
,Added
| AddPending
);
629 if (IsFlag(Pkg
,After
) == true)
640 for (int j
= 0; j
!= Depth
; j
++) clog
<< ' ';
641 clog
<< "Leave " << Pkg
.FullName() << ' ' << IsFlag(Pkg
,Added
) << ',' << IsFlag(Pkg
,AddPending
) << endl
;
647 // OrderList::DepUnPackCrit - Critical UnPacking ordering /*{{{*/
648 // ---------------------------------------------------------------------
649 /* Critical unpacking ordering strives to satisfy Conflicts: and
650 PreDepends: only. When a prdepends is encountered the Primary
651 DepFunc is changed to be DepUnPackPreD.
653 Loops are preprocessed and logged. */
654 bool pkgOrderList::DepUnPackCrit(DepIterator D
)
656 for (; D
.end() == false; ++D
)
658 if (D
.Reverse() == true)
660 /* Reverse depenanices are only interested in conflicts,
661 predepend breakage is ignored here */
662 if (D
->Type
!= pkgCache::Dep::Conflicts
&&
663 D
->Type
!= pkgCache::Dep::Obsoletes
)
666 // Duplication elimination, consider only the current version
667 if (D
.ParentPkg().CurrentVer() != D
.ParentVer())
670 /* For reverse dependencies we wish to check if the
671 dependency is satisifed in the install state. The
672 target package (caller) is going to be in the installed
674 if (CheckDep(D
) == true)
677 if (VisitNode(D
.ParentPkg(), "UnPackCrit") == false)
682 /* Forward critical dependencies MUST be correct before the
683 package can be unpacked. */
684 if (D
.IsNegative() == false &&
685 D
->Type
!= pkgCache::Dep::PreDepends
)
688 /* We wish to check if the dep is okay in the now state of the
689 target package against the install state of this package. */
690 if (CheckDep(D
) == true)
692 /* We want to catch predepends loops with the code below.
693 Conflicts loops that are Dep OK are ignored */
694 if (IsFlag(D
.TargetPkg(),AddPending
) == false ||
695 D
->Type
!= pkgCache::Dep::PreDepends
)
699 // This is the loop detection
700 if (IsFlag(D
.TargetPkg(),Added
) == true ||
701 IsFlag(D
.TargetPkg(),AddPending
) == true)
703 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
708 /* Predepends require a special ordering stage, they must have
709 all dependents installed as well */
710 DepFunc Old
= Primary
;
712 if (D
->Type
== pkgCache::Dep::PreDepends
)
713 Primary
= &pkgOrderList::DepUnPackPreD
;
714 Res
= VisitProvides(D
,true);
723 // OrderList::DepUnPackPreD - Critical UnPacking ordering with depends /*{{{*/
724 // ---------------------------------------------------------------------
725 /* Critical PreDepends (also configure immediate and essential) strives to
726 ensure not only that all conflicts+predepends are met but that this
727 package will be immediately configurable when it is unpacked.
728 Loops are preprocessed and logged. */
729 bool pkgOrderList::DepUnPackPreD(DepIterator D
)
731 if (D
.Reverse() == true)
732 return DepUnPackCrit(D
);
734 for (; D
.end() == false; ++D
)
736 if (D
.IsCritical() == false)
739 /* We wish to check if the dep is okay in the now state of the
740 target package against the install state of this package. */
741 if (CheckDep(D
) == true)
743 /* We want to catch predepends loops with the code below.
744 Conflicts loops that are Dep OK are ignored */
745 if (IsFlag(D
.TargetPkg(),AddPending
) == false ||
746 D
->Type
!= pkgCache::Dep::PreDepends
)
750 // This is the loop detection
751 if (IsFlag(D
.TargetPkg(),Added
) == true ||
752 IsFlag(D
.TargetPkg(),AddPending
) == true)
754 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
759 if (VisitProvides(D
,true) == false)
765 // OrderList::DepUnPackPre - Critical Predepends ordering /*{{{*/
766 // ---------------------------------------------------------------------
767 /* Critical PreDepends (also configure immediate and essential) strives to
768 ensure not only that all conflicts+predepends are met but that this
769 package will be immediately configurable when it is unpacked.
771 Loops are preprocessed and logged. All loops will be fatal. */
772 bool pkgOrderList::DepUnPackPre(DepIterator D
)
774 if (D
.Reverse() == true)
777 for (; D
.end() == false; ++D
)
779 /* Only consider the PreDepends or Depends. Depends are only
780 considered at the lowest depth or in the case of immediate
782 if (D
->Type
!= pkgCache::Dep::PreDepends
)
784 if (D
->Type
== pkgCache::Dep::Depends
)
786 if (Depth
== 1 && IsFlag(D
.ParentPkg(),Immediate
) == false)
793 /* We wish to check if the dep is okay in the now state of the
794 target package against the install state of this package. */
795 if (CheckDep(D
) == true)
797 /* We want to catch predepends loops with the code below.
798 Conflicts loops that are Dep OK are ignored */
799 if (IsFlag(D
.TargetPkg(),AddPending
) == false)
803 // This is the loop detection
804 if (IsFlag(D
.TargetPkg(),Added
) == true ||
805 IsFlag(D
.TargetPkg(),AddPending
) == true)
807 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
812 if (VisitProvides(D
,true) == false)
818 // OrderList::DepUnPackDep - Reverse dependency considerations /*{{{*/
819 // ---------------------------------------------------------------------
820 /* Reverse dependencies are considered to determine if unpacking this
821 package will break any existing dependencies. If so then those
822 packages are ordered before this one so that they are in the
825 The forwards depends loop is designed to bring the packages dependents
826 close to the package. This helps reduce deconfigure time.
828 Loops are irrelevent to this. */
829 bool pkgOrderList::DepUnPackDep(DepIterator D
)
832 for (; D
.end() == false; ++D
)
833 if (D
.IsCritical() == true)
835 if (D
.Reverse() == true)
837 /* Duplication prevention. We consider rev deps only on
838 the current version, a not installed package
840 if (D
.ParentPkg()->CurrentVer
== 0 ||
841 D
.ParentPkg().CurrentVer() != D
.ParentVer())
844 // The dep will not break so it is irrelevent.
845 if (CheckDep(D
) == true)
848 // Skip over missing files
849 if (IsMissing(D
.ParentPkg()) == true)
852 if (VisitNode(D
.ParentPkg(), "UnPackDep-Parent") == false)
857 if (D
->Type
== pkgCache::Dep::Depends
)
858 if (VisitProvides(D
,false) == false)
861 if (D
->Type
== pkgCache::Dep::DpkgBreaks
)
863 if (CheckDep(D
) == true)
866 if (VisitNode(D
.TargetPkg(), "UnPackDep-Target") == false)
874 // OrderList::DepConfigure - Configuration ordering /*{{{*/
875 // ---------------------------------------------------------------------
876 /* Configuration only ordering orders by the Depends: line only. It
877 orders configuration so that when a package comes to be configured it's
878 dependents are configured.
880 Loops are ingored. Depends loop entry points are chaotic. */
881 bool pkgOrderList::DepConfigure(DepIterator D
)
883 // Never consider reverse configuration dependencies.
884 if (D
.Reverse() == true)
887 for (; D
.end() == false; ++D
)
888 if (D
->Type
== pkgCache::Dep::Depends
)
889 if (VisitProvides(D
,false) == false)
894 // OrderList::DepRemove - Removal ordering /*{{{*/
895 // ---------------------------------------------------------------------
896 /* Removal visits all reverse depends. It considers if the dependency
897 of the Now state version to see if it is okay with removing this
898 package. This check should always fail, but is provided for symetery
899 with the other critical handlers.
901 Loops are preprocessed and logged. Removal loops can also be
902 detected in the critical handler. They are characterized by an
903 old version of A depending on B but the new version of A conflicting
904 with B, thus either A or B must break to install. */
905 bool pkgOrderList::DepRemove(DepIterator D
)
907 if (D
.Reverse() == false)
909 for (; D
.end() == false; ++D
)
910 if (D
->Type
== pkgCache::Dep::Depends
|| D
->Type
== pkgCache::Dep::PreDepends
)
912 // Duplication elimination, consider the current version only
913 if (D
.ParentPkg().CurrentVer() != D
.ParentVer())
916 /* We wish to see if the dep on the parent package is okay
917 in the removed (install) state of the target pkg. */
918 bool tryFixDeps
= false;
919 if (CheckDep(D
) == true)
921 // We want to catch loops with the code below.
922 if (IsFlag(D
.ParentPkg(),AddPending
) == false)
928 // This is the loop detection
929 if (IsFlag(D
.ParentPkg(),Added
) == true ||
930 IsFlag(D
.ParentPkg(),AddPending
) == true)
932 if (IsFlag(D
.ParentPkg(),AddPending
) == true)
937 if (tryFixDeps
== true)
939 for (pkgCache::DepIterator F
= D
.ParentPkg().CurrentVer().DependsList();
940 F
.end() == false; ++F
)
942 if (F
->Type
!= pkgCache::Dep::Depends
&& F
->Type
!= pkgCache::Dep::PreDepends
)
944 // Check the Providers
945 if (F
.TargetPkg()->ProvidesList
!= 0)
947 pkgCache::PrvIterator Prov
= F
.TargetPkg().ProvidesList();
948 for (; Prov
.end() == false; ++Prov
)
950 pkgCache::PkgIterator
const P
= Prov
.OwnerPkg();
951 if (IsFlag(P
, InList
) == true &&
952 IsFlag(P
, AddPending
) == true &&
953 IsFlag(P
, Added
) == false &&
954 Cache
[P
].InstallVer
== 0)
957 if (Prov
.end() == false)
958 for (pkgCache::PrvIterator Prv
= F
.TargetPkg().ProvidesList();
959 Prv
.end() == false; ++Prv
)
961 pkgCache::PkgIterator
const P
= Prv
.OwnerPkg();
962 if (IsFlag(P
, InList
) == true &&
963 IsFlag(P
, AddPending
) == false &&
964 Cache
[P
].InstallVer
!= 0 &&
965 VisitNode(P
, "Remove-P") == true)
972 if (tryFixDeps
== false)
976 // Check for Or groups
977 if ((F
->CompareOp
& pkgCache::Dep::Or
) != pkgCache::Dep::Or
)
979 // Lets see if the package is part of the Or group
980 pkgCache::DepIterator S
= F
;
981 for (; S
.end() == false; ++S
)
983 if (S
.TargetPkg() == D
.TargetPkg())
985 if ((S
->CompareOp
& pkgCache::Dep::Or
) != pkgCache::Dep::Or
||
986 CheckDep(S
)) // Or group is satisfied by another package
987 for (;S
.end() == false; ++S
);
991 // skip to the end of the or group
992 for (;S
.end() == false && (S
->CompareOp
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
; ++S
);
994 // The soon to be removed is part of the Or group
995 // start again in the or group and find something which will serve as replacement
996 for (; F
.end() == false && F
!= S
; ++F
)
998 if (IsFlag(F
.TargetPkg(), InList
) == true &&
999 IsFlag(F
.TargetPkg(), AddPending
) == false &&
1000 Cache
[F
.TargetPkg()].InstallVer
!= 0 &&
1001 VisitNode(F
.TargetPkg(), "Remove-Target") == true)
1003 Flag(F
.TargetPkg(), Immediate
);
1007 else if (F
.TargetPkg()->ProvidesList
!= 0)
1009 pkgCache::PrvIterator Prv
= F
.TargetPkg().ProvidesList();
1010 for (; Prv
.end() == false; ++Prv
)
1012 if (IsFlag(Prv
.OwnerPkg(), InList
) == true &&
1013 IsFlag(Prv
.OwnerPkg(), AddPending
) == false &&
1014 Cache
[Prv
.OwnerPkg()].InstallVer
!= 0 &&
1015 VisitNode(Prv
.OwnerPkg(), "Remove-Owner") == true)
1017 Flag(Prv
.OwnerPkg(), Immediate
);
1022 if (Prv
.end() == false)
1026 if (tryFixDeps
== false)
1031 // Skip over missing files
1032 if (IsMissing(D
.ParentPkg()) == true)
1035 if (VisitNode(D
.ParentPkg(), "Remove-Parent") == false)
1042 // OrderList::AddLoop - Add a loop to the loop list /*{{{*/
1043 // ---------------------------------------------------------------------
1044 /* We record the loops. This is a relic since loop breaking is done
1045 genericaly as part of the safety routines. */
1046 bool pkgOrderList::AddLoop(DepIterator D
)
1048 if (LoopCount
< 0 || LoopCount
>= 20)
1054 if (Loops
[LoopCount
- 1].ParentPkg() == D
.ParentPkg() ||
1055 Loops
[LoopCount
- 1].TargetPkg() == D
.ParentPkg())
1059 Loops
[LoopCount
++] = D
;
1061 // Mark the packages as being part of a loop.
1062 //Flag(D.TargetPkg(),Loop);
1063 //Flag(D.ParentPkg(),Loop);
1064 /* This is currently disabled because the Loop flag is being used for
1065 loop management in the package manager. Check the orderlist.h file for more info */
1069 // OrderList::WipeFlags - Unset the given flags from all packages /*{{{*/
1070 // ---------------------------------------------------------------------
1072 void pkgOrderList::WipeFlags(unsigned long F
)
1074 unsigned long Size
= Cache
.Head().PackageCount
;
1075 for (unsigned long I
= 0; I
!= Size
; I
++)
1079 // OrderList::CheckDep - Check a dependency for truth /*{{{*/
1080 // ---------------------------------------------------------------------
1081 /* This performs a complete analysis of the dependency wrt to the
1082 current add list. It returns true if after all events are
1083 performed it is still true. This sort of routine can be approximated
1084 by examining the DepCache, however in convoluted cases of provides
1085 this fails to produce a suitable result. */
1086 bool pkgOrderList::CheckDep(DepIterator D
)
1088 SPtrArray
<Version
*> List
= D
.AllTargets();
1090 for (Version
**I
= List
; *I
!= 0; I
++)
1092 VerIterator
Ver(Cache
,*I
);
1093 PkgIterator Pkg
= Ver
.ParentPkg();
1095 /* The meaning of Added and AddPending is subtle. AddPending is
1096 an indication that the package is looping. Because of the
1097 way ordering works Added means the package will be unpacked
1098 before this one and AddPending means after. It is therefore
1099 correct to ignore AddPending in all cases, but that exposes
1100 reverse-ordering loops which should be ignored. */
1101 if (IsFlag(Pkg
,Added
) == true ||
1102 (IsFlag(Pkg
,AddPending
) == true && D
.Reverse() == true))
1104 if (Cache
[Pkg
].InstallVer
!= *I
)
1108 if ((Version
*)Pkg
.CurrentVer() != *I
||
1109 Pkg
.State() != PkgIterator::NeedsNothing
)
1112 /* Conflicts requires that all versions are not present, depends
1114 if (D
.IsNegative() == false)
1116 // ignore provides by older versions of this package
1117 if (((D
.Reverse() == false && Pkg
== D
.ParentPkg()) ||
1118 (D
.Reverse() == true && Pkg
== D
.TargetPkg())) &&
1119 Cache
[Pkg
].InstallVer
!= *I
)
1122 /* Try to find something that does not have the after flag set
1123 if at all possible */
1124 if (IsFlag(Pkg
,After
) == true)
1134 if (IsFlag(Pkg
,After
) == true)
1135 Flag(D
.ParentPkg(),After
);
1141 // We found a hit, but it had the after flag set
1142 if (Hit
== true && D
->Type
== pkgCache::Dep::PreDepends
)
1144 Flag(D
.ParentPkg(),After
);
1148 /* Conflicts requires that all versions are not present, depends
1150 if (D
->Type
== pkgCache::Dep::Conflicts
||
1151 D
->Type
== pkgCache::Dep::Obsoletes
)