]>
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>
29 // DepCache::pkgDepCache - Constructors /*{{{*/
30 // ---------------------------------------------------------------------
32 pkgDepCache::pkgDepCache(pkgCache
*pCache
,Policy
*Plcy
) :
33 Cache(pCache
), PkgState(0), DepState(0)
38 delLocalPolicy
= LocalPolicy
= new Policy
;
41 // DepCache::~pkgDepCache - Destructor /*{{{*/
42 // ---------------------------------------------------------------------
44 pkgDepCache::~pkgDepCache()
48 delete delLocalPolicy
;
51 // DepCache::Init - Generate the initial extra structures. /*{{{*/
52 // ---------------------------------------------------------------------
53 /* This allocats the extension buffers and initializes them. */
54 bool pkgDepCache::Init(OpProgress
*Prog
)
58 PkgState
= new StateCache
[Head().PackageCount
];
59 DepState
= new unsigned char[Head().DependsCount
];
60 memset(PkgState
,0,sizeof(*PkgState
)*Head().PackageCount
);
61 memset(DepState
,0,sizeof(*DepState
)*Head().DependsCount
);
65 Prog
->OverallProgress(0,2*Head().PackageCount
,Head().PackageCount
,
66 _("Building dependency tree"));
67 Prog
->SubProgress(Head().PackageCount
,_("Candidate versions"));
70 /* Set the current state of everything. In this state all of the
71 packages are kept exactly as is. See AllUpgrade */
73 for (PkgIterator I
= PkgBegin(); I
.end() != true; I
++,Done
++)
78 // Find the proper cache slot
79 StateCache
&State
= PkgState
[I
->ID
];
82 // Figure out the install version
83 State
.CandidateVer
= GetCandidateVer(I
);
84 State
.InstallVer
= I
.CurrentVer();
85 State
.Mode
= ModeKeep
;
87 State
.Update(I
,*this);
93 Prog
->OverallProgress(Head().PackageCount
,2*Head().PackageCount
,
95 _("Building dependency tree"));
96 Prog
->SubProgress(Head().PackageCount
,_("Dependency generation"));
108 bool pkgDepCache::readStateFile(OpProgress
*Prog
)
111 string state
= _config
->FindDir("Dir::State") + "pkgstates";
112 if(FileExists(state
)) {
113 state_file
.Open(state
, FileFd::ReadOnly
);
114 int file_size
= state_file
.Size();
116 Prog
->OverallProgress(0, file_size
, 1,
117 _("Reading state information"));
119 pkgTagFile
tagfile(&state_file
);
120 pkgTagSection section
;
122 while(tagfile
.Step(section
)) {
123 string pkgname
= section
.FindS("Package");
124 pkgCache::PkgIterator pkg
=Cache
->FindPkg(pkgname
);
125 // Silently ignore unknown packages and packages with no actual
127 if(!pkg
.end() && !pkg
.VersionList().end()) {
128 short reason
= section
.FindI("Auto-Installed", 0);
130 PkgState
[pkg
->ID
].Flags
|= Flag::Auto
;
131 if(_config
->FindB("Debug::pkgAutoRemove",false))
132 std::cout
<< "Auto-Installed : " << pkgname
<< std::endl
;
135 Prog
->OverallProgress(amt
, file_size
, 1,
136 _("Reading state information"));
139 Prog
->OverallProgress(file_size
, file_size
, 1,
140 _("Reading state information"));
147 bool pkgDepCache::writeStateFile(OpProgress
*prog
)
150 string state
= _config
->FindDir("Dir::State") + "pkgstates";
152 if(_config
->FindB("Debug::pkgAutoRemove",false))
153 std::clog
<< "pkgDepCache::writeStateFile()" << std::endl
;
155 if(!StateFile
.Open(state
, FileFd::WriteEmpty
))
156 return _error
->Error(_("Failed to write StateFile %s"),
159 std::ostringstream ostr
;
160 for(pkgCache::PkgIterator pkg
=Cache
->PkgBegin(); !pkg
.end();pkg
++) {
162 if(PkgState
[pkg
->ID
].Flags
& Flag::Auto
) {
163 if(_config
->FindB("Debug::pkgAutoRemove",false))
164 std::clog
<< "AutoInstal: " << pkg
.Name() << std::endl
;
165 ostr
.str(string(""));
166 ostr
<< "Package: " << pkg
.Name()
167 << "\nAuto-Installed: 1\n\n";
168 StateFile
.Write(ostr
.str().c_str(), ostr
.str().size());
174 // DepCache::CheckDep - Checks a single dependency /*{{{*/
175 // ---------------------------------------------------------------------
176 /* This first checks the dependency against the main target package and
177 then walks along the package provides list and checks if each provides
178 will be installed then checks the provides against the dep. Res will be
179 set to the package which was used to satisfy the dep. */
180 bool pkgDepCache::CheckDep(DepIterator Dep
,int Type
,PkgIterator
&Res
)
182 Res
= Dep
.TargetPkg();
184 /* Check simple depends. A depends -should- never self match but
185 we allow it anyhow because dpkg does. Technically it is a packaging
186 bug. Conflicts may never self match */
187 if (Dep
.TargetPkg() != Dep
.ParentPkg() ||
188 (Dep
->Type
!= Dep::Conflicts
&& Dep
->Type
!= Dep::Obsoletes
))
190 PkgIterator Pkg
= Dep
.TargetPkg();
191 // Check the base package
192 if (Type
== NowVersion
&& Pkg
->CurrentVer
!= 0)
193 if (VS().CheckDep(Pkg
.CurrentVer().VerStr(),Dep
->CompareOp
,
194 Dep
.TargetVer()) == true)
197 if (Type
== InstallVersion
&& PkgState
[Pkg
->ID
].InstallVer
!= 0)
198 if (VS().CheckDep(PkgState
[Pkg
->ID
].InstVerIter(*this).VerStr(),
199 Dep
->CompareOp
,Dep
.TargetVer()) == true)
202 if (Type
== CandidateVersion
&& PkgState
[Pkg
->ID
].CandidateVer
!= 0)
203 if (VS().CheckDep(PkgState
[Pkg
->ID
].CandidateVerIter(*this).VerStr(),
204 Dep
->CompareOp
,Dep
.TargetVer()) == true)
208 if (Dep
->Type
== Dep::Obsoletes
)
211 // Check the providing packages
212 PrvIterator P
= Dep
.TargetPkg().ProvidesList();
213 PkgIterator Pkg
= Dep
.ParentPkg();
214 for (; P
.end() != true; P
++)
216 /* Provides may never be applied against the same package if it is
217 a conflicts. See the comment above. */
218 if (P
.OwnerPkg() == Pkg
&& Dep
->Type
== Dep::Conflicts
)
221 // Check if the provides is a hit
222 if (Type
== NowVersion
)
224 if (P
.OwnerPkg().CurrentVer() != P
.OwnerVer())
228 if (Type
== InstallVersion
)
230 StateCache
&State
= PkgState
[P
.OwnerPkg()->ID
];
231 if (State
.InstallVer
!= (Version
*)P
.OwnerVer())
235 if (Type
== CandidateVersion
)
237 StateCache
&State
= PkgState
[P
.OwnerPkg()->ID
];
238 if (State
.CandidateVer
!= (Version
*)P
.OwnerVer())
242 // Compare the versions.
243 if (VS().CheckDep(P
.ProvideVersion(),Dep
->CompareOp
,Dep
.TargetVer()) == true)
253 // DepCache::AddSizes - Add the packages sizes to the counters /*{{{*/
254 // ---------------------------------------------------------------------
255 /* Call with Mult = -1 to preform the inverse opration */
256 void pkgDepCache::AddSizes(const PkgIterator
&Pkg
,signed long Mult
)
258 StateCache
&P
= PkgState
[Pkg
->ID
];
260 if (Pkg
->VersionList
== 0)
263 if (Pkg
.State() == pkgCache::PkgIterator::NeedsConfigure
&&
267 // Compute the size data
268 if (P
.NewInstall() == true)
270 iUsrSize
+= (signed)(Mult
*P
.InstVerIter(*this)->InstalledSize
);
271 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
276 if (Pkg
->CurrentVer
!= 0 &&
277 (P
.InstallVer
!= (Version
*)Pkg
.CurrentVer() ||
278 (P
.iFlags
& ReInstall
) == ReInstall
) && P
.InstallVer
!= 0)
280 iUsrSize
+= (signed)(Mult
*((signed)P
.InstVerIter(*this)->InstalledSize
-
281 (signed)Pkg
.CurrentVer()->InstalledSize
));
282 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
287 if (Pkg
.State() == pkgCache::PkgIterator::NeedsUnpack
&&
290 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
295 if (Pkg
->CurrentVer
!= 0 && P
.InstallVer
== 0)
297 iUsrSize
-= (signed)(Mult
*Pkg
.CurrentVer()->InstalledSize
);
302 // DepCache::AddStates - Add the package to the state counter /*{{{*/
303 // ---------------------------------------------------------------------
304 /* This routine is tricky to use, you must make sure that it is never
305 called twice for the same package. This means the Remove/Add section
306 should be as short as possible and not encompass any code that will
307 calld Remove/Add itself. Remember, dependencies can be circular so
308 while processing a dep for Pkg it is possible that Add/Remove
309 will be called on Pkg */
310 void pkgDepCache::AddStates(const PkgIterator
&Pkg
,int Add
)
312 StateCache
&State
= PkgState
[Pkg
->ID
];
314 // The Package is broken
315 if ((State
.DepState
& DepInstMin
) != DepInstMin
)
319 if (Pkg
.State() != PkgIterator::NeedsNothing
)
323 if (Pkg
->CurrentVer
== 0)
325 if (State
.Mode
== ModeDelete
&&
326 (State
.iFlags
| Purge
) == Purge
&& Pkg
.Purge() == false)
329 if (State
.Mode
== ModeInstall
)
334 // Installed, no upgrade
335 if (State
.Status
== 0)
337 if (State
.Mode
== ModeDelete
)
340 if ((State
.iFlags
& ReInstall
) == ReInstall
)
346 // Alll 3 are possible
347 if (State
.Mode
== ModeDelete
)
349 if (State
.Mode
== ModeKeep
)
351 if (State
.Mode
== ModeInstall
)
355 // DepCache::BuildGroupOrs - Generate the Or group dep data /*{{{*/
356 // ---------------------------------------------------------------------
357 /* The or group results are stored in the last item of the or group. This
358 allows easy detection of the state of a whole or'd group. */
359 void pkgDepCache::BuildGroupOrs(VerIterator
const &V
)
361 unsigned char Group
= 0;
363 for (DepIterator D
= V
.DependsList(); D
.end() != true; D
++)
365 // Build the dependency state.
366 unsigned char &State
= DepState
[D
->ID
];
368 /* Invert for Conflicts. We have to do this twice to get the
369 right sense for a conflicts group */
370 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
373 // Add to the group if we are within an or..
377 if ((D
->CompareOp
& Dep::Or
) != Dep::Or
)
380 // Invert for Conflicts
381 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
386 // DepCache::VersionState - Perform a pass over a dependency list /*{{{*/
387 // ---------------------------------------------------------------------
388 /* This is used to run over a dependency list and determine the dep
389 state of the list, filtering it through both a Min check and a Policy
390 check. The return result will have SetMin/SetPolicy low if a check
391 fails. It uses the DepState cache for it's computations. */
392 unsigned char pkgDepCache::VersionState(DepIterator D
,unsigned char Check
,
393 unsigned char SetMin
,
394 unsigned char SetPolicy
)
396 unsigned char Dep
= 0xFF;
398 while (D
.end() != true)
400 // Compute a single dependency element (glob or)
401 DepIterator Start
= D
;
402 unsigned char State
= 0;
403 for (bool LastOR
= true; D
.end() == false && LastOR
== true; D
++)
405 State
|= DepState
[D
->ID
];
406 LastOR
= (D
->CompareOp
& Dep::Or
) == Dep::Or
;
409 // Minimum deps that must be satisfied to have a working package
410 if (Start
.IsCritical() == true)
411 if ((State
& Check
) != Check
)
414 // Policy deps that must be satisfied to install the package
415 if (IsImportantDep(Start
) == true &&
416 (State
& Check
) != Check
)
423 // DepCache::DependencyState - Compute the 3 results for a dep /*{{{*/
424 // ---------------------------------------------------------------------
425 /* This is the main dependency computation bit. It computes the 3 main
426 results for a dependencys, Now, Install and Candidate. Callers must
427 invert the result if dealing with conflicts. */
428 unsigned char pkgDepCache::DependencyState(DepIterator
&D
)
430 unsigned char State
= 0;
432 if (CheckDep(D
,NowVersion
) == true)
434 if (CheckDep(D
,InstallVersion
) == true)
436 if (CheckDep(D
,CandidateVersion
) == true)
442 // DepCache::UpdateVerState - Compute the Dep member of the state /*{{{*/
443 // ---------------------------------------------------------------------
444 /* This determines the combined dependency representation of a package
445 for its two states now and install. This is done by using the pre-generated
446 dependency information. */
447 void pkgDepCache::UpdateVerState(PkgIterator Pkg
)
449 // Empty deps are always true
450 StateCache
&State
= PkgState
[Pkg
->ID
];
451 State
.DepState
= 0xFF;
453 // Check the Current state
454 if (Pkg
->CurrentVer
!= 0)
456 DepIterator D
= Pkg
.CurrentVer().DependsList();
457 State
.DepState
&= VersionState(D
,DepNow
,DepNowMin
,DepNowPolicy
);
460 /* Check the candidate state. We do not compare against the whole as
461 a candidate state but check the candidate version against the
463 if (State
.CandidateVer
!= 0)
465 DepIterator D
= State
.CandidateVerIter(*this).DependsList();
466 State
.DepState
&= VersionState(D
,DepInstall
,DepCandMin
,DepCandPolicy
);
469 // Check target state which can only be current or installed
470 if (State
.InstallVer
!= 0)
472 DepIterator D
= State
.InstVerIter(*this).DependsList();
473 State
.DepState
&= VersionState(D
,DepInstall
,DepInstMin
,DepInstPolicy
);
477 // DepCache::Update - Figure out all the state information /*{{{*/
478 // ---------------------------------------------------------------------
479 /* This will figure out the state of all the packages and all the
480 dependencies based on the current policy. */
481 void pkgDepCache::Update(OpProgress
*Prog
)
491 // Perform the depends pass
493 for (PkgIterator I
= PkgBegin(); I
.end() != true; I
++,Done
++)
495 if (Prog
!= 0 && Done%20
== 0)
496 Prog
->Progress(Done
);
497 for (VerIterator V
= I
.VersionList(); V
.end() != true; V
++)
499 unsigned char Group
= 0;
501 for (DepIterator D
= V
.DependsList(); D
.end() != true; D
++)
503 // Build the dependency state.
504 unsigned char &State
= DepState
[D
->ID
];
505 State
= DependencyState(D
);
507 // Add to the group if we are within an or..
510 if ((D
->CompareOp
& Dep::Or
) != Dep::Or
)
513 // Invert for Conflicts
514 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
519 // Compute the pacakge dependency state and size additions
528 Prog
->Progress(Done
);
531 // DepCache::Update - Update the deps list of a package /*{{{*/
532 // ---------------------------------------------------------------------
533 /* This is a helper for update that only does the dep portion of the scan.
534 It is mainly ment to scan reverse dependencies. */
535 void pkgDepCache::Update(DepIterator D
)
537 // Update the reverse deps
538 for (;D
.end() != true; D
++)
540 unsigned char &State
= DepState
[D
->ID
];
541 State
= DependencyState(D
);
543 // Invert for Conflicts
544 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
547 RemoveStates(D
.ParentPkg());
548 BuildGroupOrs(D
.ParentVer());
549 UpdateVerState(D
.ParentPkg());
550 AddStates(D
.ParentPkg());
554 // DepCache::Update - Update the related deps of a package /*{{{*/
555 // ---------------------------------------------------------------------
556 /* This is called whenever the state of a package changes. It updates
557 all cached dependencies related to this package. */
558 void pkgDepCache::Update(PkgIterator
const &Pkg
)
560 // Recompute the dep of the package
565 // Update the reverse deps
566 Update(Pkg
.RevDependsList());
568 // Update the provides map for the current ver
569 if (Pkg
->CurrentVer
!= 0)
570 for (PrvIterator P
= Pkg
.CurrentVer().ProvidesList();
571 P
.end() != true; P
++)
572 Update(P
.ParentPkg().RevDependsList());
574 // Update the provides map for the candidate ver
575 if (PkgState
[Pkg
->ID
].CandidateVer
!= 0)
576 for (PrvIterator P
= PkgState
[Pkg
->ID
].CandidateVerIter(*this).ProvidesList();
577 P
.end() != true; P
++)
578 Update(P
.ParentPkg().RevDependsList());
583 // DepCache::MarkKeep - Put the package in the keep state /*{{{*/
584 // ---------------------------------------------------------------------
586 void pkgDepCache::MarkKeep(PkgIterator
const &Pkg
,bool Soft
)
588 // Simplifies other routines.
589 if (Pkg
.end() == true)
592 /* Reject an attempt to keep a non-source broken installed package, those
594 if (Pkg
.State() == PkgIterator::NeedsUnpack
&&
595 Pkg
.CurrentVer().Downloadable() == false)
598 /* We changed the soft state all the time so the UI is a bit nicer
600 StateCache
&P
= PkgState
[Pkg
->ID
];
602 P
.iFlags
|= AutoKept
;
604 P
.iFlags
&= ~AutoKept
;
606 // Check that it is not already kept
607 if (P
.Mode
== ModeKeep
)
610 // We dont even try to keep virtual packages..
611 if (Pkg
->VersionList
== 0)
614 P
.Flags
&= ~Flag::Auto
;
619 if (Pkg
->CurrentVer
== 0)
622 P
.InstallVer
= Pkg
.CurrentVer();
631 // DepCache::MarkDelete - Put the package in the delete state /*{{{*/
632 // ---------------------------------------------------------------------
634 void pkgDepCache::MarkDelete(PkgIterator
const &Pkg
, bool rPurge
)
636 // Simplifies other routines.
637 if (Pkg
.end() == true)
640 // Check that it is not already marked for delete
641 StateCache
&P
= PkgState
[Pkg
->ID
];
642 P
.iFlags
&= ~(AutoKept
| Purge
);
646 if ((P
.Mode
== ModeDelete
|| P
.InstallVer
== 0) &&
647 (Pkg
.Purge() == true || rPurge
== false))
650 // We dont even try to delete virtual packages..
651 if (Pkg
->VersionList
== 0)
657 if (Pkg
->CurrentVer
== 0 && (Pkg
.Purge() == true || rPurge
== false))
662 // This was not inverted before, but I think it should be
663 P
.Flags
&= ~Flag::Auto
;
670 // DepCache::MarkInstall - Put the package in the install state /*{{{*/
671 // ---------------------------------------------------------------------
673 void pkgDepCache::MarkInstall(PkgIterator
const &Pkg
,bool AutoInst
,
679 // Simplifies other routines.
680 if (Pkg
.end() == true)
683 /* Check that it is not already marked for install and that it can be
685 StateCache
&P
= PkgState
[Pkg
->ID
];
686 P
.iFlags
&= ~AutoKept
;
687 if (P
.InstBroken() == false && (P
.Mode
== ModeInstall
||
688 P
.CandidateVer
== (Version
*)Pkg
.CurrentVer()))
690 if (P
.CandidateVer
== (Version
*)Pkg
.CurrentVer() && P
.InstallVer
== 0)
695 // See if there is even any possible instalation candidate
696 if (P
.CandidateVer
== 0)
699 // We dont even try to install virtual packages..
700 if (Pkg
->VersionList
== 0)
703 /* Target the candidate version and remove the autoflag. We reset the
704 autoflag below if this was called recursively. Otherwise the user
705 should have the ability to de-auto a package by changing its state */
709 P
.Mode
= ModeInstall
;
710 P
.InstallVer
= P
.CandidateVer
;
711 // invert the auto-flag only for new installs, not for upgrades
713 P
.Flags
&= ~Flag::Auto
;
714 if (P
.CandidateVer
== (Version
*)Pkg
.CurrentVer())
721 if (AutoInst
== false)
724 DepIterator Dep
= P
.InstVerIter(*this).DependsList();
725 for (; Dep
.end() != true;)
728 DepIterator Start
= Dep
;
731 for (bool LastOR
= true; Dep
.end() == false && LastOR
== true; Dep
++,Ors
++)
733 LastOR
= (Dep
->CompareOp
& Dep::Or
) == Dep::Or
;
735 if ((DepState
[Dep
->ID
] & DepInstall
) == DepInstall
)
739 // Dep is satisfied okay.
743 /* Check if this dep should be consider for install. If it is a user
744 defined important dep and we are installed a new package then
745 it will be installed. Otherwise we only worry about critical deps */
746 if (IsImportantDep(Start
) == false)
748 if (Pkg
->CurrentVer
!= 0 && Start
.IsCritical() == false)
751 /* If we are in an or group locate the first or that can
752 succeed. We have already cached this.. */
753 for (; Ors
> 1 && (DepState
[Start
->ID
] & DepCVer
) != DepCVer
; Ors
--)
756 /* This bit is for processing the possibilty of an install/upgrade
757 fixing the problem */
758 SPtrArray
<Version
*> List
= Start
.AllTargets();
759 if ((DepState
[Start
->ID
] & DepCVer
) == DepCVer
)
761 // Right, find the best version to install..
762 Version
**Cur
= List
;
763 PkgIterator P
= Start
.TargetPkg();
764 PkgIterator
InstPkg(*Cache
,0);
766 // See if there are direct matches (at the start of the list)
767 for (; *Cur
!= 0 && (*Cur
)->ParentPkg
== P
.Index(); Cur
++)
769 PkgIterator
Pkg(*Cache
,Cache
->PkgP
+ (*Cur
)->ParentPkg
);
770 if (PkgState
[Pkg
->ID
].CandidateVer
!= *Cur
)
776 // Select the highest priority providing package
777 if (InstPkg
.end() == true)
779 pkgPrioSortList(*Cache
,Cur
);
780 for (; *Cur
!= 0; Cur
++)
782 PkgIterator
Pkg(*Cache
,Cache
->PkgP
+ (*Cur
)->ParentPkg
);
783 if (PkgState
[Pkg
->ID
].CandidateVer
!= *Cur
)
790 if (InstPkg
.end() == false)
792 MarkInstall(InstPkg
,true,Depth
+ 1);
794 // Set the autoflag, after MarkInstall because MarkInstall unsets it
795 if (P
->CurrentVer
== 0)
796 PkgState
[InstPkg
->ID
].Flags
|= Flag::Auto
;
802 /* For conflicts we just de-install the package and mark as auto,
803 Conflicts may not have or groups */
804 if (Start
->Type
== Dep::Conflicts
|| Start
->Type
== Dep::Obsoletes
)
806 for (Version
**I
= List
; *I
!= 0; I
++)
808 VerIterator
Ver(*this,*I
);
809 PkgIterator Pkg
= Ver
.ParentPkg();
812 PkgState
[Pkg
->ID
].Flags
|= Flag::Auto
;
819 // DepCache::SetReInstall - Set the reinstallation flag /*{{{*/
820 // ---------------------------------------------------------------------
822 void pkgDepCache::SetReInstall(PkgIterator
const &Pkg
,bool To
)
827 StateCache
&P
= PkgState
[Pkg
->ID
];
829 P
.iFlags
|= ReInstall
;
831 P
.iFlags
&= ~ReInstall
;
837 // DepCache::SetCandidateVersion - Change the candidate version /*{{{*/
838 // ---------------------------------------------------------------------
840 void pkgDepCache::SetCandidateVersion(VerIterator TargetVer
)
842 pkgCache::PkgIterator Pkg
= TargetVer
.ParentPkg();
843 StateCache
&P
= PkgState
[Pkg
->ID
];
848 if (P
.CandidateVer
== P
.InstallVer
)
849 P
.InstallVer
= (Version
*)TargetVer
;
850 P
.CandidateVer
= (Version
*)TargetVer
;
858 // StateCache::Update - Compute the various static display things /*{{{*/
859 // ---------------------------------------------------------------------
860 /* This is called whenever the Candidate version changes. */
861 void pkgDepCache::StateCache::Update(PkgIterator Pkg
,pkgCache
&Cache
)
864 VerIterator Ver
= CandidateVerIter(Cache
);
866 // Use a null string or the version string
867 if (Ver
.end() == true)
870 CandVersion
= Ver
.VerStr();
872 // Find the current version
874 if (Pkg
->CurrentVer
!= 0)
875 CurVersion
= Pkg
.CurrentVer().VerStr();
877 // Strip off the epochs for display
878 CurVersion
= StripEpoch(CurVersion
);
879 CandVersion
= StripEpoch(CandVersion
);
881 // Figure out if its up or down or equal
882 Status
= Ver
.CompareVer(Pkg
.CurrentVer());
883 if (Pkg
->CurrentVer
== 0 || Pkg
->VersionList
== 0 || CandidateVer
== 0)
887 // StateCache::StripEpoch - Remove the epoch specifier from the version /*{{{*/
888 // ---------------------------------------------------------------------
890 const char *pkgDepCache::StateCache::StripEpoch(const char *Ver
)
896 for (const char *I
= Ver
; *I
!= 0; I
++)
903 // Policy::GetCandidateVer - Returns the Candidate install version /*{{{*/
904 // ---------------------------------------------------------------------
905 /* The default just returns the highest available version that is not
906 a source and automatic. */
907 pkgCache::VerIterator
pkgDepCache::Policy::GetCandidateVer(PkgIterator Pkg
)
909 /* Not source/not automatic versions cannot be a candidate version
910 unless they are already installed */
911 VerIterator
Last(*(pkgCache
*)this,0);
913 for (VerIterator I
= Pkg
.VersionList(); I
.end() == false; I
++)
915 if (Pkg
.CurrentVer() == I
)
918 for (VerFileIterator J
= I
.FileList(); J
.end() == false; J
++)
920 if ((J
.File()->Flags
& Flag::NotSource
) != 0)
923 /* Stash the highest version of a not-automatic source, we use it
924 if there is nothing better */
925 if ((J
.File()->Flags
& Flag::NotAutomatic
) != 0)
927 if (Last
.end() == true)
939 // Policy::IsImportantDep - True if the dependency is important /*{{{*/
940 // ---------------------------------------------------------------------
942 bool pkgDepCache::Policy::IsImportantDep(DepIterator Dep
)
944 return Dep
.IsCritical();