]>
git.saurik.com Git - apt.git/blob - apt-pkg/orderlist.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: orderlist.cc,v 1.14 2001/05/07 05:49:43 jgg Exp $
4 /* ######################################################################
6 Order List - Represents and Manipulates an ordered list of packages.
8 A list of packages can be ordered by a number of conflicting criteria
9 each given a specific priority. Each package also has a set of flags
10 indicating some useful things about it that are derived in the
11 course of sorting. The pkgPackageManager class uses this class for
12 all of it's installation ordering needs.
14 This is a modified version of Manoj's Routine B. It consists of four
15 independent ordering algorithms that can be applied at for different
16 points in the ordering. By appling progressivly fewer ordering
17 operations it is possible to give each consideration it's own
18 priority and create an order that satisfies the lowest applicable
21 The rules for unpacking ordering are:
22 1) Unpacking ignores Depends: on all packages
23 2) Unpacking requires Conflicts: on -ALL- packages to be satisfied
24 3) Unpacking requires PreDepends: on this package only to be satisfied
25 4) Removing requires that no packages depend on the package to be
28 And the rule for configuration ordering is:
29 1) Configuring requires that the Depends: of the package be satisfied
30 Conflicts+PreDepends are ignored because unpacking says they are
31 already correct [exageration, it does check but we need not be
34 And some features that are valuable for unpacking ordering.
35 f1) Unpacking a new package should advoid breaking dependencies of
37 f2) Removal should not require a force, corrolory of f1
38 f3) Unpacking should order by depends rather than fall back to random
41 Each of the features can be enabled in the sorting routine at an
42 arbitrary priority to give quite abit of control over the final unpacking
45 The rules listed above may never be violated and are called Critical.
46 When a critical rule is violated then a loop condition is recorded
47 and will have to be delt with in the caller.
49 The ordering keeps two lists, the main list and the 'After List'. The
50 purpose of the after list is to allow packages to be delayed. This is done
51 by setting the after flag on the package. Any package which requires this
52 package to be ordered before will inherit the after flag and so on. This
53 is used for CD swap ordering where all packages on a second CD have the
54 after flag set. This forces them and all their dependents to be ordered
57 There are complications in this algorithm when presented with cycles.
58 For all known practical cases it works, all cases where it doesn't work
59 is fixable by tweaking the package descriptions. However, it should be
60 possible to impove this further to make some better choices when
61 presented with cycles.
63 ##################################################################### */
65 // Include Files /*{{{*/
68 #include <apt-pkg/orderlist.h>
69 #include <apt-pkg/depcache.h>
70 #include <apt-pkg/error.h>
71 #include <apt-pkg/configuration.h>
72 #include <apt-pkg/cacheiterators.h>
73 #include <apt-pkg/pkgcache.h>
82 pkgOrderList
*pkgOrderList::Me
= 0;
84 // OrderList::pkgOrderList - Constructor /*{{{*/
85 // ---------------------------------------------------------------------
87 pkgOrderList::pkgOrderList(pkgDepCache
*pCache
) : d(NULL
), Cache(*pCache
),
88 Primary(NULL
), Secondary(NULL
),
89 RevDepends(NULL
), Remove(NULL
),
90 AfterEnd(NULL
), FileList(NULL
),
91 LoopCount(-1), Depth(0)
93 Debug
= _config
->FindB("Debug::pkgOrderList",false);
95 /* Construct the arrays, egcs 1.0.1 bug requires the package count
97 unsigned long Size
= Cache
.Head().PackageCount
;
98 Flags
= new unsigned short[Size
];
99 End
= List
= new Package
*[Size
];
100 memset(Flags
,0,sizeof(*Flags
)*Size
);
103 // OrderList::~pkgOrderList - Destructor /*{{{*/
104 // ---------------------------------------------------------------------
106 pkgOrderList::~pkgOrderList()
112 // OrderList::IsMissing - Check if a file is missing /*{{{*/
113 // ---------------------------------------------------------------------
115 bool pkgOrderList::IsMissing(PkgIterator Pkg
)
117 // Skip packages to erase
118 if (Cache
[Pkg
].Delete() == true)
121 // Skip Packages that need configure only.
122 if ((Pkg
.State() == pkgCache::PkgIterator::NeedsConfigure
||
123 Pkg
.State() == pkgCache::PkgIterator::NeedsNothing
) &&
124 Cache
[Pkg
].Keep() == true)
130 if (FileList
[Pkg
->ID
].empty() == false)
136 // OrderList::DoRun - Does an order run /*{{{*/
137 // ---------------------------------------------------------------------
138 /* The caller is expeted to have setup the desired probe state */
139 bool pkgOrderList::DoRun()
142 unsigned long Size
= Cache
.Head().PackageCount
;
143 std::unique_ptr
<Package
*[]> NList(new Package
*[Size
]);
144 std::unique_ptr
<Package
*[]> AfterList(new Package
*[Size
]);
145 AfterEnd
= AfterList
.get();
148 WipeFlags(Added
| AddPending
| Loop
| InList
);
150 for (iterator I
= List
; I
!= End
; ++I
)
153 // Rebuild the main list into the temp list.
154 iterator OldEnd
= End
;
156 for (iterator I
= List
; I
!= OldEnd
; ++I
)
157 if (VisitNode(PkgIterator(Cache
,*I
), "DoRun") == false)
163 // Copy the after list to the end of the main list
164 for (Package
**I
= AfterList
.get(); I
!= AfterEnd
; I
++)
167 // Swap the main list to the new list
169 List
= NList
.release();
173 // OrderList::OrderCritical - Perform critical unpacking ordering /*{{{*/
174 // ---------------------------------------------------------------------
175 /* This performs predepends and immediate configuration ordering only.
176 This is termed critical unpacking ordering. Any loops that form are
177 fatal and indicate that the packages cannot be installed. */
178 bool pkgOrderList::OrderCritical()
182 Primary
= &pkgOrderList::DepUnPackPreD
;
190 qsort(List
,End
- List
,sizeof(*List
),&OrderCompareB
);
192 if (DoRun() == false)
196 return _error
->Error("Fatal, predepends looping detected");
200 clog
<< "** Critical Unpack ordering done" << endl
;
202 for (iterator I
= List
; I
!= End
; ++I
)
204 PkgIterator
P(Cache
,*I
);
205 if (IsNow(P
) == true)
206 clog
<< " " << P
.FullName() << ' ' << IsMissing(P
) << ',' << IsFlag(P
,After
) << endl
;
213 // OrderList::OrderUnpack - Perform complete unpacking ordering /*{{{*/
214 // ---------------------------------------------------------------------
215 /* This performs complete unpacking ordering and creates an order that is
216 suitable for unpacking */
217 bool pkgOrderList::OrderUnpack(string
*FileList
)
219 this->FileList
= FileList
;
221 // Setup the after flags
226 // Set the inlist flag
227 for (iterator I
= List
; I
!= End
; ++I
)
229 PkgIterator
P(Cache
,*I
);
230 if (IsMissing(P
) == true && IsNow(P
) == true)
235 Primary
= &pkgOrderList::DepUnPackCrit
;
236 Secondary
= &pkgOrderList::DepConfigure
;
237 RevDepends
= &pkgOrderList::DepUnPackDep
;
238 Remove
= &pkgOrderList::DepRemove
;
243 qsort(List
,End
- List
,sizeof(*List
),&OrderCompareA
);
246 clog
<< "** Pass A" << endl
;
247 if (DoRun() == false)
251 clog
<< "** Pass B" << endl
;
253 if (DoRun() == false)
257 clog
<< "** Pass C" << endl
;
260 Remove
= 0; // Otherwise the libreadline remove problem occurs
261 if (DoRun() == false)
265 clog
<< "** Pass D" << endl
;
267 Primary
= &pkgOrderList::DepUnPackPre
;
268 if (DoRun() == false)
273 clog
<< "** Unpack ordering done" << endl
;
275 for (iterator I
= List
; I
!= End
; ++I
)
277 PkgIterator
P(Cache
,*I
);
278 if (IsNow(P
) == true)
279 clog
<< " " << P
.FullName() << ' ' << IsMissing(P
) << ',' << IsFlag(P
,After
) << endl
;
286 // OrderList::OrderConfigure - Perform configuration ordering /*{{{*/
287 // ---------------------------------------------------------------------
288 /* This orders by depends only and produces an order which is suitable
290 bool pkgOrderList::OrderConfigure()
293 Primary
= &pkgOrderList::DepConfigure
;
301 // OrderList::Score - Score the package for sorting /*{{{*/
302 // ---------------------------------------------------------------------
303 /* Higher scores order earlier */
304 int pkgOrderList::Score(PkgIterator Pkg
)
306 // Removals should be done after we dealt with essentials
307 static int const ScoreDelete
= _config
->FindI("OrderList::Score::Delete", 100);
308 if (Cache
[Pkg
].Delete() == true)
311 // This should never happen..
312 if (Cache
[Pkg
].InstVerIter(Cache
).end() == true)
315 static int const ScoreEssential
= _config
->FindI("OrderList::Score::Essential", 200);
316 static int const ScoreImmediate
= _config
->FindI("OrderList::Score::Immediate", 10);
317 static int const ScorePreDepends
= _config
->FindI("OrderList::Score::PreDepends", 50);
320 if ((Pkg
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
321 Score
+= ScoreEssential
;
323 if (IsFlag(Pkg
,Immediate
) == true)
324 Score
+= ScoreImmediate
;
326 for (DepIterator D
= Cache
[Pkg
].InstVerIter(Cache
).DependsList();
327 D
.end() == false; ++D
)
328 if (D
->Type
== pkgCache::Dep::PreDepends
)
330 Score
+= ScorePreDepends
;
334 // Important Required Standard Optional Extra
335 if (Cache
[Pkg
].InstVerIter(Cache
)->Priority
<= 5)
337 signed short PrioMap
[] = {0,5,4,3,1,0};
338 Score
+= PrioMap
[Cache
[Pkg
].InstVerIter(Cache
)->Priority
];
343 // OrderList::FileCmp - Compare by package file /*{{{*/
344 // ---------------------------------------------------------------------
345 /* This compares by the package file that the install version is in. */
346 int pkgOrderList::FileCmp(PkgIterator A
,PkgIterator B
)
348 if (Cache
[A
].Delete() == true && Cache
[B
].Delete() == true)
350 if (Cache
[A
].Delete() == true)
352 if (Cache
[B
].Delete() == true)
355 if (Cache
[A
].InstVerIter(Cache
).FileList().end() == true)
357 if (Cache
[B
].InstVerIter(Cache
).FileList().end() == true)
360 pkgCache::PackageFile
*FA
= Cache
[A
].InstVerIter(Cache
).FileList().File();
361 pkgCache::PackageFile
*FB
= Cache
[B
].InstVerIter(Cache
).FileList().File();
369 // BoolCompare - Comparison function for two booleans /*{{{*/
370 // ---------------------------------------------------------------------
372 static int BoolCompare(bool A
,bool B
)
381 // OrderList::OrderCompareA - Order the installation by op /*{{{*/
382 // ---------------------------------------------------------------------
383 /* This provides a first-pass sort of the list and gives a decent starting
384 point for further complete ordering. It is used by OrderUnpack only */
385 int pkgOrderList::OrderCompareA(const void *a
, const void *b
)
387 PkgIterator
A(Me
->Cache
,*(Package
**)a
);
388 PkgIterator
B(Me
->Cache
,*(Package
**)b
);
390 // We order packages with a set state toward the front
392 if ((Res
= BoolCompare(Me
->IsNow(A
),Me
->IsNow(B
))) != 0)
395 // We order missing files to toward the end
396 /* if (Me->FileList != 0)
398 if ((Res = BoolCompare(Me->IsMissing(A),
399 Me->IsMissing(B))) != 0)
403 if (A
.State() != pkgCache::PkgIterator::NeedsNothing
&&
404 B
.State() == pkgCache::PkgIterator::NeedsNothing
)
407 if (A
.State() == pkgCache::PkgIterator::NeedsNothing
&&
408 B
.State() != pkgCache::PkgIterator::NeedsNothing
)
411 int ScoreA
= Me
->Score(A
);
412 int ScoreB
= Me
->Score(B
);
420 return strcmp(A
.Name(),B
.Name());
423 // OrderList::OrderCompareB - Order the installation by source /*{{{*/
424 // ---------------------------------------------------------------------
425 /* This orders by installation source. This is useful to handle
426 inter-source breaks */
427 int pkgOrderList::OrderCompareB(const void *a
, const void *b
)
429 PkgIterator
A(Me
->Cache
,*(Package
**)a
);
430 PkgIterator
B(Me
->Cache
,*(Package
**)b
);
432 if (A
.State() != pkgCache::PkgIterator::NeedsNothing
&&
433 B
.State() == pkgCache::PkgIterator::NeedsNothing
)
436 if (A
.State() == pkgCache::PkgIterator::NeedsNothing
&&
437 B
.State() != pkgCache::PkgIterator::NeedsNothing
)
440 int F
= Me
->FileCmp(A
,B
);
448 int ScoreA
= Me
->Score(A
);
449 int ScoreB
= Me
->Score(B
);
457 return strcmp(A
.Name(),B
.Name());
460 // OrderList::VisitDeps - Visit forward install dependencies /*{{{*/
461 // ---------------------------------------------------------------------
462 /* This calls the dependency function for the normal forwards dependencies
464 bool pkgOrderList::VisitDeps(DepFunc F
,PkgIterator Pkg
)
466 if (F
== 0 || Pkg
.end() == true || Cache
[Pkg
].InstallVer
== 0)
469 return (this->*F
)(Cache
[Pkg
].InstVerIter(Cache
).DependsList());
472 // OrderList::VisitRDeps - Visit reverse dependencies /*{{{*/
473 // ---------------------------------------------------------------------
474 /* This calls the dependency function for all of the normal reverse depends
476 bool pkgOrderList::VisitRDeps(DepFunc F
,PkgIterator Pkg
)
478 if (F
== 0 || Pkg
.end() == true)
481 return (this->*F
)(Pkg
.RevDependsList());
484 // OrderList::VisitRProvides - Visit provides reverse dependencies /*{{{*/
485 // ---------------------------------------------------------------------
486 /* This calls the dependency function for all reverse dependencies
487 generated by the provides line on the package. */
488 bool pkgOrderList::VisitRProvides(DepFunc F
,VerIterator Ver
)
490 if (F
== 0 || Ver
.end() == true)
494 for (PrvIterator P
= Ver
.ProvidesList(); P
.end() == false; ++P
)
495 Res
&= (this->*F
)(P
.ParentPkg().RevDependsList());
499 // OrderList::VisitProvides - Visit all of the providing packages /*{{{*/
500 // ---------------------------------------------------------------------
501 /* This routine calls visit on all providing packages.
503 If the dependency is negative it first visits packages which are
504 intended to be removed and after that all other packages.
505 It does so to avoid situations in which this package is used to
506 satisfy a (or-group/provides) dependency of another package which
507 could have been satisfied also by upgrading another package -
508 otherwise we have more broken packages dpkg needs to auto-
509 deconfigure and in very complicated situations it even decides
511 bool pkgOrderList::VisitProvides(DepIterator D
,bool Critical
)
513 std::unique_ptr
<Version
*[]> List(D
.AllTargets());
514 for (Version
**I
= List
.get(); *I
!= 0; ++I
)
516 VerIterator
Ver(Cache
,*I
);
517 PkgIterator Pkg
= Ver
.ParentPkg();
519 if (D
.IsNegative() == true && Cache
[Pkg
].Delete() == false)
522 if (Cache
[Pkg
].Keep() == true && Pkg
.State() == PkgIterator::NeedsNothing
)
525 if (D
.IsNegative() == false &&
526 Cache
[Pkg
].InstallVer
!= *I
)
529 if (D
.IsNegative() == true &&
530 (Version
*)Pkg
.CurrentVer() != *I
)
533 // Skip over missing files
534 if (Critical
== false && IsMissing(D
.ParentPkg()) == true)
537 if (VisitNode(Pkg
, "Provides-1") == false)
540 if (D
.IsNegative() == false)
542 for (Version
**I
= List
.get(); *I
!= 0; ++I
)
544 VerIterator
Ver(Cache
,*I
);
545 PkgIterator Pkg
= Ver
.ParentPkg();
547 if (Cache
[Pkg
].Delete() == true)
550 if (Cache
[Pkg
].Keep() == true && Pkg
.State() == PkgIterator::NeedsNothing
)
553 if ((Version
*)Pkg
.CurrentVer() != *I
)
556 // Skip over missing files
557 if (Critical
== false && IsMissing(D
.ParentPkg()) == true)
560 if (VisitNode(Pkg
, "Provides-2") == false)
567 // OrderList::VisitNode - Recursive ordering director /*{{{*/
568 // ---------------------------------------------------------------------
569 /* This is the core ordering routine. It calls the set dependency
570 consideration functions which then potentialy call this again. Finite
571 depth is achieved through the colouring mechinism. */
572 bool pkgOrderList::VisitNode(PkgIterator Pkg
, char const* from
)
574 // Looping or irrelevant.
575 // This should probably trancend not installed packages
576 if (Pkg
.end() == true || IsFlag(Pkg
,Added
) == true ||
577 IsFlag(Pkg
,AddPending
) == true || IsFlag(Pkg
,InList
) == false)
582 for (int j
= 0; j
!= Depth
; j
++) clog
<< ' ';
583 clog
<< "Visit " << Pkg
.FullName() << " from " << from
<< endl
;
589 Flag(Pkg
,AddPending
);
591 DepFunc Old
= Primary
;
593 // Perform immedate configuration of the package if so flagged.
594 if (IsFlag(Pkg
,Immediate
) == true && Primary
!= &pkgOrderList::DepUnPackPre
)
595 Primary
= &pkgOrderList::DepUnPackPreD
;
597 if (IsNow(Pkg
) == true)
600 if (Cache
[Pkg
].Delete() == false)
603 Res
&= Res
&& VisitDeps(Primary
,Pkg
);
604 Res
&= Res
&& VisitRDeps(Primary
,Pkg
);
605 Res
&= Res
&& VisitRProvides(Primary
,Pkg
.CurrentVer());
606 Res
&= Res
&& VisitRProvides(Primary
,Cache
[Pkg
].InstVerIter(Cache
));
609 Res
&= Res
&& VisitRDeps(RevDepends
,Pkg
);
610 Res
&= Res
&& VisitRProvides(RevDepends
,Pkg
.CurrentVer());
611 Res
&= Res
&& VisitRProvides(RevDepends
,Cache
[Pkg
].InstVerIter(Cache
));
614 Res
&= Res
&& VisitDeps(Secondary
,Pkg
);
615 Res
&= Res
&& VisitRDeps(Secondary
,Pkg
);
616 Res
&= Res
&& VisitRProvides(Secondary
,Pkg
.CurrentVer());
617 Res
&= Res
&& VisitRProvides(Secondary
,Cache
[Pkg
].InstVerIter(Cache
));
622 Res
&= Res
&& VisitRDeps(Remove
,Pkg
);
623 Res
&= Res
&& VisitRProvides(Remove
,Pkg
.CurrentVer());
627 if (IsFlag(Pkg
,Added
) == false)
629 Flag(Pkg
,Added
,Added
| AddPending
);
630 if (IsFlag(Pkg
,After
) == true)
641 for (int j
= 0; j
!= Depth
; j
++) clog
<< ' ';
642 clog
<< "Leave " << Pkg
.FullName() << ' ' << IsFlag(Pkg
,Added
) << ',' << IsFlag(Pkg
,AddPending
) << endl
;
648 // OrderList::DepUnPackCrit - Critical UnPacking ordering /*{{{*/
649 // ---------------------------------------------------------------------
650 /* Critical unpacking ordering strives to satisfy Conflicts: and
651 PreDepends: only. When a prdepends is encountered the Primary
652 DepFunc is changed to be DepUnPackPreD.
654 Loops are preprocessed and logged. */
655 bool pkgOrderList::DepUnPackCrit(DepIterator D
)
657 for (; D
.end() == false; ++D
)
659 if (D
.Reverse() == true)
661 /* Reverse depenanices are only interested in conflicts,
662 predepend breakage is ignored here */
663 if (D
->Type
!= pkgCache::Dep::Conflicts
&&
664 D
->Type
!= pkgCache::Dep::Obsoletes
)
667 // Duplication elimination, consider only the current version
668 if (D
.ParentPkg().CurrentVer() != D
.ParentVer())
671 /* For reverse dependencies we wish to check if the
672 dependency is satisifed in the install state. The
673 target package (caller) is going to be in the installed
675 if (CheckDep(D
) == true)
678 if (VisitNode(D
.ParentPkg(), "UnPackCrit") == false)
683 /* Forward critical dependencies MUST be correct before the
684 package can be unpacked. */
685 if (D
.IsNegative() == false &&
686 D
->Type
!= pkgCache::Dep::PreDepends
)
689 /* We wish to check if the dep is okay in the now state of the
690 target package against the install state of this package. */
691 if (CheckDep(D
) == true)
693 /* We want to catch predepends loops with the code below.
694 Conflicts loops that are Dep OK are ignored */
695 if (IsFlag(D
.TargetPkg(),AddPending
) == false ||
696 D
->Type
!= pkgCache::Dep::PreDepends
)
700 // This is the loop detection
701 if (IsFlag(D
.TargetPkg(),Added
) == true ||
702 IsFlag(D
.TargetPkg(),AddPending
) == true)
704 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
709 /* Predepends require a special ordering stage, they must have
710 all dependents installed as well */
711 DepFunc Old
= Primary
;
713 if (D
->Type
== pkgCache::Dep::PreDepends
)
714 Primary
= &pkgOrderList::DepUnPackPreD
;
715 Res
= VisitProvides(D
,true);
724 // OrderList::DepUnPackPreD - Critical UnPacking ordering with depends /*{{{*/
725 // ---------------------------------------------------------------------
726 /* Critical PreDepends (also configure immediate and essential) strives to
727 ensure not only that all conflicts+predepends are met but that this
728 package will be immediately configurable when it is unpacked.
729 Loops are preprocessed and logged. */
730 bool pkgOrderList::DepUnPackPreD(DepIterator D
)
732 if (D
.Reverse() == true)
733 return DepUnPackCrit(D
);
735 for (; D
.end() == false; ++D
)
737 if (D
.IsCritical() == false)
740 /* We wish to check if the dep is okay in the now state of the
741 target package against the install state of this package. */
742 if (CheckDep(D
) == true)
744 /* We want to catch predepends loops with the code below.
745 Conflicts loops that are Dep OK are ignored */
746 if (IsFlag(D
.TargetPkg(),AddPending
) == false ||
747 D
->Type
!= pkgCache::Dep::PreDepends
)
751 // This is the loop detection
752 if (IsFlag(D
.TargetPkg(),Added
) == true ||
753 IsFlag(D
.TargetPkg(),AddPending
) == true)
755 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
760 if (VisitProvides(D
,true) == false)
766 // OrderList::DepUnPackPre - Critical Predepends ordering /*{{{*/
767 // ---------------------------------------------------------------------
768 /* Critical PreDepends (also configure immediate and essential) strives to
769 ensure not only that all conflicts+predepends are met but that this
770 package will be immediately configurable when it is unpacked.
772 Loops are preprocessed and logged. All loops will be fatal. */
773 bool pkgOrderList::DepUnPackPre(DepIterator D
)
775 if (D
.Reverse() == true)
778 for (; D
.end() == false; ++D
)
780 /* Only consider the PreDepends or Depends. Depends are only
781 considered at the lowest depth or in the case of immediate
783 if (D
->Type
!= pkgCache::Dep::PreDepends
)
785 if (D
->Type
== pkgCache::Dep::Depends
)
787 if (Depth
== 1 && IsFlag(D
.ParentPkg(),Immediate
) == false)
794 /* We wish to check if the dep is okay in the now state of the
795 target package against the install state of this package. */
796 if (CheckDep(D
) == true)
798 /* We want to catch predepends loops with the code below.
799 Conflicts loops that are Dep OK are ignored */
800 if (IsFlag(D
.TargetPkg(),AddPending
) == false)
804 // This is the loop detection
805 if (IsFlag(D
.TargetPkg(),Added
) == true ||
806 IsFlag(D
.TargetPkg(),AddPending
) == true)
808 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
813 if (VisitProvides(D
,true) == false)
819 // OrderList::DepUnPackDep - Reverse dependency considerations /*{{{*/
820 // ---------------------------------------------------------------------
821 /* Reverse dependencies are considered to determine if unpacking this
822 package will break any existing dependencies. If so then those
823 packages are ordered before this one so that they are in the
826 The forwards depends loop is designed to bring the packages dependents
827 close to the package. This helps reduce deconfigure time.
829 Loops are irrelevant to this. */
830 bool pkgOrderList::DepUnPackDep(DepIterator D
)
833 for (; D
.end() == false; ++D
)
834 if (D
.IsCritical() == true)
836 if (D
.Reverse() == true)
838 /* Duplication prevention. We consider rev deps only on
839 the current version, a not installed package
841 if (D
.ParentPkg()->CurrentVer
== 0 ||
842 D
.ParentPkg().CurrentVer() != D
.ParentVer())
845 // The dep will not break so it is irrelevant.
846 if (CheckDep(D
) == true)
849 // Skip over missing files
850 if (IsMissing(D
.ParentPkg()) == true)
853 if (VisitNode(D
.ParentPkg(), "UnPackDep-Parent") == false)
858 if (D
->Type
== pkgCache::Dep::Depends
)
859 if (VisitProvides(D
,false) == false)
862 if (D
->Type
== pkgCache::Dep::DpkgBreaks
)
864 if (CheckDep(D
) == true)
867 if (VisitNode(D
.TargetPkg(), "UnPackDep-Target") == false)
875 // OrderList::DepConfigure - Configuration ordering /*{{{*/
876 // ---------------------------------------------------------------------
877 /* Configuration only ordering orders by the Depends: line only. It
878 orders configuration so that when a package comes to be configured it's
879 dependents are configured.
881 Loops are ingored. Depends loop entry points are chaotic. */
882 bool pkgOrderList::DepConfigure(DepIterator D
)
884 // Never consider reverse configuration dependencies.
885 if (D
.Reverse() == true)
888 for (; D
.end() == false; ++D
)
889 if (D
->Type
== pkgCache::Dep::Depends
)
890 if (VisitProvides(D
,false) == false)
895 // OrderList::DepRemove - Removal ordering /*{{{*/
896 // ---------------------------------------------------------------------
897 /* Checks all given dependencies if they are broken by the remove of a
898 package and if so fix it by visiting another provider or or-group
899 member to ensure that the dependee keeps working which is especially
900 important for Immediate packages like e.g. those depending on an
901 awk implementation. If the dependency can't be fixed with another
902 package this means an upgrade of the package will solve the problem. */
903 bool pkgOrderList::DepRemove(DepIterator Broken
)
905 if (Broken
.Reverse() == false)
908 for (; Broken
.end() == false; ++Broken
)
910 if (Broken
->Type
!= pkgCache::Dep::Depends
&&
911 Broken
->Type
!= pkgCache::Dep::PreDepends
)
914 PkgIterator BrokenPkg
= Broken
.ParentPkg();
915 // uninstalled packages can't break via a remove
916 if (BrokenPkg
->CurrentVer
== 0)
919 // if its already added, we can't do anything useful
920 if (IsFlag(BrokenPkg
, AddPending
) == true || IsFlag(BrokenPkg
, Added
) == true)
923 // if the dependee is going to be removed, visit it now
924 if (Cache
[BrokenPkg
].Delete() == true)
925 return VisitNode(BrokenPkg
, "Remove-Dependee");
927 // The package stays around, so find out how this is possible
928 for (DepIterator D
= BrokenPkg
.CurrentVer().DependsList(); D
.end() == false;)
930 // only important or-groups need fixing
931 if (D
->Type
!= pkgCache::Dep::Depends
&&
932 D
->Type
!= pkgCache::Dep::PreDepends
)
938 // Start is the beginning of the or-group, D is the first one after or
939 DepIterator Start
= D
;
940 bool foundBroken
= false;
941 for (bool LastOR
= true; D
.end() == false && LastOR
== true; ++D
)
943 LastOR
= (D
->CompareOp
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
;
948 // this or-group isn't the broken one: keep searching
949 if (foundBroken
== false)
952 // iterate over all members of the or-group searching for a ready replacement
953 bool readyReplacement
= false;
954 for (DepIterator OrMember
= Start
; OrMember
!= D
&& readyReplacement
== false; ++OrMember
)
956 Version
** Replacements
= OrMember
.AllTargets();
957 for (Version
**R
= Replacements
; *R
!= 0; ++R
)
959 VerIterator
Ver(Cache
,*R
);
960 // only currently installed packages can be a replacement
961 PkgIterator RPkg
= Ver
.ParentPkg();
962 if (RPkg
.CurrentVer() != Ver
)
965 // packages going to be removed can't be a replacement
966 if (Cache
[RPkg
].Delete() == true)
969 readyReplacement
= true;
972 delete[] Replacements
;
975 // something else is ready to take over, do nothing
976 if (readyReplacement
== true)
979 // see if we can visit a replacement
980 bool visitReplacement
= false;
981 for (DepIterator OrMember
= Start
; OrMember
!= D
&& visitReplacement
== false; ++OrMember
)
983 Version
** Replacements
= OrMember
.AllTargets();
984 for (Version
**R
= Replacements
; *R
!= 0; ++R
)
986 VerIterator
Ver(Cache
,*R
);
987 // consider only versions we plan to install
988 PkgIterator RPkg
= Ver
.ParentPkg();
989 if (Cache
[RPkg
].Install() == false || Cache
[RPkg
].InstallVer
!= Ver
)
992 // loops are not going to help us, so don't create them
993 if (IsFlag(RPkg
, AddPending
) == true)
996 if (IsMissing(RPkg
) == true)
999 visitReplacement
= true;
1000 if (IsFlag(BrokenPkg
, Immediate
) == false)
1002 if (VisitNode(RPkg
, "Remove-Rep") == true)
1007 Flag(RPkg
, Immediate
);
1008 if (VisitNode(RPkg
, "Remove-ImmRep") == true)
1011 visitReplacement
= false;
1013 delete[] Replacements
;
1015 if (visitReplacement
== true)
1018 // the broken package in current version can't be fixed, so install new version
1019 if (IsMissing(BrokenPkg
) == true)
1022 if (VisitNode(BrokenPkg
, "Remove-Upgrade") == false)
1030 // OrderList::AddLoop - Add a loop to the loop list /*{{{*/
1031 // ---------------------------------------------------------------------
1032 /* We record the loops. This is a relic since loop breaking is done
1033 genericaly as part of the safety routines. */
1034 bool pkgOrderList::AddLoop(DepIterator D
)
1036 if (LoopCount
< 0 || LoopCount
>= 20)
1042 if (Loops
[LoopCount
- 1].ParentPkg() == D
.ParentPkg() ||
1043 Loops
[LoopCount
- 1].TargetPkg() == D
.ParentPkg())
1047 Loops
[LoopCount
++] = D
;
1049 // Mark the packages as being part of a loop.
1050 //Flag(D.TargetPkg(),Loop);
1051 //Flag(D.ParentPkg(),Loop);
1052 /* This is currently disabled because the Loop flag is being used for
1053 loop management in the package manager. Check the orderlist.h file for more info */
1057 // OrderList::WipeFlags - Unset the given flags from all packages /*{{{*/
1058 // ---------------------------------------------------------------------
1060 void pkgOrderList::WipeFlags(unsigned long F
)
1062 unsigned long Size
= Cache
.Head().PackageCount
;
1063 for (unsigned long I
= 0; I
!= Size
; I
++)
1067 // OrderList::CheckDep - Check a dependency for truth /*{{{*/
1068 // ---------------------------------------------------------------------
1069 /* This performs a complete analysis of the dependency wrt to the
1070 current add list. It returns true if after all events are
1071 performed it is still true. This sort of routine can be approximated
1072 by examining the DepCache, however in convoluted cases of provides
1073 this fails to produce a suitable result. */
1074 bool pkgOrderList::CheckDep(DepIterator D
)
1076 std::unique_ptr
<Version
*[]> List(D
.AllTargets());
1078 for (Version
**I
= List
.get(); *I
!= 0; I
++)
1080 VerIterator
Ver(Cache
,*I
);
1081 PkgIterator Pkg
= Ver
.ParentPkg();
1083 /* The meaning of Added and AddPending is subtle. AddPending is
1084 an indication that the package is looping. Because of the
1085 way ordering works Added means the package will be unpacked
1086 before this one and AddPending means after. It is therefore
1087 correct to ignore AddPending in all cases, but that exposes
1088 reverse-ordering loops which should be ignored. */
1089 if (IsFlag(Pkg
,Added
) == true ||
1090 (IsFlag(Pkg
,AddPending
) == true && D
.Reverse() == true))
1092 if (Cache
[Pkg
].InstallVer
!= *I
)
1096 if ((Version
*)Pkg
.CurrentVer() != *I
||
1097 Pkg
.State() != PkgIterator::NeedsNothing
)
1100 /* Conflicts requires that all versions are not present, depends
1102 if (D
.IsNegative() == false)
1104 // ignore provides by older versions of this package
1105 if (((D
.Reverse() == false && Pkg
== D
.ParentPkg()) ||
1106 (D
.Reverse() == true && Pkg
== D
.TargetPkg())) &&
1107 Cache
[Pkg
].InstallVer
!= *I
)
1110 /* Try to find something that does not have the after flag set
1111 if at all possible */
1112 if (IsFlag(Pkg
,After
) == true)
1122 if (IsFlag(Pkg
,After
) == true)
1123 Flag(D
.ParentPkg(),After
);
1129 // We found a hit, but it had the after flag set
1130 if (Hit
== true && D
->Type
== pkgCache::Dep::PreDepends
)
1132 Flag(D
.ParentPkg(),After
);
1136 /* Conflicts requires that all versions are not present, depends
1138 if (D
->Type
== pkgCache::Dep::Conflicts
||
1139 D
->Type
== pkgCache::Dep::Obsoletes
)