]>
git.saurik.com Git - apt.git/blob - apt-pkg/orderlist.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: orderlist.cc,v 1.14 2001/05/07 05:49:43 jgg Exp $
4 /* ######################################################################
6 Order List - Represents and Manipulates an ordered list of packages.
8 A list of packages can be ordered by a number of conflicting criteria
9 each given a specific priority. Each package also has a set of flags
10 indicating some useful things about it that are derived in the
11 course of sorting. The pkgPackageManager class uses this class for
12 all of it's installation ordering needs.
14 This is a modified version of Manoj's Routine B. It consists of four
15 independent ordering algorithms that can be applied at for different
16 points in the ordering. By appling progressivly fewer ordering
17 operations it is possible to give each consideration it's own
18 priority and create an order that satisfies the lowest applicable
21 The rules for unpacking ordering are:
22 1) Unpacking ignores Depends: on all packages
23 2) Unpacking requires Conflicts: on -ALL- packages to be satisfied
24 3) Unpacking requires PreDepends: on this package only to be satisfied
25 4) Removing requires that no packages depend on the package to be
28 And the rule for configuration ordering is:
29 1) Configuring requires that the Depends: of the package be satisfied
30 Conflicts+PreDepends are ignored because unpacking says they are
31 already correct [exageration, it does check but we need not be
34 And some features that are valuable for unpacking ordering.
35 f1) Unpacking a new package should advoid breaking dependencies of
37 f2) Removal should not require a force, corrolory of f1
38 f3) Unpacking should order by depends rather than fall back to random
41 Each of the features can be enabled in the sorting routine at an
42 arbitrary priority to give quite abit of control over the final unpacking
45 The rules listed above may never be violated and are called Critical.
46 When a critical rule is violated then a loop condition is recorded
47 and will have to be delt with in the caller.
49 The ordering keeps two lists, the main list and the 'After List'. The
50 purpose of the after list is to allow packages to be delayed. This is done
51 by setting the after flag on the package. Any package which requires this
52 package to be ordered before will inherit the after flag and so on. This
53 is used for CD swap ordering where all packages on a second CD have the
54 after flag set. This forces them and all their dependents to be ordered
57 There are complications in this algorithm when presented with cycles.
58 For all known practical cases it works, all cases where it doesn't work
59 is fixable by tweaking the package descriptions. However, it should be
60 possible to impove this further to make some better choices when
61 presented with cycles.
63 ##################################################################### */
65 // Include Files /*{{{*/
66 #include <apt-pkg/orderlist.h>
67 #include <apt-pkg/depcache.h>
68 #include <apt-pkg/error.h>
69 #include <apt-pkg/version.h>
70 #include <apt-pkg/sptr.h>
71 #include <apt-pkg/configuration.h>
78 pkgOrderList
*pkgOrderList::Me
= 0;
80 // OrderList::pkgOrderList - Constructor /*{{{*/
81 // ---------------------------------------------------------------------
83 pkgOrderList::pkgOrderList(pkgDepCache
*pCache
) : Cache(*pCache
)
91 Debug
= _config
->FindB("Debug::pkgOrderList",false);
93 /* Construct the arrays, egcs 1.0.1 bug requires the package count
95 unsigned long Size
= Cache
.Head().PackageCount
;
96 Flags
= new unsigned short[Size
];
97 End
= List
= new Package
*[Size
];
98 memset(Flags
,0,sizeof(*Flags
)*Size
);
101 // OrderList::~pkgOrderList - Destructor /*{{{*/
102 // ---------------------------------------------------------------------
104 pkgOrderList::~pkgOrderList()
110 // OrderList::IsMissing - Check if a file is missing /*{{{*/
111 // ---------------------------------------------------------------------
113 bool pkgOrderList::IsMissing(PkgIterator Pkg
)
115 // Skip packages to erase
116 if (Cache
[Pkg
].Delete() == true)
119 // Skip Packages that need configure only.
120 if (Pkg
.State() == pkgCache::PkgIterator::NeedsConfigure
&&
121 Cache
[Pkg
].Keep() == true)
127 if (FileList
[Pkg
->ID
].empty() == false)
132 // OrderList::DoRun - Does an order run /*{{{*/
133 // ---------------------------------------------------------------------
134 /* The caller is expeted to have setup the desired probe state */
135 bool pkgOrderList::DoRun()
138 unsigned long Size
= Cache
.Head().PackageCount
;
139 SPtrArray
<Package
*> NList
= new Package
*[Size
];
140 SPtrArray
<Package
*> AfterList
= new Package
*[Size
];
141 AfterEnd
= AfterList
;
144 WipeFlags(Added
| AddPending
| Loop
| InList
);
146 for (iterator I
= List
; I
!= End
; I
++)
149 // Rebuild the main list into the temp list.
150 iterator OldEnd
= End
;
152 for (iterator I
= List
; I
!= OldEnd
; I
++)
153 if (VisitNode(PkgIterator(Cache
,*I
)) == false)
159 // Copy the after list to the end of the main list
160 for (Package
**I
= AfterList
; I
!= AfterEnd
; I
++)
163 // Swap the main list to the new list
165 List
= NList
.UnGuard();
169 // OrderList::OrderCritical - Perform critical unpacking ordering /*{{{*/
170 // ---------------------------------------------------------------------
171 /* This performs predepends and immediate configuration ordering only.
172 This is termed critical unpacking ordering. Any loops that form are
173 fatal and indicate that the packages cannot be installed. */
174 bool pkgOrderList::OrderCritical()
178 Primary
= &pkgOrderList::DepUnPackPre
;
186 qsort(List
,End
- List
,sizeof(*List
),&OrderCompareB
);
188 if (DoRun() == false)
192 return _error
->Error("Fatal, predepends looping detected");
196 // OrderList::OrderUnpack - Perform complete unpacking ordering /*{{{*/
197 // ---------------------------------------------------------------------
198 /* This performs complete unpacking ordering and creates an order that is
199 suitable for unpacking */
200 bool pkgOrderList::OrderUnpack(string
*FileList
)
202 this->FileList
= FileList
;
204 // Setup the after flags
209 // Set the inlist flag
210 for (iterator I
= List
; I
!= End
; I
++)
212 PkgIterator
P(Cache
,*I
);
213 if (IsMissing(P
) == true && IsNow(P
) == true)
218 Primary
= &pkgOrderList::DepUnPackCrit
;
219 Secondary
= &pkgOrderList::DepConfigure
;
220 RevDepends
= &pkgOrderList::DepUnPackDep
;
221 Remove
= &pkgOrderList::DepRemove
;
226 qsort(List
,End
- List
,sizeof(*List
),&OrderCompareA
);
229 clog
<< "** Pass A" << endl
;
230 if (DoRun() == false)
234 clog
<< "** Pass B" << endl
;
236 if (DoRun() == false)
240 clog
<< "** Pass C" << endl
;
243 Remove
= 0; // Otherwise the libreadline remove problem occures
244 if (DoRun() == false)
248 clog
<< "** Pass D" << endl
;
250 Primary
= &pkgOrderList::DepUnPackPre
;
251 if (DoRun() == false)
256 clog
<< "** Unpack ordering done" << endl
;
258 for (iterator I
= List
; I
!= End
; I
++)
260 PkgIterator
P(Cache
,*I
);
261 if (IsNow(P
) == true)
262 clog
<< P
.Name() << ' ' << IsMissing(P
) << ',' << IsFlag(P
,After
) << endl
;
269 // OrderList::OrderConfigure - Perform configuration ordering /*{{{*/
270 // ---------------------------------------------------------------------
271 /* This orders by depends only and produces an order which is suitable
273 bool pkgOrderList::OrderConfigure()
276 Primary
= &pkgOrderList::DepConfigure
;
284 // OrderList::Score - Score the package for sorting /*{{{*/
285 // ---------------------------------------------------------------------
286 /* Higher scores order earlier */
287 int pkgOrderList::Score(PkgIterator Pkg
)
289 // Removal is always done first
290 if (Cache
[Pkg
].Delete() == true)
293 // This should never happen..
294 if (Cache
[Pkg
].InstVerIter(Cache
).end() == true)
298 if ((Pkg
->Flags
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
)
301 if (IsFlag(Pkg
,Immediate
) == true)
304 for (DepIterator D
= Cache
[Pkg
].InstVerIter(Cache
).DependsList();
305 D
.end() == false; D
++)
306 if (D
->Type
== pkgCache::Dep::PreDepends
)
312 // Important Required Standard Optional Extra
313 signed short PrioMap
[] = {0,5,4,3,1,0};
314 if (Cache
[Pkg
].InstVerIter(Cache
)->Priority
<= 5)
315 Score
+= PrioMap
[Cache
[Pkg
].InstVerIter(Cache
)->Priority
];
319 // OrderList::FileCmp - Compare by package file /*{{{*/
320 // ---------------------------------------------------------------------
321 /* This compares by the package file that the install version is in. */
322 int pkgOrderList::FileCmp(PkgIterator A
,PkgIterator B
)
324 if (Cache
[A
].Delete() == true && Cache
[B
].Delete() == true)
326 if (Cache
[A
].Delete() == true)
328 if (Cache
[B
].Delete() == true)
331 if (Cache
[A
].InstVerIter(Cache
).FileList().end() == true)
333 if (Cache
[B
].InstVerIter(Cache
).FileList().end() == true)
336 pkgCache::PackageFile
*FA
= Cache
[A
].InstVerIter(Cache
).FileList().File();
337 pkgCache::PackageFile
*FB
= Cache
[B
].InstVerIter(Cache
).FileList().File();
345 // BoolCompare - Comparison function for two booleans /*{{{*/
346 // ---------------------------------------------------------------------
348 static int BoolCompare(bool A
,bool B
)
357 // OrderList::OrderCompareA - Order the installation by op /*{{{*/
358 // ---------------------------------------------------------------------
359 /* This provides a first-pass sort of the list and gives a decent starting
360 point for further complete ordering. It is used by OrderUnpack only */
361 int pkgOrderList::OrderCompareA(const void *a
, const void *b
)
363 PkgIterator
A(Me
->Cache
,*(Package
**)a
);
364 PkgIterator
B(Me
->Cache
,*(Package
**)b
);
366 // We order packages with a set state toward the front
368 if ((Res
= BoolCompare(Me
->IsNow(A
),Me
->IsNow(B
))) != 0)
371 // We order missing files to toward the end
372 /* if (Me->FileList != 0)
374 if ((Res = BoolCompare(Me->IsMissing(A),
375 Me->IsMissing(B))) != 0)
379 if (A
.State() != pkgCache::PkgIterator::NeedsNothing
&&
380 B
.State() == pkgCache::PkgIterator::NeedsNothing
)
383 if (A
.State() == pkgCache::PkgIterator::NeedsNothing
&&
384 B
.State() != pkgCache::PkgIterator::NeedsNothing
)
387 int ScoreA
= Me
->Score(A
);
388 int ScoreB
= Me
->Score(B
);
395 return strcmp(A
.Name(),B
.Name());
398 // OrderList::OrderCompareB - Order the installation by source /*{{{*/
399 // ---------------------------------------------------------------------
400 /* This orders by installation source. This is useful to handle
401 inter-source breaks */
402 int pkgOrderList::OrderCompareB(const void *a
, const void *b
)
404 PkgIterator
A(Me
->Cache
,*(Package
**)a
);
405 PkgIterator
B(Me
->Cache
,*(Package
**)b
);
407 if (A
.State() != pkgCache::PkgIterator::NeedsNothing
&&
408 B
.State() == pkgCache::PkgIterator::NeedsNothing
)
411 if (A
.State() == pkgCache::PkgIterator::NeedsNothing
&&
412 B
.State() != pkgCache::PkgIterator::NeedsNothing
)
415 int F
= Me
->FileCmp(A
,B
);
423 int ScoreA
= Me
->Score(A
);
424 int ScoreB
= Me
->Score(B
);
431 return strcmp(A
.Name(),B
.Name());
434 // OrderList::VisitDeps - Visit forward install dependencies /*{{{*/
435 // ---------------------------------------------------------------------
436 /* This calls the dependency function for the normal forwards dependencies
438 bool pkgOrderList::VisitDeps(DepFunc F
,PkgIterator Pkg
)
440 if (F
== 0 || Pkg
.end() == true || Cache
[Pkg
].InstallVer
== 0)
443 return (this->*F
)(Cache
[Pkg
].InstVerIter(Cache
).DependsList());
446 // OrderList::VisitRDeps - Visit reverse dependencies /*{{{*/
447 // ---------------------------------------------------------------------
448 /* This calls the dependency function for all of the normal reverse depends
450 bool pkgOrderList::VisitRDeps(DepFunc F
,PkgIterator Pkg
)
452 if (F
== 0 || Pkg
.end() == true)
455 return (this->*F
)(Pkg
.RevDependsList());
458 // OrderList::VisitRProvides - Visit provides reverse dependencies /*{{{*/
459 // ---------------------------------------------------------------------
460 /* This calls the dependency function for all reverse dependencies
461 generated by the provides line on the package. */
462 bool pkgOrderList::VisitRProvides(DepFunc F
,VerIterator Ver
)
464 if (F
== 0 || Ver
.end() == true)
468 for (PrvIterator P
= Ver
.ProvidesList(); P
.end() == false; P
++)
469 Res
&= (this->*F
)(P
.ParentPkg().RevDependsList());
473 // OrderList::VisitProvides - Visit all of the providing packages /*{{{*/
474 // ---------------------------------------------------------------------
475 /* This routine calls visit on all providing packages. */
476 bool pkgOrderList::VisitProvides(DepIterator D
,bool Critical
)
478 SPtrArray
<Version
*> List
= D
.AllTargets();
479 for (Version
**I
= List
; *I
!= 0; I
++)
481 VerIterator
Ver(Cache
,*I
);
482 PkgIterator Pkg
= Ver
.ParentPkg();
484 if (Cache
[Pkg
].Keep() == true && Pkg
.State() == PkgIterator::NeedsNothing
)
487 if (D
->Type
!= pkgCache::Dep::Conflicts
&&
488 D
->Type
!= pkgCache::Dep::DpkgBreaks
&&
489 D
->Type
!= pkgCache::Dep::Obsoletes
&&
490 Cache
[Pkg
].InstallVer
!= *I
)
493 if ((D
->Type
== pkgCache::Dep::Conflicts
||
494 D
->Type
== pkgCache::Dep::DpkgBreaks
||
495 D
->Type
== pkgCache::Dep::Obsoletes
) &&
496 (Version
*)Pkg
.CurrentVer() != *I
)
499 // Skip over missing files
500 if (Critical
== false && IsMissing(D
.ParentPkg()) == true)
503 if (VisitNode(Pkg
) == false)
509 // OrderList::VisitNode - Recursive ordering director /*{{{*/
510 // ---------------------------------------------------------------------
511 /* This is the core ordering routine. It calls the set dependency
512 consideration functions which then potentialy call this again. Finite
513 depth is achived through the colouring mechinism. */
514 bool pkgOrderList::VisitNode(PkgIterator Pkg
)
516 // Looping or irrelevent.
517 // This should probably trancend not installed packages
518 if (Pkg
.end() == true || IsFlag(Pkg
,Added
) == true ||
519 IsFlag(Pkg
,AddPending
) == true || IsFlag(Pkg
,InList
) == false)
524 for (int j
= 0; j
!= Depth
; j
++) clog
<< ' ';
525 clog
<< "Visit " << Pkg
.Name() << endl
;
531 Flag(Pkg
,AddPending
);
533 DepFunc Old
= Primary
;
535 // Perform immedate configuration of the package if so flagged.
536 if (IsFlag(Pkg
,Immediate
) == true && Primary
!= &pkgOrderList::DepUnPackPre
)
537 Primary
= &pkgOrderList::DepUnPackPreD
;
539 if (IsNow(Pkg
) == true)
542 if (Cache
[Pkg
].Delete() == false)
545 Res
&= Res
&& VisitDeps(Primary
,Pkg
);
546 Res
&= Res
&& VisitRDeps(Primary
,Pkg
);
547 Res
&= Res
&& VisitRProvides(Primary
,Pkg
.CurrentVer());
548 Res
&= Res
&& VisitRProvides(Primary
,Cache
[Pkg
].InstVerIter(Cache
));
551 Res
&= Res
&& VisitRDeps(RevDepends
,Pkg
);
552 Res
&= Res
&& VisitRProvides(RevDepends
,Pkg
.CurrentVer());
553 Res
&= Res
&& VisitRProvides(RevDepends
,Cache
[Pkg
].InstVerIter(Cache
));
556 Res
&= Res
&& VisitDeps(Secondary
,Pkg
);
557 Res
&= Res
&& VisitRDeps(Secondary
,Pkg
);
558 Res
&= Res
&& VisitRProvides(Secondary
,Pkg
.CurrentVer());
559 Res
&= Res
&& VisitRProvides(Secondary
,Cache
[Pkg
].InstVerIter(Cache
));
564 Res
&= Res
&& VisitRDeps(Remove
,Pkg
);
565 Res
&= Res
&& VisitRProvides(Remove
,Pkg
.CurrentVer());
569 if (IsFlag(Pkg
,Added
) == false)
571 Flag(Pkg
,Added
,Added
| AddPending
);
572 if (IsFlag(Pkg
,After
) == true)
583 for (int j
= 0; j
!= Depth
; j
++) clog
<< ' ';
584 clog
<< "Leave " << Pkg
.Name() << ' ' << IsFlag(Pkg
,Added
) << ',' << IsFlag(Pkg
,AddPending
) << endl
;
590 // OrderList::DepUnPackCrit - Critical UnPacking ordering /*{{{*/
591 // ---------------------------------------------------------------------
592 /* Critical unpacking ordering strives to satisfy Conflicts: and
593 PreDepends: only. When a prdepends is encountered the Primary
594 DepFunc is changed to be DepUnPackPreD.
596 Loops are preprocessed and logged. */
597 bool pkgOrderList::DepUnPackCrit(DepIterator D
)
599 for (; D
.end() == false; D
++)
601 if (D
.Reverse() == true)
603 /* Reverse depenanices are only interested in conflicts,
604 predepend breakage is ignored here */
605 if (D
->Type
!= pkgCache::Dep::Conflicts
&&
606 D
->Type
!= pkgCache::Dep::Obsoletes
)
609 // Duplication elimination, consider only the current version
610 if (D
.ParentPkg().CurrentVer() != D
.ParentVer())
613 /* For reverse dependencies we wish to check if the
614 dependency is satisifed in the install state. The
615 target package (caller) is going to be in the installed
617 if (CheckDep(D
) == true)
620 if (VisitNode(D
.ParentPkg()) == false)
625 /* Forward critical dependencies MUST be correct before the
626 package can be unpacked. */
627 if (D
->Type
!= pkgCache::Dep::Conflicts
&&
628 D
->Type
!= pkgCache::Dep::DpkgBreaks
&&
629 D
->Type
!= pkgCache::Dep::Obsoletes
&&
630 D
->Type
!= pkgCache::Dep::PreDepends
)
633 /* We wish to check if the dep is okay in the now state of the
634 target package against the install state of this package. */
635 if (CheckDep(D
) == true)
637 /* We want to catch predepends loops with the code below.
638 Conflicts loops that are Dep OK are ignored */
639 if (IsFlag(D
.TargetPkg(),AddPending
) == false ||
640 D
->Type
!= pkgCache::Dep::PreDepends
)
644 // This is the loop detection
645 if (IsFlag(D
.TargetPkg(),Added
) == true ||
646 IsFlag(D
.TargetPkg(),AddPending
) == true)
648 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
653 /* Predepends require a special ordering stage, they must have
654 all dependents installed as well */
655 DepFunc Old
= Primary
;
657 if (D
->Type
== pkgCache::Dep::PreDepends
)
658 Primary
= &pkgOrderList::DepUnPackPreD
;
659 Res
= VisitProvides(D
,true);
668 // OrderList::DepUnPackPreD - Critical UnPacking ordering with depends /*{{{*/
669 // ---------------------------------------------------------------------
670 /* Critical PreDepends (also configure immediate and essential) strives to
671 ensure not only that all conflicts+predepends are met but that this
672 package will be immediately configurable when it is unpacked.
673 Loops are preprocessed and logged. */
674 bool pkgOrderList::DepUnPackPreD(DepIterator D
)
676 if (D
.Reverse() == true)
677 return DepUnPackCrit(D
);
679 for (; D
.end() == false; D
++)
681 if (D
.IsCritical() == false)
684 /* We wish to check if the dep is okay in the now state of the
685 target package against the install state of this package. */
686 if (CheckDep(D
) == true)
688 /* We want to catch predepends loops with the code below.
689 Conflicts loops that are Dep OK are ignored */
690 if (IsFlag(D
.TargetPkg(),AddPending
) == false ||
691 D
->Type
!= pkgCache::Dep::PreDepends
)
695 // This is the loop detection
696 if (IsFlag(D
.TargetPkg(),Added
) == true ||
697 IsFlag(D
.TargetPkg(),AddPending
) == true)
699 if (IsFlag(D
.TargetPkg(),AddPending
) == true)
704 if (VisitProvides(D
,true) == false)
710 // OrderList::DepUnPackPre - Critical Predepends ordering /*{{{*/
711 // ---------------------------------------------------------------------
712 /* Critical PreDepends (also configure immediate and essential) strives to
713 ensure not only that all conflicts+predepends are met but that this
714 package will be immediately configurable when it is unpacked.
716 Loops are preprocessed and logged. All loops will be fatal. */
717 bool pkgOrderList::DepUnPackPre(DepIterator D
)
719 if (D
.Reverse() == true)
722 for (; D
.end() == false; D
++)
724 /* Only consider the PreDepends or Depends. Depends are only
725 considered at the lowest depth or in the case of immediate
727 if (D
->Type
!= pkgCache::Dep::PreDepends
)
729 if (D
->Type
== pkgCache::Dep::Depends
)
731 if (Depth
== 1 && IsFlag(D
.ParentPkg(),Immediate
) == false)
738 /* We wish to check if the dep is okay in the now state of the
739 target package against the install state of this package. */
740 if (CheckDep(D
) == true)
742 /* We want to catch predepends loops with the code below.
743 Conflicts loops that are Dep OK are ignored */
744 if (IsFlag(D
.TargetPkg(),AddPending
) == false)
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::DepUnPackDep - Reverse dependency considerations /*{{{*/
764 // ---------------------------------------------------------------------
765 /* Reverse dependencies are considered to determine if unpacking this
766 package will break any existing dependencies. If so then those
767 packages are ordered before this one so that they are in the
770 The forwards depends loop is designed to bring the packages dependents
771 close to the package. This helps reduce deconfigure time.
773 Loops are irrelevent to this. */
774 bool pkgOrderList::DepUnPackDep(DepIterator D
)
777 for (; D
.end() == false; D
++)
778 if (D
.IsCritical() == true)
780 if (D
.Reverse() == true)
782 /* Duplication prevention. We consider rev deps only on
783 the current version, a not installed package
785 if (D
.ParentPkg()->CurrentVer
== 0 ||
786 D
.ParentPkg().CurrentVer() != D
.ParentVer())
789 // The dep will not break so it is irrelevent.
790 if (CheckDep(D
) == true)
793 // Skip over missing files
794 if (IsMissing(D
.ParentPkg()) == true)
797 if (VisitNode(D
.ParentPkg()) == false)
802 if (D
->Type
== pkgCache::Dep::Depends
)
803 if (VisitProvides(D
,false) == false)
806 if (D
->Type
== pkgCache::Dep::DpkgBreaks
)
808 if (CheckDep(D
) == true)
811 if (VisitNode(D
.TargetPkg()) == false)
819 // OrderList::DepConfigure - Configuration ordering /*{{{*/
820 // ---------------------------------------------------------------------
821 /* Configuration only ordering orders by the Depends: line only. It
822 orders configuration so that when a package comes to be configured it's
823 dependents are configured.
825 Loops are ingored. Depends loop entry points are chaotic. */
826 bool pkgOrderList::DepConfigure(DepIterator D
)
828 // Never consider reverse configuration dependencies.
829 if (D
.Reverse() == true)
832 for (; D
.end() == false; D
++)
833 if (D
->Type
== pkgCache::Dep::Depends
)
834 if (VisitProvides(D
,false) == false)
839 // OrderList::DepRemove - Removal ordering /*{{{*/
840 // ---------------------------------------------------------------------
841 /* Removal visits all reverse depends. It considers if the dependency
842 of the Now state version to see if it is okay with removing this
843 package. This check should always fail, but is provided for symetery
844 with the other critical handlers.
846 Loops are preprocessed and logged. Removal loops can also be
847 detected in the critical handler. They are characterized by an
848 old version of A depending on B but the new version of A conflicting
849 with B, thus either A or B must break to install. */
850 bool pkgOrderList::DepRemove(DepIterator D
)
852 if (D
.Reverse() == false)
854 for (; D
.end() == false; D
++)
855 if (D
->Type
== pkgCache::Dep::Depends
|| D
->Type
== pkgCache::Dep::PreDepends
)
857 // Duplication elimination, consider the current version only
858 if (D
.ParentPkg().CurrentVer() != D
.ParentVer())
861 /* We wish to see if the dep on the parent package is okay
862 in the removed (install) state of the target pkg. */
863 if (CheckDep(D
) == true)
865 // We want to catch loops with the code below.
866 if (IsFlag(D
.ParentPkg(),AddPending
) == false)
870 // This is the loop detection
871 if (IsFlag(D
.ParentPkg(),Added
) == true ||
872 IsFlag(D
.ParentPkg(),AddPending
) == true)
874 if (IsFlag(D
.ParentPkg(),AddPending
) == true)
879 // Skip over missing files
880 if (IsMissing(D
.ParentPkg()) == true)
883 if (VisitNode(D
.ParentPkg()) == false)
890 // OrderList::AddLoop - Add a loop to the loop list /*{{{*/
891 // ---------------------------------------------------------------------
892 /* We record the loops. This is a relic since loop breaking is done
893 genericaly as part of the safety routines. */
894 bool pkgOrderList::AddLoop(DepIterator D
)
896 if (LoopCount
< 0 || LoopCount
>= 20)
902 if (Loops
[LoopCount
- 1].ParentPkg() == D
.ParentPkg() ||
903 Loops
[LoopCount
- 1].TargetPkg() == D
.ParentPkg())
907 Loops
[LoopCount
++] = D
;
909 // Mark the packages as being part of a loop.
910 Flag(D
.TargetPkg(),Loop
);
911 Flag(D
.ParentPkg(),Loop
);
915 // OrderList::WipeFlags - Unset the given flags from all packages /*{{{*/
916 // ---------------------------------------------------------------------
918 void pkgOrderList::WipeFlags(unsigned long F
)
920 unsigned long Size
= Cache
.Head().PackageCount
;
921 for (unsigned long I
= 0; I
!= Size
; I
++)
925 // OrderList::CheckDep - Check a dependency for truth /*{{{*/
926 // ---------------------------------------------------------------------
927 /* This performs a complete analysis of the dependency wrt to the
928 current add list. It returns true if after all events are
929 performed it is still true. This sort of routine can be approximated
930 by examining the DepCache, however in convoluted cases of provides
931 this fails to produce a suitable result. */
932 bool pkgOrderList::CheckDep(DepIterator D
)
934 SPtrArray
<Version
*> List
= D
.AllTargets();
936 for (Version
**I
= List
; *I
!= 0; I
++)
938 VerIterator
Ver(Cache
,*I
);
939 PkgIterator Pkg
= Ver
.ParentPkg();
941 /* The meaning of Added and AddPending is subtle. AddPending is
942 an indication that the package is looping. Because of the
943 way ordering works Added means the package will be unpacked
944 before this one and AddPending means after. It is therefore
945 correct to ignore AddPending in all cases, but that exposes
946 reverse-ordering loops which should be ignored. */
947 if (IsFlag(Pkg
,Added
) == true ||
948 (IsFlag(Pkg
,AddPending
) == true && D
.Reverse() == true))
950 if (Cache
[Pkg
].InstallVer
!= *I
)
954 if ((Version
*)Pkg
.CurrentVer() != *I
||
955 Pkg
.State() != PkgIterator::NeedsNothing
)
958 /* Conflicts requires that all versions are not present, depends
960 if (D
->Type
!= pkgCache::Dep::Conflicts
&&
961 D
->Type
!= pkgCache::Dep::DpkgBreaks
&&
962 D
->Type
!= pkgCache::Dep::Obsoletes
)
964 /* Try to find something that does not have the after flag set
965 if at all possible */
966 if (IsFlag(Pkg
,After
) == true)
976 if (IsFlag(Pkg
,After
) == true)
977 Flag(D
.ParentPkg(),After
);
983 // We found a hit, but it had the after flag set
984 if (Hit
== true && D
->Type
== pkgCache::Dep::PreDepends
)
986 Flag(D
.ParentPkg(),After
);
990 /* Conflicts requires that all versions are not present, depends
992 if (D
->Type
== pkgCache::Dep::Conflicts
||
993 D
->Type
== pkgCache::Dep::Obsoletes
)