]>
git.saurik.com Git - apt.git/blob - apt-pkg/orderlist.cc
   1 // -*- mode: cpp; mode: fold -*- 
   3 // $Id: orderlist.cc,v 1.2 1998/07/12 23:58:28 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 usefull 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    arbitary priority to give quite abit of control over the final unpacking 
  45    The rules listed above my 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    ##################################################################### */ 
  51 // Include Files                                                        /*{{{*/ 
  53 #pragma implementation "apt-pkg/orderlist.h" 
  55 #include <apt-pkg/orderlist.h> 
  56 #include <apt-pkg/depcache.h> 
  57 #include <apt-pkg/error.h> 
  58 #include <apt-pkg/version.h> 
  61 pkgOrderList 
*pkgOrderList::Me 
= 0; 
  63 // OrderList::pkgOrderList - Constructor                                /*{{{*/ 
  64 // --------------------------------------------------------------------- 
  66 pkgOrderList::pkgOrderList(pkgDepCache 
&Cache
) : Cache(Cache
) 
  74    /* Construct the arrays, egcs 1.0.1 bug requires the package count 
  76    unsigned long Size 
= Cache
.HeaderP
->PackageCount
; 
  77    Flags 
= new unsigned char[Size
]; 
  78    End 
= List 
= new Package 
*[Size
]; 
  79    memset(Flags
,0,sizeof(*Flags
)*Size
); 
  82 // OrderList::~pkgOrderList - Destructor                                /*{{{*/ 
  83 // --------------------------------------------------------------------- 
  85 pkgOrderList::~pkgOrderList() 
  92 // OrderList::DoRun - Does an order run                                 /*{{{*/ 
  93 // --------------------------------------------------------------------- 
  94 /* The caller is expeted to have setup the desired probe state */ 
  95 bool pkgOrderList::DoRun() 
  98    unsigned long Size 
= Cache
.HeaderP
->PackageCount
; 
  99    Package 
**NList 
= new Package 
*[Size
]; 
 102    WipeFlags(Added 
| AddPending 
| Loop 
| InList
); 
 104    for (iterator I 
= List
; I 
!= End
; I
++) 
 107    // Rebuild the main list into the temp list. 
 108    iterator OldEnd 
= End
; 
 110    for (iterator I 
= List
; I 
!= OldEnd
; I
++) 
 111       if (VisitNode(PkgIterator(Cache
,*I
)) == false) 
 118    // Swap the main list to the new list 
 124 // OrderList::OrderCritical - Perform critical unpacking ordering       /*{{{*/ 
 125 // --------------------------------------------------------------------- 
 126 /* This performs predepends and immediate configuration ordering only.  
 127    This is termed critical unpacking ordering. Any loops that form are 
 128    fatal and indicate that the packages cannot be installed. */ 
 129 bool pkgOrderList::OrderCritical() 
 131    Primary 
= &DepUnPackPre
; 
 139    qsort(List
,End 
- List
,sizeof(*List
),&OrderCompareB
);    
 141    if (DoRun() == false) 
 145       return _error
->Error("Fatal, predepends looping detected"); 
 149 // OrderList::OrderUnpack - Perform complete unpacking ordering         /*{{{*/ 
 150 // --------------------------------------------------------------------- 
 151 /* This performs complete unpacking ordering and creates an order that is 
 152    suitable for unpacking */ 
 153 bool pkgOrderList::OrderUnpack() 
 155    Primary 
= &DepUnPackCrit
; 
 156    Secondary 
= &DepConfigure
; 
 157    RevDepends 
= &DepUnPackDep
; 
 163    qsort(List
,End 
- List
,sizeof(*List
),&OrderCompareA
); 
 165    if (DoRun() == false) 
 169    if (DoRun() == false) 
 174    Remove 
= 0;             // Otherwise the libreadline remove problem occures 
 175    if (DoRun() == false) 
 179    Primary 
= &DepUnPackPre
; 
 180    if (DoRun() == false) 
 183 /*   cout << "----------END" << endl; 
 185    for (iterator I = List; I != End; I++) 
 187       PkgIterator P(Cache,*I); 
 188       cout << P.Name() << endl; 
 194 // OrderList::OrderConfigure - Perform configuration ordering           /*{{{*/ 
 195 // --------------------------------------------------------------------- 
 196 /* This orders by depends only and produces an order which is suitable 
 198 bool pkgOrderList::OrderConfigure() 
 200    Primary 
= &DepConfigure
; 
 209 // OrderList::Score - Score the package for sorting                     /*{{{*/ 
 210 // --------------------------------------------------------------------- 
 211 /* Higher scores order earlier */ 
 212 int pkgOrderList::Score(PkgIterator Pkg
) 
 214    // Removal is always done first 
 215    if (Cache
[Pkg
].Delete() == true) 
 219    if ((Pkg
->Flags 
& pkgCache::Flag::Essential
) == pkgCache::Flag::Essential
) 
 222    for (DepIterator D 
= Cache
[Pkg
].InstVerIter(Cache
).DependsList();  
 223         D
.end() == false; D
++) 
 224       if (D
->Type 
== pkgCache::Dep::PreDepends
) 
 230    // Important Required Standard Optional Extra 
 231    signed short PrioMap
[] = {0,5,4,3,1,0}; 
 232    if (Cache
[Pkg
].InstVerIter(Cache
)->Priority 
<= 5) 
 233       Score 
+= PrioMap
[Cache
[Pkg
].InstVerIter(Cache
)->Priority
]; 
 237 // OrderList::FileCmp - Compare by package file                         /*{{{*/ 
 238 // --------------------------------------------------------------------- 
 239 /* This compares by the package file that the install version is in. */ 
 240 int pkgOrderList::FileCmp(PkgIterator A
,PkgIterator B
) 
 242    if (Cache
[A
].Delete() == true && Cache
[B
].Delete() == true) 
 244    if (Cache
[A
].Delete() == true) 
 246    if (Cache
[B
].Delete() == true) 
 249    if (Cache
[A
].InstVerIter(Cache
).FileList().end() == true) 
 251    if (Cache
[A
].InstVerIter(Cache
).FileList().end() == true) 
 254    pkgCache::PackageFile 
*FA 
= Cache
[A
].InstVerIter(Cache
).FileList().File(); 
 255    pkgCache::PackageFile 
*FB 
= Cache
[B
].InstVerIter(Cache
).FileList().File(); 
 263 // OrderList::OrderCompareA - Order the installation by op              /*{{{*/ 
 264 // --------------------------------------------------------------------- 
 265 /* This provides a first-pass sort of the list and gives a decent starting 
 266     point for further complete ordering. It is used by OrderUnpack only */ 
 267 int pkgOrderList::OrderCompareA(const void *a
, const void *b
) 
 269    PkgIterator 
A(Me
->Cache
,*(Package 
**)a
); 
 270    PkgIterator 
B(Me
->Cache
,*(Package 
**)b
); 
 272    if (A
.State() != pkgCache::PkgIterator::NeedsNothing 
&&  
 273        B
.State() == pkgCache::PkgIterator::NeedsNothing
) 
 276    if (A
.State() == pkgCache::PkgIterator::NeedsNothing 
&&  
 277        B
.State() != pkgCache::PkgIterator::NeedsNothing
) 
 280    int ScoreA 
= Me
->Score(A
); 
 281    int ScoreB 
= Me
->Score(B
); 
 288    return strcmp(A
.Name(),B
.Name()); 
 291 // OrderList::OrderCompareB - Order the installation by source          /*{{{*/ 
 292 // --------------------------------------------------------------------- 
 293 /* This orders by installation source. This is usefull to handle 
 294    inter-source breaks */ 
 295 int pkgOrderList::OrderCompareB(const void *a
, const void *b
) 
 297    PkgIterator 
A(Me
->Cache
,*(Package 
**)a
); 
 298    PkgIterator 
B(Me
->Cache
,*(Package 
**)b
); 
 300    if (A
.State() != pkgCache::PkgIterator::NeedsNothing 
&&  
 301        B
.State() == pkgCache::PkgIterator::NeedsNothing
) 
 304    if (A
.State() == pkgCache::PkgIterator::NeedsNothing 
&&  
 305        B
.State() != pkgCache::PkgIterator::NeedsNothing
) 
 308    int F 
= Me
->FileCmp(A
,B
); 
 316    int ScoreA 
= Me
->Score(A
); 
 317    int ScoreB 
= Me
->Score(B
); 
 324    return strcmp(A
.Name(),B
.Name()); 
 328 // OrderList::VisitDeps - Visit forward install dependencies            /*{{{*/ 
 329 // --------------------------------------------------------------------- 
 330 /* This calls the dependency function for the normal forwards dependencies 
 332 bool pkgOrderList::VisitDeps(DepFunc F
,PkgIterator Pkg
) 
 334    if (F 
== 0 || Pkg
.end() == true || Cache
[Pkg
].InstallVer 
== 0) 
 337    return (this->*F
)(Cache
[Pkg
].InstVerIter(Cache
).DependsList()); 
 340 // OrderList::VisitRDeps - Visit reverse dependencies                   /*{{{*/ 
 341 // --------------------------------------------------------------------- 
 342 /* This calls the dependency function for all of the normal reverse depends 
 344 bool pkgOrderList::VisitRDeps(DepFunc F
,PkgIterator Pkg
) 
 346    if (F 
== 0 || Pkg
.end() == true) 
 349    return (this->*F
)(Pkg
.RevDependsList()); 
 352 // OrderList::VisitRProvides - Visit provides reverse dependencies      /*{{{*/ 
 353 // --------------------------------------------------------------------- 
 354 /* This calls the dependency function for all reverse dependencies 
 355    generated by the provides line on the package. */ 
 356 bool pkgOrderList::VisitRProvides(DepFunc F
,VerIterator Ver
) 
 358    if (F 
== 0 || Ver
.end() == true) 
 362    for (PrvIterator P 
= Ver
.ProvidesList(); P
.end() == false; P
++) 
 363       Res 
&= (this->*F
)(P
.ParentPkg().RevDependsList()); 
 367 // OrderList::VisitProvides - Visit all of the providing packages       /*{{{*/ 
 368 // --------------------------------------------------------------------- 
 369 /* This routine calls visit on all providing packages. */ 
 370 bool pkgOrderList::VisitProvides(DepIterator D
) 
 372    Version 
**List 
= D
.AllTargets(); 
 373    for (Version 
**I 
= List
; *I 
!= 0; I
++) 
 375       VerIterator 
Ver(Cache
,*I
); 
 376       PkgIterator Pkg 
= Ver
.ParentPkg(); 
 378       if (Cache
[Pkg
].Keep() == true) 
 381       if (D
->Type 
!= pkgCache::Dep::Conflicts 
&& Cache
[Pkg
].InstallVer 
!= *I
) 
 384       if (D
->Type 
== pkgCache::Dep::Conflicts 
&& (Version 
*)Pkg
.CurrentVer() != *I
) 
 387       if (VisitNode(Pkg
) == false) 
 397 // OrderList::VisitNode - Recursive ordering director                   /*{{{*/ 
 398 // --------------------------------------------------------------------- 
 399 /* This is the core ordering routine. It calls the set dependency 
 400    consideration functions which then potentialy call this again. Finite 
 401    depth is achived through the colouring mechinism. */ 
 402 bool pkgOrderList::VisitNode(PkgIterator Pkg
) 
 404    // Looping or irrelevent. 
 405    if (Pkg
.end() == true || IsFlag(Pkg
,Added
) == true ||  
 406        IsFlag(Pkg
,AddPending
) == true || IsFlag(Pkg
,InList
) == false) 
 409 /* for (int j = 0; j != Depth; j++) cout << ' '; 
 410  cout << "Visit " << Pkg.Name() << endl;*/ 
 414    Flag(Pkg
,AddPending
); 
 416    DepFunc Old 
= Primary
; 
 418    // Perform immedate configuration of the package if so flagged. 
 419    if (IsFlag(Pkg
,Immediate
) == true && Primary 
!= &DepUnPackPre
) 
 420       Primary 
= &DepUnPackPreD
; 
 423    if (Cache
[Pkg
].Delete() == false) 
 426       Res 
&= Res 
&& VisitDeps(Primary
,Pkg
); 
 427       Res 
&= Res 
&& VisitRDeps(Primary
,Pkg
); 
 428       Res 
&= Res 
&& VisitRProvides(Primary
,Pkg
.CurrentVer()); 
 429       Res 
&= Res 
&& VisitRProvides(Primary
,Cache
[Pkg
].InstVerIter(Cache
)); 
 432       Res 
&= Res 
&& VisitRDeps(RevDepends
,Pkg
); 
 433       Res 
&= Res 
&& VisitRProvides(RevDepends
,Pkg
.CurrentVer()); 
 434       Res 
&= Res 
&& VisitRProvides(RevDepends
,Cache
[Pkg
].InstVerIter(Cache
)); 
 437       Res 
&= Res 
&& VisitDeps(Secondary
,Pkg
); 
 438       Res 
&= Res 
&& VisitRDeps(Secondary
,Pkg
); 
 439       Res 
&= Res 
&& VisitRProvides(Secondary
,Pkg
.CurrentVer()); 
 440       Res 
&= Res 
&& VisitRProvides(Secondary
,Cache
[Pkg
].InstVerIter(Cache
)); 
 445       Res 
&= Res 
&& VisitRDeps(Remove
,Pkg
); 
 446       Res 
&= Res 
&& VisitRProvides(Remove
,Pkg
.CurrentVer()); 
 449    if (IsFlag(Pkg
,Added
) == false) 
 451       Flag(Pkg
,Added
,Added 
| AddPending
); 
 459 /* for (int j = 0; j != Depth; j++) cout << ' '; 
 460    cout << "Leave " << Pkg.Name() << ' ' << IsFlag(Pkg,Added) << ',' << IsFlag(Pkg,AddPending) << endl;*/ 
 466 // OrderList::DepUnPackCrit - Critical UnPacking ordering               /*{{{*/ 
 467 // --------------------------------------------------------------------- 
 468 /* Critical unpacking ordering strives to satisfy Conflicts: and  
 469    PreDepends: only. When a prdepends is encountered the Primary  
 470    DepFunc is changed to be DepUnPackPreD.  
 472    Loops are preprocessed and logged. */ 
 473 bool pkgOrderList::DepUnPackCrit(DepIterator D
) 
 475    for (; D
.end() == false; D
++) 
 477       if (D
.Reverse() == true) 
 479          /* Reverse depenanices are only interested in conflicts, 
 480             predepend breakage is ignored here */ 
 481          if (D
->Type 
!= pkgCache::Dep::Conflicts
) 
 484          // Duplication elimination, consider only the current version 
 485          if (D
.ParentPkg().CurrentVer() != D
.ParentVer()) 
 488          /* For reverse dependencies we wish to check if the 
 489             dependency is satisifed in the install state. The 
 490             target package (caller) is going to be in the installed 
 492          if (CheckDep(D
) == true) 
 495          if (VisitNode(D
.ParentPkg()) == false) 
 500          /* Forward critical dependencies MUST be correct before the  
 501             package can be unpacked. */ 
 502          if (D
->Type 
!= pkgCache::Dep::Conflicts 
&& D
->Type 
!= pkgCache::Dep::PreDepends
) 
 505          /* We wish to check if the dep is okay in the now state of the 
 506             target package against the install state of this package. */ 
 507          if (CheckDep(D
) == true) 
 509             /* We want to catch predepends loops with the code below. 
 510                Conflicts loops that are Dep OK are ignored */ 
 511             if (IsFlag(D
.TargetPkg(),AddPending
) == false || 
 512                 D
->Type 
!= pkgCache::Dep::PreDepends
) 
 516          // This is the loop detection 
 517          if (IsFlag(D
.TargetPkg(),Added
) == true ||  
 518              IsFlag(D
.TargetPkg(),AddPending
) == true) 
 520             if (IsFlag(D
.TargetPkg(),AddPending
) == true) 
 525          /* Predepends require a special ordering stage, they must have 
 526             all dependents installed as well */ 
 527          DepFunc Old 
= Primary
; 
 529          if (D
->Type 
== pkgCache::Dep::PreDepends
) 
 530             Primary 
= &DepUnPackPreD
; 
 531          Res 
= VisitProvides(D
); 
 540 // OrderList::DepUnPackPreD - Critical UnPacking ordering with depends  /*{{{*/ 
 541 // --------------------------------------------------------------------- 
 542 /* Critical PreDepends (also configure immediate and essential) strives to 
 543    ensure not only that all conflicts+predepends are met but that this 
 544    package will be immediately configurable when it is unpacked.  
 546    Loops are preprocessed and logged. */ 
 547 bool pkgOrderList::DepUnPackPreD(DepIterator D
) 
 549    if (D
.Reverse() == true) 
 550       return DepUnPackCrit(D
); 
 552    for (; D
.end() == false; D
++) 
 554       if (D
.IsCritical() == false) 
 557       /* We wish to check if the dep is okay in the now state of the 
 558          target package against the install state of this package. */ 
 559       if (CheckDep(D
) == true) 
 561          /* We want to catch predepends loops with the code below. 
 562             Conflicts loops that are Dep OK are ignored */ 
 563          if (IsFlag(D
.TargetPkg(),AddPending
) == false || 
 564              D
->Type 
!= pkgCache::Dep::PreDepends
) 
 568       // This is the loop detection 
 569       if (IsFlag(D
.TargetPkg(),Added
) == true ||  
 570           IsFlag(D
.TargetPkg(),AddPending
) == true) 
 572          if (IsFlag(D
.TargetPkg(),AddPending
) == true) 
 577       if (VisitProvides(D
) == false) 
 583 // OrderList::DepUnPackPre - Critical Predepends ordering               /*{{{*/ 
 584 // --------------------------------------------------------------------- 
 585 /* Critical PreDepends (also configure immediate and essential) strives to 
 586    ensure not only that all conflicts+predepends are met but that this 
 587    package will be immediately configurable when it is unpacked.  
 589    Loops are preprocessed and logged. All loops will be fatal. */ 
 590 bool pkgOrderList::DepUnPackPre(DepIterator D
) 
 592    if (D
.Reverse() == true) 
 595    for (; D
.end() == false; D
++) 
 597       /* Only consider the PreDepends or Depends. Depends are only 
 598          considered at the lowest depth or in the case of immediate 
 600       if (D
->Type 
!= pkgCache::Dep::PreDepends
) 
 602          if (D
->Type 
== pkgCache::Dep::Depends
) 
 604             if (Depth 
== 1 && IsFlag(D
.ParentPkg(),Immediate
) == false) 
 611       /* We wish to check if the dep is okay in the now state of the 
 612          target package against the install state of this package. */ 
 613       if (CheckDep(D
) == true) 
 615          /* We want to catch predepends loops with the code below. 
 616             Conflicts loops that are Dep OK are ignored */ 
 617          if (IsFlag(D
.TargetPkg(),AddPending
) == false) 
 621       // This is the loop detection 
 622       if (IsFlag(D
.TargetPkg(),Added
) == true ||  
 623           IsFlag(D
.TargetPkg(),AddPending
) == true) 
 625          if (IsFlag(D
.TargetPkg(),AddPending
) == true) 
 630       if (VisitProvides(D
) == false) 
 636 // OrderList::DepUnPackDep - Reverse dependency considerations          /*{{{*/ 
 637 // --------------------------------------------------------------------- 
 638 /* Reverse dependencies are considered to determine if unpacking this 
 639    package will break any existing dependencies. If so then those 
 640    packages are ordered before this one so that they are in the 
 643    The forwards depends loop is designed to bring the packages dependents 
 644    close to the package. This helps reduce deconfigure time.  
 646    Loops are irrelevent to this. */ 
 647 bool pkgOrderList::DepUnPackDep(DepIterator D
) 
 650    for (; D
.end() == false; D
++) 
 651       if (D
.IsCritical() == true) 
 653          if (D
.Reverse() == true) 
 655             /* Duplication prevention. We consider rev deps only on 
 656                the current version, a not installed package 
 658             if (D
.ParentPkg()->CurrentVer 
== 0 || 
 659                 D
.ParentPkg().CurrentVer() != D
.ParentVer()) 
 662             // The dep will not break so it is irrelevent. 
 663             if (CheckDep(D
) == true) 
 666             if (VisitNode(D
.ParentPkg()) == false) 
 670             if (D
->Type 
== pkgCache::Dep::Depends
) 
 671                if (VisitProvides(D
) == false) 
 677 // OrderList::DepConfigure - Configuration ordering                     /*{{{*/ 
 678 // --------------------------------------------------------------------- 
 679 /* Configuration only ordering orders by the Depends: line only. It 
 680    orders configuration so that when a package comes to be configured it's 
 681    dependents are configured.  
 683    Loops are ingored. Depends loop entry points are chaotic. */ 
 684 bool pkgOrderList::DepConfigure(DepIterator D
) 
 686    // Never consider reverse configuration dependencies. 
 687    if (D
.Reverse() == true) 
 690    for (; D
.end() == false; D
++) 
 691       if (D
->Type 
== pkgCache::Dep::Depends
) 
 692          if (VisitProvides(D
) == false) 
 697 // OrderList::DepRemove - Removal ordering                              /*{{{*/ 
 698 // --------------------------------------------------------------------- 
 699 /* Removal visits all reverse depends. It considers if the dependency 
 700    of the Now state version to see if it is okay with removing this 
 701    package. This check should always fail, but is provided for symetery 
 702    with the other critical handlers. 
 704    Loops are preprocessed and logged. Removal loops can also be 
 705    detected in the critical handler. They are characterized by an 
 706    old version of A depending on B but the new version of A conflicting 
 707    with B, thus either A or B must break to install. */ 
 708 bool pkgOrderList::DepRemove(DepIterator D
) 
 710    if (D
.Reverse() == false) 
 712    for (; D
.end() == false; D
++) 
 713       if (D
->Type 
== pkgCache::Dep::Depends 
|| D
->Type 
== pkgCache::Dep::PreDepends
) 
 715          // Duplication elimination, consider the current version only 
 716          if (D
.ParentPkg().CurrentVer() != D
.ParentVer()) 
 719          /* We wish to see if the dep on the parent package is okay 
 720             in the removed (install) state of the target pkg. */          
 721          if (CheckDep(D
) == true) 
 723             // We want to catch loops with the code below. 
 724             if (IsFlag(D
.ParentPkg(),AddPending
) == false) 
 728          // This is the loop detection 
 729          if (IsFlag(D
.ParentPkg(),Added
) == true ||  
 730              IsFlag(D
.ParentPkg(),AddPending
) == true) 
 732             if (IsFlag(D
.ParentPkg(),AddPending
) == true) 
 737          if (VisitNode(D
.ParentPkg()) == false) 
 745 // OrderList::AddLoop - Add a loop to the loop list                     /*{{{*/ 
 746 // --------------------------------------------------------------------- 
 747 /* We record the loops. This is a relic since loop breaking is done  
 748    genericaly as part of the safety routines. */ 
 749 bool pkgOrderList::AddLoop(DepIterator D
) 
 751    if (LoopCount 
< 0 || LoopCount 
>= 20) 
 757       if (Loops
[LoopCount 
- 1].ParentPkg() == D
.ParentPkg() || 
 758           Loops
[LoopCount 
- 1].TargetPkg() == D
.ParentPkg()) 
 762    Loops
[LoopCount
++] = D
; 
 764    // Mark the packages as being part of a loop. 
 765    Flag(D
.TargetPkg(),Loop
); 
 766    Flag(D
.ParentPkg(),Loop
); 
 770 // OrderList::WipeFlags - Unset the given flags from all packages       /*{{{*/ 
 771 // --------------------------------------------------------------------- 
 773 void pkgOrderList::WipeFlags(unsigned long F
) 
 775    unsigned long Size 
= Cache
.HeaderP
->PackageCount
; 
 776    for (unsigned long I 
= 0; I 
!= Size
; I
++) 
 780 // OrderList::CheckDep - Check a dependency for truth                   /*{{{*/ 
 781 // --------------------------------------------------------------------- 
 782 /* This performs a complete analysis of the dependency wrt to the 
 783    current add list. It returns true if after all events are 
 784    performed it is still true. This sort of routine can be approximated 
 785    by examining the DepCache, however in convoluted cases of provides 
 786    this fails to produce a suitable result. */ 
 787 bool pkgOrderList::CheckDep(DepIterator D
) 
 789    Version 
**List 
= D
.AllTargets(); 
 790    for (Version 
**I 
= List
; *I 
!= 0; I
++) 
 792       VerIterator 
Ver(Cache
,*I
); 
 793       PkgIterator Pkg 
= Ver
.ParentPkg(); 
 795       /* The meaning of Added and AddPending is subtle. AddPending is 
 796          an indication that the package is looping. Because of the 
 797          way ordering works Added means the package will be unpacked 
 798          before this one and AddPending means after. It is therefore 
 799          correct to ignore AddPending in all cases, but that exposes 
 800          reverse-ordering loops which should be ignore. */ 
 801       if (IsFlag(Pkg
,Added
) == true ||  
 802           (IsFlag(Pkg
,AddPending
) == true && D
.Reverse() == true)) 
 804          if (Cache
[Pkg
].InstallVer 
!= *I
) 
 808          if ((Version 
*)Pkg
.CurrentVer() != *I 
||  
 809              Pkg
.State() != PkgIterator::NeedsNothing
) 
 814       /* Conflicts requires that all versions are not present, depends 
 816       if (D
->Type 
!= pkgCache::Dep::Conflicts
) 
 823    /* Conflicts requires that all versions are not present, depends 
 825    if (D
->Type 
== pkgCache::Dep::Conflicts
)