]>
git.saurik.com Git - apt.git/blob - apt-pkg/orderlist.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: orderlist.cc,v 1.11 2000/01/16 08:45:47 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 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 ##################################################################### */
59 // Include Files /*{{{*/
61 #pragma implementation "apt-pkg/orderlist.h"
63 #include <apt-pkg/orderlist.h>
64 #include <apt-pkg/depcache.h>
65 #include <apt-pkg/error.h>
66 #include <apt-pkg/version.h>
69 pkgOrderList
*pkgOrderList::Me
= 0;
71 // OrderList::pkgOrderList - Constructor /*{{{*/
72 // ---------------------------------------------------------------------
74 pkgOrderList::pkgOrderList(pkgDepCache
&Cache
) : Cache(Cache
)
83 /* Construct the arrays, egcs 1.0.1 bug requires the package count
85 unsigned long Size
= Cache
.HeaderP
->PackageCount
;
86 Flags
= new unsigned short[Size
];
87 End
= List
= new Package
*[Size
];
88 memset(Flags
,0,sizeof(*Flags
)*Size
);
91 // OrderList::~pkgOrderList - Destructor /*{{{*/
92 // ---------------------------------------------------------------------
94 pkgOrderList::~pkgOrderList()
100 // OrderList::IsMissing - Check if a file is missing /*{{{*/
101 // ---------------------------------------------------------------------
103 bool pkgOrderList::IsMissing(PkgIterator Pkg
)
105 // Skip packages to erase
106 if (Cache
[Pkg
].Delete() == true)
109 // Skip Packages that need configure only.
110 if (Pkg
.State() == pkgCache::PkgIterator::NeedsConfigure
&&
111 Cache
[Pkg
].Keep() == true)
114 if (FileList
!= 0 && FileList
[Pkg
->ID
].empty() == false)
120 // OrderList::DoRun - Does an order run /*{{{*/
121 // ---------------------------------------------------------------------
122 /* The caller is expeted to have setup the desired probe state */
123 bool pkgOrderList::DoRun()
126 unsigned long Size
= Cache
.HeaderP
->PackageCount
;
127 Package
**NList
= new Package
*[Size
];
128 AfterList
= new Package
*[Size
];
129 AfterEnd
= AfterList
;
132 WipeFlags(Added
| AddPending
| Loop
| InList
);
134 for (iterator I
= List
; I
!= End
; I
++)
137 // Rebuild the main list into the temp list.
138 iterator OldEnd
= End
;
140 for (iterator I
= List
; I
!= OldEnd
; I
++)
141 if (VisitNode(PkgIterator(Cache
,*I
)) == false)
149 // Copy the after list to the end of the main list
150 for (Package
**I
= AfterList
; I
!= AfterEnd
; I
++)
153 // Swap the main list to the new list
160 // OrderList::OrderCritical - Perform critical unpacking ordering /*{{{*/
161 // ---------------------------------------------------------------------
162 /* This performs predepends and immediate configuration ordering only.
163 This is termed critical unpacking ordering. Any loops that form are
164 fatal and indicate that the packages cannot be installed. */
165 bool pkgOrderList::OrderCritical()
169 Primary
= &pkgOrderList::DepUnPackPre
;
177 qsort(List
,End
- List
,sizeof(*List
),&OrderCompareB
);
179 if (DoRun() == false)
183 return _error
->Error("Fatal, predepends looping detected");
187 // OrderList::OrderUnpack - Perform complete unpacking ordering /*{{{*/
188 // ---------------------------------------------------------------------
189 /* This performs complete unpacking ordering and creates an order that is
190 suitable for unpacking */
191 bool pkgOrderList::OrderUnpack(string
*FileList
)
193 this->FileList
= FileList
;
195 // Setup the after flags
200 // Set the inlist flag
201 for (iterator I
= List
; I
!= End
; I
++)
203 PkgIterator
P(Cache
,*I
);
204 if (IsMissing(P
) == true && IsNow(P
) == true)
209 Primary
= &pkgOrderList::DepUnPackCrit
;
210 Secondary
= &pkgOrderList::DepConfigure
;
211 RevDepends
= &pkgOrderList::DepUnPackDep
;
212 Remove
= &pkgOrderList::DepRemove
;
217 qsort(List
,End
- List
,sizeof(*List
),&OrderCompareA
);
219 if (DoRun() == false)
223 if (DoRun() == false)
228 Remove
= 0; // Otherwise the libreadline remove problem occures
229 if (DoRun() == false)
233 Primary
= &pkgOrderList::DepUnPackPre
;
234 if (DoRun() == false)
237 /* cout << "----------END" << endl;
239 for (iterator I = List; I != End; I++)
241 PkgIterator P(Cache,*I);
242 if (IsNow(P) == true)
243 cout << P.Name() << ' ' << IsMissing(P) << ',' << IsFlag(P,After) << endl;
249 // OrderList::OrderConfigure - Perform configuration ordering /*{{{*/
250 // ---------------------------------------------------------------------
251 /* This orders by depends only and produces an order which is suitable
253 bool pkgOrderList::OrderConfigure()
256 Primary
= &pkgOrderList::DepConfigure
;
265 // OrderList::Score - Score the package for sorting /*{{{*/
266 // ---------------------------------------------------------------------
267 /* Higher scores order earlier */
268 int pkgOrderList::Score(PkgIterator Pkg
)
270 // Removal is always done first
271 if (Cache
[Pkg
].Delete() == true)
274 // This should never happen..
275 if (Cache
[Pkg
].InstVerIter(Cache
).end() == true)
279 if ((Pkg
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
282 for (DepIterator D
= Cache
[Pkg
].InstVerIter(Cache
).DependsList();
283 D
.end() == false; D
++)
284 if (D
->Type
== pkgCache::Dep::PreDepends
)
290 // Important Required Standard Optional Extra
291 signed short PrioMap
[] = {0,5,4,3,1,0};
292 if (Cache
[Pkg
].InstVerIter(Cache
)->Priority
<= 5)
293 Score
+= PrioMap
[Cache
[Pkg
].InstVerIter(Cache
)->Priority
];
297 // OrderList::FileCmp - Compare by package file /*{{{*/
298 // ---------------------------------------------------------------------
299 /* This compares by the package file that the install version is in. */
300 int pkgOrderList::FileCmp(PkgIterator A
,PkgIterator B
)
302 if (Cache
[A
].Delete() == true && Cache
[B
].Delete() == true)
304 if (Cache
[A
].Delete() == true)
306 if (Cache
[B
].Delete() == true)
309 if (Cache
[A
].InstVerIter(Cache
).FileList().end() == true)
311 if (Cache
[B
].InstVerIter(Cache
).FileList().end() == true)
314 pkgCache::PackageFile
*FA
= Cache
[A
].InstVerIter(Cache
).FileList().File();
315 pkgCache::PackageFile
*FB
= Cache
[B
].InstVerIter(Cache
).FileList().File();
323 // BoolCompare - Comparison function for two booleans /*{{{*/
324 // ---------------------------------------------------------------------
326 static int BoolCompare(bool A
,bool B
)
335 // OrderList::OrderCompareA - Order the installation by op /*{{{*/
336 // ---------------------------------------------------------------------
337 /* This provides a first-pass sort of the list and gives a decent starting
338 point for further complete ordering. It is used by OrderUnpack only */
339 int pkgOrderList::OrderCompareA(const void *a
, const void *b
)
341 PkgIterator
A(Me
->Cache
,*(Package
**)a
);
342 PkgIterator
B(Me
->Cache
,*(Package
**)b
);
344 // We order packages with a set state toward the front
346 if ((Res
= BoolCompare(Me
->IsNow(A
),Me
->IsNow(B
))) != 0)
349 // We order missing files to toward the end
350 /* if (Me->FileList != 0)
352 if ((Res = BoolCompare(Me->IsMissing(A),
353 Me->IsMissing(B))) != 0)
357 if (A
.State() != pkgCache::PkgIterator::NeedsNothing
&&
358 B
.State() == pkgCache::PkgIterator::NeedsNothing
)
361 if (A
.State() == pkgCache::PkgIterator::NeedsNothing
&&
362 B
.State() != pkgCache::PkgIterator::NeedsNothing
)
365 int ScoreA
= Me
->Score(A
);
366 int ScoreB
= Me
->Score(B
);
373 return strcmp(A
.Name(),B
.Name());
376 // OrderList::OrderCompareB - Order the installation by source /*{{{*/
377 // ---------------------------------------------------------------------
378 /* This orders by installation source. This is usefull to handle
379 inter-source breaks */
380 int pkgOrderList::OrderCompareB(const void *a
, const void *b
)
382 PkgIterator
A(Me
->Cache
,*(Package
**)a
);
383 PkgIterator
B(Me
->Cache
,*(Package
**)b
);
385 if (A
.State() != pkgCache::PkgIterator::NeedsNothing
&&
386 B
.State() == pkgCache::PkgIterator::NeedsNothing
)
389 if (A
.State() == pkgCache::PkgIterator::NeedsNothing
&&
390 B
.State() != pkgCache::PkgIterator::NeedsNothing
)
393 int F
= Me
->FileCmp(A
,B
);
401 int ScoreA
= Me
->Score(A
);
402 int ScoreB
= Me
->Score(B
);
409 return strcmp(A
.Name(),B
.Name());
413 // OrderList::VisitDeps - Visit forward install dependencies /*{{{*/
414 // ---------------------------------------------------------------------
415 /* This calls the dependency function for the normal forwards dependencies
417 bool pkgOrderList::VisitDeps(DepFunc F
,PkgIterator Pkg
)
419 if (F
== 0 || Pkg
.end() == true || Cache
[Pkg
].InstallVer
== 0)
422 return (this->*F
)(Cache
[Pkg
].InstVerIter(Cache
).DependsList());
425 // OrderList::VisitRDeps - Visit reverse dependencies /*{{{*/
426 // ---------------------------------------------------------------------
427 /* This calls the dependency function for all of the normal reverse depends
429 bool pkgOrderList::VisitRDeps(DepFunc F
,PkgIterator Pkg
)
431 if (F
== 0 || Pkg
.end() == true)
434 return (this->*F
)(Pkg
.RevDependsList());
437 // OrderList::VisitRProvides - Visit provides reverse dependencies /*{{{*/
438 // ---------------------------------------------------------------------
439 /* This calls the dependency function for all reverse dependencies
440 generated by the provides line on the package. */
441 bool pkgOrderList::VisitRProvides(DepFunc F
,VerIterator Ver
)
443 if (F
== 0 || Ver
.end() == true)
447 for (PrvIterator P
= Ver
.ProvidesList(); P
.end() == false; P
++)
448 Res
&= (this->*F
)(P
.ParentPkg().RevDependsList());
452 // OrderList::VisitProvides - Visit all of the providing packages /*{{{*/
453 // ---------------------------------------------------------------------
454 /* This routine calls visit on all providing packages. */
455 bool pkgOrderList::VisitProvides(DepIterator D
,bool Critical
)
457 Version
**List
= D
.AllTargets();
458 for (Version
**I
= List
; *I
!= 0; I
++)
460 VerIterator
Ver(Cache
,*I
);
461 PkgIterator Pkg
= Ver
.ParentPkg();
463 if (Cache
[Pkg
].Keep() == true && Pkg
.State() == PkgIterator::NeedsNothing
)
466 if (D
->Type
!= pkgCache::Dep::Conflicts
&& Cache
[Pkg
].InstallVer
!= *I
)
469 if (D
->Type
== pkgCache::Dep::Conflicts
&& (Version
*)Pkg
.CurrentVer() != *I
)
472 // Skip over missing files
473 if (Critical
== false && IsMissing(D
.ParentPkg()) == true)
476 if (VisitNode(Pkg
) == false)
486 // OrderList::VisitNode - Recursive ordering director /*{{{*/
487 // ---------------------------------------------------------------------
488 /* This is the core ordering routine. It calls the set dependency
489 consideration functions which then potentialy call this again. Finite
490 depth is achived through the colouring mechinism. */
491 bool pkgOrderList::VisitNode(PkgIterator Pkg
)
493 // Looping or irrelevent.
494 // This should probably trancend not installed packages
495 if (Pkg
.end() == true || IsFlag(Pkg
,Added
) == true ||
496 IsFlag(Pkg
,AddPending
) == true || IsFlag(Pkg
,InList
) == false)
499 /* for (int j = 0; j != Depth; j++) cout << ' ';
500 cout << "Visit " << Pkg.Name() << endl;*/
504 Flag(Pkg
,AddPending
);
506 DepFunc Old
= Primary
;
508 // Perform immedate configuration of the package if so flagged.
509 if (IsFlag(Pkg
,Immediate
) == true && Primary
!= &pkgOrderList::DepUnPackPre
)
510 Primary
= &pkgOrderList::DepUnPackPreD
;
512 if (IsNow(Pkg
) == true)
515 if (Cache
[Pkg
].Delete() == false)
518 Res
&= Res
&& VisitDeps(Primary
,Pkg
);
519 Res
&= Res
&& VisitRDeps(Primary
,Pkg
);
520 Res
&= Res
&& VisitRProvides(Primary
,Pkg
.CurrentVer());
521 Res
&= Res
&& VisitRProvides(Primary
,Cache
[Pkg
].InstVerIter(Cache
));
524 Res
&= Res
&& VisitRDeps(RevDepends
,Pkg
);
525 Res
&= Res
&& VisitRProvides(RevDepends
,Pkg
.CurrentVer());
526 Res
&= Res
&& VisitRProvides(RevDepends
,Cache
[Pkg
].InstVerIter(Cache
));
529 Res
&= Res
&& VisitDeps(Secondary
,Pkg
);
530 Res
&= Res
&& VisitRDeps(Secondary
,Pkg
);
531 Res
&= Res
&& VisitRProvides(Secondary
,Pkg
.CurrentVer());
532 Res
&= Res
&& VisitRProvides(Secondary
,Cache
[Pkg
].InstVerIter(Cache
));
537 Res
&= Res
&& VisitRDeps(Remove
,Pkg
);
538 Res
&= Res
&& VisitRProvides(Remove
,Pkg
.CurrentVer());
542 if (IsFlag(Pkg
,Added
) == false)
544 Flag(Pkg
,Added
,Added
| AddPending
);
545 if (IsFlag(Pkg
,After
) == true)
554 /* for (int j = 0; j != Depth; j++) cout << ' ';
555 cout << "Leave " << Pkg.Name() << ' ' << IsFlag(Pkg,Added) << ',' << IsFlag(Pkg,AddPending) << endl;*/
561 // OrderList::DepUnPackCrit - Critical UnPacking ordering /*{{{*/
562 // ---------------------------------------------------------------------
563 /* Critical unpacking ordering strives to satisfy Conflicts: and
564 PreDepends: only. When a prdepends is encountered the Primary
565 DepFunc is changed to be DepUnPackPreD.
567 Loops are preprocessed and logged. */
568 bool pkgOrderList::DepUnPackCrit(DepIterator D
)
570 for (; D
.end() == false; D
++)
572 if (D
.Reverse() == true)
574 /* Reverse depenanices are only interested in conflicts,
575 predepend breakage is ignored here */
576 if (D
->Type
!= pkgCache::Dep::Conflicts
)
579 // Duplication elimination, consider only the current version
580 if (D
.ParentPkg().CurrentVer() != D
.ParentVer())
583 /* For reverse dependencies we wish to check if the
584 dependency is satisifed in the install state. The
585 target package (caller) is going to be in the installed
587 if (CheckDep(D
) == true)
590 if (VisitNode(D
.ParentPkg()) == false)
595 /* Forward critical dependencies MUST be correct before the
596 package can be unpacked. */
597 if (D
->Type
!= pkgCache::Dep::Conflicts
&& D
->Type
!= pkgCache::Dep::PreDepends
)
600 /* We wish to check if the dep is okay in the now state of the
601 target package against the install state of this package. */
602 if (CheckDep(D
) == true)
604 /* We want to catch predepends loops with the code below.
605 Conflicts loops that are Dep OK are ignored */
606 if (IsFlag(D
.TargetPkg(),AddPending
) == false ||
607 D
->Type
!= pkgCache::Dep::PreDepends
)
611 // This is the loop detection
612 if (IsFlag(D
.TargetPkg(),Added
) == true ||
613 IsFlag(D
.TargetPkg(),AddPending
) == true)
615 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
620 /* Predepends require a special ordering stage, they must have
621 all dependents installed as well */
622 DepFunc Old
= Primary
;
624 if (D
->Type
== pkgCache::Dep::PreDepends
)
625 Primary
= &pkgOrderList::DepUnPackPreD
;
626 Res
= VisitProvides(D
,true);
635 // OrderList::DepUnPackPreD - Critical UnPacking ordering with depends /*{{{*/
636 // ---------------------------------------------------------------------
637 /* Critical PreDepends (also configure immediate and essential) strives to
638 ensure not only that all conflicts+predepends are met but that this
639 package will be immediately configurable when it is unpacked.
641 Loops are preprocessed and logged. */
642 bool pkgOrderList::DepUnPackPreD(DepIterator D
)
644 if (D
.Reverse() == true)
645 return DepUnPackCrit(D
);
647 for (; D
.end() == false; D
++)
649 if (D
.IsCritical() == false)
652 /* We wish to check if the dep is okay in the now state of the
653 target package against the install state of this package. */
654 if (CheckDep(D
) == true)
656 /* We want to catch predepends loops with the code below.
657 Conflicts loops that are Dep OK are ignored */
658 if (IsFlag(D
.TargetPkg(),AddPending
) == false ||
659 D
->Type
!= pkgCache::Dep::PreDepends
)
663 // This is the loop detection
664 if (IsFlag(D
.TargetPkg(),Added
) == true ||
665 IsFlag(D
.TargetPkg(),AddPending
) == true)
667 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
672 if (VisitProvides(D
,true) == false)
678 // OrderList::DepUnPackPre - Critical Predepends ordering /*{{{*/
679 // ---------------------------------------------------------------------
680 /* Critical PreDepends (also configure immediate and essential) strives to
681 ensure not only that all conflicts+predepends are met but that this
682 package will be immediately configurable when it is unpacked.
684 Loops are preprocessed and logged. All loops will be fatal. */
685 bool pkgOrderList::DepUnPackPre(DepIterator D
)
687 if (D
.Reverse() == true)
690 for (; D
.end() == false; D
++)
692 /* Only consider the PreDepends or Depends. Depends are only
693 considered at the lowest depth or in the case of immediate
695 if (D
->Type
!= pkgCache::Dep::PreDepends
)
697 if (D
->Type
== pkgCache::Dep::Depends
)
699 if (Depth
== 1 && IsFlag(D
.ParentPkg(),Immediate
) == false)
706 /* We wish to check if the dep is okay in the now state of the
707 target package against the install state of this package. */
708 if (CheckDep(D
) == true)
710 /* We want to catch predepends loops with the code below.
711 Conflicts loops that are Dep OK are ignored */
712 if (IsFlag(D
.TargetPkg(),AddPending
) == false)
716 // This is the loop detection
717 if (IsFlag(D
.TargetPkg(),Added
) == true ||
718 IsFlag(D
.TargetPkg(),AddPending
) == true)
720 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
725 if (VisitProvides(D
,true) == false)
731 // OrderList::DepUnPackDep - Reverse dependency considerations /*{{{*/
732 // ---------------------------------------------------------------------
733 /* Reverse dependencies are considered to determine if unpacking this
734 package will break any existing dependencies. If so then those
735 packages are ordered before this one so that they are in the
738 The forwards depends loop is designed to bring the packages dependents
739 close to the package. This helps reduce deconfigure time.
741 Loops are irrelevent to this. */
742 bool pkgOrderList::DepUnPackDep(DepIterator D
)
745 for (; D
.end() == false; D
++)
746 if (D
.IsCritical() == true)
748 if (D
.Reverse() == true)
750 /* Duplication prevention. We consider rev deps only on
751 the current version, a not installed package
753 if (D
.ParentPkg()->CurrentVer
== 0 ||
754 D
.ParentPkg().CurrentVer() != D
.ParentVer())
757 // The dep will not break so it is irrelevent.
758 if (CheckDep(D
) == true)
761 // Skip over missing files
762 if (IsMissing(D
.ParentPkg()) == true)
765 if (VisitNode(D
.ParentPkg()) == false)
769 if (D
->Type
== pkgCache::Dep::Depends
)
770 if (VisitProvides(D
,false) == false)
776 // OrderList::DepConfigure - Configuration ordering /*{{{*/
777 // ---------------------------------------------------------------------
778 /* Configuration only ordering orders by the Depends: line only. It
779 orders configuration so that when a package comes to be configured it's
780 dependents are configured.
782 Loops are ingored. Depends loop entry points are chaotic. */
783 bool pkgOrderList::DepConfigure(DepIterator D
)
785 // Never consider reverse configuration dependencies.
786 if (D
.Reverse() == true)
789 for (; D
.end() == false; D
++)
790 if (D
->Type
== pkgCache::Dep::Depends
)
791 if (VisitProvides(D
,false) == false)
796 // OrderList::DepRemove - Removal ordering /*{{{*/
797 // ---------------------------------------------------------------------
798 /* Removal visits all reverse depends. It considers if the dependency
799 of the Now state version to see if it is okay with removing this
800 package. This check should always fail, but is provided for symetery
801 with the other critical handlers.
803 Loops are preprocessed and logged. Removal loops can also be
804 detected in the critical handler. They are characterized by an
805 old version of A depending on B but the new version of A conflicting
806 with B, thus either A or B must break to install. */
807 bool pkgOrderList::DepRemove(DepIterator D
)
809 if (D
.Reverse() == false)
811 for (; D
.end() == false; D
++)
812 if (D
->Type
== pkgCache::Dep::Depends
|| D
->Type
== pkgCache::Dep::PreDepends
)
814 // Duplication elimination, consider the current version only
815 if (D
.ParentPkg().CurrentVer() != D
.ParentVer())
818 /* We wish to see if the dep on the parent package is okay
819 in the removed (install) state of the target pkg. */
820 if (CheckDep(D
) == true)
822 // We want to catch loops with the code below.
823 if (IsFlag(D
.ParentPkg(),AddPending
) == false)
827 // This is the loop detection
828 if (IsFlag(D
.ParentPkg(),Added
) == true ||
829 IsFlag(D
.ParentPkg(),AddPending
) == true)
831 if (IsFlag(D
.ParentPkg(),AddPending
) == true)
836 // Skip over missing files
837 if (IsMissing(D
.ParentPkg()) == true)
840 if (VisitNode(D
.ParentPkg()) == false)
848 // OrderList::AddLoop - Add a loop to the loop list /*{{{*/
849 // ---------------------------------------------------------------------
850 /* We record the loops. This is a relic since loop breaking is done
851 genericaly as part of the safety routines. */
852 bool pkgOrderList::AddLoop(DepIterator D
)
854 if (LoopCount
< 0 || LoopCount
>= 20)
860 if (Loops
[LoopCount
- 1].ParentPkg() == D
.ParentPkg() ||
861 Loops
[LoopCount
- 1].TargetPkg() == D
.ParentPkg())
865 Loops
[LoopCount
++] = D
;
867 // Mark the packages as being part of a loop.
868 Flag(D
.TargetPkg(),Loop
);
869 Flag(D
.ParentPkg(),Loop
);
873 // OrderList::WipeFlags - Unset the given flags from all packages /*{{{*/
874 // ---------------------------------------------------------------------
876 void pkgOrderList::WipeFlags(unsigned long F
)
878 unsigned long Size
= Cache
.HeaderP
->PackageCount
;
879 for (unsigned long I
= 0; I
!= Size
; I
++)
883 // OrderList::CheckDep - Check a dependency for truth /*{{{*/
884 // ---------------------------------------------------------------------
885 /* This performs a complete analysis of the dependency wrt to the
886 current add list. It returns true if after all events are
887 performed it is still true. This sort of routine can be approximated
888 by examining the DepCache, however in convoluted cases of provides
889 this fails to produce a suitable result. */
890 bool pkgOrderList::CheckDep(DepIterator D
)
892 Version
**List
= D
.AllTargets();
894 for (Version
**I
= List
; *I
!= 0; I
++)
896 VerIterator
Ver(Cache
,*I
);
897 PkgIterator Pkg
= Ver
.ParentPkg();
899 /* The meaning of Added and AddPending is subtle. AddPending is
900 an indication that the package is looping. Because of the
901 way ordering works Added means the package will be unpacked
902 before this one and AddPending means after. It is therefore
903 correct to ignore AddPending in all cases, but that exposes
904 reverse-ordering loops which should be ignored. */
905 if (IsFlag(Pkg
,Added
) == true ||
906 (IsFlag(Pkg
,AddPending
) == true && D
.Reverse() == true))
908 if (Cache
[Pkg
].InstallVer
!= *I
)
912 if ((Version
*)Pkg
.CurrentVer() != *I
||
913 Pkg
.State() != PkgIterator::NeedsNothing
)
916 /* Conflicts requires that all versions are not present, depends
918 if (D
->Type
!= pkgCache::Dep::Conflicts
)
920 /* Try to find something that does not have the after flag set
921 if at all possible */
922 if (IsFlag(Pkg
,After
) == true)
933 if (IsFlag(Pkg
,After
) == true)
934 Flag(D
.ParentPkg(),After
);
942 // We found a hit, but it had the after flag set
943 if (Hit
== true && D
->Type
== pkgCache::Dep::PreDepends
)
945 Flag(D
.ParentPkg(),After
);
949 /* Conflicts requires that all versions are not present, depends
951 if (D
->Type
== pkgCache::Dep::Conflicts
)