]>
git.saurik.com Git - apt.git/blob - apt-pkg/orderlist.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: orderlist.cc,v 1.9 1999/11/04 06:05:02 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 usefull 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 arbitary 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 ##################################################################### */
51 // Include Files /*{{{*/
53 #pragma implementation "apt-pkg/orderlist.h"
55 #include <apt-pkg/orderlist.h>
56 #include <apt-pkg/depcache.h>
57 #include <apt-pkg/error.h>
58 #include <apt-pkg/version.h>
61 pkgOrderList
*pkgOrderList::Me
= 0;
63 // OrderList::pkgOrderList - Constructor /*{{{*/
64 // ---------------------------------------------------------------------
66 pkgOrderList::pkgOrderList(pkgDepCache
&Cache
) : Cache(Cache
)
75 /* Construct the arrays, egcs 1.0.1 bug requires the package count
77 unsigned long Size
= Cache
.HeaderP
->PackageCount
;
78 Flags
= new unsigned char[Size
];
79 End
= List
= new Package
*[Size
];
80 memset(Flags
,0,sizeof(*Flags
)*Size
);
83 // OrderList::~pkgOrderList - Destructor /*{{{*/
84 // ---------------------------------------------------------------------
86 pkgOrderList::~pkgOrderList()
92 // OrderList::IsMissing - Check if a file is missing /*{{{*/
93 // ---------------------------------------------------------------------
95 bool pkgOrderList::IsMissing(PkgIterator Pkg
)
97 // Skip packages to erase
98 if (Cache
[Pkg
].Delete() == true)
101 // Skip Packages that need configure only.
102 if (Pkg
.State() == pkgCache::PkgIterator::NeedsConfigure
&&
103 Cache
[Pkg
].Keep() == true)
106 if (FileList
!= 0 && FileList
[Pkg
->ID
].empty() == false)
112 // OrderList::DoRun - Does an order run /*{{{*/
113 // ---------------------------------------------------------------------
114 /* The caller is expeted to have setup the desired probe state */
115 bool pkgOrderList::DoRun()
118 unsigned long Size
= Cache
.HeaderP
->PackageCount
;
119 Package
**NList
= new Package
*[Size
];
122 WipeFlags(Added
| AddPending
| Loop
| InList
);
124 for (iterator I
= List
; I
!= End
; I
++)
127 // Rebuild the main list into the temp list.
128 iterator OldEnd
= End
;
130 for (iterator I
= List
; I
!= OldEnd
; I
++)
131 if (VisitNode(PkgIterator(Cache
,*I
)) == false)
138 // Swap the main list to the new list
144 // OrderList::OrderCritical - Perform critical unpacking ordering /*{{{*/
145 // ---------------------------------------------------------------------
146 /* This performs predepends and immediate configuration ordering only.
147 This is termed critical unpacking ordering. Any loops that form are
148 fatal and indicate that the packages cannot be installed. */
149 bool pkgOrderList::OrderCritical()
153 Primary
= &pkgOrderList::DepUnPackPre
;
161 qsort(List
,End
- List
,sizeof(*List
),&OrderCompareB
);
163 if (DoRun() == false)
167 return _error
->Error("Fatal, predepends looping detected");
171 // OrderList::OrderUnpack - Perform complete unpacking ordering /*{{{*/
172 // ---------------------------------------------------------------------
173 /* This performs complete unpacking ordering and creates an order that is
174 suitable for unpacking */
175 bool pkgOrderList::OrderUnpack(string
*FileList
)
177 this->FileList
= FileList
;
179 Primary
= &pkgOrderList::DepUnPackCrit
;
180 Secondary
= &pkgOrderList::DepConfigure
;
181 RevDepends
= &pkgOrderList::DepUnPackDep
;
182 Remove
= &pkgOrderList::DepRemove
;
187 qsort(List
,End
- List
,sizeof(*List
),&OrderCompareA
);
189 if (DoRun() == false)
193 if (DoRun() == false)
198 Remove
= 0; // Otherwise the libreadline remove problem occures
199 if (DoRun() == false)
203 Primary
= &pkgOrderList::DepUnPackPre
;
204 if (DoRun() == false)
207 /* cout << "----------END" << endl;
209 for (iterator I = List; I != End; I++)
211 PkgIterator P(Cache,*I);
212 cout << P.Name() << endl;
218 // OrderList::OrderConfigure - Perform configuration ordering /*{{{*/
219 // ---------------------------------------------------------------------
220 /* This orders by depends only and produces an order which is suitable
222 bool pkgOrderList::OrderConfigure()
225 Primary
= &pkgOrderList::DepConfigure
;
234 // OrderList::Score - Score the package for sorting /*{{{*/
235 // ---------------------------------------------------------------------
236 /* Higher scores order earlier */
237 int pkgOrderList::Score(PkgIterator Pkg
)
239 // Removal is always done first
240 if (Cache
[Pkg
].Delete() == true)
243 // This should never happen..
244 if (Cache
[Pkg
].InstVerIter(Cache
).end() == true)
248 if ((Pkg
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
251 for (DepIterator D
= Cache
[Pkg
].InstVerIter(Cache
).DependsList();
252 D
.end() == false; D
++)
253 if (D
->Type
== pkgCache::Dep::PreDepends
)
259 // Important Required Standard Optional Extra
260 signed short PrioMap
[] = {0,5,4,3,1,0};
261 if (Cache
[Pkg
].InstVerIter(Cache
)->Priority
<= 5)
262 Score
+= PrioMap
[Cache
[Pkg
].InstVerIter(Cache
)->Priority
];
266 // OrderList::FileCmp - Compare by package file /*{{{*/
267 // ---------------------------------------------------------------------
268 /* This compares by the package file that the install version is in. */
269 int pkgOrderList::FileCmp(PkgIterator A
,PkgIterator B
)
271 if (Cache
[A
].Delete() == true && Cache
[B
].Delete() == true)
273 if (Cache
[A
].Delete() == true)
275 if (Cache
[B
].Delete() == true)
278 if (Cache
[A
].InstVerIter(Cache
).FileList().end() == true)
280 if (Cache
[B
].InstVerIter(Cache
).FileList().end() == true)
283 pkgCache::PackageFile
*FA
= Cache
[A
].InstVerIter(Cache
).FileList().File();
284 pkgCache::PackageFile
*FB
= Cache
[B
].InstVerIter(Cache
).FileList().File();
292 // BoolCompare - Comparison function for two booleans /*{{{*/
293 // ---------------------------------------------------------------------
295 static int BoolCompare(bool A
,bool B
)
304 // OrderList::OrderCompareA - Order the installation by op /*{{{*/
305 // ---------------------------------------------------------------------
306 /* This provides a first-pass sort of the list and gives a decent starting
307 point for further complete ordering. It is used by OrderUnpack only */
308 int pkgOrderList::OrderCompareA(const void *a
, const void *b
)
310 PkgIterator
A(Me
->Cache
,*(Package
**)a
);
311 PkgIterator
B(Me
->Cache
,*(Package
**)b
);
313 // We order packages with a set state toward the front
315 if ((Res
= BoolCompare(Me
->IsNow(A
),Me
->IsNow(B
))) == 0)
318 // We order missing files to toward the end
319 if (Me
->FileList
!= 0)
321 if ((Res
= BoolCompare(Me
->IsMissing(A
),
322 Me
->IsMissing(B
))) == 0)
326 if (A
.State() != pkgCache::PkgIterator::NeedsNothing
&&
327 B
.State() == pkgCache::PkgIterator::NeedsNothing
)
330 if (A
.State() == pkgCache::PkgIterator::NeedsNothing
&&
331 B
.State() != pkgCache::PkgIterator::NeedsNothing
)
334 int ScoreA
= Me
->Score(A
);
335 int ScoreB
= Me
->Score(B
);
342 return strcmp(A
.Name(),B
.Name());
345 // OrderList::OrderCompareB - Order the installation by source /*{{{*/
346 // ---------------------------------------------------------------------
347 /* This orders by installation source. This is usefull to handle
348 inter-source breaks */
349 int pkgOrderList::OrderCompareB(const void *a
, const void *b
)
351 PkgIterator
A(Me
->Cache
,*(Package
**)a
);
352 PkgIterator
B(Me
->Cache
,*(Package
**)b
);
354 if (A
.State() != pkgCache::PkgIterator::NeedsNothing
&&
355 B
.State() == pkgCache::PkgIterator::NeedsNothing
)
358 if (A
.State() == pkgCache::PkgIterator::NeedsNothing
&&
359 B
.State() != pkgCache::PkgIterator::NeedsNothing
)
362 int F
= Me
->FileCmp(A
,B
);
370 int ScoreA
= Me
->Score(A
);
371 int ScoreB
= Me
->Score(B
);
378 return strcmp(A
.Name(),B
.Name());
382 // OrderList::VisitDeps - Visit forward install dependencies /*{{{*/
383 // ---------------------------------------------------------------------
384 /* This calls the dependency function for the normal forwards dependencies
386 bool pkgOrderList::VisitDeps(DepFunc F
,PkgIterator Pkg
)
388 if (F
== 0 || Pkg
.end() == true || Cache
[Pkg
].InstallVer
== 0)
391 return (this->*F
)(Cache
[Pkg
].InstVerIter(Cache
).DependsList());
394 // OrderList::VisitRDeps - Visit reverse dependencies /*{{{*/
395 // ---------------------------------------------------------------------
396 /* This calls the dependency function for all of the normal reverse depends
398 bool pkgOrderList::VisitRDeps(DepFunc F
,PkgIterator Pkg
)
400 if (F
== 0 || Pkg
.end() == true)
403 return (this->*F
)(Pkg
.RevDependsList());
406 // OrderList::VisitRProvides - Visit provides reverse dependencies /*{{{*/
407 // ---------------------------------------------------------------------
408 /* This calls the dependency function for all reverse dependencies
409 generated by the provides line on the package. */
410 bool pkgOrderList::VisitRProvides(DepFunc F
,VerIterator Ver
)
412 if (F
== 0 || Ver
.end() == true)
416 for (PrvIterator P
= Ver
.ProvidesList(); P
.end() == false; P
++)
417 Res
&= (this->*F
)(P
.ParentPkg().RevDependsList());
421 // OrderList::VisitProvides - Visit all of the providing packages /*{{{*/
422 // ---------------------------------------------------------------------
423 /* This routine calls visit on all providing packages. */
424 bool pkgOrderList::VisitProvides(DepIterator D
,bool Critical
)
426 Version
**List
= D
.AllTargets();
427 for (Version
**I
= List
; *I
!= 0; I
++)
429 VerIterator
Ver(Cache
,*I
);
430 PkgIterator Pkg
= Ver
.ParentPkg();
432 if (Cache
[Pkg
].Keep() == true && Pkg
.State() == PkgIterator::NeedsNothing
)
435 if (D
->Type
!= pkgCache::Dep::Conflicts
&& Cache
[Pkg
].InstallVer
!= *I
)
438 if (D
->Type
== pkgCache::Dep::Conflicts
&& (Version
*)Pkg
.CurrentVer() != *I
)
441 // Skip over missing files
442 if (Critical
== false && IsMissing(D
.ParentPkg()) == true)
445 if (VisitNode(Pkg
) == false)
455 // OrderList::VisitNode - Recursive ordering director /*{{{*/
456 // ---------------------------------------------------------------------
457 /* This is the core ordering routine. It calls the set dependency
458 consideration functions which then potentialy call this again. Finite
459 depth is achived through the colouring mechinism. */
460 bool pkgOrderList::VisitNode(PkgIterator Pkg
)
462 // Looping or irrelevent.
463 // This should probably trancend not installed packages
464 if (Pkg
.end() == true || IsFlag(Pkg
,Added
) == true ||
465 IsFlag(Pkg
,AddPending
) == true || IsFlag(Pkg
,InList
) == false)
468 /* for (int j = 0; j != Depth; j++) cout << ' ';
469 cout << "Visit " << Pkg.Name() << endl;*/
473 Flag(Pkg
,AddPending
);
475 DepFunc Old
= Primary
;
477 // Perform immedate configuration of the package if so flagged.
478 if (IsFlag(Pkg
,Immediate
) == true && Primary
!= &pkgOrderList::DepUnPackPre
)
479 Primary
= &pkgOrderList::DepUnPackPreD
;
481 if (IsNow(Pkg
) == true)
484 if (Cache
[Pkg
].Delete() == false)
487 Res
&= Res
&& VisitDeps(Primary
,Pkg
);
488 Res
&= Res
&& VisitRDeps(Primary
,Pkg
);
489 Res
&= Res
&& VisitRProvides(Primary
,Pkg
.CurrentVer());
490 Res
&= Res
&& VisitRProvides(Primary
,Cache
[Pkg
].InstVerIter(Cache
));
493 Res
&= Res
&& VisitRDeps(RevDepends
,Pkg
);
494 Res
&= Res
&& VisitRProvides(RevDepends
,Pkg
.CurrentVer());
495 Res
&= Res
&& VisitRProvides(RevDepends
,Cache
[Pkg
].InstVerIter(Cache
));
498 Res
&= Res
&& VisitDeps(Secondary
,Pkg
);
499 Res
&= Res
&& VisitRDeps(Secondary
,Pkg
);
500 Res
&= Res
&& VisitRProvides(Secondary
,Pkg
.CurrentVer());
501 Res
&= Res
&& VisitRProvides(Secondary
,Cache
[Pkg
].InstVerIter(Cache
));
506 Res
&= Res
&& VisitRDeps(Remove
,Pkg
);
507 Res
&= Res
&& VisitRProvides(Remove
,Pkg
.CurrentVer());
511 if (IsFlag(Pkg
,Added
) == false)
513 Flag(Pkg
,Added
,Added
| AddPending
);
521 /* for (int j = 0; j != Depth; j++) cout << ' ';
522 cout << "Leave " << Pkg.Name() << ' ' << IsFlag(Pkg,Added) << ',' << IsFlag(Pkg,AddPending) << endl;*/
528 // OrderList::DepUnPackCrit - Critical UnPacking ordering /*{{{*/
529 // ---------------------------------------------------------------------
530 /* Critical unpacking ordering strives to satisfy Conflicts: and
531 PreDepends: only. When a prdepends is encountered the Primary
532 DepFunc is changed to be DepUnPackPreD.
534 Loops are preprocessed and logged. */
535 bool pkgOrderList::DepUnPackCrit(DepIterator D
)
537 for (; D
.end() == false; D
++)
539 if (D
.Reverse() == true)
541 /* Reverse depenanices are only interested in conflicts,
542 predepend breakage is ignored here */
543 if (D
->Type
!= pkgCache::Dep::Conflicts
)
546 // Duplication elimination, consider only the current version
547 if (D
.ParentPkg().CurrentVer() != D
.ParentVer())
550 /* For reverse dependencies we wish to check if the
551 dependency is satisifed in the install state. The
552 target package (caller) is going to be in the installed
554 if (CheckDep(D
) == true)
557 if (VisitNode(D
.ParentPkg()) == false)
562 /* Forward critical dependencies MUST be correct before the
563 package can be unpacked. */
564 if (D
->Type
!= pkgCache::Dep::Conflicts
&& D
->Type
!= pkgCache::Dep::PreDepends
)
567 /* We wish to check if the dep is okay in the now state of the
568 target package against the install state of this package. */
569 if (CheckDep(D
) == true)
571 /* We want to catch predepends loops with the code below.
572 Conflicts loops that are Dep OK are ignored */
573 if (IsFlag(D
.TargetPkg(),AddPending
) == false ||
574 D
->Type
!= pkgCache::Dep::PreDepends
)
578 // This is the loop detection
579 if (IsFlag(D
.TargetPkg(),Added
) == true ||
580 IsFlag(D
.TargetPkg(),AddPending
) == true)
582 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
587 /* Predepends require a special ordering stage, they must have
588 all dependents installed as well */
589 DepFunc Old
= Primary
;
591 if (D
->Type
== pkgCache::Dep::PreDepends
)
592 Primary
= &pkgOrderList::DepUnPackPreD
;
593 Res
= VisitProvides(D
,true);
602 // OrderList::DepUnPackPreD - Critical UnPacking ordering with depends /*{{{*/
603 // ---------------------------------------------------------------------
604 /* Critical PreDepends (also configure immediate and essential) strives to
605 ensure not only that all conflicts+predepends are met but that this
606 package will be immediately configurable when it is unpacked.
608 Loops are preprocessed and logged. */
609 bool pkgOrderList::DepUnPackPreD(DepIterator D
)
611 if (D
.Reverse() == true)
612 return DepUnPackCrit(D
);
614 for (; D
.end() == false; D
++)
616 if (D
.IsCritical() == false)
619 /* We wish to check if the dep is okay in the now state of the
620 target package against the install state of this package. */
621 if (CheckDep(D
) == true)
623 /* We want to catch predepends loops with the code below.
624 Conflicts loops that are Dep OK are ignored */
625 if (IsFlag(D
.TargetPkg(),AddPending
) == false ||
626 D
->Type
!= pkgCache::Dep::PreDepends
)
630 // This is the loop detection
631 if (IsFlag(D
.TargetPkg(),Added
) == true ||
632 IsFlag(D
.TargetPkg(),AddPending
) == true)
634 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
639 if (VisitProvides(D
,true) == false)
645 // OrderList::DepUnPackPre - Critical Predepends ordering /*{{{*/
646 // ---------------------------------------------------------------------
647 /* Critical PreDepends (also configure immediate and essential) strives to
648 ensure not only that all conflicts+predepends are met but that this
649 package will be immediately configurable when it is unpacked.
651 Loops are preprocessed and logged. All loops will be fatal. */
652 bool pkgOrderList::DepUnPackPre(DepIterator D
)
654 if (D
.Reverse() == true)
657 for (; D
.end() == false; D
++)
659 /* Only consider the PreDepends or Depends. Depends are only
660 considered at the lowest depth or in the case of immediate
662 if (D
->Type
!= pkgCache::Dep::PreDepends
)
664 if (D
->Type
== pkgCache::Dep::Depends
)
666 if (Depth
== 1 && IsFlag(D
.ParentPkg(),Immediate
) == false)
673 /* We wish to check if the dep is okay in the now state of the
674 target package against the install state of this package. */
675 if (CheckDep(D
) == true)
677 /* We want to catch predepends loops with the code below.
678 Conflicts loops that are Dep OK are ignored */
679 if (IsFlag(D
.TargetPkg(),AddPending
) == false)
683 // This is the loop detection
684 if (IsFlag(D
.TargetPkg(),Added
) == true ||
685 IsFlag(D
.TargetPkg(),AddPending
) == true)
687 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
692 if (VisitProvides(D
,true) == false)
698 // OrderList::DepUnPackDep - Reverse dependency considerations /*{{{*/
699 // ---------------------------------------------------------------------
700 /* Reverse dependencies are considered to determine if unpacking this
701 package will break any existing dependencies. If so then those
702 packages are ordered before this one so that they are in the
705 The forwards depends loop is designed to bring the packages dependents
706 close to the package. This helps reduce deconfigure time.
708 Loops are irrelevent to this. */
709 bool pkgOrderList::DepUnPackDep(DepIterator D
)
712 for (; D
.end() == false; D
++)
713 if (D
.IsCritical() == true)
715 if (D
.Reverse() == true)
717 /* Duplication prevention. We consider rev deps only on
718 the current version, a not installed package
720 if (D
.ParentPkg()->CurrentVer
== 0 ||
721 D
.ParentPkg().CurrentVer() != D
.ParentVer())
724 // The dep will not break so it is irrelevent.
725 if (CheckDep(D
) == true)
728 // Skip over missing files
729 if (IsMissing(D
.ParentPkg()) == true)
732 if (VisitNode(D
.ParentPkg()) == false)
736 if (D
->Type
== pkgCache::Dep::Depends
)
737 if (VisitProvides(D
,false) == false)
743 // OrderList::DepConfigure - Configuration ordering /*{{{*/
744 // ---------------------------------------------------------------------
745 /* Configuration only ordering orders by the Depends: line only. It
746 orders configuration so that when a package comes to be configured it's
747 dependents are configured.
749 Loops are ingored. Depends loop entry points are chaotic. */
750 bool pkgOrderList::DepConfigure(DepIterator D
)
752 // Never consider reverse configuration dependencies.
753 if (D
.Reverse() == true)
756 for (; D
.end() == false; D
++)
757 if (D
->Type
== pkgCache::Dep::Depends
)
758 if (VisitProvides(D
,false) == false)
763 // OrderList::DepRemove - Removal ordering /*{{{*/
764 // ---------------------------------------------------------------------
765 /* Removal visits all reverse depends. It considers if the dependency
766 of the Now state version to see if it is okay with removing this
767 package. This check should always fail, but is provided for symetery
768 with the other critical handlers.
770 Loops are preprocessed and logged. Removal loops can also be
771 detected in the critical handler. They are characterized by an
772 old version of A depending on B but the new version of A conflicting
773 with B, thus either A or B must break to install. */
774 bool pkgOrderList::DepRemove(DepIterator D
)
776 if (D
.Reverse() == false)
778 for (; D
.end() == false; D
++)
779 if (D
->Type
== pkgCache::Dep::Depends
|| D
->Type
== pkgCache::Dep::PreDepends
)
781 // Duplication elimination, consider the current version only
782 if (D
.ParentPkg().CurrentVer() != D
.ParentVer())
785 /* We wish to see if the dep on the parent package is okay
786 in the removed (install) state of the target pkg. */
787 if (CheckDep(D
) == true)
789 // We want to catch loops with the code below.
790 if (IsFlag(D
.ParentPkg(),AddPending
) == false)
794 // This is the loop detection
795 if (IsFlag(D
.ParentPkg(),Added
) == true ||
796 IsFlag(D
.ParentPkg(),AddPending
) == true)
798 if (IsFlag(D
.ParentPkg(),AddPending
) == true)
803 // Skip over missing files
804 if (IsMissing(D
.ParentPkg()) == true)
807 if (VisitNode(D
.ParentPkg()) == false)
815 // OrderList::AddLoop - Add a loop to the loop list /*{{{*/
816 // ---------------------------------------------------------------------
817 /* We record the loops. This is a relic since loop breaking is done
818 genericaly as part of the safety routines. */
819 bool pkgOrderList::AddLoop(DepIterator D
)
821 if (LoopCount
< 0 || LoopCount
>= 20)
827 if (Loops
[LoopCount
- 1].ParentPkg() == D
.ParentPkg() ||
828 Loops
[LoopCount
- 1].TargetPkg() == D
.ParentPkg())
832 Loops
[LoopCount
++] = D
;
834 // Mark the packages as being part of a loop.
835 Flag(D
.TargetPkg(),Loop
);
836 Flag(D
.ParentPkg(),Loop
);
840 // OrderList::WipeFlags - Unset the given flags from all packages /*{{{*/
841 // ---------------------------------------------------------------------
843 void pkgOrderList::WipeFlags(unsigned long F
)
845 unsigned long Size
= Cache
.HeaderP
->PackageCount
;
846 for (unsigned long I
= 0; I
!= Size
; I
++)
850 // OrderList::CheckDep - Check a dependency for truth /*{{{*/
851 // ---------------------------------------------------------------------
852 /* This performs a complete analysis of the dependency wrt to the
853 current add list. It returns true if after all events are
854 performed it is still true. This sort of routine can be approximated
855 by examining the DepCache, however in convoluted cases of provides
856 this fails to produce a suitable result. */
857 bool pkgOrderList::CheckDep(DepIterator D
)
859 Version
**List
= D
.AllTargets();
860 for (Version
**I
= List
; *I
!= 0; I
++)
862 VerIterator
Ver(Cache
,*I
);
863 PkgIterator Pkg
= Ver
.ParentPkg();
865 /* The meaning of Added and AddPending is subtle. AddPending is
866 an indication that the package is looping. Because of the
867 way ordering works Added means the package will be unpacked
868 before this one and AddPending means after. It is therefore
869 correct to ignore AddPending in all cases, but that exposes
870 reverse-ordering loops which should be ignore. */
871 if (IsFlag(Pkg
,Added
) == true ||
872 (IsFlag(Pkg
,AddPending
) == true && D
.Reverse() == true))
874 if (Cache
[Pkg
].InstallVer
!= *I
)
878 if ((Version
*)Pkg
.CurrentVer() != *I
||
879 Pkg
.State() != PkgIterator::NeedsNothing
)
884 /* Conflicts requires that all versions are not present, depends
886 if (D
->Type
!= pkgCache::Dep::Conflicts
)
893 /* Conflicts requires that all versions are not present, depends
895 if (D
->Type
== pkgCache::Dep::Conflicts
)