]>
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 /*{{{*/
66 #include <apt-pkg/orderlist.h>
67 #include <apt-pkg/depcache.h>
68 #include <apt-pkg/error.h>
69 #include <apt-pkg/version.h>
70 #include <apt-pkg/sptr.h>
71 #include <apt-pkg/configuration.h>
78 pkgOrderList
*pkgOrderList::Me
= 0;
80 // OrderList::pkgOrderList - Constructor /*{{{*/
81 // ---------------------------------------------------------------------
83 pkgOrderList::pkgOrderList(pkgDepCache
*pCache
) : Cache(*pCache
)
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 Cache
[Pkg
].Keep() == true)
127 if (FileList
[Pkg
->ID
].empty() == false)
132 // OrderList::DoRun - Does an order run /*{{{*/
133 // ---------------------------------------------------------------------
134 /* The caller is expeted to have setup the desired probe state */
135 bool pkgOrderList::DoRun()
138 unsigned long Size
= Cache
.Head().PackageCount
;
139 SPtrArray
<Package
*> NList
= new Package
*[Size
];
140 SPtrArray
<Package
*> AfterList
= new Package
*[Size
];
141 AfterEnd
= AfterList
;
144 WipeFlags(Added
| AddPending
| Loop
| InList
);
146 for (iterator I
= List
; I
!= End
; I
++)
149 // Rebuild the main list into the temp list.
150 iterator OldEnd
= End
;
152 for (iterator I
= List
; I
!= OldEnd
; I
++)
153 if (VisitNode(PkgIterator(Cache
,*I
)) == false)
159 // Copy the after list to the end of the main list
160 for (Package
**I
= AfterList
; I
!= AfterEnd
; I
++)
163 // Swap the main list to the new list
165 List
= NList
.UnGuard();
169 // OrderList::OrderCritical - Perform critical unpacking ordering /*{{{*/
170 // ---------------------------------------------------------------------
171 /* This performs predepends and immediate configuration ordering only.
172 This is termed critical unpacking ordering. Any loops that form are
173 fatal and indicate that the packages cannot be installed. */
174 bool pkgOrderList::OrderCritical()
178 Primary
= &pkgOrderList::DepUnPackPreD
;
186 qsort(List
,End
- List
,sizeof(*List
),&OrderCompareB
);
188 if (DoRun() == false)
192 return _error
->Error("Fatal, predepends looping detected");
196 clog
<< "** Critical Unpack ordering done" << endl
;
198 for (iterator I
= List
; I
!= End
; I
++)
200 PkgIterator
P(Cache
,*I
);
201 if (IsNow(P
) == true)
202 clog
<< " " << P
.Name() << ' ' << IsMissing(P
) << ',' << IsFlag(P
,After
) << endl
;
209 // OrderList::OrderUnpack - Perform complete unpacking ordering /*{{{*/
210 // ---------------------------------------------------------------------
211 /* This performs complete unpacking ordering and creates an order that is
212 suitable for unpacking */
213 bool pkgOrderList::OrderUnpack(string
*FileList
)
215 this->FileList
= FileList
;
217 // Setup the after flags
222 // Set the inlist flag
223 for (iterator I
= List
; I
!= End
; I
++)
225 PkgIterator
P(Cache
,*I
);
226 if (IsMissing(P
) == true && IsNow(P
) == true)
231 Primary
= &pkgOrderList::DepUnPackCrit
;
232 Secondary
= &pkgOrderList::DepConfigure
;
233 RevDepends
= &pkgOrderList::DepUnPackDep
;
234 Remove
= &pkgOrderList::DepRemove
;
239 qsort(List
,End
- List
,sizeof(*List
),&OrderCompareA
);
242 clog
<< "** Pass A" << endl
;
243 if (DoRun() == false)
247 clog
<< "** Pass B" << endl
;
249 if (DoRun() == false)
253 clog
<< "** Pass C" << endl
;
256 Remove
= 0; // Otherwise the libreadline remove problem occures
257 if (DoRun() == false)
261 clog
<< "** Pass D" << endl
;
263 Primary
= &pkgOrderList::DepUnPackPre
;
264 if (DoRun() == false)
269 clog
<< "** Unpack ordering done" << endl
;
271 for (iterator I
= List
; I
!= End
; I
++)
273 PkgIterator
P(Cache
,*I
);
274 if (IsNow(P
) == true)
275 clog
<< " " << P
.Name() << ' ' << IsMissing(P
) << ',' << IsFlag(P
,After
) << endl
;
282 // OrderList::OrderConfigure - Perform configuration ordering /*{{{*/
283 // ---------------------------------------------------------------------
284 /* This orders by depends only and produces an order which is suitable
286 bool pkgOrderList::OrderConfigure()
289 Primary
= &pkgOrderList::DepConfigure
;
297 // OrderList::Score - Score the package for sorting /*{{{*/
298 // ---------------------------------------------------------------------
299 /* Higher scores order earlier */
300 int pkgOrderList::Score(PkgIterator Pkg
)
302 static int const ScoreDelete
= _config
->FindI("OrderList::Score::Delete", 500);
304 // Removal is always done first
305 if (Cache
[Pkg
].Delete() == true)
308 // This should never happen..
309 if (Cache
[Pkg
].InstVerIter(Cache
).end() == true)
312 static int const ScoreEssential
= _config
->FindI("OrderList::Score::Essential", 200);
313 static int const ScoreImmediate
= _config
->FindI("OrderList::Score::Immediate", 10);
314 static int const ScorePreDepends
= _config
->FindI("OrderList::Score::PreDepends", 50);
317 if ((Pkg
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
318 Score
+= ScoreEssential
;
320 if (IsFlag(Pkg
,Immediate
) == true)
321 Score
+= ScoreImmediate
;
323 for (DepIterator D
= Cache
[Pkg
].InstVerIter(Cache
).DependsList();
324 D
.end() == false; D
++)
325 if (D
->Type
== pkgCache::Dep::PreDepends
)
327 Score
+= ScorePreDepends
;
331 // Important Required Standard Optional Extra
332 signed short PrioMap
[] = {0,5,4,3,1,0};
333 if (Cache
[Pkg
].InstVerIter(Cache
)->Priority
<= 5)
334 Score
+= PrioMap
[Cache
[Pkg
].InstVerIter(Cache
)->Priority
];
338 // OrderList::FileCmp - Compare by package file /*{{{*/
339 // ---------------------------------------------------------------------
340 /* This compares by the package file that the install version is in. */
341 int pkgOrderList::FileCmp(PkgIterator A
,PkgIterator B
)
343 if (Cache
[A
].Delete() == true && Cache
[B
].Delete() == true)
345 if (Cache
[A
].Delete() == true)
347 if (Cache
[B
].Delete() == true)
350 if (Cache
[A
].InstVerIter(Cache
).FileList().end() == true)
352 if (Cache
[B
].InstVerIter(Cache
).FileList().end() == true)
355 pkgCache::PackageFile
*FA
= Cache
[A
].InstVerIter(Cache
).FileList().File();
356 pkgCache::PackageFile
*FB
= Cache
[B
].InstVerIter(Cache
).FileList().File();
364 // BoolCompare - Comparison function for two booleans /*{{{*/
365 // ---------------------------------------------------------------------
367 static int BoolCompare(bool A
,bool B
)
376 // OrderList::OrderCompareA - Order the installation by op /*{{{*/
377 // ---------------------------------------------------------------------
378 /* This provides a first-pass sort of the list and gives a decent starting
379 point for further complete ordering. It is used by OrderUnpack only */
380 int pkgOrderList::OrderCompareA(const void *a
, const void *b
)
382 PkgIterator
A(Me
->Cache
,*(Package
**)a
);
383 PkgIterator
B(Me
->Cache
,*(Package
**)b
);
385 // We order packages with a set state toward the front
387 if ((Res
= BoolCompare(Me
->IsNow(A
),Me
->IsNow(B
))) != 0)
390 // We order missing files to toward the end
391 /* if (Me->FileList != 0)
393 if ((Res = BoolCompare(Me->IsMissing(A),
394 Me->IsMissing(B))) != 0)
398 if (A
.State() != pkgCache::PkgIterator::NeedsNothing
&&
399 B
.State() == pkgCache::PkgIterator::NeedsNothing
)
402 if (A
.State() == pkgCache::PkgIterator::NeedsNothing
&&
403 B
.State() != pkgCache::PkgIterator::NeedsNothing
)
406 int ScoreA
= Me
->Score(A
);
407 int ScoreB
= Me
->Score(B
);
415 return strcmp(A
.Name(),B
.Name());
418 // OrderList::OrderCompareB - Order the installation by source /*{{{*/
419 // ---------------------------------------------------------------------
420 /* This orders by installation source. This is useful to handle
421 inter-source breaks */
422 int pkgOrderList::OrderCompareB(const void *a
, const void *b
)
424 PkgIterator
A(Me
->Cache
,*(Package
**)a
);
425 PkgIterator
B(Me
->Cache
,*(Package
**)b
);
427 if (A
.State() != pkgCache::PkgIterator::NeedsNothing
&&
428 B
.State() == pkgCache::PkgIterator::NeedsNothing
)
431 if (A
.State() == pkgCache::PkgIterator::NeedsNothing
&&
432 B
.State() != pkgCache::PkgIterator::NeedsNothing
)
435 int F
= Me
->FileCmp(A
,B
);
443 int ScoreA
= Me
->Score(A
);
444 int ScoreB
= Me
->Score(B
);
452 return strcmp(A
.Name(),B
.Name());
455 // OrderList::VisitDeps - Visit forward install dependencies /*{{{*/
456 // ---------------------------------------------------------------------
457 /* This calls the dependency function for the normal forwards dependencies
459 bool pkgOrderList::VisitDeps(DepFunc F
,PkgIterator Pkg
)
461 if (F
== 0 || Pkg
.end() == true || Cache
[Pkg
].InstallVer
== 0)
464 return (this->*F
)(Cache
[Pkg
].InstVerIter(Cache
).DependsList());
467 // OrderList::VisitRDeps - Visit reverse dependencies /*{{{*/
468 // ---------------------------------------------------------------------
469 /* This calls the dependency function for all of the normal reverse depends
471 bool pkgOrderList::VisitRDeps(DepFunc F
,PkgIterator Pkg
)
473 if (F
== 0 || Pkg
.end() == true)
476 return (this->*F
)(Pkg
.RevDependsList());
479 // OrderList::VisitRProvides - Visit provides reverse dependencies /*{{{*/
480 // ---------------------------------------------------------------------
481 /* This calls the dependency function for all reverse dependencies
482 generated by the provides line on the package. */
483 bool pkgOrderList::VisitRProvides(DepFunc F
,VerIterator Ver
)
485 if (F
== 0 || Ver
.end() == true)
489 for (PrvIterator P
= Ver
.ProvidesList(); P
.end() == false; P
++)
490 Res
&= (this->*F
)(P
.ParentPkg().RevDependsList());
494 // OrderList::VisitProvides - Visit all of the providing packages /*{{{*/
495 // ---------------------------------------------------------------------
496 /* This routine calls visit on all providing packages. */
497 bool pkgOrderList::VisitProvides(DepIterator D
,bool Critical
)
499 SPtrArray
<Version
*> List
= D
.AllTargets();
500 for (Version
**I
= List
; *I
!= 0; I
++)
502 VerIterator
Ver(Cache
,*I
);
503 PkgIterator Pkg
= Ver
.ParentPkg();
505 if (Cache
[Pkg
].Keep() == true && Pkg
.State() == PkgIterator::NeedsNothing
)
508 if (D
->Type
!= pkgCache::Dep::Conflicts
&&
509 D
->Type
!= pkgCache::Dep::DpkgBreaks
&&
510 D
->Type
!= pkgCache::Dep::Obsoletes
&&
511 Cache
[Pkg
].InstallVer
!= *I
)
514 if ((D
->Type
== pkgCache::Dep::Conflicts
||
515 D
->Type
== pkgCache::Dep::DpkgBreaks
||
516 D
->Type
== pkgCache::Dep::Obsoletes
) &&
517 (Version
*)Pkg
.CurrentVer() != *I
)
520 // Skip over missing files
521 if (Critical
== false && IsMissing(D
.ParentPkg()) == true)
524 if (VisitNode(Pkg
) == false)
530 // OrderList::VisitNode - Recursive ordering director /*{{{*/
531 // ---------------------------------------------------------------------
532 /* This is the core ordering routine. It calls the set dependency
533 consideration functions which then potentialy call this again. Finite
534 depth is achived through the colouring mechinism. */
535 bool pkgOrderList::VisitNode(PkgIterator Pkg
)
537 // Looping or irrelevent.
538 // This should probably trancend not installed packages
539 if (Pkg
.end() == true || IsFlag(Pkg
,Added
) == true ||
540 IsFlag(Pkg
,AddPending
) == true || IsFlag(Pkg
,InList
) == false)
545 for (int j
= 0; j
!= Depth
; j
++) clog
<< ' ';
546 clog
<< "Visit " << Pkg
.Name() << endl
;
552 Flag(Pkg
,AddPending
);
554 DepFunc Old
= Primary
;
556 // Perform immedate configuration of the package if so flagged.
557 if (IsFlag(Pkg
,Immediate
) == true && Primary
!= &pkgOrderList::DepUnPackPre
)
558 Primary
= &pkgOrderList::DepUnPackPreD
;
560 if (IsNow(Pkg
) == true)
563 if (Cache
[Pkg
].Delete() == false)
566 Res
&= Res
&& VisitDeps(Primary
,Pkg
);
567 Res
&= Res
&& VisitRDeps(Primary
,Pkg
);
568 Res
&= Res
&& VisitRProvides(Primary
,Pkg
.CurrentVer());
569 Res
&= Res
&& VisitRProvides(Primary
,Cache
[Pkg
].InstVerIter(Cache
));
572 Res
&= Res
&& VisitRDeps(RevDepends
,Pkg
);
573 Res
&= Res
&& VisitRProvides(RevDepends
,Pkg
.CurrentVer());
574 Res
&= Res
&& VisitRProvides(RevDepends
,Cache
[Pkg
].InstVerIter(Cache
));
577 Res
&= Res
&& VisitDeps(Secondary
,Pkg
);
578 Res
&= Res
&& VisitRDeps(Secondary
,Pkg
);
579 Res
&= Res
&& VisitRProvides(Secondary
,Pkg
.CurrentVer());
580 Res
&= Res
&& VisitRProvides(Secondary
,Cache
[Pkg
].InstVerIter(Cache
));
585 Res
&= Res
&& VisitRDeps(Remove
,Pkg
);
586 Res
&= Res
&& VisitRProvides(Remove
,Pkg
.CurrentVer());
590 if (IsFlag(Pkg
,Added
) == false)
592 Flag(Pkg
,Added
,Added
| AddPending
);
593 if (IsFlag(Pkg
,After
) == true)
604 for (int j
= 0; j
!= Depth
; j
++) clog
<< ' ';
605 clog
<< "Leave " << Pkg
.Name() << ' ' << IsFlag(Pkg
,Added
) << ',' << IsFlag(Pkg
,AddPending
) << endl
;
611 // OrderList::DepUnPackCrit - Critical UnPacking ordering /*{{{*/
612 // ---------------------------------------------------------------------
613 /* Critical unpacking ordering strives to satisfy Conflicts: and
614 PreDepends: only. When a prdepends is encountered the Primary
615 DepFunc is changed to be DepUnPackPreD.
617 Loops are preprocessed and logged. */
618 bool pkgOrderList::DepUnPackCrit(DepIterator D
)
620 for (; D
.end() == false; D
++)
622 if (D
.Reverse() == true)
624 /* Reverse depenanices are only interested in conflicts,
625 predepend breakage is ignored here */
626 if (D
->Type
!= pkgCache::Dep::Conflicts
&&
627 D
->Type
!= pkgCache::Dep::Obsoletes
)
630 // Duplication elimination, consider only the current version
631 if (D
.ParentPkg().CurrentVer() != D
.ParentVer())
634 /* For reverse dependencies we wish to check if the
635 dependency is satisifed in the install state. The
636 target package (caller) is going to be in the installed
638 if (CheckDep(D
) == true)
641 if (VisitNode(D
.ParentPkg()) == false)
646 /* Forward critical dependencies MUST be correct before the
647 package can be unpacked. */
648 if (D
->Type
!= pkgCache::Dep::Conflicts
&&
649 D
->Type
!= pkgCache::Dep::DpkgBreaks
&&
650 D
->Type
!= pkgCache::Dep::Obsoletes
&&
651 D
->Type
!= pkgCache::Dep::PreDepends
)
654 /* We wish to check if the dep is okay in the now state of the
655 target package against the install state of this package. */
656 if (CheckDep(D
) == true)
658 /* We want to catch predepends loops with the code below.
659 Conflicts loops that are Dep OK are ignored */
660 if (IsFlag(D
.TargetPkg(),AddPending
) == false ||
661 D
->Type
!= pkgCache::Dep::PreDepends
)
665 // This is the loop detection
666 if (IsFlag(D
.TargetPkg(),Added
) == true ||
667 IsFlag(D
.TargetPkg(),AddPending
) == true)
669 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
674 /* Predepends require a special ordering stage, they must have
675 all dependents installed as well */
676 DepFunc Old
= Primary
;
678 if (D
->Type
== pkgCache::Dep::PreDepends
)
679 Primary
= &pkgOrderList::DepUnPackPreD
;
680 Res
= VisitProvides(D
,true);
689 // OrderList::DepUnPackPreD - Critical UnPacking ordering with depends /*{{{*/
690 // ---------------------------------------------------------------------
691 /* Critical PreDepends (also configure immediate and essential) strives to
692 ensure not only that all conflicts+predepends are met but that this
693 package will be immediately configurable when it is unpacked.
694 Loops are preprocessed and logged. */
695 bool pkgOrderList::DepUnPackPreD(DepIterator D
)
697 if (D
.Reverse() == true)
698 return DepUnPackCrit(D
);
700 for (; D
.end() == false; D
++)
702 if (D
.IsCritical() == false)
705 /* We wish to check if the dep is okay in the now state of the
706 target package against the install state of this package. */
707 if (CheckDep(D
) == true)
709 /* We want to catch predepends loops with the code below.
710 Conflicts loops that are Dep OK are ignored */
711 if (IsFlag(D
.TargetPkg(),AddPending
) == false ||
712 D
->Type
!= pkgCache::Dep::PreDepends
)
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::DepUnPackPre - Critical Predepends ordering /*{{{*/
732 // ---------------------------------------------------------------------
733 /* Critical PreDepends (also configure immediate and essential) strives to
734 ensure not only that all conflicts+predepends are met but that this
735 package will be immediately configurable when it is unpacked.
737 Loops are preprocessed and logged. All loops will be fatal. */
738 bool pkgOrderList::DepUnPackPre(DepIterator D
)
740 if (D
.Reverse() == true)
743 for (; D
.end() == false; D
++)
745 /* Only consider the PreDepends or Depends. Depends are only
746 considered at the lowest depth or in the case of immediate
748 if (D
->Type
!= pkgCache::Dep::PreDepends
)
750 if (D
->Type
== pkgCache::Dep::Depends
)
752 if (Depth
== 1 && IsFlag(D
.ParentPkg(),Immediate
) == false)
759 /* We wish to check if the dep is okay in the now state of the
760 target package against the install state of this package. */
761 if (CheckDep(D
) == true)
763 /* We want to catch predepends loops with the code below.
764 Conflicts loops that are Dep OK are ignored */
765 if (IsFlag(D
.TargetPkg(),AddPending
) == false)
769 // This is the loop detection
770 if (IsFlag(D
.TargetPkg(),Added
) == true ||
771 IsFlag(D
.TargetPkg(),AddPending
) == true)
773 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
778 if (VisitProvides(D
,true) == false)
784 // OrderList::DepUnPackDep - Reverse dependency considerations /*{{{*/
785 // ---------------------------------------------------------------------
786 /* Reverse dependencies are considered to determine if unpacking this
787 package will break any existing dependencies. If so then those
788 packages are ordered before this one so that they are in the
791 The forwards depends loop is designed to bring the packages dependents
792 close to the package. This helps reduce deconfigure time.
794 Loops are irrelevent to this. */
795 bool pkgOrderList::DepUnPackDep(DepIterator D
)
798 for (; D
.end() == false; D
++)
799 if (D
.IsCritical() == true)
801 if (D
.Reverse() == true)
803 /* Duplication prevention. We consider rev deps only on
804 the current version, a not installed package
806 if (D
.ParentPkg()->CurrentVer
== 0 ||
807 D
.ParentPkg().CurrentVer() != D
.ParentVer())
810 // The dep will not break so it is irrelevent.
811 if (CheckDep(D
) == true)
814 // Skip over missing files
815 if (IsMissing(D
.ParentPkg()) == true)
818 if (VisitNode(D
.ParentPkg()) == false)
823 if (D
->Type
== pkgCache::Dep::Depends
)
824 if (VisitProvides(D
,false) == false)
827 if (D
->Type
== pkgCache::Dep::DpkgBreaks
)
829 if (CheckDep(D
) == true)
832 if (VisitNode(D
.TargetPkg()) == false)
840 // OrderList::DepConfigure - Configuration ordering /*{{{*/
841 // ---------------------------------------------------------------------
842 /* Configuration only ordering orders by the Depends: line only. It
843 orders configuration so that when a package comes to be configured it's
844 dependents are configured.
846 Loops are ingored. Depends loop entry points are chaotic. */
847 bool pkgOrderList::DepConfigure(DepIterator D
)
849 // Never consider reverse configuration dependencies.
850 if (D
.Reverse() == true)
853 for (; D
.end() == false; D
++)
854 if (D
->Type
== pkgCache::Dep::Depends
)
855 if (VisitProvides(D
,false) == false)
860 // OrderList::DepRemove - Removal ordering /*{{{*/
861 // ---------------------------------------------------------------------
862 /* Removal visits all reverse depends. It considers if the dependency
863 of the Now state version to see if it is okay with removing this
864 package. This check should always fail, but is provided for symetery
865 with the other critical handlers.
867 Loops are preprocessed and logged. Removal loops can also be
868 detected in the critical handler. They are characterized by an
869 old version of A depending on B but the new version of A conflicting
870 with B, thus either A or B must break to install. */
871 bool pkgOrderList::DepRemove(DepIterator D
)
873 if (D
.Reverse() == false)
875 for (; D
.end() == false; D
++)
876 if (D
->Type
== pkgCache::Dep::Depends
|| D
->Type
== pkgCache::Dep::PreDepends
)
878 // Duplication elimination, consider the current version only
879 if (D
.ParentPkg().CurrentVer() != D
.ParentVer())
882 /* We wish to see if the dep on the parent package is okay
883 in the removed (install) state of the target pkg. */
884 if (CheckDep(D
) == true)
886 // We want to catch loops with the code below.
887 if (IsFlag(D
.ParentPkg(),AddPending
) == false)
891 // This is the loop detection
892 if (IsFlag(D
.ParentPkg(),Added
) == true ||
893 IsFlag(D
.ParentPkg(),AddPending
) == true)
895 if (IsFlag(D
.ParentPkg(),AddPending
) == true)
900 // Skip over missing files
901 if (IsMissing(D
.ParentPkg()) == true)
904 if (VisitNode(D
.ParentPkg()) == false)
911 // OrderList::AddLoop - Add a loop to the loop list /*{{{*/
912 // ---------------------------------------------------------------------
913 /* We record the loops. This is a relic since loop breaking is done
914 genericaly as part of the safety routines. */
915 bool pkgOrderList::AddLoop(DepIterator D
)
917 if (LoopCount
< 0 || LoopCount
>= 20)
923 if (Loops
[LoopCount
- 1].ParentPkg() == D
.ParentPkg() ||
924 Loops
[LoopCount
- 1].TargetPkg() == D
.ParentPkg())
928 Loops
[LoopCount
++] = D
;
930 // Mark the packages as being part of a loop.
931 Flag(D
.TargetPkg(),Loop
);
932 Flag(D
.ParentPkg(),Loop
);
936 // OrderList::WipeFlags - Unset the given flags from all packages /*{{{*/
937 // ---------------------------------------------------------------------
939 void pkgOrderList::WipeFlags(unsigned long F
)
941 unsigned long Size
= Cache
.Head().PackageCount
;
942 for (unsigned long I
= 0; I
!= Size
; I
++)
946 // OrderList::CheckDep - Check a dependency for truth /*{{{*/
947 // ---------------------------------------------------------------------
948 /* This performs a complete analysis of the dependency wrt to the
949 current add list. It returns true if after all events are
950 performed it is still true. This sort of routine can be approximated
951 by examining the DepCache, however in convoluted cases of provides
952 this fails to produce a suitable result. */
953 bool pkgOrderList::CheckDep(DepIterator D
)
955 SPtrArray
<Version
*> List
= D
.AllTargets();
957 for (Version
**I
= List
; *I
!= 0; I
++)
959 VerIterator
Ver(Cache
,*I
);
960 PkgIterator Pkg
= Ver
.ParentPkg();
962 /* The meaning of Added and AddPending is subtle. AddPending is
963 an indication that the package is looping. Because of the
964 way ordering works Added means the package will be unpacked
965 before this one and AddPending means after. It is therefore
966 correct to ignore AddPending in all cases, but that exposes
967 reverse-ordering loops which should be ignored. */
968 if (IsFlag(Pkg
,Added
) == true ||
969 (IsFlag(Pkg
,AddPending
) == true && D
.Reverse() == true))
971 if (Cache
[Pkg
].InstallVer
!= *I
)
975 if ((Version
*)Pkg
.CurrentVer() != *I
||
976 Pkg
.State() != PkgIterator::NeedsNothing
)
979 /* Conflicts requires that all versions are not present, depends
981 if (D
->Type
!= pkgCache::Dep::Conflicts
&&
982 D
->Type
!= pkgCache::Dep::DpkgBreaks
&&
983 D
->Type
!= pkgCache::Dep::Obsoletes
)
985 /* Try to find something that does not have the after flag set
986 if at all possible */
987 if (IsFlag(Pkg
,After
) == true)
997 if (IsFlag(Pkg
,After
) == true)
998 Flag(D
.ParentPkg(),After
);
1004 // We found a hit, but it had the after flag set
1005 if (Hit
== true && D
->Type
== pkgCache::Dep::PreDepends
)
1007 Flag(D
.ParentPkg(),After
);
1011 /* Conflicts requires that all versions are not present, depends
1013 if (D
->Type
== pkgCache::Dep::Conflicts
||
1014 D
->Type
== pkgCache::Dep::Obsoletes
)