]>
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/version.h> 
  72 #include <apt-pkg/sptr.h> 
  73 #include <apt-pkg/configuration.h> 
  80 pkgOrderList 
*pkgOrderList::Me 
= 0; 
  82 // OrderList::pkgOrderList - Constructor                                /*{{{*/ 
  83 // --------------------------------------------------------------------- 
  85 pkgOrderList::pkgOrderList(pkgDepCache 
*pCache
) : Cache(*pCache
), 
  86                                                   Primary(NULL
), Secondary(NULL
), 
  87                                                   RevDepends(NULL
), Remove(NULL
), 
  88                                                   AfterEnd(NULL
), FileList(NULL
), 
  89                                                   LoopCount(-1), Depth(0) 
  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
), "DoRun") == 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    // Removals should be done after we dealt with essentials 
 305    static int const ScoreDelete 
= _config
->FindI("OrderList::Score::Delete", 100); 
 306    if (Cache
[Pkg
].Delete() == true) 
 309    // This should never happen.. 
 310    if (Cache
[Pkg
].InstVerIter(Cache
).end() == true) 
 313    static int const ScoreEssential 
= _config
->FindI("OrderList::Score::Essential", 200); 
 314    static int const ScoreImmediate 
= _config
->FindI("OrderList::Score::Immediate", 10); 
 315    static int const ScorePreDepends 
= _config
->FindI("OrderList::Score::PreDepends", 50); 
 318    if ((Pkg
->Flags 
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
) 
 319       Score 
+= ScoreEssential
; 
 321    if (IsFlag(Pkg
,Immediate
) == true) 
 322       Score 
+= ScoreImmediate
; 
 324    for (DepIterator D 
= Cache
[Pkg
].InstVerIter(Cache
).DependsList(); 
 325         D
.end() == false; ++D
) 
 326       if (D
->Type 
== pkgCache::Dep::PreDepends
) 
 328          Score 
+= ScorePreDepends
; 
 332    // Important Required Standard Optional Extra 
 333    if (Cache
[Pkg
].InstVerIter(Cache
)->Priority 
<= 5) 
 335       signed short PrioMap
[] = {0,5,4,3,1,0}; 
 336       Score 
+= PrioMap
[Cache
[Pkg
].InstVerIter(Cache
)->Priority
]; 
 341 // OrderList::FileCmp - Compare by package file                         /*{{{*/ 
 342 // --------------------------------------------------------------------- 
 343 /* This compares by the package file that the install version is in. */ 
 344 int pkgOrderList::FileCmp(PkgIterator A
,PkgIterator B
) 
 346    if (Cache
[A
].Delete() == true && Cache
[B
].Delete() == true) 
 348    if (Cache
[A
].Delete() == true) 
 350    if (Cache
[B
].Delete() == true) 
 353    if (Cache
[A
].InstVerIter(Cache
).FileList().end() == true) 
 355    if (Cache
[B
].InstVerIter(Cache
).FileList().end() == true) 
 358    pkgCache::PackageFile 
*FA 
= Cache
[A
].InstVerIter(Cache
).FileList().File(); 
 359    pkgCache::PackageFile 
*FB 
= Cache
[B
].InstVerIter(Cache
).FileList().File(); 
 367 // BoolCompare - Comparison function for two booleans                   /*{{{*/ 
 368 // --------------------------------------------------------------------- 
 370 static int BoolCompare(bool A
,bool B
) 
 379 // OrderList::OrderCompareA - Order the installation by op              /*{{{*/ 
 380 // --------------------------------------------------------------------- 
 381 /* This provides a first-pass sort of the list and gives a decent starting 
 382     point for further complete ordering. It is used by OrderUnpack only */ 
 383 int pkgOrderList::OrderCompareA(const void *a
, const void *b
) 
 385    PkgIterator 
A(Me
->Cache
,*(Package 
**)a
); 
 386    PkgIterator 
B(Me
->Cache
,*(Package 
**)b
); 
 388    // We order packages with a set state toward the front 
 390    if ((Res 
= BoolCompare(Me
->IsNow(A
),Me
->IsNow(B
))) != 0) 
 393    // We order missing files to toward the end 
 394 /*   if (Me->FileList != 0) 
 396       if ((Res = BoolCompare(Me->IsMissing(A), 
 397                              Me->IsMissing(B))) != 0) 
 401    if (A
.State() != pkgCache::PkgIterator::NeedsNothing 
&&  
 402        B
.State() == pkgCache::PkgIterator::NeedsNothing
) 
 405    if (A
.State() == pkgCache::PkgIterator::NeedsNothing 
&&  
 406        B
.State() != pkgCache::PkgIterator::NeedsNothing
) 
 409    int ScoreA 
= Me
->Score(A
); 
 410    int ScoreB 
= Me
->Score(B
); 
 418    return strcmp(A
.Name(),B
.Name()); 
 421 // OrderList::OrderCompareB - Order the installation by source          /*{{{*/ 
 422 // --------------------------------------------------------------------- 
 423 /* This orders by installation source. This is useful to handle 
 424    inter-source breaks */ 
 425 int pkgOrderList::OrderCompareB(const void *a
, const void *b
) 
 427    PkgIterator 
A(Me
->Cache
,*(Package 
**)a
); 
 428    PkgIterator 
B(Me
->Cache
,*(Package 
**)b
); 
 430    if (A
.State() != pkgCache::PkgIterator::NeedsNothing 
&&  
 431        B
.State() == pkgCache::PkgIterator::NeedsNothing
) 
 434    if (A
.State() == pkgCache::PkgIterator::NeedsNothing 
&&  
 435        B
.State() != pkgCache::PkgIterator::NeedsNothing
) 
 438    int F 
= Me
->FileCmp(A
,B
); 
 446    int ScoreA 
= Me
->Score(A
); 
 447    int ScoreB 
= Me
->Score(B
); 
 455    return strcmp(A
.Name(),B
.Name()); 
 458 // OrderList::VisitDeps - Visit forward install dependencies            /*{{{*/ 
 459 // --------------------------------------------------------------------- 
 460 /* This calls the dependency function for the normal forwards dependencies 
 462 bool pkgOrderList::VisitDeps(DepFunc F
,PkgIterator Pkg
) 
 464    if (F 
== 0 || Pkg
.end() == true || Cache
[Pkg
].InstallVer 
== 0) 
 467    return (this->*F
)(Cache
[Pkg
].InstVerIter(Cache
).DependsList()); 
 470 // OrderList::VisitRDeps - Visit reverse dependencies                   /*{{{*/ 
 471 // --------------------------------------------------------------------- 
 472 /* This calls the dependency function for all of the normal reverse depends 
 474 bool pkgOrderList::VisitRDeps(DepFunc F
,PkgIterator Pkg
) 
 476    if (F 
== 0 || Pkg
.end() == true) 
 479    return (this->*F
)(Pkg
.RevDependsList()); 
 482 // OrderList::VisitRProvides - Visit provides reverse dependencies      /*{{{*/ 
 483 // --------------------------------------------------------------------- 
 484 /* This calls the dependency function for all reverse dependencies 
 485    generated by the provides line on the package. */ 
 486 bool pkgOrderList::VisitRProvides(DepFunc F
,VerIterator Ver
) 
 488    if (F 
== 0 || Ver
.end() == true) 
 492    for (PrvIterator P 
= Ver
.ProvidesList(); P
.end() == false; ++P
) 
 493       Res 
&= (this->*F
)(P
.ParentPkg().RevDependsList()); 
 497 // OrderList::VisitProvides - Visit all of the providing packages       /*{{{*/ 
 498 // --------------------------------------------------------------------- 
 499 /* This routine calls visit on all providing packages. 
 501    If the dependency is negative it first visits packages which are 
 502    intended to be removed and after that all other packages. 
 503    It does so to avoid situations in which this package is used to 
 504    satisfy a (or-group/provides) dependency of another package which 
 505    could have been satisfied also by upgrading another package - 
 506    otherwise we have more broken packages dpkg needs to auto- 
 507    deconfigure and in very complicated situations it even decides 
 509 bool pkgOrderList::VisitProvides(DepIterator D
,bool Critical
) 
 511    SPtrArray
<Version 
*> List 
= D
.AllTargets(); 
 512    for (Version 
**I 
= List
; *I 
!= 0; ++I
) 
 514       VerIterator 
Ver(Cache
,*I
); 
 515       PkgIterator Pkg 
= Ver
.ParentPkg(); 
 517       if (D
.IsNegative() == true && Cache
[Pkg
].Delete() == false) 
 520       if (Cache
[Pkg
].Keep() == true && Pkg
.State() == PkgIterator::NeedsNothing
) 
 523       if (D
.IsNegative() == false && 
 524           Cache
[Pkg
].InstallVer 
!= *I
) 
 527       if (D
.IsNegative() == true && 
 528           (Version 
*)Pkg
.CurrentVer() != *I
) 
 531       // Skip over missing files 
 532       if (Critical 
== false && IsMissing(D
.ParentPkg()) == true) 
 535       if (VisitNode(Pkg
, "Provides-1") == false) 
 538    if (D
.IsNegative() == false) 
 540    for (Version 
**I 
= List
; *I 
!= 0; ++I
) 
 542       VerIterator 
Ver(Cache
,*I
); 
 543       PkgIterator Pkg 
= Ver
.ParentPkg(); 
 545       if (Cache
[Pkg
].Delete() == true) 
 548       if (Cache
[Pkg
].Keep() == true && Pkg
.State() == PkgIterator::NeedsNothing
) 
 551       if ((Version 
*)Pkg
.CurrentVer() != *I
) 
 554       // Skip over missing files 
 555       if (Critical 
== false && IsMissing(D
.ParentPkg()) == true) 
 558       if (VisitNode(Pkg
, "Provides-2") == false) 
 565 // OrderList::VisitNode - Recursive ordering director                   /*{{{*/ 
 566 // --------------------------------------------------------------------- 
 567 /* This is the core ordering routine. It calls the set dependency 
 568    consideration functions which then potentialy call this again. Finite 
 569    depth is achieved through the colouring mechinism. */ 
 570 bool pkgOrderList::VisitNode(PkgIterator Pkg
, char const* from
) 
 572    // Looping or irrelevant. 
 573    // This should probably trancend not installed packages 
 574    if (Pkg
.end() == true || IsFlag(Pkg
,Added
) == true ||  
 575        IsFlag(Pkg
,AddPending
) == true || IsFlag(Pkg
,InList
) == false) 
 580       for (int j 
= 0; j 
!= Depth
; j
++) clog 
<< ' '; 
 581       clog 
<< "Visit " << Pkg
.FullName() << " from " << from 
<< endl
; 
 587    Flag(Pkg
,AddPending
); 
 589    DepFunc Old 
= Primary
; 
 591    // Perform immedate configuration of the package if so flagged. 
 592    if (IsFlag(Pkg
,Immediate
) == true && Primary 
!= &pkgOrderList::DepUnPackPre
) 
 593       Primary 
= &pkgOrderList::DepUnPackPreD
; 
 595    if (IsNow(Pkg
) == true) 
 598       if (Cache
[Pkg
].Delete() == false) 
 601          Res 
&= Res 
&& VisitDeps(Primary
,Pkg
); 
 602          Res 
&= Res 
&& VisitRDeps(Primary
,Pkg
); 
 603          Res 
&= Res 
&& VisitRProvides(Primary
,Pkg
.CurrentVer()); 
 604          Res 
&= Res 
&& VisitRProvides(Primary
,Cache
[Pkg
].InstVerIter(Cache
)); 
 607          Res 
&= Res 
&& VisitRDeps(RevDepends
,Pkg
); 
 608          Res 
&= Res 
&& VisitRProvides(RevDepends
,Pkg
.CurrentVer()); 
 609          Res 
&= Res 
&& VisitRProvides(RevDepends
,Cache
[Pkg
].InstVerIter(Cache
)); 
 612          Res 
&= Res 
&& VisitDeps(Secondary
,Pkg
); 
 613          Res 
&= Res 
&& VisitRDeps(Secondary
,Pkg
); 
 614          Res 
&= Res 
&& VisitRProvides(Secondary
,Pkg
.CurrentVer()); 
 615          Res 
&= Res 
&& VisitRProvides(Secondary
,Cache
[Pkg
].InstVerIter(Cache
)); 
 620          Res 
&= Res 
&& VisitRDeps(Remove
,Pkg
); 
 621          Res 
&= Res 
&& VisitRProvides(Remove
,Pkg
.CurrentVer()); 
 625    if (IsFlag(Pkg
,Added
) == false) 
 627       Flag(Pkg
,Added
,Added 
| AddPending
); 
 628       if (IsFlag(Pkg
,After
) == true) 
 639       for (int j 
= 0; j 
!= Depth
; j
++) clog 
<< ' '; 
 640       clog 
<< "Leave " << Pkg
.FullName() << ' ' << IsFlag(Pkg
,Added
) << ',' << IsFlag(Pkg
,AddPending
) << endl
; 
 646 // OrderList::DepUnPackCrit - Critical UnPacking ordering               /*{{{*/ 
 647 // --------------------------------------------------------------------- 
 648 /* Critical unpacking ordering strives to satisfy Conflicts: and  
 649    PreDepends: only. When a prdepends is encountered the Primary  
 650    DepFunc is changed to be DepUnPackPreD.  
 652    Loops are preprocessed and logged. */ 
 653 bool pkgOrderList::DepUnPackCrit(DepIterator D
) 
 655    for (; D
.end() == false; ++D
) 
 657       if (D
.Reverse() == true) 
 659          /* Reverse depenanices are only interested in conflicts, 
 660             predepend breakage is ignored here */ 
 661          if (D
->Type 
!= pkgCache::Dep::Conflicts 
&&  
 662              D
->Type 
!= pkgCache::Dep::Obsoletes
) 
 665          // Duplication elimination, consider only the current version 
 666          if (D
.ParentPkg().CurrentVer() != D
.ParentVer()) 
 669          /* For reverse dependencies we wish to check if the 
 670             dependency is satisifed in the install state. The 
 671             target package (caller) is going to be in the installed 
 673          if (CheckDep(D
) == true) 
 676          if (VisitNode(D
.ParentPkg(), "UnPackCrit") == false) 
 681          /* Forward critical dependencies MUST be correct before the  
 682             package can be unpacked. */ 
 683          if (D
.IsNegative() == false && 
 684              D
->Type 
!= pkgCache::Dep::PreDepends
) 
 687          /* We wish to check if the dep is okay in the now state of the 
 688             target package against the install state of this package. */ 
 689          if (CheckDep(D
) == true) 
 691             /* We want to catch predepends loops with the code below. 
 692                Conflicts loops that are Dep OK are ignored */ 
 693             if (IsFlag(D
.TargetPkg(),AddPending
) == false || 
 694                 D
->Type 
!= pkgCache::Dep::PreDepends
) 
 698          // This is the loop detection 
 699          if (IsFlag(D
.TargetPkg(),Added
) == true ||  
 700              IsFlag(D
.TargetPkg(),AddPending
) == true) 
 702             if (IsFlag(D
.TargetPkg(),AddPending
) == true) 
 707          /* Predepends require a special ordering stage, they must have 
 708             all dependents installed as well */ 
 709          DepFunc Old 
= Primary
; 
 711          if (D
->Type 
== pkgCache::Dep::PreDepends
) 
 712             Primary 
= &pkgOrderList::DepUnPackPreD
; 
 713          Res 
= VisitProvides(D
,true); 
 722 // OrderList::DepUnPackPreD - Critical UnPacking ordering with depends  /*{{{*/ 
 723 // --------------------------------------------------------------------- 
 724 /* Critical PreDepends (also configure immediate and essential) strives to 
 725    ensure not only that all conflicts+predepends are met but that this 
 726    package will be immediately configurable when it is unpacked. 
 727    Loops are preprocessed and logged. */ 
 728 bool pkgOrderList::DepUnPackPreD(DepIterator D
) 
 730    if (D
.Reverse() == true) 
 731       return DepUnPackCrit(D
); 
 733    for (; D
.end() == false; ++D
) 
 735       if (D
.IsCritical() == 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 || 
 745              D
->Type 
!= pkgCache::Dep::PreDepends
) 
 749       // This is the loop detection 
 750       if (IsFlag(D
.TargetPkg(),Added
) == true ||  
 751           IsFlag(D
.TargetPkg(),AddPending
) == true) 
 753          if (IsFlag(D
.TargetPkg(),AddPending
) == true) 
 758       if (VisitProvides(D
,true) == false) 
 764 // OrderList::DepUnPackPre - Critical Predepends ordering               /*{{{*/ 
 765 // --------------------------------------------------------------------- 
 766 /* Critical PreDepends (also configure immediate and essential) strives to 
 767    ensure not only that all conflicts+predepends are met but that this 
 768    package will be immediately configurable when it is unpacked.  
 770    Loops are preprocessed and logged. All loops will be fatal. */ 
 771 bool pkgOrderList::DepUnPackPre(DepIterator D
) 
 773    if (D
.Reverse() == true) 
 776    for (; D
.end() == false; ++D
) 
 778       /* Only consider the PreDepends or Depends. Depends are only 
 779          considered at the lowest depth or in the case of immediate 
 781       if (D
->Type 
!= pkgCache::Dep::PreDepends
) 
 783          if (D
->Type 
== pkgCache::Dep::Depends
) 
 785             if (Depth 
== 1 && IsFlag(D
.ParentPkg(),Immediate
) == false) 
 792       /* We wish to check if the dep is okay in the now state of the 
 793          target package against the install state of this package. */ 
 794       if (CheckDep(D
) == true) 
 796          /* We want to catch predepends loops with the code below. 
 797             Conflicts loops that are Dep OK are ignored */ 
 798          if (IsFlag(D
.TargetPkg(),AddPending
) == false) 
 802       // This is the loop detection 
 803       if (IsFlag(D
.TargetPkg(),Added
) == true ||  
 804           IsFlag(D
.TargetPkg(),AddPending
) == true) 
 806          if (IsFlag(D
.TargetPkg(),AddPending
) == true) 
 811       if (VisitProvides(D
,true) == false) 
 817 // OrderList::DepUnPackDep - Reverse dependency considerations          /*{{{*/ 
 818 // --------------------------------------------------------------------- 
 819 /* Reverse dependencies are considered to determine if unpacking this 
 820    package will break any existing dependencies. If so then those 
 821    packages are ordered before this one so that they are in the 
 824    The forwards depends loop is designed to bring the packages dependents 
 825    close to the package. This helps reduce deconfigure time.  
 827    Loops are irrelevant to this. */ 
 828 bool pkgOrderList::DepUnPackDep(DepIterator D
) 
 831    for (; D
.end() == false; ++D
) 
 832       if (D
.IsCritical() == true) 
 834          if (D
.Reverse() == true) 
 836             /* Duplication prevention. We consider rev deps only on 
 837                the current version, a not installed package 
 839             if (D
.ParentPkg()->CurrentVer 
== 0 || 
 840                 D
.ParentPkg().CurrentVer() != D
.ParentVer()) 
 843             // The dep will not break so it is irrelevant. 
 844             if (CheckDep(D
) == true) 
 847             // Skip over missing files 
 848             if (IsMissing(D
.ParentPkg()) == true) 
 851             if (VisitNode(D
.ParentPkg(), "UnPackDep-Parent") == false) 
 856             if (D
->Type 
== pkgCache::Dep::Depends
) 
 857                if (VisitProvides(D
,false) == false) 
 860             if (D
->Type 
== pkgCache::Dep::DpkgBreaks
) 
 862                if (CheckDep(D
) == true) 
 865                if (VisitNode(D
.TargetPkg(), "UnPackDep-Target") == false) 
 873 // OrderList::DepConfigure - Configuration ordering                     /*{{{*/ 
 874 // --------------------------------------------------------------------- 
 875 /* Configuration only ordering orders by the Depends: line only. It 
 876    orders configuration so that when a package comes to be configured it's 
 877    dependents are configured.  
 879    Loops are ingored. Depends loop entry points are chaotic. */ 
 880 bool pkgOrderList::DepConfigure(DepIterator D
) 
 882    // Never consider reverse configuration dependencies. 
 883    if (D
.Reverse() == true) 
 886    for (; D
.end() == false; ++D
) 
 887       if (D
->Type 
== pkgCache::Dep::Depends
) 
 888          if (VisitProvides(D
,false) == false) 
 893 // OrderList::DepRemove - Removal ordering                              /*{{{*/ 
 894 // --------------------------------------------------------------------- 
 895 /* Checks all given dependencies if they are broken by the remove of a 
 896    package and if so fix it by visiting another provider or or-group 
 897    member to ensure that the dependee keeps working which is especially 
 898    important for Immediate packages like e.g. those depending on an 
 899    awk implementation. If the dependency can't be fixed with another 
 900    package this means an upgrade of the package will solve the problem. */ 
 901 bool pkgOrderList::DepRemove(DepIterator Broken
) 
 903    if (Broken
.Reverse() == false) 
 906    for (; Broken
.end() == false; ++Broken
) 
 908       if (Broken
->Type 
!= pkgCache::Dep::Depends 
&& 
 909             Broken
->Type 
!= pkgCache::Dep::PreDepends
) 
 912       PkgIterator BrokenPkg 
= Broken
.ParentPkg(); 
 913       // uninstalled packages can't break via a remove 
 914       if (BrokenPkg
->CurrentVer 
== 0) 
 917       // if its already added, we can't do anything useful 
 918       if (IsFlag(BrokenPkg
, AddPending
) == true || IsFlag(BrokenPkg
, Added
) == true) 
 921       // if the dependee is going to be removed, visit it now 
 922       if (Cache
[BrokenPkg
].Delete() == true) 
 923          return VisitNode(BrokenPkg
, "Remove-Dependee"); 
 925       // The package stays around, so find out how this is possible 
 926       for (DepIterator D 
= BrokenPkg
.CurrentVer().DependsList(); D
.end() == false;) 
 928          // only important or-groups need fixing 
 929          if (D
->Type 
!= pkgCache::Dep::Depends 
&& 
 930                D
->Type 
!= pkgCache::Dep::PreDepends
) 
 936          // Start is the beginning of the or-group, D is the first one after or 
 937          DepIterator Start 
= D
; 
 938          bool foundBroken 
= false; 
 939          for (bool LastOR 
= true; D
.end() == false && LastOR 
== true; ++D
) 
 941             LastOR 
= (D
->CompareOp 
& pkgCache::Dep::Or
) == pkgCache::Dep::Or
; 
 946          // this or-group isn't the broken one: keep searching 
 947          if (foundBroken 
== false) 
 950          // iterate over all members of the or-group searching for a ready replacement 
 951          bool readyReplacement 
= false; 
 952          for (DepIterator OrMember 
= Start
; OrMember 
!= D 
&& readyReplacement 
== false; ++OrMember
) 
 954             Version 
** Replacements 
= OrMember
.AllTargets(); 
 955             for (Version 
**R 
= Replacements
; *R 
!= 0; ++R
) 
 957                VerIterator 
Ver(Cache
,*R
); 
 958                // only currently installed packages can be a replacement 
 959                PkgIterator RPkg 
= Ver
.ParentPkg(); 
 960                if (RPkg
.CurrentVer() != Ver
) 
 963                // packages going to be removed can't be a replacement 
 964                if (Cache
[RPkg
].Delete() == true) 
 967                readyReplacement 
= true; 
 970             delete[] Replacements
; 
 973          // something else is ready to take over, do nothing 
 974          if (readyReplacement 
== true) 
 977          // see if we can visit a replacement 
 978          bool visitReplacement 
= false; 
 979          for (DepIterator OrMember 
= Start
; OrMember 
!= D 
&& visitReplacement 
== false; ++OrMember
) 
 981             Version 
** Replacements 
= OrMember
.AllTargets(); 
 982             for (Version 
**R 
= Replacements
; *R 
!= 0; ++R
) 
 984                VerIterator 
Ver(Cache
,*R
); 
 985                // consider only versions we plan to install 
 986                PkgIterator RPkg 
= Ver
.ParentPkg(); 
 987                if (Cache
[RPkg
].Install() == false || Cache
[RPkg
].InstallVer 
!= Ver
) 
 990                // loops are not going to help us, so don't create them 
 991                if (IsFlag(RPkg
, AddPending
) == true) 
 994                if (IsMissing(RPkg
) == true) 
 997                visitReplacement 
= true; 
 998                if (IsFlag(BrokenPkg
, Immediate
) == false) 
1000                   if (VisitNode(RPkg
, "Remove-Rep") == true) 
1005                   Flag(RPkg
, Immediate
); 
1006                   if (VisitNode(RPkg
, "Remove-ImmRep") == true) 
1009                visitReplacement 
= false; 
1011             delete[] Replacements
; 
1013          if (visitReplacement 
== true) 
1016          // the broken package in current version can't be fixed, so install new version 
1017          if (IsMissing(BrokenPkg
) == true) 
1020          if (VisitNode(BrokenPkg
, "Remove-Upgrade") == false) 
1028 // OrderList::AddLoop - Add a loop to the loop list                     /*{{{*/ 
1029 // --------------------------------------------------------------------- 
1030 /* We record the loops. This is a relic since loop breaking is done  
1031    genericaly as part of the safety routines. */ 
1032 bool pkgOrderList::AddLoop(DepIterator D
) 
1034    if (LoopCount 
< 0 || LoopCount 
>= 20) 
1040       if (Loops
[LoopCount 
- 1].ParentPkg() == D
.ParentPkg() || 
1041           Loops
[LoopCount 
- 1].TargetPkg() == D
.ParentPkg()) 
1045    Loops
[LoopCount
++] = D
; 
1047    // Mark the packages as being part of a loop. 
1048    //Flag(D.TargetPkg(),Loop); 
1049    //Flag(D.ParentPkg(),Loop); 
1050    /* This is currently disabled because the Loop flag is being used for 
1051       loop management in the package manager. Check the orderlist.h file for more info */ 
1055 // OrderList::WipeFlags - Unset the given flags from all packages       /*{{{*/ 
1056 // --------------------------------------------------------------------- 
1058 void pkgOrderList::WipeFlags(unsigned long F
) 
1060    unsigned long Size 
= Cache
.Head().PackageCount
; 
1061    for (unsigned long I 
= 0; I 
!= Size
; I
++) 
1065 // OrderList::CheckDep - Check a dependency for truth                   /*{{{*/ 
1066 // --------------------------------------------------------------------- 
1067 /* This performs a complete analysis of the dependency wrt to the 
1068    current add list. It returns true if after all events are 
1069    performed it is still true. This sort of routine can be approximated 
1070    by examining the DepCache, however in convoluted cases of provides 
1071    this fails to produce a suitable result. */ 
1072 bool pkgOrderList::CheckDep(DepIterator D
) 
1074    SPtrArray
<Version 
*> List 
= D
.AllTargets(); 
1076    for (Version 
**I 
= List
; *I 
!= 0; I
++) 
1078       VerIterator 
Ver(Cache
,*I
); 
1079       PkgIterator Pkg 
= Ver
.ParentPkg(); 
1081       /* The meaning of Added and AddPending is subtle. AddPending is 
1082          an indication that the package is looping. Because of the 
1083          way ordering works Added means the package will be unpacked 
1084          before this one and AddPending means after. It is therefore 
1085          correct to ignore AddPending in all cases, but that exposes 
1086          reverse-ordering loops which should be ignored. */ 
1087       if (IsFlag(Pkg
,Added
) == true || 
1088           (IsFlag(Pkg
,AddPending
) == true && D
.Reverse() == true)) 
1090          if (Cache
[Pkg
].InstallVer 
!= *I
) 
1094          if ((Version 
*)Pkg
.CurrentVer() != *I 
||  
1095              Pkg
.State() != PkgIterator::NeedsNothing
) 
1098       /* Conflicts requires that all versions are not present, depends 
1100       if (D
.IsNegative() == false) 
1102          // ignore provides by older versions of this package 
1103          if (((D
.Reverse() == false && Pkg 
== D
.ParentPkg()) || 
1104               (D
.Reverse() == true && Pkg 
== D
.TargetPkg())) && 
1105              Cache
[Pkg
].InstallVer 
!= *I
) 
1108          /* Try to find something that does not have the after flag set 
1109             if at all possible */ 
1110          if (IsFlag(Pkg
,After
) == true) 
1120          if (IsFlag(Pkg
,After
) == true) 
1121             Flag(D
.ParentPkg(),After
); 
1127    // We found a hit, but it had the after flag set 
1128    if (Hit 
== true && D
->Type 
== pkgCache::Dep::PreDepends
) 
1130       Flag(D
.ParentPkg(),After
); 
1134    /* Conflicts requires that all versions are not present, depends 
1136    if (D
->Type 
== pkgCache::Dep::Conflicts 
|| 
1137        D
->Type 
== pkgCache::Dep::Obsoletes
)