]>
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)
130 // Missing Pseudo packages are missing if the real package is missing
131 if (pkgCache::VerIterator(Cache
, Cache
[Pkg
].CandidateVer
).Pseudo() == true)
132 return IsMissing(Pkg
.Group().FindPkg("all"));
137 // OrderList::DoRun - Does an order run /*{{{*/
138 // ---------------------------------------------------------------------
139 /* The caller is expeted to have setup the desired probe state */
140 bool pkgOrderList::DoRun()
143 unsigned long Size
= Cache
.Head().PackageCount
;
144 SPtrArray
<Package
*> NList
= new Package
*[Size
];
145 SPtrArray
<Package
*> AfterList
= new Package
*[Size
];
146 AfterEnd
= AfterList
;
149 WipeFlags(Added
| AddPending
| Loop
| InList
);
151 for (iterator I
= List
; I
!= End
; I
++)
154 // Rebuild the main list into the temp list.
155 iterator OldEnd
= End
;
157 for (iterator I
= List
; I
!= OldEnd
; I
++)
158 if (VisitNode(PkgIterator(Cache
,*I
)) == false)
164 // Copy the after list to the end of the main list
165 for (Package
**I
= AfterList
; I
!= AfterEnd
; I
++)
168 // Swap the main list to the new list
170 List
= NList
.UnGuard();
174 // OrderList::OrderCritical - Perform critical unpacking ordering /*{{{*/
175 // ---------------------------------------------------------------------
176 /* This performs predepends and immediate configuration ordering only.
177 This is termed critical unpacking ordering. Any loops that form are
178 fatal and indicate that the packages cannot be installed. */
179 bool pkgOrderList::OrderCritical()
183 Primary
= &pkgOrderList::DepUnPackPreD
;
191 qsort(List
,End
- List
,sizeof(*List
),&OrderCompareB
);
193 if (DoRun() == false)
197 return _error
->Error("Fatal, predepends looping detected");
201 clog
<< "** Critical Unpack ordering done" << endl
;
203 for (iterator I
= List
; I
!= End
; I
++)
205 PkgIterator
P(Cache
,*I
);
206 if (IsNow(P
) == true)
207 clog
<< " " << P
.FullName() << ' ' << IsMissing(P
) << ',' << IsFlag(P
,After
) << endl
;
214 // OrderList::OrderUnpack - Perform complete unpacking ordering /*{{{*/
215 // ---------------------------------------------------------------------
216 /* This performs complete unpacking ordering and creates an order that is
217 suitable for unpacking */
218 bool pkgOrderList::OrderUnpack(string
*FileList
)
220 this->FileList
= FileList
;
222 // Setup the after flags
227 // Set the inlist flag
228 for (iterator I
= List
; I
!= End
; I
++)
230 PkgIterator
P(Cache
,*I
);
231 if (IsMissing(P
) == true && IsNow(P
) == true)
236 Primary
= &pkgOrderList::DepUnPackCrit
;
237 Secondary
= &pkgOrderList::DepConfigure
;
238 RevDepends
= &pkgOrderList::DepUnPackDep
;
239 Remove
= &pkgOrderList::DepRemove
;
244 qsort(List
,End
- List
,sizeof(*List
),&OrderCompareA
);
247 clog
<< "** Pass A" << endl
;
248 if (DoRun() == false)
252 clog
<< "** Pass B" << endl
;
254 if (DoRun() == false)
258 clog
<< "** Pass C" << endl
;
261 Remove
= 0; // Otherwise the libreadline remove problem occures
262 if (DoRun() == false)
266 clog
<< "** Pass D" << endl
;
268 Primary
= &pkgOrderList::DepUnPackPre
;
269 if (DoRun() == false)
274 clog
<< "** Unpack ordering done" << endl
;
276 for (iterator I
= List
; I
!= End
; I
++)
278 PkgIterator
P(Cache
,*I
);
279 if (IsNow(P
) == true)
280 clog
<< " " << P
.FullName() << ' ' << IsMissing(P
) << ',' << IsFlag(P
,After
) << endl
;
287 // OrderList::OrderConfigure - Perform configuration ordering /*{{{*/
288 // ---------------------------------------------------------------------
289 /* This orders by depends only and produces an order which is suitable
291 bool pkgOrderList::OrderConfigure()
294 Primary
= &pkgOrderList::DepConfigure
;
302 // OrderList::Score - Score the package for sorting /*{{{*/
303 // ---------------------------------------------------------------------
304 /* Higher scores order earlier */
305 int pkgOrderList::Score(PkgIterator Pkg
)
307 static int const ScoreDelete
= _config
->FindI("OrderList::Score::Delete", 500);
309 // Removal is always done first
310 if (Cache
[Pkg
].Delete() == true)
313 // This should never happen..
314 if (Cache
[Pkg
].InstVerIter(Cache
).end() == true)
317 static int const ScoreEssential
= _config
->FindI("OrderList::Score::Essential", 200);
318 static int const ScoreImmediate
= _config
->FindI("OrderList::Score::Immediate", 10);
319 static int const ScorePreDepends
= _config
->FindI("OrderList::Score::PreDepends", 50);
322 if ((Pkg
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
323 Score
+= ScoreEssential
;
325 if (IsFlag(Pkg
,Immediate
) == true)
326 Score
+= ScoreImmediate
;
328 for (DepIterator D
= Cache
[Pkg
].InstVerIter(Cache
).DependsList();
329 D
.end() == false; D
++)
330 if (D
->Type
== pkgCache::Dep::PreDepends
)
332 Score
+= ScorePreDepends
;
336 // Important Required Standard Optional Extra
337 signed short PrioMap
[] = {0,5,4,3,1,0};
338 if (Cache
[Pkg
].InstVerIter(Cache
)->Priority
<= 5)
339 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. */
502 bool pkgOrderList::VisitProvides(DepIterator D
,bool Critical
)
504 SPtrArray
<Version
*> List
= D
.AllTargets();
505 for (Version
**I
= List
; *I
!= 0; I
++)
507 VerIterator
Ver(Cache
,*I
);
508 PkgIterator Pkg
= Ver
.ParentPkg();
510 if (Cache
[Pkg
].Keep() == true && Pkg
.State() == PkgIterator::NeedsNothing
)
513 if (D
->Type
!= pkgCache::Dep::Conflicts
&&
514 D
->Type
!= pkgCache::Dep::DpkgBreaks
&&
515 D
->Type
!= pkgCache::Dep::Obsoletes
&&
516 Cache
[Pkg
].InstallVer
!= *I
)
519 if ((D
->Type
== pkgCache::Dep::Conflicts
||
520 D
->Type
== pkgCache::Dep::DpkgBreaks
||
521 D
->Type
== pkgCache::Dep::Obsoletes
) &&
522 (Version
*)Pkg
.CurrentVer() != *I
)
525 // Skip over missing files
526 if (Critical
== false && IsMissing(D
.ParentPkg()) == true)
529 if (VisitNode(Pkg
) == false)
535 // OrderList::VisitNode - Recursive ordering director /*{{{*/
536 // ---------------------------------------------------------------------
537 /* This is the core ordering routine. It calls the set dependency
538 consideration functions which then potentialy call this again. Finite
539 depth is achived through the colouring mechinism. */
540 bool pkgOrderList::VisitNode(PkgIterator Pkg
)
542 // Looping or irrelevent.
543 // This should probably trancend not installed packages
544 if (Pkg
.end() == true || IsFlag(Pkg
,Added
) == true ||
545 IsFlag(Pkg
,AddPending
) == true || IsFlag(Pkg
,InList
) == false)
550 for (int j
= 0; j
!= Depth
; j
++) clog
<< ' ';
551 clog
<< "Visit " << Pkg
.FullName() << endl
;
557 Flag(Pkg
,AddPending
);
559 DepFunc Old
= Primary
;
561 // Perform immedate configuration of the package if so flagged.
562 if (IsFlag(Pkg
,Immediate
) == true && Primary
!= &pkgOrderList::DepUnPackPre
)
563 Primary
= &pkgOrderList::DepUnPackPreD
;
565 if (IsNow(Pkg
) == true)
568 if (Cache
[Pkg
].Delete() == false)
571 Res
&= Res
&& VisitDeps(Primary
,Pkg
);
572 Res
&= Res
&& VisitRDeps(Primary
,Pkg
);
573 Res
&= Res
&& VisitRProvides(Primary
,Pkg
.CurrentVer());
574 Res
&= Res
&& VisitRProvides(Primary
,Cache
[Pkg
].InstVerIter(Cache
));
577 Res
&= Res
&& VisitRDeps(RevDepends
,Pkg
);
578 Res
&= Res
&& VisitRProvides(RevDepends
,Pkg
.CurrentVer());
579 Res
&= Res
&& VisitRProvides(RevDepends
,Cache
[Pkg
].InstVerIter(Cache
));
582 Res
&= Res
&& VisitDeps(Secondary
,Pkg
);
583 Res
&= Res
&& VisitRDeps(Secondary
,Pkg
);
584 Res
&= Res
&& VisitRProvides(Secondary
,Pkg
.CurrentVer());
585 Res
&= Res
&& VisitRProvides(Secondary
,Cache
[Pkg
].InstVerIter(Cache
));
590 Res
&= Res
&& VisitRDeps(Remove
,Pkg
);
591 Res
&= Res
&& VisitRProvides(Remove
,Pkg
.CurrentVer());
595 if (IsFlag(Pkg
,Added
) == false)
597 Flag(Pkg
,Added
,Added
| AddPending
);
598 if (IsFlag(Pkg
,After
) == true)
609 for (int j
= 0; j
!= Depth
; j
++) clog
<< ' ';
610 clog
<< "Leave " << Pkg
.FullName() << ' ' << IsFlag(Pkg
,Added
) << ',' << IsFlag(Pkg
,AddPending
) << endl
;
616 // OrderList::DepUnPackCrit - Critical UnPacking ordering /*{{{*/
617 // ---------------------------------------------------------------------
618 /* Critical unpacking ordering strives to satisfy Conflicts: and
619 PreDepends: only. When a prdepends is encountered the Primary
620 DepFunc is changed to be DepUnPackPreD.
622 Loops are preprocessed and logged. */
623 bool pkgOrderList::DepUnPackCrit(DepIterator D
)
625 for (; D
.end() == false; D
++)
627 if (D
.Reverse() == true)
629 /* Reverse depenanices are only interested in conflicts,
630 predepend breakage is ignored here */
631 if (D
->Type
!= pkgCache::Dep::Conflicts
&&
632 D
->Type
!= pkgCache::Dep::Obsoletes
)
635 // Duplication elimination, consider only the current version
636 if (D
.ParentPkg().CurrentVer() != D
.ParentVer())
639 /* For reverse dependencies we wish to check if the
640 dependency is satisifed in the install state. The
641 target package (caller) is going to be in the installed
643 if (CheckDep(D
) == true)
646 if (VisitNode(D
.ParentPkg()) == false)
651 /* Forward critical dependencies MUST be correct before the
652 package can be unpacked. */
653 if (D
->Type
!= pkgCache::Dep::Conflicts
&&
654 D
->Type
!= pkgCache::Dep::DpkgBreaks
&&
655 D
->Type
!= pkgCache::Dep::Obsoletes
&&
656 D
->Type
!= pkgCache::Dep::PreDepends
)
659 /* We wish to check if the dep is okay in the now state of the
660 target package against the install state of this package. */
661 if (CheckDep(D
) == true)
663 /* We want to catch predepends loops with the code below.
664 Conflicts loops that are Dep OK are ignored */
665 if (IsFlag(D
.TargetPkg(),AddPending
) == false ||
666 D
->Type
!= pkgCache::Dep::PreDepends
)
670 // This is the loop detection
671 if (IsFlag(D
.TargetPkg(),Added
) == true ||
672 IsFlag(D
.TargetPkg(),AddPending
) == true)
674 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
679 /* Predepends require a special ordering stage, they must have
680 all dependents installed as well */
681 DepFunc Old
= Primary
;
683 if (D
->Type
== pkgCache::Dep::PreDepends
)
684 Primary
= &pkgOrderList::DepUnPackPreD
;
685 Res
= VisitProvides(D
,true);
694 // OrderList::DepUnPackPreD - Critical UnPacking ordering with depends /*{{{*/
695 // ---------------------------------------------------------------------
696 /* Critical PreDepends (also configure immediate and essential) strives to
697 ensure not only that all conflicts+predepends are met but that this
698 package will be immediately configurable when it is unpacked.
699 Loops are preprocessed and logged. */
700 bool pkgOrderList::DepUnPackPreD(DepIterator D
)
702 if (D
.Reverse() == true)
703 return DepUnPackCrit(D
);
705 for (; D
.end() == false; D
++)
707 if (D
.IsCritical() == false)
710 /* We wish to check if the dep is okay in the now state of the
711 target package against the install state of this package. */
712 if (CheckDep(D
) == true)
714 /* We want to catch predepends loops with the code below.
715 Conflicts loops that are Dep OK are ignored */
716 if (IsFlag(D
.TargetPkg(),AddPending
) == false ||
717 D
->Type
!= pkgCache::Dep::PreDepends
)
721 // This is the loop detection
722 if (IsFlag(D
.TargetPkg(),Added
) == true ||
723 IsFlag(D
.TargetPkg(),AddPending
) == true)
725 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
730 if (VisitProvides(D
,true) == false)
736 // OrderList::DepUnPackPre - Critical Predepends ordering /*{{{*/
737 // ---------------------------------------------------------------------
738 /* Critical PreDepends (also configure immediate and essential) strives to
739 ensure not only that all conflicts+predepends are met but that this
740 package will be immediately configurable when it is unpacked.
742 Loops are preprocessed and logged. All loops will be fatal. */
743 bool pkgOrderList::DepUnPackPre(DepIterator D
)
745 if (D
.Reverse() == true)
748 for (; D
.end() == false; D
++)
750 /* Only consider the PreDepends or Depends. Depends are only
751 considered at the lowest depth or in the case of immediate
753 if (D
->Type
!= pkgCache::Dep::PreDepends
)
755 if (D
->Type
== pkgCache::Dep::Depends
)
757 if (Depth
== 1 && IsFlag(D
.ParentPkg(),Immediate
) == false)
764 /* We wish to check if the dep is okay in the now state of the
765 target package against the install state of this package. */
766 if (CheckDep(D
) == true)
768 /* We want to catch predepends loops with the code below.
769 Conflicts loops that are Dep OK are ignored */
770 if (IsFlag(D
.TargetPkg(),AddPending
) == false)
774 // This is the loop detection
775 if (IsFlag(D
.TargetPkg(),Added
) == true ||
776 IsFlag(D
.TargetPkg(),AddPending
) == true)
778 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
783 if (VisitProvides(D
,true) == false)
789 // OrderList::DepUnPackDep - Reverse dependency considerations /*{{{*/
790 // ---------------------------------------------------------------------
791 /* Reverse dependencies are considered to determine if unpacking this
792 package will break any existing dependencies. If so then those
793 packages are ordered before this one so that they are in the
796 The forwards depends loop is designed to bring the packages dependents
797 close to the package. This helps reduce deconfigure time.
799 Loops are irrelevent to this. */
800 bool pkgOrderList::DepUnPackDep(DepIterator D
)
803 for (; D
.end() == false; D
++)
804 if (D
.IsCritical() == true)
806 if (D
.Reverse() == true)
808 /* Duplication prevention. We consider rev deps only on
809 the current version, a not installed package
811 if (D
.ParentPkg()->CurrentVer
== 0 ||
812 D
.ParentPkg().CurrentVer() != D
.ParentVer())
815 // The dep will not break so it is irrelevent.
816 if (CheckDep(D
) == true)
819 // Skip over missing files
820 if (IsMissing(D
.ParentPkg()) == true)
823 if (VisitNode(D
.ParentPkg()) == false)
828 if (D
->Type
== pkgCache::Dep::Depends
)
829 if (VisitProvides(D
,false) == false)
832 if (D
->Type
== pkgCache::Dep::DpkgBreaks
)
834 if (CheckDep(D
) == true)
837 if (VisitNode(D
.TargetPkg()) == false)
845 // OrderList::DepConfigure - Configuration ordering /*{{{*/
846 // ---------------------------------------------------------------------
847 /* Configuration only ordering orders by the Depends: line only. It
848 orders configuration so that when a package comes to be configured it's
849 dependents are configured.
851 Loops are ingored. Depends loop entry points are chaotic. */
852 bool pkgOrderList::DepConfigure(DepIterator D
)
854 // Never consider reverse configuration dependencies.
855 if (D
.Reverse() == true)
858 for (; D
.end() == false; D
++)
859 if (D
->Type
== pkgCache::Dep::Depends
)
860 if (VisitProvides(D
,false) == false)
865 // OrderList::DepRemove - Removal ordering /*{{{*/
866 // ---------------------------------------------------------------------
867 /* Removal visits all reverse depends. It considers if the dependency
868 of the Now state version to see if it is okay with removing this
869 package. This check should always fail, but is provided for symetery
870 with the other critical handlers.
872 Loops are preprocessed and logged. Removal loops can also be
873 detected in the critical handler. They are characterized by an
874 old version of A depending on B but the new version of A conflicting
875 with B, thus either A or B must break to install. */
876 bool pkgOrderList::DepRemove(DepIterator D
)
878 if (D
.Reverse() == false)
880 for (; D
.end() == false; D
++)
881 if (D
->Type
== pkgCache::Dep::Depends
|| D
->Type
== pkgCache::Dep::PreDepends
)
883 // Duplication elimination, consider the current version only
884 if (D
.ParentPkg().CurrentVer() != D
.ParentVer())
887 /* We wish to see if the dep on the parent package is okay
888 in the removed (install) state of the target pkg. */
889 if (CheckDep(D
) == true)
891 // We want to catch loops with the code below.
892 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 // Skip over missing files
906 if (IsMissing(D
.ParentPkg()) == true)
909 if (VisitNode(D
.ParentPkg()) == false)
916 // OrderList::AddLoop - Add a loop to the loop list /*{{{*/
917 // ---------------------------------------------------------------------
918 /* We record the loops. This is a relic since loop breaking is done
919 genericaly as part of the safety routines. */
920 bool pkgOrderList::AddLoop(DepIterator D
)
922 if (LoopCount
< 0 || LoopCount
>= 20)
928 if (Loops
[LoopCount
- 1].ParentPkg() == D
.ParentPkg() ||
929 Loops
[LoopCount
- 1].TargetPkg() == D
.ParentPkg())
933 Loops
[LoopCount
++] = D
;
935 // Mark the packages as being part of a loop.
936 Flag(D
.TargetPkg(),Loop
);
937 Flag(D
.ParentPkg(),Loop
);
941 // OrderList::WipeFlags - Unset the given flags from all packages /*{{{*/
942 // ---------------------------------------------------------------------
944 void pkgOrderList::WipeFlags(unsigned long F
)
946 unsigned long Size
= Cache
.Head().PackageCount
;
947 for (unsigned long I
= 0; I
!= Size
; I
++)
951 // OrderList::CheckDep - Check a dependency for truth /*{{{*/
952 // ---------------------------------------------------------------------
953 /* This performs a complete analysis of the dependency wrt to the
954 current add list. It returns true if after all events are
955 performed it is still true. This sort of routine can be approximated
956 by examining the DepCache, however in convoluted cases of provides
957 this fails to produce a suitable result. */
958 bool pkgOrderList::CheckDep(DepIterator D
)
960 SPtrArray
<Version
*> List
= D
.AllTargets();
962 for (Version
**I
= List
; *I
!= 0; I
++)
964 VerIterator
Ver(Cache
,*I
);
965 PkgIterator Pkg
= Ver
.ParentPkg();
967 /* The meaning of Added and AddPending is subtle. AddPending is
968 an indication that the package is looping. Because of the
969 way ordering works Added means the package will be unpacked
970 before this one and AddPending means after. It is therefore
971 correct to ignore AddPending in all cases, but that exposes
972 reverse-ordering loops which should be ignored. */
973 if (IsFlag(Pkg
,Added
) == true ||
974 (IsFlag(Pkg
,AddPending
) == true && D
.Reverse() == true))
976 if (Cache
[Pkg
].InstallVer
!= *I
)
980 if ((Version
*)Pkg
.CurrentVer() != *I
||
981 Pkg
.State() != PkgIterator::NeedsNothing
)
984 /* Conflicts requires that all versions are not present, depends
986 if (D
->Type
!= pkgCache::Dep::Conflicts
&&
987 D
->Type
!= pkgCache::Dep::DpkgBreaks
&&
988 D
->Type
!= pkgCache::Dep::Obsoletes
)
990 /* Try to find something that does not have the after flag set
991 if at all possible */
992 if (IsFlag(Pkg
,After
) == true)
1002 if (IsFlag(Pkg
,After
) == true)
1003 Flag(D
.ParentPkg(),After
);
1009 // We found a hit, but it had the after flag set
1010 if (Hit
== true && D
->Type
== pkgCache::Dep::PreDepends
)
1012 Flag(D
.ParentPkg(),After
);
1016 /* Conflicts requires that all versions are not present, depends
1018 if (D
->Type
== pkgCache::Dep::Conflicts
||
1019 D
->Type
== pkgCache::Dep::Obsoletes
)