]>
git.saurik.com Git - apt.git/blob - apt-pkg/orderlist.cc
d5bd1958103ecd595cbd9a73daab1d968ffd79e3
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 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
)) == 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 signed short PrioMap
[] = {0,5,4,3,1,0};
335 if (Cache
[Pkg
].InstVerIter(Cache
)->Priority
<= 5)
336 Score
+= PrioMap
[Cache
[Pkg
].InstVerIter(Cache
)->Priority
];
340 // OrderList::FileCmp - Compare by package file /*{{{*/
341 // ---------------------------------------------------------------------
342 /* This compares by the package file that the install version is in. */
343 int pkgOrderList::FileCmp(PkgIterator A
,PkgIterator B
)
345 if (Cache
[A
].Delete() == true && Cache
[B
].Delete() == true)
347 if (Cache
[A
].Delete() == true)
349 if (Cache
[B
].Delete() == true)
352 if (Cache
[A
].InstVerIter(Cache
).FileList().end() == true)
354 if (Cache
[B
].InstVerIter(Cache
).FileList().end() == true)
357 pkgCache::PackageFile
*FA
= Cache
[A
].InstVerIter(Cache
).FileList().File();
358 pkgCache::PackageFile
*FB
= Cache
[B
].InstVerIter(Cache
).FileList().File();
366 // BoolCompare - Comparison function for two booleans /*{{{*/
367 // ---------------------------------------------------------------------
369 static int BoolCompare(bool A
,bool B
)
378 // OrderList::OrderCompareA - Order the installation by op /*{{{*/
379 // ---------------------------------------------------------------------
380 /* This provides a first-pass sort of the list and gives a decent starting
381 point for further complete ordering. It is used by OrderUnpack only */
382 int pkgOrderList::OrderCompareA(const void *a
, const void *b
)
384 PkgIterator
A(Me
->Cache
,*(Package
**)a
);
385 PkgIterator
B(Me
->Cache
,*(Package
**)b
);
387 // We order packages with a set state toward the front
389 if ((Res
= BoolCompare(Me
->IsNow(A
),Me
->IsNow(B
))) != 0)
392 // We order missing files to toward the end
393 /* if (Me->FileList != 0)
395 if ((Res = BoolCompare(Me->IsMissing(A),
396 Me->IsMissing(B))) != 0)
400 if (A
.State() != pkgCache::PkgIterator::NeedsNothing
&&
401 B
.State() == pkgCache::PkgIterator::NeedsNothing
)
404 if (A
.State() == pkgCache::PkgIterator::NeedsNothing
&&
405 B
.State() != pkgCache::PkgIterator::NeedsNothing
)
408 int ScoreA
= Me
->Score(A
);
409 int ScoreB
= Me
->Score(B
);
417 return strcmp(A
.Name(),B
.Name());
420 // OrderList::OrderCompareB - Order the installation by source /*{{{*/
421 // ---------------------------------------------------------------------
422 /* This orders by installation source. This is useful to handle
423 inter-source breaks */
424 int pkgOrderList::OrderCompareB(const void *a
, const void *b
)
426 PkgIterator
A(Me
->Cache
,*(Package
**)a
);
427 PkgIterator
B(Me
->Cache
,*(Package
**)b
);
429 if (A
.State() != pkgCache::PkgIterator::NeedsNothing
&&
430 B
.State() == pkgCache::PkgIterator::NeedsNothing
)
433 if (A
.State() == pkgCache::PkgIterator::NeedsNothing
&&
434 B
.State() != pkgCache::PkgIterator::NeedsNothing
)
437 int F
= Me
->FileCmp(A
,B
);
445 int ScoreA
= Me
->Score(A
);
446 int ScoreB
= Me
->Score(B
);
454 return strcmp(A
.Name(),B
.Name());
457 // OrderList::VisitDeps - Visit forward install dependencies /*{{{*/
458 // ---------------------------------------------------------------------
459 /* This calls the dependency function for the normal forwards dependencies
461 bool pkgOrderList::VisitDeps(DepFunc F
,PkgIterator Pkg
)
463 if (F
== 0 || Pkg
.end() == true || Cache
[Pkg
].InstallVer
== 0)
466 return (this->*F
)(Cache
[Pkg
].InstVerIter(Cache
).DependsList());
469 // OrderList::VisitRDeps - Visit reverse dependencies /*{{{*/
470 // ---------------------------------------------------------------------
471 /* This calls the dependency function for all of the normal reverse depends
473 bool pkgOrderList::VisitRDeps(DepFunc F
,PkgIterator Pkg
)
475 if (F
== 0 || Pkg
.end() == true)
478 return (this->*F
)(Pkg
.RevDependsList());
481 // OrderList::VisitRProvides - Visit provides reverse dependencies /*{{{*/
482 // ---------------------------------------------------------------------
483 /* This calls the dependency function for all reverse dependencies
484 generated by the provides line on the package. */
485 bool pkgOrderList::VisitRProvides(DepFunc F
,VerIterator Ver
)
487 if (F
== 0 || Ver
.end() == true)
491 for (PrvIterator P
= Ver
.ProvidesList(); P
.end() == false; P
++)
492 Res
&= (this->*F
)(P
.ParentPkg().RevDependsList());
496 // OrderList::VisitProvides - Visit all of the providing packages /*{{{*/
497 // ---------------------------------------------------------------------
498 /* This routine calls visit on all providing packages. */
499 bool pkgOrderList::VisitProvides(DepIterator D
,bool Critical
)
501 SPtrArray
<Version
*> List
= D
.AllTargets();
502 for (Version
**I
= List
; *I
!= 0; I
++)
504 VerIterator
Ver(Cache
,*I
);
505 PkgIterator Pkg
= Ver
.ParentPkg();
507 if (Cache
[Pkg
].Keep() == true && Pkg
.State() == PkgIterator::NeedsNothing
)
510 if (D
->Type
!= pkgCache::Dep::Conflicts
&&
511 D
->Type
!= pkgCache::Dep::DpkgBreaks
&&
512 D
->Type
!= pkgCache::Dep::Obsoletes
&&
513 Cache
[Pkg
].InstallVer
!= *I
)
516 if ((D
->Type
== pkgCache::Dep::Conflicts
||
517 D
->Type
== pkgCache::Dep::DpkgBreaks
||
518 D
->Type
== pkgCache::Dep::Obsoletes
) &&
519 (Version
*)Pkg
.CurrentVer() != *I
)
522 // Skip over missing files
523 if (Critical
== false && IsMissing(D
.ParentPkg()) == true)
526 if (VisitNode(Pkg
) == false)
532 // OrderList::VisitNode - Recursive ordering director /*{{{*/
533 // ---------------------------------------------------------------------
534 /* This is the core ordering routine. It calls the set dependency
535 consideration functions which then potentialy call this again. Finite
536 depth is achived through the colouring mechinism. */
537 bool pkgOrderList::VisitNode(PkgIterator Pkg
)
539 // Looping or irrelevent.
540 // This should probably trancend not installed packages
541 if (Pkg
.end() == true || IsFlag(Pkg
,Added
) == true ||
542 IsFlag(Pkg
,AddPending
) == true || IsFlag(Pkg
,InList
) == false)
547 for (int j
= 0; j
!= Depth
; j
++) clog
<< ' ';
548 clog
<< "Visit " << Pkg
.FullName() << endl
;
554 Flag(Pkg
,AddPending
);
556 DepFunc Old
= Primary
;
558 // Perform immedate configuration of the package if so flagged.
559 if (IsFlag(Pkg
,Immediate
) == true && Primary
!= &pkgOrderList::DepUnPackPre
)
560 Primary
= &pkgOrderList::DepUnPackPreD
;
562 if (IsNow(Pkg
) == true)
565 if (Cache
[Pkg
].Delete() == false)
568 Res
&= Res
&& VisitDeps(Primary
,Pkg
);
569 Res
&= Res
&& VisitRDeps(Primary
,Pkg
);
570 Res
&= Res
&& VisitRProvides(Primary
,Pkg
.CurrentVer());
571 Res
&= Res
&& VisitRProvides(Primary
,Cache
[Pkg
].InstVerIter(Cache
));
574 Res
&= Res
&& VisitRDeps(RevDepends
,Pkg
);
575 Res
&= Res
&& VisitRProvides(RevDepends
,Pkg
.CurrentVer());
576 Res
&= Res
&& VisitRProvides(RevDepends
,Cache
[Pkg
].InstVerIter(Cache
));
579 Res
&= Res
&& VisitDeps(Secondary
,Pkg
);
580 Res
&= Res
&& VisitRDeps(Secondary
,Pkg
);
581 Res
&= Res
&& VisitRProvides(Secondary
,Pkg
.CurrentVer());
582 Res
&= Res
&& VisitRProvides(Secondary
,Cache
[Pkg
].InstVerIter(Cache
));
587 Res
&= Res
&& VisitRDeps(Remove
,Pkg
);
588 Res
&= Res
&& VisitRProvides(Remove
,Pkg
.CurrentVer());
592 if (IsFlag(Pkg
,Added
) == false)
594 Flag(Pkg
,Added
,Added
| AddPending
);
595 if (IsFlag(Pkg
,After
) == true)
606 for (int j
= 0; j
!= Depth
; j
++) clog
<< ' ';
607 clog
<< "Leave " << Pkg
.FullName() << ' ' << IsFlag(Pkg
,Added
) << ',' << IsFlag(Pkg
,AddPending
) << endl
;
613 // OrderList::DepUnPackCrit - Critical UnPacking ordering /*{{{*/
614 // ---------------------------------------------------------------------
615 /* Critical unpacking ordering strives to satisfy Conflicts: and
616 PreDepends: only. When a prdepends is encountered the Primary
617 DepFunc is changed to be DepUnPackPreD.
619 Loops are preprocessed and logged. */
620 bool pkgOrderList::DepUnPackCrit(DepIterator D
)
622 for (; D
.end() == false; D
++)
624 if (D
.Reverse() == true)
626 /* Reverse depenanices are only interested in conflicts,
627 predepend breakage is ignored here */
628 if (D
->Type
!= pkgCache::Dep::Conflicts
&&
629 D
->Type
!= pkgCache::Dep::Obsoletes
)
632 // Duplication elimination, consider only the current version
633 if (D
.ParentPkg().CurrentVer() != D
.ParentVer())
636 /* For reverse dependencies we wish to check if the
637 dependency is satisifed in the install state. The
638 target package (caller) is going to be in the installed
640 if (CheckDep(D
) == true)
643 if (VisitNode(D
.ParentPkg()) == false)
648 /* Forward critical dependencies MUST be correct before the
649 package can be unpacked. */
650 if (D
->Type
!= pkgCache::Dep::Conflicts
&&
651 D
->Type
!= pkgCache::Dep::DpkgBreaks
&&
652 D
->Type
!= pkgCache::Dep::Obsoletes
&&
653 D
->Type
!= pkgCache::Dep::PreDepends
)
656 /* We wish to check if the dep is okay in the now state of the
657 target package against the install state of this package. */
658 if (CheckDep(D
) == true)
660 /* We want to catch predepends loops with the code below.
661 Conflicts loops that are Dep OK are ignored */
662 if (IsFlag(D
.TargetPkg(),AddPending
) == false ||
663 D
->Type
!= pkgCache::Dep::PreDepends
)
667 // This is the loop detection
668 if (IsFlag(D
.TargetPkg(),Added
) == true ||
669 IsFlag(D
.TargetPkg(),AddPending
) == true)
671 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
676 /* Predepends require a special ordering stage, they must have
677 all dependents installed as well */
678 DepFunc Old
= Primary
;
680 if (D
->Type
== pkgCache::Dep::PreDepends
)
681 Primary
= &pkgOrderList::DepUnPackPreD
;
682 Res
= VisitProvides(D
,true);
691 // OrderList::DepUnPackPreD - Critical UnPacking ordering with depends /*{{{*/
692 // ---------------------------------------------------------------------
693 /* Critical PreDepends (also configure immediate and essential) strives to
694 ensure not only that all conflicts+predepends are met but that this
695 package will be immediately configurable when it is unpacked.
696 Loops are preprocessed and logged. */
697 bool pkgOrderList::DepUnPackPreD(DepIterator D
)
699 if (D
.Reverse() == true)
700 return DepUnPackCrit(D
);
702 for (; D
.end() == false; D
++)
704 if (D
.IsCritical() == false)
707 /* We wish to check if the dep is okay in the now state of the
708 target package against the install state of this package. */
709 if (CheckDep(D
) == true)
711 /* We want to catch predepends loops with the code below.
712 Conflicts loops that are Dep OK are ignored */
713 if (IsFlag(D
.TargetPkg(),AddPending
) == false ||
714 D
->Type
!= pkgCache::Dep::PreDepends
)
718 // This is the loop detection
719 if (IsFlag(D
.TargetPkg(),Added
) == true ||
720 IsFlag(D
.TargetPkg(),AddPending
) == true)
722 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
727 if (VisitProvides(D
,true) == false)
733 // OrderList::DepUnPackPre - Critical Predepends ordering /*{{{*/
734 // ---------------------------------------------------------------------
735 /* Critical PreDepends (also configure immediate and essential) strives to
736 ensure not only that all conflicts+predepends are met but that this
737 package will be immediately configurable when it is unpacked.
739 Loops are preprocessed and logged. All loops will be fatal. */
740 bool pkgOrderList::DepUnPackPre(DepIterator D
)
742 if (D
.Reverse() == true)
745 for (; D
.end() == false; D
++)
747 /* Only consider the PreDepends or Depends. Depends are only
748 considered at the lowest depth or in the case of immediate
750 if (D
->Type
!= pkgCache::Dep::PreDepends
)
752 if (D
->Type
== pkgCache::Dep::Depends
)
754 if (Depth
== 1 && IsFlag(D
.ParentPkg(),Immediate
) == false)
761 /* We wish to check if the dep is okay in the now state of the
762 target package against the install state of this package. */
763 if (CheckDep(D
) == true)
765 /* We want to catch predepends loops with the code below.
766 Conflicts loops that are Dep OK are ignored */
767 if (IsFlag(D
.TargetPkg(),AddPending
) == false)
771 // This is the loop detection
772 if (IsFlag(D
.TargetPkg(),Added
) == true ||
773 IsFlag(D
.TargetPkg(),AddPending
) == true)
775 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
780 if (VisitProvides(D
,true) == false)
786 // OrderList::DepUnPackDep - Reverse dependency considerations /*{{{*/
787 // ---------------------------------------------------------------------
788 /* Reverse dependencies are considered to determine if unpacking this
789 package will break any existing dependencies. If so then those
790 packages are ordered before this one so that they are in the
793 The forwards depends loop is designed to bring the packages dependents
794 close to the package. This helps reduce deconfigure time.
796 Loops are irrelevent to this. */
797 bool pkgOrderList::DepUnPackDep(DepIterator D
)
800 for (; D
.end() == false; D
++)
801 if (D
.IsCritical() == true)
803 if (D
.Reverse() == true)
805 /* Duplication prevention. We consider rev deps only on
806 the current version, a not installed package
808 if (D
.ParentPkg()->CurrentVer
== 0 ||
809 D
.ParentPkg().CurrentVer() != D
.ParentVer())
812 // The dep will not break so it is irrelevent.
813 if (CheckDep(D
) == true)
816 // Skip over missing files
817 if (IsMissing(D
.ParentPkg()) == true)
820 if (VisitNode(D
.ParentPkg()) == false)
825 if (D
->Type
== pkgCache::Dep::Depends
)
826 if (VisitProvides(D
,false) == false)
829 if (D
->Type
== pkgCache::Dep::DpkgBreaks
)
831 if (CheckDep(D
) == true)
834 if (VisitNode(D
.TargetPkg()) == false)
842 // OrderList::DepConfigure - Configuration ordering /*{{{*/
843 // ---------------------------------------------------------------------
844 /* Configuration only ordering orders by the Depends: line only. It
845 orders configuration so that when a package comes to be configured it's
846 dependents are configured.
848 Loops are ingored. Depends loop entry points are chaotic. */
849 bool pkgOrderList::DepConfigure(DepIterator D
)
851 // Never consider reverse configuration dependencies.
852 if (D
.Reverse() == true)
855 for (; D
.end() == false; D
++)
856 if (D
->Type
== pkgCache::Dep::Depends
)
857 if (VisitProvides(D
,false) == false)
862 // OrderList::DepRemove - Removal ordering /*{{{*/
863 // ---------------------------------------------------------------------
864 /* Removal visits all reverse depends. It considers if the dependency
865 of the Now state version to see if it is okay with removing this
866 package. This check should always fail, but is provided for symetery
867 with the other critical handlers.
869 Loops are preprocessed and logged. Removal loops can also be
870 detected in the critical handler. They are characterized by an
871 old version of A depending on B but the new version of A conflicting
872 with B, thus either A or B must break to install. */
873 bool pkgOrderList::DepRemove(DepIterator D
)
875 if (D
.Reverse() == false)
877 for (; D
.end() == false; D
++)
878 if (D
->Type
== pkgCache::Dep::Depends
|| D
->Type
== pkgCache::Dep::PreDepends
)
880 // Duplication elimination, consider the current version only
881 if (D
.ParentPkg().CurrentVer() != D
.ParentVer())
884 /* We wish to see if the dep on the parent package is okay
885 in the removed (install) state of the target pkg. */
886 bool tryFixDeps
= false;
887 if (CheckDep(D
) == true)
889 // We want to catch loops with the code below.
890 if (IsFlag(D
.ParentPkg(),AddPending
) == false)
896 // This is the loop detection
897 if (IsFlag(D
.ParentPkg(),Added
) == true ||
898 IsFlag(D
.ParentPkg(),AddPending
) == true)
900 if (IsFlag(D
.ParentPkg(),AddPending
) == true)
905 if (tryFixDeps
== true)
907 for (pkgCache::DepIterator F
= D
.ParentPkg().CurrentVer().DependsList();
908 F
.end() == false; ++F
)
910 if (F
->Type
!= pkgCache::Dep::Depends
&& F
->Type
!= pkgCache::Dep::PreDepends
)
912 // Check the Providers
913 if (F
.TargetPkg()->ProvidesList
!= 0)
915 pkgCache::PrvIterator Prov
= F
.TargetPkg().ProvidesList();
916 for (; Prov
.end() == false; ++Prov
)
918 pkgCache::PkgIterator
const P
= Prov
.OwnerPkg();
919 if (IsFlag(P
, InList
) == true &&
920 IsFlag(P
, AddPending
) == true &&
921 IsFlag(P
, Added
) == false &&
922 Cache
[P
].InstallVer
== 0)
925 if (Prov
.end() == false)
926 for (pkgCache::PrvIterator Prv
= F
.TargetPkg().ProvidesList();
927 Prv
.end() == false; ++Prv
)
929 pkgCache::PkgIterator
const P
= Prv
.OwnerPkg();
930 if (IsFlag(P
, InList
) == true &&
931 IsFlag(P
, AddPending
) == false &&
932 Cache
[P
].InstallVer
!= 0 &&
933 VisitNode(P
) == true)
940 if (tryFixDeps
== false)
944 // Check for Or groups
945 if ((F
->CompareOp
& pkgCache::Dep::Or
) != pkgCache::Dep::Or
)
947 // Lets see if the package is part of the Or group
948 pkgCache::DepIterator S
= F
;
949 for (; S
.end() == false; ++S
)
951 if (S
.TargetPkg() == D
.TargetPkg())
953 if ((S
->CompareOp
& pkgCache::Dep::Or
) != pkgCache::Dep::Or
||
954 CheckDep(S
)) // Or group is satisfied by another package
955 for (;S
.end() == false; ++S
);
959 // skip to the end of the or group
960 for (;S
.end() == false && (S
->CompareOp
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
; ++S
);
962 // The soon to be removed is part of the Or group
963 // start again in the or group and find something which will serve as replacement
964 for (; F
.end() == false && F
!= S
; ++F
)
966 if (IsFlag(F
.TargetPkg(), InList
) == true &&
967 IsFlag(F
.TargetPkg(), AddPending
) == false &&
968 Cache
[F
.TargetPkg()].InstallVer
!= 0 &&
969 VisitNode(F
.TargetPkg()) == true)
971 Flag(F
.TargetPkg(), Immediate
);
975 else if (F
.TargetPkg()->ProvidesList
!= 0)
977 pkgCache::PrvIterator Prv
= F
.TargetPkg().ProvidesList();
978 for (; Prv
.end() == false; ++Prv
)
980 if (IsFlag(Prv
.OwnerPkg(), InList
) == true &&
981 IsFlag(Prv
.OwnerPkg(), AddPending
) == false &&
982 Cache
[Prv
.OwnerPkg()].InstallVer
!= 0 &&
983 VisitNode(Prv
.OwnerPkg()) == true)
985 Flag(Prv
.OwnerPkg(), Immediate
);
990 if (Prv
.end() == false)
994 if (tryFixDeps
== false)
999 // Skip over missing files
1000 if (IsMissing(D
.ParentPkg()) == true)
1003 if (VisitNode(D
.ParentPkg()) == false)
1010 // OrderList::AddLoop - Add a loop to the loop list /*{{{*/
1011 // ---------------------------------------------------------------------
1012 /* We record the loops. This is a relic since loop breaking is done
1013 genericaly as part of the safety routines. */
1014 bool pkgOrderList::AddLoop(DepIterator D
)
1016 if (LoopCount
< 0 || LoopCount
>= 20)
1022 if (Loops
[LoopCount
- 1].ParentPkg() == D
.ParentPkg() ||
1023 Loops
[LoopCount
- 1].TargetPkg() == D
.ParentPkg())
1027 Loops
[LoopCount
++] = D
;
1029 // Mark the packages as being part of a loop.
1030 Flag(D
.TargetPkg(),Loop
);
1031 Flag(D
.ParentPkg(),Loop
);
1035 // OrderList::WipeFlags - Unset the given flags from all packages /*{{{*/
1036 // ---------------------------------------------------------------------
1038 void pkgOrderList::WipeFlags(unsigned long F
)
1040 unsigned long Size
= Cache
.Head().PackageCount
;
1041 for (unsigned long I
= 0; I
!= Size
; I
++)
1045 // OrderList::CheckDep - Check a dependency for truth /*{{{*/
1046 // ---------------------------------------------------------------------
1047 /* This performs a complete analysis of the dependency wrt to the
1048 current add list. It returns true if after all events are
1049 performed it is still true. This sort of routine can be approximated
1050 by examining the DepCache, however in convoluted cases of provides
1051 this fails to produce a suitable result. */
1052 bool pkgOrderList::CheckDep(DepIterator D
)
1054 SPtrArray
<Version
*> List
= D
.AllTargets();
1056 for (Version
**I
= List
; *I
!= 0; I
++)
1058 VerIterator
Ver(Cache
,*I
);
1059 PkgIterator Pkg
= Ver
.ParentPkg();
1061 /* The meaning of Added and AddPending is subtle. AddPending is
1062 an indication that the package is looping. Because of the
1063 way ordering works Added means the package will be unpacked
1064 before this one and AddPending means after. It is therefore
1065 correct to ignore AddPending in all cases, but that exposes
1066 reverse-ordering loops which should be ignored. */
1067 if (IsFlag(Pkg
,Added
) == true ||
1068 (IsFlag(Pkg
,AddPending
) == true && D
.Reverse() == true))
1070 if (Cache
[Pkg
].InstallVer
!= *I
)
1074 if ((Version
*)Pkg
.CurrentVer() != *I
||
1075 Pkg
.State() != PkgIterator::NeedsNothing
)
1078 /* Conflicts requires that all versions are not present, depends
1080 if (D
->Type
!= pkgCache::Dep::Conflicts
&&
1081 D
->Type
!= pkgCache::Dep::DpkgBreaks
&&
1082 D
->Type
!= pkgCache::Dep::Obsoletes
)
1084 /* Try to find something that does not have the after flag set
1085 if at all possible */
1086 if (IsFlag(Pkg
,After
) == true)
1096 if (IsFlag(Pkg
,After
) == true)
1097 Flag(D
.ParentPkg(),After
);
1103 // We found a hit, but it had the after flag set
1104 if (Hit
== true && D
->Type
== pkgCache::Dep::PreDepends
)
1106 Flag(D
.ParentPkg(),After
);
1110 /* Conflicts requires that all versions are not present, depends
1112 if (D
->Type
== pkgCache::Dep::Conflicts
||
1113 D
->Type
== pkgCache::Dep::Obsoletes
)