]>
git.saurik.com Git - apt.git/blob - apt-pkg/depcache.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: depcache.cc,v 1.25 2001/05/27 05:36:04 jgg Exp $
4 /* ######################################################################
6 Dependency Cache - Caches Dependency information.
8 ##################################################################### */
10 // Include Files /*{{{*/
12 #pragma implementation "apt-pkg/depcache.h"
14 #include <apt-pkg/depcache.h>
15 #include <apt-pkg/version.h>
16 #include <apt-pkg/error.h>
17 #include <apt-pkg/sptr.h>
18 #include <apt-pkg/algorithms.h>
20 #include <apt-pkg/fileutl.h>
21 #include <apt-pkg/configuration.h>
22 #include <apt-pkg/tagfile.h>
27 // DepCache::pkgDepCache - Constructors /*{{{*/
28 // ---------------------------------------------------------------------
30 pkgDepCache::pkgDepCache(pkgCache
*pCache
,Policy
*Plcy
) :
31 Cache(pCache
), PkgState(0), DepState(0)
36 delLocalPolicy
= LocalPolicy
= new Policy
;
39 // DepCache::~pkgDepCache - Destructor /*{{{*/
40 // ---------------------------------------------------------------------
42 pkgDepCache::~pkgDepCache()
46 delete delLocalPolicy
;
49 // DepCache::Init - Generate the initial extra structures. /*{{{*/
50 // ---------------------------------------------------------------------
51 /* This allocats the extension buffers and initializes them. */
52 bool pkgDepCache::Init(OpProgress
*Prog
)
56 PkgState
= new StateCache
[Head().PackageCount
];
57 DepState
= new unsigned char[Head().DependsCount
];
58 memset(PkgState
,0,sizeof(*PkgState
)*Head().PackageCount
);
59 memset(DepState
,0,sizeof(*DepState
)*Head().DependsCount
);
63 Prog
->OverallProgress(0,2*Head().PackageCount
,Head().PackageCount
,
64 _("Building dependency tree"));
65 Prog
->SubProgress(Head().PackageCount
,_("Candidate versions"));
68 /* Set the current state of everything. In this state all of the
69 packages are kept exactly as is. See AllUpgrade */
71 for (PkgIterator I
= PkgBegin(); I
.end() != true; I
++,Done
++)
76 // Find the proper cache slot
77 StateCache
&State
= PkgState
[I
->ID
];
79 State
.DirtyState
= pkgCache::State::RemoveUnknown
;
80 //State.AutomaticRemove = I->AutomaticRemove;
81 State
.AutomaticRemove
= pkgCache::State::RemoveUnknown
;
83 // Figure out the install version
84 State
.CandidateVer
= GetCandidateVer(I
);
85 State
.InstallVer
= I
.CurrentVer();
86 State
.Mode
= ModeKeep
;
88 State
.Update(I
,*this);
94 Prog
->OverallProgress(Head().PackageCount
,2*Head().PackageCount
,
96 _("Building dependency tree"));
97 Prog
->SubProgress(Head().PackageCount
,_("Dependency generation"));
106 bool pkgDepCache::readStateFile(OpProgress
*Prog
)
109 string state
= _config
->FindDir("Dir::State") + "pkgstates";
110 if(FileExists(state
)) {
111 state_file
.Open(state
, FileFd::ReadOnly
);
112 int file_size
= state_file
.Size();
113 Prog
->OverallProgress(0, file_size
, 1,
114 _("Reading extended state information"));
116 pkgTagFile
tagfile(&state_file
);
117 pkgTagSection section
;
119 while(tagfile
.Step(section
)) {
120 string pkgname
= section
.FindS("Package");
121 pkgCache::PkgIterator pkg
=Cache
->FindPkg(pkgname
);
122 // Silently ignore unknown packages and packages with no actual
124 if(!pkg
.end() && !pkg
.VersionList().end()) {
125 short reason
= section
.FindI("Remove-Reason",
126 pkgCache::State::RemoveManual
);
127 PkgState
[pkg
->ID
].AutomaticRemove
= reason
;
128 //std::cout << "Set: " << pkgname << " to " << reason << std::endl;
130 Prog
->OverallProgress(amt
, file_size
, 1,
131 _("Reading extended state information"));
133 Prog
->OverallProgress(file_size
, file_size
, 1,
134 _("Reading extended state information"));
141 bool pkgDepCache::writeStateFile(OpProgress
*prog
)
143 // write the auto-mark list ----------------------------------
146 string state
= _config
->FindDir("Dir::State") + "pkgstates";
148 if(!StateFile
.Open(state
, FileFd::WriteEmpty
))
149 return _error
->Error(_("Failed to write StateFile %s"),
152 std::ostringstream ostr
;
153 for(pkgCache::PkgIterator pkg
=Cache
->PkgBegin(); !pkg
.end();pkg
++) {
155 // clear out no longer installed pkg
156 if(PkgState
[pkg
->ID
].Delete() || pkg
.CurrentVer() == NULL
)
157 PkgState
[pkg
->ID
].AutomaticRemove
= pkgCache::State::RemoveUnknown
;
159 // check if we have new information
160 if(PkgState
[pkg
->ID
].Flags
& pkgCache::Flag::Auto
) {
161 std::cout
<< "pkg: " << pkg
.Name() << " is auto-dep" << std::endl
;
162 PkgState
[pkg
->ID
].AutomaticRemove
= pkgCache::State::RemoveRequired
;
165 if(PkgState
[pkg
->ID
].AutomaticRemove
!= pkgCache::State::RemoveUnknown
) {
166 ostr
.str(string(""));
167 ostr
<< "Package: " << pkg
.Name()
168 << "\nRemove-Reason: "
169 << (int)(PkgState
[pkg
->ID
].AutomaticRemove
) << "\n\n";
170 StateFile
.Write(ostr
.str().c_str(), ostr
.str().size());
171 //std::cout << "Writing auto-mark: " << ostr.str() << endl;
177 // DepCache::CheckDep - Checks a single dependency /*{{{*/
178 // ---------------------------------------------------------------------
179 /* This first checks the dependency against the main target package and
180 then walks along the package provides list and checks if each provides
181 will be installed then checks the provides against the dep. Res will be
182 set to the package which was used to satisfy the dep. */
183 bool pkgDepCache::CheckDep(DepIterator Dep
,int Type
,PkgIterator
&Res
)
185 Res
= Dep
.TargetPkg();
187 /* Check simple depends. A depends -should- never self match but
188 we allow it anyhow because dpkg does. Technically it is a packaging
189 bug. Conflicts may never self match */
190 if (Dep
.TargetPkg() != Dep
.ParentPkg() ||
191 (Dep
->Type
!= Dep::Conflicts
&& Dep
->Type
!= Dep::Obsoletes
))
193 PkgIterator Pkg
= Dep
.TargetPkg();
194 // Check the base package
195 if (Type
== NowVersion
&& Pkg
->CurrentVer
!= 0)
196 if (VS().CheckDep(Pkg
.CurrentVer().VerStr(),Dep
->CompareOp
,
197 Dep
.TargetVer()) == true)
200 if (Type
== InstallVersion
&& PkgState
[Pkg
->ID
].InstallVer
!= 0)
201 if (VS().CheckDep(PkgState
[Pkg
->ID
].InstVerIter(*this).VerStr(),
202 Dep
->CompareOp
,Dep
.TargetVer()) == true)
205 if (Type
== CandidateVersion
&& PkgState
[Pkg
->ID
].CandidateVer
!= 0)
206 if (VS().CheckDep(PkgState
[Pkg
->ID
].CandidateVerIter(*this).VerStr(),
207 Dep
->CompareOp
,Dep
.TargetVer()) == true)
211 if (Dep
->Type
== Dep::Obsoletes
)
214 // Check the providing packages
215 PrvIterator P
= Dep
.TargetPkg().ProvidesList();
216 PkgIterator Pkg
= Dep
.ParentPkg();
217 for (; P
.end() != true; P
++)
219 /* Provides may never be applied against the same package if it is
220 a conflicts. See the comment above. */
221 if (P
.OwnerPkg() == Pkg
&& Dep
->Type
== Dep::Conflicts
)
224 // Check if the provides is a hit
225 if (Type
== NowVersion
)
227 if (P
.OwnerPkg().CurrentVer() != P
.OwnerVer())
231 if (Type
== InstallVersion
)
233 StateCache
&State
= PkgState
[P
.OwnerPkg()->ID
];
234 if (State
.InstallVer
!= (Version
*)P
.OwnerVer())
238 if (Type
== CandidateVersion
)
240 StateCache
&State
= PkgState
[P
.OwnerPkg()->ID
];
241 if (State
.CandidateVer
!= (Version
*)P
.OwnerVer())
245 // Compare the versions.
246 if (VS().CheckDep(P
.ProvideVersion(),Dep
->CompareOp
,Dep
.TargetVer()) == true)
256 // DepCache::AddSizes - Add the packages sizes to the counters /*{{{*/
257 // ---------------------------------------------------------------------
258 /* Call with Mult = -1 to preform the inverse opration */
259 void pkgDepCache::AddSizes(const PkgIterator
&Pkg
,signed long Mult
)
261 StateCache
&P
= PkgState
[Pkg
->ID
];
263 if (Pkg
->VersionList
== 0)
266 if (Pkg
.State() == pkgCache::PkgIterator::NeedsConfigure
&&
270 // Compute the size data
271 if (P
.NewInstall() == true)
273 iUsrSize
+= (signed)(Mult
*P
.InstVerIter(*this)->InstalledSize
);
274 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
279 if (Pkg
->CurrentVer
!= 0 &&
280 (P
.InstallVer
!= (Version
*)Pkg
.CurrentVer() ||
281 (P
.iFlags
& ReInstall
) == ReInstall
) && P
.InstallVer
!= 0)
283 iUsrSize
+= (signed)(Mult
*((signed)P
.InstVerIter(*this)->InstalledSize
-
284 (signed)Pkg
.CurrentVer()->InstalledSize
));
285 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
290 if (Pkg
.State() == pkgCache::PkgIterator::NeedsUnpack
&&
293 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
298 if (Pkg
->CurrentVer
!= 0 && P
.InstallVer
== 0)
300 iUsrSize
-= (signed)(Mult
*Pkg
.CurrentVer()->InstalledSize
);
305 // DepCache::AddStates - Add the package to the state counter /*{{{*/
306 // ---------------------------------------------------------------------
307 /* This routine is tricky to use, you must make sure that it is never
308 called twice for the same package. This means the Remove/Add section
309 should be as short as possible and not encompass any code that will
310 calld Remove/Add itself. Remember, dependencies can be circular so
311 while processing a dep for Pkg it is possible that Add/Remove
312 will be called on Pkg */
313 void pkgDepCache::AddStates(const PkgIterator
&Pkg
,int Add
)
315 StateCache
&State
= PkgState
[Pkg
->ID
];
317 // The Package is broken
318 if ((State
.DepState
& DepInstMin
) != DepInstMin
)
322 if (Pkg
.State() != PkgIterator::NeedsNothing
)
326 if (Pkg
->CurrentVer
== 0)
328 if (State
.Mode
== ModeDelete
&&
329 (State
.iFlags
| Purge
) == Purge
&& Pkg
.Purge() == false)
332 if (State
.Mode
== ModeInstall
)
337 // Installed, no upgrade
338 if (State
.Status
== 0)
340 if (State
.Mode
== ModeDelete
)
343 if ((State
.iFlags
& ReInstall
) == ReInstall
)
349 // Alll 3 are possible
350 if (State
.Mode
== ModeDelete
)
352 if (State
.Mode
== ModeKeep
)
354 if (State
.Mode
== ModeInstall
)
358 // DepCache::BuildGroupOrs - Generate the Or group dep data /*{{{*/
359 // ---------------------------------------------------------------------
360 /* The or group results are stored in the last item of the or group. This
361 allows easy detection of the state of a whole or'd group. */
362 void pkgDepCache::BuildGroupOrs(VerIterator
const &V
)
364 unsigned char Group
= 0;
366 for (DepIterator D
= V
.DependsList(); D
.end() != true; D
++)
368 // Build the dependency state.
369 unsigned char &State
= DepState
[D
->ID
];
371 /* Invert for Conflicts. We have to do this twice to get the
372 right sense for a conflicts group */
373 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
376 // Add to the group if we are within an or..
380 if ((D
->CompareOp
& Dep::Or
) != Dep::Or
)
383 // Invert for Conflicts
384 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
389 // DepCache::VersionState - Perform a pass over a dependency list /*{{{*/
390 // ---------------------------------------------------------------------
391 /* This is used to run over a dependency list and determine the dep
392 state of the list, filtering it through both a Min check and a Policy
393 check. The return result will have SetMin/SetPolicy low if a check
394 fails. It uses the DepState cache for it's computations. */
395 unsigned char pkgDepCache::VersionState(DepIterator D
,unsigned char Check
,
396 unsigned char SetMin
,
397 unsigned char SetPolicy
)
399 unsigned char Dep
= 0xFF;
401 while (D
.end() != true)
403 // Compute a single dependency element (glob or)
404 DepIterator Start
= D
;
405 unsigned char State
= 0;
406 for (bool LastOR
= true; D
.end() == false && LastOR
== true; D
++)
408 State
|= DepState
[D
->ID
];
409 LastOR
= (D
->CompareOp
& Dep::Or
) == Dep::Or
;
412 // Minimum deps that must be satisfied to have a working package
413 if (Start
.IsCritical() == true)
414 if ((State
& Check
) != Check
)
417 // Policy deps that must be satisfied to install the package
418 if (IsImportantDep(Start
) == true &&
419 (State
& Check
) != Check
)
426 // DepCache::DependencyState - Compute the 3 results for a dep /*{{{*/
427 // ---------------------------------------------------------------------
428 /* This is the main dependency computation bit. It computes the 3 main
429 results for a dependencys, Now, Install and Candidate. Callers must
430 invert the result if dealing with conflicts. */
431 unsigned char pkgDepCache::DependencyState(DepIterator
&D
)
433 unsigned char State
= 0;
435 if (CheckDep(D
,NowVersion
) == true)
437 if (CheckDep(D
,InstallVersion
) == true)
439 if (CheckDep(D
,CandidateVersion
) == true)
445 // DepCache::UpdateVerState - Compute the Dep member of the state /*{{{*/
446 // ---------------------------------------------------------------------
447 /* This determines the combined dependency representation of a package
448 for its two states now and install. This is done by using the pre-generated
449 dependency information. */
450 void pkgDepCache::UpdateVerState(PkgIterator Pkg
)
452 // Empty deps are always true
453 StateCache
&State
= PkgState
[Pkg
->ID
];
454 State
.DepState
= 0xFF;
456 // Check the Current state
457 if (Pkg
->CurrentVer
!= 0)
459 DepIterator D
= Pkg
.CurrentVer().DependsList();
460 State
.DepState
&= VersionState(D
,DepNow
,DepNowMin
,DepNowPolicy
);
463 /* Check the candidate state. We do not compare against the whole as
464 a candidate state but check the candidate version against the
466 if (State
.CandidateVer
!= 0)
468 DepIterator D
= State
.CandidateVerIter(*this).DependsList();
469 State
.DepState
&= VersionState(D
,DepInstall
,DepCandMin
,DepCandPolicy
);
472 // Check target state which can only be current or installed
473 if (State
.InstallVer
!= 0)
475 DepIterator D
= State
.InstVerIter(*this).DependsList();
476 State
.DepState
&= VersionState(D
,DepInstall
,DepInstMin
,DepInstPolicy
);
480 // DepCache::Update - Figure out all the state information /*{{{*/
481 // ---------------------------------------------------------------------
482 /* This will figure out the state of all the packages and all the
483 dependencies based on the current policy. */
484 void pkgDepCache::Update(OpProgress
*Prog
)
494 // Perform the depends pass
496 for (PkgIterator I
= PkgBegin(); I
.end() != true; I
++,Done
++)
498 if (Prog
!= 0 && Done%20
== 0)
499 Prog
->Progress(Done
);
500 for (VerIterator V
= I
.VersionList(); V
.end() != true; V
++)
502 unsigned char Group
= 0;
504 for (DepIterator D
= V
.DependsList(); D
.end() != true; D
++)
506 // Build the dependency state.
507 unsigned char &State
= DepState
[D
->ID
];
508 State
= DependencyState(D
);
510 // Add to the group if we are within an or..
513 if ((D
->CompareOp
& Dep::Or
) != Dep::Or
)
516 // Invert for Conflicts
517 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
522 // Compute the pacakge dependency state and size additions
531 Prog
->Progress(Done
);
534 // DepCache::Update - Update the deps list of a package /*{{{*/
535 // ---------------------------------------------------------------------
536 /* This is a helper for update that only does the dep portion of the scan.
537 It is mainly ment to scan reverse dependencies. */
538 void pkgDepCache::Update(DepIterator D
)
540 // Update the reverse deps
541 for (;D
.end() != true; D
++)
543 unsigned char &State
= DepState
[D
->ID
];
544 State
= DependencyState(D
);
546 // Invert for Conflicts
547 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
550 RemoveStates(D
.ParentPkg());
551 BuildGroupOrs(D
.ParentVer());
552 UpdateVerState(D
.ParentPkg());
553 AddStates(D
.ParentPkg());
557 // DepCache::Update - Update the related deps of a package /*{{{*/
558 // ---------------------------------------------------------------------
559 /* This is called whenever the state of a package changes. It updates
560 all cached dependencies related to this package. */
561 void pkgDepCache::Update(PkgIterator
const &Pkg
)
563 // Recompute the dep of the package
568 // Update the reverse deps
569 Update(Pkg
.RevDependsList());
571 // Update the provides map for the current ver
572 if (Pkg
->CurrentVer
!= 0)
573 for (PrvIterator P
= Pkg
.CurrentVer().ProvidesList();
574 P
.end() != true; P
++)
575 Update(P
.ParentPkg().RevDependsList());
577 // Update the provides map for the candidate ver
578 if (PkgState
[Pkg
->ID
].CandidateVer
!= 0)
579 for (PrvIterator P
= PkgState
[Pkg
->ID
].CandidateVerIter(*this).ProvidesList();
580 P
.end() != true; P
++)
581 Update(P
.ParentPkg().RevDependsList());
586 // DepCache::MarkKeep - Put the package in the keep state /*{{{*/
587 // ---------------------------------------------------------------------
589 void pkgDepCache::MarkKeep(PkgIterator
const &Pkg
,bool Soft
)
591 // Simplifies other routines.
592 if (Pkg
.end() == true)
595 /* Reject an attempt to keep a non-source broken installed package, those
597 if (Pkg
.State() == PkgIterator::NeedsUnpack
&&
598 Pkg
.CurrentVer().Downloadable() == false)
601 /* We changed the soft state all the time so the UI is a bit nicer
603 StateCache
&P
= PkgState
[Pkg
->ID
];
605 P
.iFlags
|= AutoKept
;
607 P
.iFlags
&= ~AutoKept
;
609 // Check that it is not already kept
610 if (P
.Mode
== ModeKeep
)
613 // We dont even try to keep virtual packages..
614 if (Pkg
->VersionList
== 0)
617 P
.Flags
&= ~Flag::Auto
;
622 if (Pkg
->CurrentVer
== 0)
625 P
.InstallVer
= Pkg
.CurrentVer();
634 // DepCache::MarkDelete - Put the package in the delete state /*{{{*/
635 // ---------------------------------------------------------------------
637 void pkgDepCache::MarkDelete(PkgIterator
const &Pkg
, bool rPurge
)
639 // Simplifies other routines.
640 if (Pkg
.end() == true)
643 // Check that it is not already marked for delete
644 StateCache
&P
= PkgState
[Pkg
->ID
];
645 P
.iFlags
&= ~(AutoKept
| Purge
);
649 if ((P
.Mode
== ModeDelete
|| P
.InstallVer
== 0) &&
650 (Pkg
.Purge() == true || rPurge
== false))
653 // We dont even try to delete virtual packages..
654 if (Pkg
->VersionList
== 0)
660 if (Pkg
->CurrentVer
== 0 && (Pkg
.Purge() == true || rPurge
== false))
665 // This was not inverted before, but I think it should be
666 P
.Flags
&= ~Flag::Auto
;
673 // DepCache::MarkInstall - Put the package in the install state /*{{{*/
674 // ---------------------------------------------------------------------
676 void pkgDepCache::MarkInstall(PkgIterator
const &Pkg
,bool AutoInst
,
682 // Simplifies other routines.
683 if (Pkg
.end() == true)
686 /* Check that it is not already marked for install and that it can be
688 StateCache
&P
= PkgState
[Pkg
->ID
];
689 P
.iFlags
&= ~AutoKept
;
690 if (P
.InstBroken() == false && (P
.Mode
== ModeInstall
||
691 P
.CandidateVer
== (Version
*)Pkg
.CurrentVer()))
693 if (P
.CandidateVer
== (Version
*)Pkg
.CurrentVer() && P
.InstallVer
== 0)
698 // See if there is even any possible instalation candidate
699 if (P
.CandidateVer
== 0)
702 // We dont even try to install virtual packages..
703 if (Pkg
->VersionList
== 0)
706 /* Target the candidate version and remove the autoflag. We reset the
707 autoflag below if this was called recursively. Otherwise the user
708 should have the ability to de-auto a package by changing its state */
712 P
.Mode
= ModeInstall
;
713 P
.InstallVer
= P
.CandidateVer
;
714 P
.Flags
&= ~Flag::Auto
;
715 if (P
.CandidateVer
== (Version
*)Pkg
.CurrentVer())
722 if (AutoInst
== false)
725 DepIterator Dep
= P
.InstVerIter(*this).DependsList();
726 for (; Dep
.end() != true;)
729 DepIterator Start
= Dep
;
732 for (bool LastOR
= true; Dep
.end() == false && LastOR
== true; Dep
++,Ors
++)
734 LastOR
= (Dep
->CompareOp
& Dep::Or
) == Dep::Or
;
736 if ((DepState
[Dep
->ID
] & DepInstall
) == DepInstall
)
740 // Dep is satisfied okay.
744 /* Check if this dep should be consider for install. If it is a user
745 defined important dep and we are installed a new package then
746 it will be installed. Otherwise we only worry about critical deps */
747 if (IsImportantDep(Start
) == false)
749 if (Pkg
->CurrentVer
!= 0 && Start
.IsCritical() == false)
752 /* If we are in an or group locate the first or that can
753 succeed. We have already cached this.. */
754 for (; Ors
> 1 && (DepState
[Start
->ID
] & DepCVer
) != DepCVer
; Ors
--)
757 /* This bit is for processing the possibilty of an install/upgrade
758 fixing the problem */
759 SPtrArray
<Version
*> List
= Start
.AllTargets();
760 if ((DepState
[Start
->ID
] & DepCVer
) == DepCVer
)
762 // Right, find the best version to install..
763 Version
**Cur
= List
;
764 PkgIterator P
= Start
.TargetPkg();
765 PkgIterator
InstPkg(*Cache
,0);
767 // See if there are direct matches (at the start of the list)
768 for (; *Cur
!= 0 && (*Cur
)->ParentPkg
== P
.Index(); Cur
++)
770 PkgIterator
Pkg(*Cache
,Cache
->PkgP
+ (*Cur
)->ParentPkg
);
771 if (PkgState
[Pkg
->ID
].CandidateVer
!= *Cur
)
777 // Select the highest priority providing package
778 if (InstPkg
.end() == true)
780 pkgPrioSortList(*Cache
,Cur
);
781 for (; *Cur
!= 0; Cur
++)
783 PkgIterator
Pkg(*Cache
,Cache
->PkgP
+ (*Cur
)->ParentPkg
);
784 if (PkgState
[Pkg
->ID
].CandidateVer
!= *Cur
)
791 if (InstPkg
.end() == false)
793 MarkInstall(InstPkg
,true,Depth
+ 1);
795 // Set the autoflag, after MarkInstall because MarkInstall unsets it
796 if (P
->CurrentVer
== 0)
797 PkgState
[InstPkg
->ID
].Flags
|= Flag::Auto
;
803 /* For conflicts we just de-install the package and mark as auto,
804 Conflicts may not have or groups */
805 if (Start
->Type
== Dep::Conflicts
|| Start
->Type
== Dep::Obsoletes
)
807 for (Version
**I
= List
; *I
!= 0; I
++)
809 VerIterator
Ver(*this,*I
);
810 PkgIterator Pkg
= Ver
.ParentPkg();
813 PkgState
[Pkg
->ID
].Flags
|= Flag::Auto
;
820 // DepCache::SetReInstall - Set the reinstallation flag /*{{{*/
821 // ---------------------------------------------------------------------
823 void pkgDepCache::SetReInstall(PkgIterator
const &Pkg
,bool To
)
828 StateCache
&P
= PkgState
[Pkg
->ID
];
830 P
.iFlags
|= ReInstall
;
832 P
.iFlags
&= ~ReInstall
;
838 // DepCache::SetDirty - Switch the package between dirty states /*{{{*/
839 // ---------------------------------------------------------------------
841 void pkgDepCache::SetDirty(PkgIterator
const &Pkg
, pkgCache::State::PkgRemoveState To
)
843 StateCache
&P
= PkgState
[Pkg
->ID
];
847 // DepCache::SetCandidateVersion - Change the candidate version /*{{{*/
848 // ---------------------------------------------------------------------
850 void pkgDepCache::SetCandidateVersion(VerIterator TargetVer
)
852 pkgCache::PkgIterator Pkg
= TargetVer
.ParentPkg();
853 StateCache
&P
= PkgState
[Pkg
->ID
];
858 if (P
.CandidateVer
== P
.InstallVer
)
859 P
.InstallVer
= (Version
*)TargetVer
;
860 P
.CandidateVer
= (Version
*)TargetVer
;
868 // StateCache::Update - Compute the various static display things /*{{{*/
869 // ---------------------------------------------------------------------
870 /* This is called whenever the Candidate version changes. */
871 void pkgDepCache::StateCache::Update(PkgIterator Pkg
,pkgCache
&Cache
)
874 VerIterator Ver
= CandidateVerIter(Cache
);
876 // Use a null string or the version string
877 if (Ver
.end() == true)
880 CandVersion
= Ver
.VerStr();
882 // Find the current version
884 if (Pkg
->CurrentVer
!= 0)
885 CurVersion
= Pkg
.CurrentVer().VerStr();
887 // Strip off the epochs for display
888 CurVersion
= StripEpoch(CurVersion
);
889 CandVersion
= StripEpoch(CandVersion
);
891 // Figure out if its up or down or equal
892 Status
= Ver
.CompareVer(Pkg
.CurrentVer());
893 if (Pkg
->CurrentVer
== 0 || Pkg
->VersionList
== 0 || CandidateVer
== 0)
897 // StateCache::StripEpoch - Remove the epoch specifier from the version /*{{{*/
898 // ---------------------------------------------------------------------
900 const char *pkgDepCache::StateCache::StripEpoch(const char *Ver
)
906 for (const char *I
= Ver
; *I
!= 0; I
++)
913 // Policy::GetCandidateVer - Returns the Candidate install version /*{{{*/
914 // ---------------------------------------------------------------------
915 /* The default just returns the highest available version that is not
916 a source and automatic. */
917 pkgCache::VerIterator
pkgDepCache::Policy::GetCandidateVer(PkgIterator Pkg
)
919 /* Not source/not automatic versions cannot be a candidate version
920 unless they are already installed */
921 VerIterator
Last(*(pkgCache
*)this,0);
923 for (VerIterator I
= Pkg
.VersionList(); I
.end() == false; I
++)
925 if (Pkg
.CurrentVer() == I
)
928 for (VerFileIterator J
= I
.FileList(); J
.end() == false; J
++)
930 if ((J
.File()->Flags
& Flag::NotSource
) != 0)
933 /* Stash the highest version of a not-automatic source, we use it
934 if there is nothing better */
935 if ((J
.File()->Flags
& Flag::NotAutomatic
) != 0)
937 if (Last
.end() == true)
949 // Policy::IsImportantDep - True if the dependency is important /*{{{*/
950 // ---------------------------------------------------------------------
952 bool pkgDepCache::Policy::IsImportantDep(DepIterator Dep
)
954 return Dep
.IsCritical();