]>
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>
83 // OrderList::pkgOrderList - Constructor /*{{{*/
84 // ---------------------------------------------------------------------
86 pkgOrderList::pkgOrderList(pkgDepCache
*pCache
) : d(NULL
), Cache(*pCache
),
87 Primary(NULL
), Secondary(NULL
),
88 RevDepends(NULL
), Remove(NULL
),
89 AfterEnd(NULL
), FileList(NULL
),
90 LoopCount(-1), Depth(0)
92 Debug
= _config
->FindB("Debug::pkgOrderList",false);
94 /* Construct the arrays, egcs 1.0.1 bug requires the package count
96 unsigned long Size
= Cache
.Head().PackageCount
;
97 Flags
= new unsigned short[Size
];
98 End
= List
= new Package
*[Size
];
99 memset(Flags
,0,sizeof(*Flags
)*Size
);
102 // OrderList::~pkgOrderList - Destructor /*{{{*/
103 // ---------------------------------------------------------------------
105 pkgOrderList::~pkgOrderList()
111 // OrderList::IsMissing - Check if a file is missing /*{{{*/
112 // ---------------------------------------------------------------------
114 bool pkgOrderList::IsMissing(PkgIterator Pkg
)
116 // Skip packages to erase
117 if (Cache
[Pkg
].Delete() == true)
120 // Skip Packages that need configure only.
121 if ((Pkg
.State() == pkgCache::PkgIterator::NeedsConfigure
||
122 Pkg
.State() == pkgCache::PkgIterator::NeedsNothing
) &&
123 Cache
[Pkg
].Keep() == true)
129 if (FileList
[Pkg
->ID
].empty() == false)
135 // OrderList::DoRun - Does an order run /*{{{*/
136 // ---------------------------------------------------------------------
137 /* The caller is expeted to have setup the desired probe state */
138 bool pkgOrderList::DoRun()
141 unsigned long Size
= Cache
.Head().PackageCount
;
142 std::unique_ptr
<Package
*[]> NList(new Package
*[Size
]);
143 std::unique_ptr
<Package
*[]> AfterList(new Package
*[Size
]);
144 AfterEnd
= AfterList
.get();
147 WipeFlags(Added
| AddPending
| Loop
| InList
);
149 for (iterator I
= List
; I
!= End
; ++I
)
152 // Rebuild the main list into the temp list.
153 iterator OldEnd
= End
;
155 for (iterator I
= List
; I
!= OldEnd
; ++I
)
156 if (VisitNode(PkgIterator(Cache
,*I
), "DoRun") == false)
162 // Copy the after list to the end of the main list
163 for (Package
**I
= AfterList
.get(); I
!= AfterEnd
; I
++)
166 // Swap the main list to the new list
168 List
= NList
.release();
172 // OrderList::OrderCritical - Perform critical unpacking ordering /*{{{*/
173 // ---------------------------------------------------------------------
174 /* This performs predepends and immediate configuration ordering only.
175 This is termed critical unpacking ordering. Any loops that form are
176 fatal and indicate that the packages cannot be installed. */
177 bool pkgOrderList::OrderCritical()
181 Primary
= &pkgOrderList::DepUnPackPreD
;
188 std::sort(List
,End
, [this](Package
*a
, Package
*b
) { return OrderCompareB(a
, b
) < 0; } );
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
;
240 std::sort(List
,End
, [this](Package
*a
, Package
*b
) { return OrderCompareA(a
, b
) < 0; });
243 clog
<< "** Pass A" << endl
;
244 if (DoRun() == false)
248 clog
<< "** Pass B" << endl
;
250 if (DoRun() == false)
254 clog
<< "** Pass C" << endl
;
257 Remove
= 0; // Otherwise the libreadline remove problem occurs
258 if (DoRun() == false)
262 clog
<< "** Pass D" << endl
;
264 Primary
= &pkgOrderList::DepUnPackPre
;
265 if (DoRun() == false)
270 clog
<< "** Unpack ordering done" << endl
;
272 for (iterator I
= List
; I
!= End
; ++I
)
274 PkgIterator
P(Cache
,*I
);
275 if (IsNow(P
) == true)
276 clog
<< " " << P
.FullName() << ' ' << IsMissing(P
) << ',' << IsFlag(P
,After
) << endl
;
283 // OrderList::OrderConfigure - Perform configuration ordering /*{{{*/
284 // ---------------------------------------------------------------------
285 /* This orders by depends only and produces an order which is suitable
287 bool pkgOrderList::OrderConfigure()
290 Primary
= &pkgOrderList::DepConfigure
;
298 // OrderList::Score - Score the package for sorting /*{{{*/
299 // ---------------------------------------------------------------------
300 /* Higher scores order earlier */
301 int pkgOrderList::Score(PkgIterator Pkg
)
303 // Removals should be done after we dealt with essentials
304 static int const ScoreDelete
= _config
->FindI("OrderList::Score::Delete", 100);
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 // Required Important Standard Optional Extra
332 if (Cache
[Pkg
].InstVerIter(Cache
)->Priority
<= 5)
334 signed short PrioMap
[] = {0,5,4,3,1,0};
335 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(Package
*a
, Package
*b
)
384 PkgIterator
A(Cache
,a
);
385 PkgIterator
B(Cache
,b
);
387 // We order packages with a set state toward the front
389 if ((Res
= BoolCompare(IsNow(A
),IsNow(B
))) != 0)
392 // We order missing files to toward the end
393 /* if (FileList != 0)
395 if ((Res = BoolCompare(IsMissing(A),
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
= Score(A
);
409 int ScoreB
= 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(Package
*a
, Package
*b
)
426 PkgIterator
A(Cache
,a
);
427 PkgIterator
B(Cache
,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
= FileCmp(A
,B
);
445 int ScoreA
= Score(A
);
446 int ScoreB
= 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.
500 If the dependency is negative it first visits packages which are
501 intended to be removed and after that all other packages.
502 It does so to avoid situations in which this package is used to
503 satisfy a (or-group/provides) dependency of another package which
504 could have been satisfied also by upgrading another package -
505 otherwise we have more broken packages dpkg needs to auto-
506 deconfigure and in very complicated situations it even decides
508 bool pkgOrderList::VisitProvides(DepIterator D
,bool Critical
)
510 std::unique_ptr
<Version
*[]> List(D
.AllTargets());
511 for (Version
**I
= List
.get(); *I
!= 0; ++I
)
513 VerIterator
Ver(Cache
,*I
);
514 PkgIterator Pkg
= Ver
.ParentPkg();
516 if (D
.IsNegative() == true && Cache
[Pkg
].Delete() == false)
519 if (Cache
[Pkg
].Keep() == true && Pkg
.State() == PkgIterator::NeedsNothing
)
522 if (D
.IsNegative() == false &&
523 Cache
[Pkg
].InstallVer
!= *I
)
526 if (D
.IsNegative() == true &&
527 (Version
*)Pkg
.CurrentVer() != *I
)
530 // Skip over missing files
531 if (Critical
== false && IsMissing(D
.ParentPkg()) == true)
534 if (VisitNode(Pkg
, "Provides-1") == false)
537 if (D
.IsNegative() == false)
539 for (Version
**I
= List
.get(); *I
!= 0; ++I
)
541 VerIterator
Ver(Cache
,*I
);
542 PkgIterator Pkg
= Ver
.ParentPkg();
544 if (Cache
[Pkg
].Delete() == true)
547 if (Cache
[Pkg
].Keep() == true && Pkg
.State() == PkgIterator::NeedsNothing
)
550 if ((Version
*)Pkg
.CurrentVer() != *I
)
553 // Skip over missing files
554 if (Critical
== false && IsMissing(D
.ParentPkg()) == true)
557 if (VisitNode(Pkg
, "Provides-2") == false)
564 // OrderList::VisitNode - Recursive ordering director /*{{{*/
565 // ---------------------------------------------------------------------
566 /* This is the core ordering routine. It calls the set dependency
567 consideration functions which then potentialy call this again. Finite
568 depth is achieved through the colouring mechinism. */
569 bool pkgOrderList::VisitNode(PkgIterator Pkg
, char const* from
)
571 // Looping or irrelevant.
572 // This should probably trancend not installed packages
573 if (Pkg
.end() == true || IsFlag(Pkg
,Added
) == true ||
574 IsFlag(Pkg
,AddPending
) == true || IsFlag(Pkg
,InList
) == false)
579 for (int j
= 0; j
!= Depth
; j
++) clog
<< ' ';
580 clog
<< "Visit " << Pkg
.FullName() << " from " << from
<< endl
;
586 Flag(Pkg
,AddPending
);
588 DepFunc Old
= Primary
;
590 // Perform immedate configuration of the package if so flagged.
591 if (IsFlag(Pkg
,Immediate
) == true && Primary
!= &pkgOrderList::DepUnPackPre
)
592 Primary
= &pkgOrderList::DepUnPackPreD
;
594 if (IsNow(Pkg
) == true)
597 if (Cache
[Pkg
].Delete() == false)
600 Res
&= Res
&& VisitDeps(Primary
,Pkg
);
601 Res
&= Res
&& VisitRDeps(Primary
,Pkg
);
602 Res
&= Res
&& VisitRProvides(Primary
,Pkg
.CurrentVer());
603 Res
&= Res
&& VisitRProvides(Primary
,Cache
[Pkg
].InstVerIter(Cache
));
606 Res
&= Res
&& VisitRDeps(RevDepends
,Pkg
);
607 Res
&= Res
&& VisitRProvides(RevDepends
,Pkg
.CurrentVer());
608 Res
&= Res
&& VisitRProvides(RevDepends
,Cache
[Pkg
].InstVerIter(Cache
));
611 Res
&= Res
&& VisitDeps(Secondary
,Pkg
);
612 Res
&= Res
&& VisitRDeps(Secondary
,Pkg
);
613 Res
&= Res
&& VisitRProvides(Secondary
,Pkg
.CurrentVer());
614 Res
&= Res
&& VisitRProvides(Secondary
,Cache
[Pkg
].InstVerIter(Cache
));
619 Res
&= Res
&& VisitRDeps(Remove
,Pkg
);
620 Res
&= Res
&& VisitRProvides(Remove
,Pkg
.CurrentVer());
624 if (IsFlag(Pkg
,Added
) == false)
626 Flag(Pkg
,Added
,Added
| AddPending
);
627 if (IsFlag(Pkg
,After
) == true)
638 for (int j
= 0; j
!= Depth
; j
++) clog
<< ' ';
639 clog
<< "Leave " << Pkg
.FullName() << ' ' << IsFlag(Pkg
,Added
) << ',' << IsFlag(Pkg
,AddPending
) << endl
;
645 // OrderList::DepUnPackCrit - Critical UnPacking ordering /*{{{*/
646 // ---------------------------------------------------------------------
647 /* Critical unpacking ordering strives to satisfy Conflicts: and
648 PreDepends: only. When a prdepends is encountered the Primary
649 DepFunc is changed to be DepUnPackPreD.
651 Loops are preprocessed and logged. */
652 bool pkgOrderList::DepUnPackCrit(DepIterator D
)
654 for (; D
.end() == false; ++D
)
656 if (D
.Reverse() == true)
658 /* Reverse depenanices are only interested in conflicts,
659 predepend breakage is ignored here */
660 if (D
->Type
!= pkgCache::Dep::Conflicts
&&
661 D
->Type
!= pkgCache::Dep::Obsoletes
)
664 // Duplication elimination, consider only the current version
665 if (D
.ParentPkg().CurrentVer() != D
.ParentVer())
668 /* For reverse dependencies we wish to check if the
669 dependency is satisifed in the install state. The
670 target package (caller) is going to be in the installed
672 if (CheckDep(D
) == true)
675 if (VisitNode(D
.ParentPkg(), "UnPackCrit") == false)
680 /* Forward critical dependencies MUST be correct before the
681 package can be unpacked. */
682 if (D
.IsNegative() == false &&
683 D
->Type
!= pkgCache::Dep::PreDepends
)
686 /* We wish to check if the dep is okay in the now state of the
687 target package against the install state of this package. */
688 if (CheckDep(D
) == true)
690 /* We want to catch predepends loops with the code below.
691 Conflicts loops that are Dep OK are ignored */
692 if (IsFlag(D
.TargetPkg(),AddPending
) == false ||
693 D
->Type
!= pkgCache::Dep::PreDepends
)
697 // This is the loop detection
698 if (IsFlag(D
.TargetPkg(),Added
) == true ||
699 IsFlag(D
.TargetPkg(),AddPending
) == true)
701 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
706 /* Predepends require a special ordering stage, they must have
707 all dependents installed as well */
708 DepFunc Old
= Primary
;
710 if (D
->Type
== pkgCache::Dep::PreDepends
)
711 Primary
= &pkgOrderList::DepUnPackPreD
;
712 Res
= VisitProvides(D
,true);
721 // OrderList::DepUnPackPreD - Critical UnPacking ordering with depends /*{{{*/
722 // ---------------------------------------------------------------------
723 /* Critical PreDepends (also configure immediate and essential) strives to
724 ensure not only that all conflicts+predepends are met but that this
725 package will be immediately configurable when it is unpacked.
726 Loops are preprocessed and logged. */
727 bool pkgOrderList::DepUnPackPreD(DepIterator D
)
729 if (D
.Reverse() == true)
730 return DepUnPackCrit(D
);
732 for (; D
.end() == false; ++D
)
734 if (D
.IsCritical() == false)
737 /* We wish to check if the dep is okay in the now state of the
738 target package against the install state of this package. */
739 if (CheckDep(D
) == true)
741 /* We want to catch predepends loops with the code below.
742 Conflicts loops that are Dep OK are ignored */
743 if (IsFlag(D
.TargetPkg(),AddPending
) == false ||
744 D
->Type
!= pkgCache::Dep::PreDepends
)
748 // This is the loop detection
749 if (IsFlag(D
.TargetPkg(),Added
) == true ||
750 IsFlag(D
.TargetPkg(),AddPending
) == true)
752 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
757 if (VisitProvides(D
,true) == false)
763 // OrderList::DepUnPackPre - Critical Predepends ordering /*{{{*/
764 // ---------------------------------------------------------------------
765 /* Critical PreDepends (also configure immediate and essential) strives to
766 ensure not only that all conflicts+predepends are met but that this
767 package will be immediately configurable when it is unpacked.
769 Loops are preprocessed and logged. All loops will be fatal. */
770 bool pkgOrderList::DepUnPackPre(DepIterator D
)
772 if (D
.Reverse() == true)
775 for (; D
.end() == false; ++D
)
777 /* Only consider the PreDepends or Depends. Depends are only
778 considered at the lowest depth or in the case of immediate
780 if (D
->Type
!= pkgCache::Dep::PreDepends
)
782 if (D
->Type
== pkgCache::Dep::Depends
)
784 if (Depth
== 1 && IsFlag(D
.ParentPkg(),Immediate
) == false)
791 /* We wish to check if the dep is okay in the now state of the
792 target package against the install state of this package. */
793 if (CheckDep(D
) == true)
795 /* We want to catch predepends loops with the code below.
796 Conflicts loops that are Dep OK are ignored */
797 if (IsFlag(D
.TargetPkg(),AddPending
) == false)
801 // This is the loop detection
802 if (IsFlag(D
.TargetPkg(),Added
) == true ||
803 IsFlag(D
.TargetPkg(),AddPending
) == true)
805 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
810 if (VisitProvides(D
,true) == false)
816 // OrderList::DepUnPackDep - Reverse dependency considerations /*{{{*/
817 // ---------------------------------------------------------------------
818 /* Reverse dependencies are considered to determine if unpacking this
819 package will break any existing dependencies. If so then those
820 packages are ordered before this one so that they are in the
823 The forwards depends loop is designed to bring the packages dependents
824 close to the package. This helps reduce deconfigure time.
826 Loops are irrelevant to this. */
827 bool pkgOrderList::DepUnPackDep(DepIterator D
)
830 for (; D
.end() == false; ++D
)
831 if (D
.IsCritical() == true)
833 if (D
.Reverse() == true)
835 /* Duplication prevention. We consider rev deps only on
836 the current version, a not installed package
838 if (D
.ParentPkg()->CurrentVer
== 0 ||
839 D
.ParentPkg().CurrentVer() != D
.ParentVer())
842 // The dep will not break so it is irrelevant.
843 if (CheckDep(D
) == true)
846 // Skip over missing files
847 if (IsMissing(D
.ParentPkg()) == true)
850 if (VisitNode(D
.ParentPkg(), "UnPackDep-Parent") == false)
855 if (D
->Type
== pkgCache::Dep::Depends
)
856 if (VisitProvides(D
,false) == false)
859 if (D
->Type
== pkgCache::Dep::DpkgBreaks
)
861 if (CheckDep(D
) == true)
864 if (VisitNode(D
.TargetPkg(), "UnPackDep-Target") == false)
872 // OrderList::DepConfigure - Configuration ordering /*{{{*/
873 // ---------------------------------------------------------------------
874 /* Configuration only ordering orders by the Depends: line only. It
875 orders configuration so that when a package comes to be configured it's
876 dependents are configured.
878 Loops are ingored. Depends loop entry points are chaotic. */
879 bool pkgOrderList::DepConfigure(DepIterator D
)
881 // Never consider reverse configuration dependencies.
882 if (D
.Reverse() == true)
885 for (; D
.end() == false; ++D
)
886 if (D
->Type
== pkgCache::Dep::Depends
)
887 if (VisitProvides(D
,false) == false)
892 // OrderList::DepRemove - Removal ordering /*{{{*/
893 // ---------------------------------------------------------------------
894 /* Checks all given dependencies if they are broken by the remove of a
895 package and if so fix it by visiting another provider or or-group
896 member to ensure that the dependee keeps working which is especially
897 important for Immediate packages like e.g. those depending on an
898 awk implementation. If the dependency can't be fixed with another
899 package this means an upgrade of the package will solve the problem. */
900 bool pkgOrderList::DepRemove(DepIterator Broken
)
902 if (Broken
.Reverse() == false)
905 for (; Broken
.end() == false; ++Broken
)
907 if (Broken
->Type
!= pkgCache::Dep::Depends
&&
908 Broken
->Type
!= pkgCache::Dep::PreDepends
)
911 PkgIterator BrokenPkg
= Broken
.ParentPkg();
912 // uninstalled packages can't break via a remove
913 if (BrokenPkg
->CurrentVer
== 0)
916 // if its already added, we can't do anything useful
917 if (IsFlag(BrokenPkg
, AddPending
) == true || IsFlag(BrokenPkg
, Added
) == true)
920 // if the dependee is going to be removed, visit it now
921 if (Cache
[BrokenPkg
].Delete() == true)
922 return VisitNode(BrokenPkg
, "Remove-Dependee");
924 // The package stays around, so find out how this is possible
925 for (DepIterator D
= BrokenPkg
.CurrentVer().DependsList(); D
.end() == false;)
927 // only important or-groups need fixing
928 if (D
->Type
!= pkgCache::Dep::Depends
&&
929 D
->Type
!= pkgCache::Dep::PreDepends
)
935 // Start is the beginning of the or-group, D is the first one after or
936 DepIterator Start
= D
;
937 bool foundBroken
= false;
938 for (bool LastOR
= true; D
.end() == false && LastOR
== true; ++D
)
940 LastOR
= (D
->CompareOp
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
;
945 // this or-group isn't the broken one: keep searching
946 if (foundBroken
== false)
949 // iterate over all members of the or-group searching for a ready replacement
950 bool readyReplacement
= false;
951 for (DepIterator OrMember
= Start
; OrMember
!= D
&& readyReplacement
== false; ++OrMember
)
953 Version
** Replacements
= OrMember
.AllTargets();
954 for (Version
**R
= Replacements
; *R
!= 0; ++R
)
956 VerIterator
Ver(Cache
,*R
);
957 // only currently installed packages can be a replacement
958 PkgIterator RPkg
= Ver
.ParentPkg();
959 if (RPkg
.CurrentVer() != Ver
)
962 // packages going to be removed can't be a replacement
963 if (Cache
[RPkg
].Delete() == true)
966 readyReplacement
= true;
969 delete[] Replacements
;
972 // something else is ready to take over, do nothing
973 if (readyReplacement
== true)
976 // see if we can visit a replacement
977 bool visitReplacement
= false;
978 for (DepIterator OrMember
= Start
; OrMember
!= D
&& visitReplacement
== false; ++OrMember
)
980 Version
** Replacements
= OrMember
.AllTargets();
981 for (Version
**R
= Replacements
; *R
!= 0; ++R
)
983 VerIterator
Ver(Cache
,*R
);
984 // consider only versions we plan to install
985 PkgIterator RPkg
= Ver
.ParentPkg();
986 if (Cache
[RPkg
].Install() == false || Cache
[RPkg
].InstallVer
!= Ver
)
989 // loops are not going to help us, so don't create them
990 if (IsFlag(RPkg
, AddPending
) == true)
993 if (IsMissing(RPkg
) == true)
996 visitReplacement
= true;
997 if (IsFlag(BrokenPkg
, Immediate
) == false)
999 if (VisitNode(RPkg
, "Remove-Rep") == true)
1004 Flag(RPkg
, Immediate
);
1005 if (VisitNode(RPkg
, "Remove-ImmRep") == true)
1008 visitReplacement
= false;
1010 delete[] Replacements
;
1012 if (visitReplacement
== true)
1015 // the broken package in current version can't be fixed, so install new version
1016 if (IsMissing(BrokenPkg
) == true)
1019 if (VisitNode(BrokenPkg
, "Remove-Upgrade") == false)
1027 // OrderList::AddLoop - Add a loop to the loop list /*{{{*/
1028 // ---------------------------------------------------------------------
1029 /* We record the loops. This is a relic since loop breaking is done
1030 genericaly as part of the safety routines. */
1031 bool pkgOrderList::AddLoop(DepIterator D
)
1033 if (LoopCount
< 0 || LoopCount
>= 20)
1039 if (Loops
[LoopCount
- 1].ParentPkg() == D
.ParentPkg() ||
1040 Loops
[LoopCount
- 1].TargetPkg() == D
.ParentPkg())
1044 Loops
[LoopCount
++] = D
;
1046 // Mark the packages as being part of a loop.
1047 //Flag(D.TargetPkg(),Loop);
1048 //Flag(D.ParentPkg(),Loop);
1049 /* This is currently disabled because the Loop flag is being used for
1050 loop management in the package manager. Check the orderlist.h file for more info */
1054 // OrderList::WipeFlags - Unset the given flags from all packages /*{{{*/
1055 // ---------------------------------------------------------------------
1057 void pkgOrderList::WipeFlags(unsigned long F
)
1059 unsigned long Size
= Cache
.Head().PackageCount
;
1060 for (unsigned long I
= 0; I
!= Size
; I
++)
1064 // OrderList::CheckDep - Check a dependency for truth /*{{{*/
1065 // ---------------------------------------------------------------------
1066 /* This performs a complete analysis of the dependency wrt to the
1067 current add list. It returns true if after all events are
1068 performed it is still true. This sort of routine can be approximated
1069 by examining the DepCache, however in convoluted cases of provides
1070 this fails to produce a suitable result. */
1071 bool pkgOrderList::CheckDep(DepIterator D
)
1073 std::unique_ptr
<Version
*[]> List(D
.AllTargets());
1075 for (Version
**I
= List
.get(); *I
!= 0; I
++)
1077 VerIterator
Ver(Cache
,*I
);
1078 PkgIterator Pkg
= Ver
.ParentPkg();
1080 /* The meaning of Added and AddPending is subtle. AddPending is
1081 an indication that the package is looping. Because of the
1082 way ordering works Added means the package will be unpacked
1083 before this one and AddPending means after. It is therefore
1084 correct to ignore AddPending in all cases, but that exposes
1085 reverse-ordering loops which should be ignored. */
1086 if (IsFlag(Pkg
,Added
) == true ||
1087 (IsFlag(Pkg
,AddPending
) == true && D
.Reverse() == true))
1089 if (Cache
[Pkg
].InstallVer
!= *I
)
1093 if ((Version
*)Pkg
.CurrentVer() != *I
||
1094 Pkg
.State() != PkgIterator::NeedsNothing
)
1097 /* Conflicts requires that all versions are not present, depends
1099 if (D
.IsNegative() == false)
1101 // ignore provides by older versions of this package
1102 if (((D
.Reverse() == false && Pkg
== D
.ParentPkg()) ||
1103 (D
.Reverse() == true && Pkg
== D
.TargetPkg())) &&
1104 Cache
[Pkg
].InstallVer
!= *I
)
1107 /* Try to find something that does not have the after flag set
1108 if at all possible */
1109 if (IsFlag(Pkg
,After
) == true)
1119 if (IsFlag(Pkg
,After
) == true)
1120 Flag(D
.ParentPkg(),After
);
1126 // We found a hit, but it had the after flag set
1127 if (Hit
== true && D
->Type
== pkgCache::Dep::PreDepends
)
1129 Flag(D
.ParentPkg(),After
);
1133 /* Conflicts requires that all versions are not present, depends
1135 if (D
->Type
== pkgCache::Dep::Conflicts
||
1136 D
->Type
== pkgCache::Dep::Obsoletes
)