]>
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         Pkg
.State() == pkgCache::PkgIterator::NeedsNothing
) && 
 122        Cache
[Pkg
].Keep() == true) 
 128    if (FileList
[Pkg
->ID
].empty() == false) 
 134 // OrderList::DoRun - Does an order run                                 /*{{{*/ 
 135 // --------------------------------------------------------------------- 
 136 /* The caller is expeted to have setup the desired probe state */ 
 137 bool pkgOrderList::DoRun() 
 140    unsigned long Size 
= Cache
.Head().PackageCount
; 
 141    SPtrArray
<Package 
*> NList 
= new Package 
*[Size
]; 
 142    SPtrArray
<Package 
*> AfterList 
= new Package 
*[Size
]; 
 143    AfterEnd 
= AfterList
; 
 146    WipeFlags(Added 
| AddPending 
| Loop 
| InList
); 
 148    for (iterator I 
= List
; I 
!= End
; ++I
) 
 151    // Rebuild the main list into the temp list. 
 152    iterator OldEnd 
= End
; 
 154    for (iterator I 
= List
; I 
!= OldEnd
; ++I
) 
 155       if (VisitNode(PkgIterator(Cache
,*I
)) == false) 
 161    // Copy the after list to the end of the main list 
 162    for (Package 
**I 
= AfterList
; I 
!= AfterEnd
; I
++) 
 165    // Swap the main list to the new list 
 167    List 
= NList
.UnGuard(); 
 171 // OrderList::OrderCritical - Perform critical unpacking ordering       /*{{{*/ 
 172 // --------------------------------------------------------------------- 
 173 /* This performs predepends and immediate configuration ordering only.  
 174    This is termed critical unpacking ordering. Any loops that form are 
 175    fatal and indicate that the packages cannot be installed. */ 
 176 bool pkgOrderList::OrderCritical() 
 180    Primary 
= &pkgOrderList::DepUnPackPreD
; 
 188    qsort(List
,End 
- List
,sizeof(*List
),&OrderCompareB
); 
 190    if (DoRun() == false) 
 194       return _error
->Error("Fatal, predepends looping detected"); 
 198       clog 
<< "** Critical Unpack ordering done" << endl
; 
 200       for (iterator I 
= List
; I 
!= End
; ++I
) 
 202          PkgIterator 
P(Cache
,*I
); 
 203          if (IsNow(P
) == true) 
 204             clog 
<< "  " << P
.FullName() << ' ' << IsMissing(P
) << ',' << IsFlag(P
,After
) << endl
; 
 211 // OrderList::OrderUnpack - Perform complete unpacking ordering         /*{{{*/ 
 212 // --------------------------------------------------------------------- 
 213 /* This performs complete unpacking ordering and creates an order that is 
 214    suitable for unpacking */ 
 215 bool pkgOrderList::OrderUnpack(string 
*FileList
) 
 217    this->FileList 
= FileList
; 
 219    // Setup the after flags 
 224       // Set the inlist flag 
 225       for (iterator I 
= List
; I 
!= End
; ++I
) 
 227          PkgIterator 
P(Cache
,*I
); 
 228          if (IsMissing(P
) == true && IsNow(P
) == true) 
 233    Primary 
= &pkgOrderList::DepUnPackCrit
; 
 234    Secondary 
= &pkgOrderList::DepConfigure
; 
 235    RevDepends 
= &pkgOrderList::DepUnPackDep
; 
 236    Remove 
= &pkgOrderList::DepRemove
; 
 241    qsort(List
,End 
- List
,sizeof(*List
),&OrderCompareA
); 
 244       clog 
<< "** Pass A" << endl
; 
 245    if (DoRun() == false) 
 249       clog 
<< "** Pass B" << endl
; 
 251    if (DoRun() == false) 
 255       clog 
<< "** Pass C" << endl
; 
 258    Remove 
= 0;             // Otherwise the libreadline remove problem occures 
 259    if (DoRun() == false) 
 263       clog 
<< "** Pass D" << endl
; 
 265    Primary 
= &pkgOrderList::DepUnPackPre
; 
 266    if (DoRun() == false) 
 271       clog 
<< "** Unpack ordering done" << endl
; 
 273       for (iterator I 
= List
; I 
!= End
; ++I
) 
 275          PkgIterator 
P(Cache
,*I
); 
 276          if (IsNow(P
) == true) 
 277             clog 
<< "  " << P
.FullName() << ' ' << IsMissing(P
) << ',' << IsFlag(P
,After
) << endl
; 
 284 // OrderList::OrderConfigure - Perform configuration ordering           /*{{{*/ 
 285 // --------------------------------------------------------------------- 
 286 /* This orders by depends only and produces an order which is suitable 
 288 bool pkgOrderList::OrderConfigure() 
 291    Primary 
= &pkgOrderList::DepConfigure
; 
 299 // OrderList::Score - Score the package for sorting                     /*{{{*/ 
 300 // --------------------------------------------------------------------- 
 301 /* Higher scores order earlier */ 
 302 int pkgOrderList::Score(PkgIterator Pkg
) 
 304    static int const ScoreDelete 
= _config
->FindI("OrderList::Score::Delete", 500); 
 306    // Removal is always done first 
 307    if (Cache
[Pkg
].Delete() == true) 
 310    // This should never happen.. 
 311    if (Cache
[Pkg
].InstVerIter(Cache
).end() == true) 
 314    static int const ScoreEssential 
= _config
->FindI("OrderList::Score::Essential", 200); 
 315    static int const ScoreImmediate 
= _config
->FindI("OrderList::Score::Immediate", 10); 
 316    static int const ScorePreDepends 
= _config
->FindI("OrderList::Score::PreDepends", 50); 
 319    if ((Pkg
->Flags 
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
) 
 320       Score 
+= ScoreEssential
; 
 322    if (IsFlag(Pkg
,Immediate
) == true) 
 323       Score 
+= ScoreImmediate
; 
 325    for (DepIterator D 
= Cache
[Pkg
].InstVerIter(Cache
).DependsList(); 
 326         D
.end() == false; ++D
) 
 327       if (D
->Type 
== pkgCache::Dep::PreDepends
) 
 329          Score 
+= ScorePreDepends
; 
 333    // Important Required Standard Optional Extra 
 334    signed short PrioMap
[] = {0,5,4,3,1,0}; 
 335    if (Cache
[Pkg
].InstVerIter(Cache
)->Priority 
<= 5) 
 336       Score 
+= PrioMap
[Cache
[Pkg
].InstVerIter(Cache
)->Priority
]; 
 340 // OrderList::FileCmp - Compare by package file                         /*{{{*/ 
 341 // --------------------------------------------------------------------- 
 342 /* This compares by the package file that the install version is in. */ 
 343 int pkgOrderList::FileCmp(PkgIterator A
,PkgIterator B
) 
 345    if (Cache
[A
].Delete() == true && Cache
[B
].Delete() == true) 
 347    if (Cache
[A
].Delete() == true) 
 349    if (Cache
[B
].Delete() == true) 
 352    if (Cache
[A
].InstVerIter(Cache
).FileList().end() == true) 
 354    if (Cache
[B
].InstVerIter(Cache
).FileList().end() == true) 
 357    pkgCache::PackageFile 
*FA 
= Cache
[A
].InstVerIter(Cache
).FileList().File(); 
 358    pkgCache::PackageFile 
*FB 
= Cache
[B
].InstVerIter(Cache
).FileList().File(); 
 366 // BoolCompare - Comparison function for two booleans                   /*{{{*/ 
 367 // --------------------------------------------------------------------- 
 369 static int BoolCompare(bool A
,bool B
) 
 378 // OrderList::OrderCompareA - Order the installation by op              /*{{{*/ 
 379 // --------------------------------------------------------------------- 
 380 /* This provides a first-pass sort of the list and gives a decent starting 
 381     point for further complete ordering. It is used by OrderUnpack only */ 
 382 int pkgOrderList::OrderCompareA(const void *a
, const void *b
) 
 384    PkgIterator 
A(Me
->Cache
,*(Package 
**)a
); 
 385    PkgIterator 
B(Me
->Cache
,*(Package 
**)b
); 
 387    // We order packages with a set state toward the front 
 389    if ((Res 
= BoolCompare(Me
->IsNow(A
),Me
->IsNow(B
))) != 0) 
 392    // We order missing files to toward the end 
 393 /*   if (Me->FileList != 0) 
 395       if ((Res = BoolCompare(Me->IsMissing(A), 
 396                              Me->IsMissing(B))) != 0) 
 400    if (A
.State() != pkgCache::PkgIterator::NeedsNothing 
&&  
 401        B
.State() == pkgCache::PkgIterator::NeedsNothing
) 
 404    if (A
.State() == pkgCache::PkgIterator::NeedsNothing 
&&  
 405        B
.State() != pkgCache::PkgIterator::NeedsNothing
) 
 408    int ScoreA 
= Me
->Score(A
); 
 409    int ScoreB 
= Me
->Score(B
); 
 417    return strcmp(A
.Name(),B
.Name()); 
 420 // OrderList::OrderCompareB - Order the installation by source          /*{{{*/ 
 421 // --------------------------------------------------------------------- 
 422 /* This orders by installation source. This is useful to handle 
 423    inter-source breaks */ 
 424 int pkgOrderList::OrderCompareB(const void *a
, const void *b
) 
 426    PkgIterator 
A(Me
->Cache
,*(Package 
**)a
); 
 427    PkgIterator 
B(Me
->Cache
,*(Package 
**)b
); 
 429    if (A
.State() != pkgCache::PkgIterator::NeedsNothing 
&&  
 430        B
.State() == pkgCache::PkgIterator::NeedsNothing
) 
 433    if (A
.State() == pkgCache::PkgIterator::NeedsNothing 
&&  
 434        B
.State() != pkgCache::PkgIterator::NeedsNothing
) 
 437    int F 
= Me
->FileCmp(A
,B
); 
 445    int ScoreA 
= Me
->Score(A
); 
 446    int ScoreB 
= Me
->Score(B
); 
 454    return strcmp(A
.Name(),B
.Name()); 
 457 // OrderList::VisitDeps - Visit forward install dependencies            /*{{{*/ 
 458 // --------------------------------------------------------------------- 
 459 /* This calls the dependency function for the normal forwards dependencies 
 461 bool pkgOrderList::VisitDeps(DepFunc F
,PkgIterator Pkg
) 
 463    if (F 
== 0 || Pkg
.end() == true || Cache
[Pkg
].InstallVer 
== 0) 
 466    return (this->*F
)(Cache
[Pkg
].InstVerIter(Cache
).DependsList()); 
 469 // OrderList::VisitRDeps - Visit reverse dependencies                   /*{{{*/ 
 470 // --------------------------------------------------------------------- 
 471 /* This calls the dependency function for all of the normal reverse depends 
 473 bool pkgOrderList::VisitRDeps(DepFunc F
,PkgIterator Pkg
) 
 475    if (F 
== 0 || Pkg
.end() == true) 
 478    return (this->*F
)(Pkg
.RevDependsList()); 
 481 // OrderList::VisitRProvides - Visit provides reverse dependencies      /*{{{*/ 
 482 // --------------------------------------------------------------------- 
 483 /* This calls the dependency function for all reverse dependencies 
 484    generated by the provides line on the package. */ 
 485 bool pkgOrderList::VisitRProvides(DepFunc F
,VerIterator Ver
) 
 487    if (F 
== 0 || Ver
.end() == true) 
 491    for (PrvIterator P 
= Ver
.ProvidesList(); P
.end() == false; ++P
) 
 492       Res 
&= (this->*F
)(P
.ParentPkg().RevDependsList()); 
 496 // OrderList::VisitProvides - Visit all of the providing packages       /*{{{*/ 
 497 // --------------------------------------------------------------------- 
 498 /* This routine calls visit on all providing packages. */ 
 499 bool pkgOrderList::VisitProvides(DepIterator D
,bool Critical
) 
 501    SPtrArray
<Version 
*> List 
= D
.AllTargets(); 
 502    for (Version 
**I 
= List
; *I 
!= 0; I
++) 
 504       VerIterator 
Ver(Cache
,*I
); 
 505       PkgIterator Pkg 
= Ver
.ParentPkg(); 
 507       if (Cache
[Pkg
].Keep() == true && Pkg
.State() == PkgIterator::NeedsNothing
) 
 510       if (D
.IsNegative() == false && 
 511           Cache
[Pkg
].InstallVer 
!= *I
) 
 514       if (D
.IsNegative() == true && 
 515           (Version 
*)Pkg
.CurrentVer() != *I
) 
 518       // Skip over missing files 
 519       if (Critical 
== false && IsMissing(D
.ParentPkg()) == true) 
 522       if (VisitNode(Pkg
) == false) 
 528 // OrderList::VisitNode - Recursive ordering director                   /*{{{*/ 
 529 // --------------------------------------------------------------------- 
 530 /* This is the core ordering routine. It calls the set dependency 
 531    consideration functions which then potentialy call this again. Finite 
 532    depth is achived through the colouring mechinism. */ 
 533 bool pkgOrderList::VisitNode(PkgIterator Pkg
) 
 535    // Looping or irrelevent. 
 536    // This should probably trancend not installed packages 
 537    if (Pkg
.end() == true || IsFlag(Pkg
,Added
) == true ||  
 538        IsFlag(Pkg
,AddPending
) == true || IsFlag(Pkg
,InList
) == false) 
 543       for (int j 
= 0; j 
!= Depth
; j
++) clog 
<< ' '; 
 544       clog 
<< "Visit " << Pkg
.FullName() << endl
; 
 550    Flag(Pkg
,AddPending
); 
 552    DepFunc Old 
= Primary
; 
 554    // Perform immedate configuration of the package if so flagged. 
 555    if (IsFlag(Pkg
,Immediate
) == true && Primary 
!= &pkgOrderList::DepUnPackPre
) 
 556       Primary 
= &pkgOrderList::DepUnPackPreD
; 
 558    if (IsNow(Pkg
) == true) 
 561       if (Cache
[Pkg
].Delete() == false) 
 564          Res 
&= Res 
&& VisitDeps(Primary
,Pkg
); 
 565          Res 
&= Res 
&& VisitRDeps(Primary
,Pkg
); 
 566          Res 
&= Res 
&& VisitRProvides(Primary
,Pkg
.CurrentVer()); 
 567          Res 
&= Res 
&& VisitRProvides(Primary
,Cache
[Pkg
].InstVerIter(Cache
)); 
 570          Res 
&= Res 
&& VisitRDeps(RevDepends
,Pkg
); 
 571          Res 
&= Res 
&& VisitRProvides(RevDepends
,Pkg
.CurrentVer()); 
 572          Res 
&= Res 
&& VisitRProvides(RevDepends
,Cache
[Pkg
].InstVerIter(Cache
)); 
 575          Res 
&= Res 
&& VisitDeps(Secondary
,Pkg
); 
 576          Res 
&= Res 
&& VisitRDeps(Secondary
,Pkg
); 
 577          Res 
&= Res 
&& VisitRProvides(Secondary
,Pkg
.CurrentVer()); 
 578          Res 
&= Res 
&& VisitRProvides(Secondary
,Cache
[Pkg
].InstVerIter(Cache
)); 
 583          Res 
&= Res 
&& VisitRDeps(Remove
,Pkg
); 
 584          Res 
&= Res 
&& VisitRProvides(Remove
,Pkg
.CurrentVer()); 
 588    if (IsFlag(Pkg
,Added
) == false) 
 590       Flag(Pkg
,Added
,Added 
| AddPending
); 
 591       if (IsFlag(Pkg
,After
) == true) 
 602       for (int j 
= 0; j 
!= Depth
; j
++) clog 
<< ' '; 
 603       clog 
<< "Leave " << Pkg
.FullName() << ' ' << IsFlag(Pkg
,Added
) << ',' << IsFlag(Pkg
,AddPending
) << endl
; 
 609 // OrderList::DepUnPackCrit - Critical UnPacking ordering               /*{{{*/ 
 610 // --------------------------------------------------------------------- 
 611 /* Critical unpacking ordering strives to satisfy Conflicts: and  
 612    PreDepends: only. When a prdepends is encountered the Primary  
 613    DepFunc is changed to be DepUnPackPreD.  
 615    Loops are preprocessed and logged. */ 
 616 bool pkgOrderList::DepUnPackCrit(DepIterator D
) 
 618    for (; D
.end() == false; ++D
) 
 620       if (D
.Reverse() == true) 
 622          /* Reverse depenanices are only interested in conflicts, 
 623             predepend breakage is ignored here */ 
 624          if (D
->Type 
!= pkgCache::Dep::Conflicts 
&&  
 625              D
->Type 
!= pkgCache::Dep::Obsoletes
) 
 628          // Duplication elimination, consider only the current version 
 629          if (D
.ParentPkg().CurrentVer() != D
.ParentVer()) 
 632          /* For reverse dependencies we wish to check if the 
 633             dependency is satisifed in the install state. The 
 634             target package (caller) is going to be in the installed 
 636          if (CheckDep(D
) == true) 
 639          if (VisitNode(D
.ParentPkg()) == false) 
 644          /* Forward critical dependencies MUST be correct before the  
 645             package can be unpacked. */ 
 646          if (D
.IsNegative() == false && 
 647              D
->Type 
!= pkgCache::Dep::PreDepends
) 
 650          /* We wish to check if the dep is okay in the now state of the 
 651             target package against the install state of this package. */ 
 652          if (CheckDep(D
) == true) 
 654             /* We want to catch predepends loops with the code below. 
 655                Conflicts loops that are Dep OK are ignored */ 
 656             if (IsFlag(D
.TargetPkg(),AddPending
) == false || 
 657                 D
->Type 
!= pkgCache::Dep::PreDepends
) 
 661          // This is the loop detection 
 662          if (IsFlag(D
.TargetPkg(),Added
) == true ||  
 663              IsFlag(D
.TargetPkg(),AddPending
) == true) 
 665             if (IsFlag(D
.TargetPkg(),AddPending
) == true) 
 670          /* Predepends require a special ordering stage, they must have 
 671             all dependents installed as well */ 
 672          DepFunc Old 
= Primary
; 
 674          if (D
->Type 
== pkgCache::Dep::PreDepends
) 
 675             Primary 
= &pkgOrderList::DepUnPackPreD
; 
 676          Res 
= VisitProvides(D
,true); 
 685 // OrderList::DepUnPackPreD - Critical UnPacking ordering with depends  /*{{{*/ 
 686 // --------------------------------------------------------------------- 
 687 /* Critical PreDepends (also configure immediate and essential) strives to 
 688    ensure not only that all conflicts+predepends are met but that this 
 689    package will be immediately configurable when it is unpacked. 
 690    Loops are preprocessed and logged. */ 
 691 bool pkgOrderList::DepUnPackPreD(DepIterator D
) 
 693    if (D
.Reverse() == true) 
 694       return DepUnPackCrit(D
); 
 696    for (; D
.end() == false; ++D
) 
 698       if (D
.IsCritical() == false) 
 701       /* We wish to check if the dep is okay in the now state of the 
 702          target package against the install state of this package. */ 
 703       if (CheckDep(D
) == true) 
 705          /* We want to catch predepends loops with the code below. 
 706             Conflicts loops that are Dep OK are ignored */ 
 707          if (IsFlag(D
.TargetPkg(),AddPending
) == false || 
 708              D
->Type 
!= pkgCache::Dep::PreDepends
) 
 712       // This is the loop detection 
 713       if (IsFlag(D
.TargetPkg(),Added
) == true ||  
 714           IsFlag(D
.TargetPkg(),AddPending
) == true) 
 716          if (IsFlag(D
.TargetPkg(),AddPending
) == true) 
 721       if (VisitProvides(D
,true) == false) 
 727 // OrderList::DepUnPackPre - Critical Predepends ordering               /*{{{*/ 
 728 // --------------------------------------------------------------------- 
 729 /* Critical PreDepends (also configure immediate and essential) strives to 
 730    ensure not only that all conflicts+predepends are met but that this 
 731    package will be immediately configurable when it is unpacked.  
 733    Loops are preprocessed and logged. All loops will be fatal. */ 
 734 bool pkgOrderList::DepUnPackPre(DepIterator D
) 
 736    if (D
.Reverse() == true) 
 739    for (; D
.end() == false; ++D
) 
 741       /* Only consider the PreDepends or Depends. Depends are only 
 742          considered at the lowest depth or in the case of immediate 
 744       if (D
->Type 
!= pkgCache::Dep::PreDepends
) 
 746          if (D
->Type 
== pkgCache::Dep::Depends
) 
 748             if (Depth 
== 1 && IsFlag(D
.ParentPkg(),Immediate
) == false) 
 755       /* We wish to check if the dep is okay in the now state of the 
 756          target package against the install state of this package. */ 
 757       if (CheckDep(D
) == true) 
 759          /* We want to catch predepends loops with the code below. 
 760             Conflicts loops that are Dep OK are ignored */ 
 761          if (IsFlag(D
.TargetPkg(),AddPending
) == false) 
 765       // This is the loop detection 
 766       if (IsFlag(D
.TargetPkg(),Added
) == true ||  
 767           IsFlag(D
.TargetPkg(),AddPending
) == true) 
 769          if (IsFlag(D
.TargetPkg(),AddPending
) == true) 
 774       if (VisitProvides(D
,true) == false) 
 780 // OrderList::DepUnPackDep - Reverse dependency considerations          /*{{{*/ 
 781 // --------------------------------------------------------------------- 
 782 /* Reverse dependencies are considered to determine if unpacking this 
 783    package will break any existing dependencies. If so then those 
 784    packages are ordered before this one so that they are in the 
 787    The forwards depends loop is designed to bring the packages dependents 
 788    close to the package. This helps reduce deconfigure time.  
 790    Loops are irrelevent to this. */ 
 791 bool pkgOrderList::DepUnPackDep(DepIterator D
) 
 794    for (; D
.end() == false; ++D
) 
 795       if (D
.IsCritical() == true) 
 797          if (D
.Reverse() == true) 
 799             /* Duplication prevention. We consider rev deps only on 
 800                the current version, a not installed package 
 802             if (D
.ParentPkg()->CurrentVer 
== 0 || 
 803                 D
.ParentPkg().CurrentVer() != D
.ParentVer()) 
 806             // The dep will not break so it is irrelevent. 
 807             if (CheckDep(D
) == true) 
 810             // Skip over missing files 
 811             if (IsMissing(D
.ParentPkg()) == true) 
 814             if (VisitNode(D
.ParentPkg()) == false) 
 819             if (D
->Type 
== pkgCache::Dep::Depends
) 
 820                if (VisitProvides(D
,false) == false) 
 823             if (D
->Type 
== pkgCache::Dep::DpkgBreaks
) 
 825                if (CheckDep(D
) == true) 
 828                if (VisitNode(D
.TargetPkg()) == false) 
 836 // OrderList::DepConfigure - Configuration ordering                     /*{{{*/ 
 837 // --------------------------------------------------------------------- 
 838 /* Configuration only ordering orders by the Depends: line only. It 
 839    orders configuration so that when a package comes to be configured it's 
 840    dependents are configured.  
 842    Loops are ingored. Depends loop entry points are chaotic. */ 
 843 bool pkgOrderList::DepConfigure(DepIterator D
) 
 845    // Never consider reverse configuration dependencies. 
 846    if (D
.Reverse() == true) 
 849    for (; D
.end() == false; ++D
) 
 850       if (D
->Type 
== pkgCache::Dep::Depends
) 
 851          if (VisitProvides(D
,false) == false) 
 856 // OrderList::DepRemove - Removal ordering                              /*{{{*/ 
 857 // --------------------------------------------------------------------- 
 858 /* Removal visits all reverse depends. It considers if the dependency 
 859    of the Now state version to see if it is okay with removing this 
 860    package. This check should always fail, but is provided for symetery 
 861    with the other critical handlers. 
 863    Loops are preprocessed and logged. Removal loops can also be 
 864    detected in the critical handler. They are characterized by an 
 865    old version of A depending on B but the new version of A conflicting 
 866    with B, thus either A or B must break to install. */ 
 867 bool pkgOrderList::DepRemove(DepIterator D
) 
 869    if (D
.Reverse() == false) 
 871    for (; D
.end() == false; ++D
) 
 872       if (D
->Type 
== pkgCache::Dep::Depends 
|| D
->Type 
== pkgCache::Dep::PreDepends
) 
 874          // Duplication elimination, consider the current version only 
 875          if (D
.ParentPkg().CurrentVer() != D
.ParentVer()) 
 878          /* We wish to see if the dep on the parent package is okay 
 879             in the removed (install) state of the target pkg. */ 
 880          bool tryFixDeps 
= false; 
 881          if (CheckDep(D
) == true) 
 883             // We want to catch loops with the code below. 
 884             if (IsFlag(D
.ParentPkg(),AddPending
) == false) 
 890          // This is the loop detection 
 891          if (IsFlag(D
.ParentPkg(),Added
) == true ||  
 892              IsFlag(D
.ParentPkg(),AddPending
) == true) 
 894             if (IsFlag(D
.ParentPkg(),AddPending
) == true) 
 899          if (tryFixDeps 
== true) 
 901             for (pkgCache::DepIterator F 
= D
.ParentPkg().CurrentVer().DependsList(); 
 902                  F
.end() == false; ++F
) 
 904                if (F
->Type 
!= pkgCache::Dep::Depends 
&& F
->Type 
!= pkgCache::Dep::PreDepends
) 
 906                // Check the Providers 
 907                if (F
.TargetPkg()->ProvidesList 
!= 0) 
 909                   pkgCache::PrvIterator Prov 
= F
.TargetPkg().ProvidesList(); 
 910                   for (; Prov
.end() == false; ++Prov
) 
 912                      pkgCache::PkgIterator 
const P 
= Prov
.OwnerPkg(); 
 913                      if (IsFlag(P
, InList
) == true && 
 914                          IsFlag(P
, AddPending
) == true && 
 915                          IsFlag(P
, Added
) == false && 
 916                          Cache
[P
].InstallVer 
== 0) 
 919                   if (Prov
.end() == false) 
 920                      for (pkgCache::PrvIterator Prv 
= F
.TargetPkg().ProvidesList(); 
 921                           Prv
.end() == false; ++Prv
) 
 923                         pkgCache::PkgIterator 
const P 
= Prv
.OwnerPkg(); 
 924                         if (IsFlag(P
, InList
) == true && 
 925                             IsFlag(P
, AddPending
) == false && 
 926                             Cache
[P
].InstallVer 
!= 0 && 
 927                             VisitNode(P
) == true) 
 934                   if (tryFixDeps 
== false) 
 938                // Check for Or groups 
 939                if ((F
->CompareOp 
& pkgCache::Dep::Or
) != pkgCache::Dep::Or
) 
 941                // Lets see if the package is part of the Or group 
 942                pkgCache::DepIterator S 
= F
; 
 943                for (; S
.end() == false; ++S
) 
 945                   if (S
.TargetPkg() == D
.TargetPkg()) 
 947                   if ((S
->CompareOp 
& pkgCache::Dep::Or
) != pkgCache::Dep::Or 
|| 
 948                       CheckDep(S
)) // Or group is satisfied by another package 
 949                      for (;S
.end() == false; ++S
); 
 953                // skip to the end of the or group 
 954                for (;S
.end() == false && (S
->CompareOp 
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
; ++S
); 
 956                // The soon to be removed is part of the Or group 
 957                // start again in the or group and find something which will serve as replacement 
 958                for (; F
.end() == false && F 
!= S
; ++F
) 
 960                   if (IsFlag(F
.TargetPkg(), InList
) == true && 
 961                       IsFlag(F
.TargetPkg(), AddPending
) == false && 
 962                       Cache
[F
.TargetPkg()].InstallVer 
!= 0 && 
 963                       VisitNode(F
.TargetPkg()) == true) 
 965                      Flag(F
.TargetPkg(), Immediate
); 
 969                   else if (F
.TargetPkg()->ProvidesList 
!= 0) 
 971                      pkgCache::PrvIterator Prv 
= F
.TargetPkg().ProvidesList(); 
 972                      for (; Prv
.end() == false; ++Prv
) 
 974                         if (IsFlag(Prv
.OwnerPkg(), InList
) == true && 
 975                             IsFlag(Prv
.OwnerPkg(), AddPending
) == false && 
 976                             Cache
[Prv
.OwnerPkg()].InstallVer 
!= 0 && 
 977                             VisitNode(Prv
.OwnerPkg()) == true) 
 979                            Flag(Prv
.OwnerPkg(), Immediate
); 
 984                      if (Prv
.end() == false) 
 988                if (tryFixDeps 
== false) 
 993          // Skip over missing files 
 994          if (IsMissing(D
.ParentPkg()) == true) 
 997          if (VisitNode(D
.ParentPkg()) == false) 
1004 // OrderList::AddLoop - Add a loop to the loop list                     /*{{{*/ 
1005 // --------------------------------------------------------------------- 
1006 /* We record the loops. This is a relic since loop breaking is done  
1007    genericaly as part of the safety routines. */ 
1008 bool pkgOrderList::AddLoop(DepIterator D
) 
1010    if (LoopCount 
< 0 || LoopCount 
>= 20) 
1016       if (Loops
[LoopCount 
- 1].ParentPkg() == D
.ParentPkg() || 
1017           Loops
[LoopCount 
- 1].TargetPkg() == D
.ParentPkg()) 
1021    Loops
[LoopCount
++] = D
; 
1023    // Mark the packages as being part of a loop. 
1024    Flag(D
.TargetPkg(),Loop
); 
1025    Flag(D
.ParentPkg(),Loop
); 
1029 // OrderList::WipeFlags - Unset the given flags from all packages       /*{{{*/ 
1030 // --------------------------------------------------------------------- 
1032 void pkgOrderList::WipeFlags(unsigned long F
) 
1034    unsigned long Size 
= Cache
.Head().PackageCount
; 
1035    for (unsigned long I 
= 0; I 
!= Size
; I
++) 
1039 // OrderList::CheckDep - Check a dependency for truth                   /*{{{*/ 
1040 // --------------------------------------------------------------------- 
1041 /* This performs a complete analysis of the dependency wrt to the 
1042    current add list. It returns true if after all events are 
1043    performed it is still true. This sort of routine can be approximated 
1044    by examining the DepCache, however in convoluted cases of provides 
1045    this fails to produce a suitable result. */ 
1046 bool pkgOrderList::CheckDep(DepIterator D
) 
1048    SPtrArray
<Version 
*> List 
= D
.AllTargets(); 
1050    for (Version 
**I 
= List
; *I 
!= 0; I
++) 
1052       VerIterator 
Ver(Cache
,*I
); 
1053       PkgIterator Pkg 
= Ver
.ParentPkg(); 
1055       /* The meaning of Added and AddPending is subtle. AddPending is 
1056          an indication that the package is looping. Because of the 
1057          way ordering works Added means the package will be unpacked 
1058          before this one and AddPending means after. It is therefore 
1059          correct to ignore AddPending in all cases, but that exposes 
1060          reverse-ordering loops which should be ignored. */ 
1061       if (IsFlag(Pkg
,Added
) == true || 
1062           (IsFlag(Pkg
,AddPending
) == true && D
.Reverse() == true)) 
1064          if (Cache
[Pkg
].InstallVer 
!= *I
) 
1068          if ((Version 
*)Pkg
.CurrentVer() != *I 
||  
1069              Pkg
.State() != PkgIterator::NeedsNothing
) 
1072       /* Conflicts requires that all versions are not present, depends 
1074       if (D
.IsNegative() == false) 
1076          // ignore provides by older versions of this package 
1077          if (((D
.Reverse() == false && Pkg 
== D
.ParentPkg()) || 
1078               (D
.Reverse() == true && Pkg 
== D
.TargetPkg())) && 
1079              Cache
[Pkg
].InstallVer 
!= *I
) 
1082          /* Try to find something that does not have the after flag set 
1083             if at all possible */ 
1084          if (IsFlag(Pkg
,After
) == true) 
1094          if (IsFlag(Pkg
,After
) == true) 
1095             Flag(D
.ParentPkg(),After
); 
1101    // We found a hit, but it had the after flag set 
1102    if (Hit 
== true && D
->Type 
== pkgCache::Dep::PreDepends
) 
1104       Flag(D
.ParentPkg(),After
); 
1108    /* Conflicts requires that all versions are not present, depends 
1110    if (D
->Type 
== pkgCache::Dep::Conflicts 
|| 
1111        D
->Type 
== pkgCache::Dep::Obsoletes
)