]>
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("Install-Reason", 0);
130 PkgState
[pkg
->ID
].Flags
|= pkgCache::Flag::Auto
;
131 if(_config
->FindB("Debug::pkgAutoRemove",false))
132 std::cout
<< "Install-Reason for: " << pkgname
133 << " is " << reason
<< std::endl
;
136 Prog
->OverallProgress(amt
, file_size
, 1,
137 _("Reading state information"));
140 Prog
->OverallProgress(file_size
, file_size
, 1,
141 _("Reading state information"));
148 bool pkgDepCache::writeStateFile(OpProgress
*prog
)
151 string state
= _config
->FindDir("Dir::State") + "pkgstates";
153 if(_config
->FindB("Debug::pkgAutoRemove",false))
154 std::clog
<< "pkgDepCache::writeStateFile()" << std::endl
;
156 if(!StateFile
.Open(state
, FileFd::WriteEmpty
))
157 return _error
->Error(_("Failed to write StateFile %s"),
160 std::ostringstream ostr
;
161 for(pkgCache::PkgIterator pkg
=Cache
->PkgBegin(); !pkg
.end();pkg
++) {
163 if(PkgState
[pkg
->ID
].Flags
& pkgCache::Flag::Auto
) {
164 if(_config
->FindB("Debug::pkgAutoRemove",false))
165 std::clog
<< "AutoInstal: " << pkg
.Name() << std::endl
;
166 ostr
.str(string(""));
167 ostr
<< "Package: " << pkg
.Name()
168 << "\nInstall-Reason: 1\n\n";
169 StateFile
.Write(ostr
.str().c_str(), ostr
.str().size());
175 // DepCache::CheckDep - Checks a single dependency /*{{{*/
176 // ---------------------------------------------------------------------
177 /* This first checks the dependency against the main target package and
178 then walks along the package provides list and checks if each provides
179 will be installed then checks the provides against the dep. Res will be
180 set to the package which was used to satisfy the dep. */
181 bool pkgDepCache::CheckDep(DepIterator Dep
,int Type
,PkgIterator
&Res
)
183 Res
= Dep
.TargetPkg();
185 /* Check simple depends. A depends -should- never self match but
186 we allow it anyhow because dpkg does. Technically it is a packaging
187 bug. Conflicts may never self match */
188 if (Dep
.TargetPkg() != Dep
.ParentPkg() ||
189 (Dep
->Type
!= Dep::Conflicts
&& Dep
->Type
!= Dep::Obsoletes
))
191 PkgIterator Pkg
= Dep
.TargetPkg();
192 // Check the base package
193 if (Type
== NowVersion
&& Pkg
->CurrentVer
!= 0)
194 if (VS().CheckDep(Pkg
.CurrentVer().VerStr(),Dep
->CompareOp
,
195 Dep
.TargetVer()) == true)
198 if (Type
== InstallVersion
&& PkgState
[Pkg
->ID
].InstallVer
!= 0)
199 if (VS().CheckDep(PkgState
[Pkg
->ID
].InstVerIter(*this).VerStr(),
200 Dep
->CompareOp
,Dep
.TargetVer()) == true)
203 if (Type
== CandidateVersion
&& PkgState
[Pkg
->ID
].CandidateVer
!= 0)
204 if (VS().CheckDep(PkgState
[Pkg
->ID
].CandidateVerIter(*this).VerStr(),
205 Dep
->CompareOp
,Dep
.TargetVer()) == true)
209 if (Dep
->Type
== Dep::Obsoletes
)
212 // Check the providing packages
213 PrvIterator P
= Dep
.TargetPkg().ProvidesList();
214 PkgIterator Pkg
= Dep
.ParentPkg();
215 for (; P
.end() != true; P
++)
217 /* Provides may never be applied against the same package if it is
218 a conflicts. See the comment above. */
219 if (P
.OwnerPkg() == Pkg
&& Dep
->Type
== Dep::Conflicts
)
222 // Check if the provides is a hit
223 if (Type
== NowVersion
)
225 if (P
.OwnerPkg().CurrentVer() != P
.OwnerVer())
229 if (Type
== InstallVersion
)
231 StateCache
&State
= PkgState
[P
.OwnerPkg()->ID
];
232 if (State
.InstallVer
!= (Version
*)P
.OwnerVer())
236 if (Type
== CandidateVersion
)
238 StateCache
&State
= PkgState
[P
.OwnerPkg()->ID
];
239 if (State
.CandidateVer
!= (Version
*)P
.OwnerVer())
243 // Compare the versions.
244 if (VS().CheckDep(P
.ProvideVersion(),Dep
->CompareOp
,Dep
.TargetVer()) == true)
254 // DepCache::AddSizes - Add the packages sizes to the counters /*{{{*/
255 // ---------------------------------------------------------------------
256 /* Call with Mult = -1 to preform the inverse opration */
257 void pkgDepCache::AddSizes(const PkgIterator
&Pkg
,signed long Mult
)
259 StateCache
&P
= PkgState
[Pkg
->ID
];
261 if (Pkg
->VersionList
== 0)
264 if (Pkg
.State() == pkgCache::PkgIterator::NeedsConfigure
&&
268 // Compute the size data
269 if (P
.NewInstall() == true)
271 iUsrSize
+= (signed)(Mult
*P
.InstVerIter(*this)->InstalledSize
);
272 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
277 if (Pkg
->CurrentVer
!= 0 &&
278 (P
.InstallVer
!= (Version
*)Pkg
.CurrentVer() ||
279 (P
.iFlags
& ReInstall
) == ReInstall
) && P
.InstallVer
!= 0)
281 iUsrSize
+= (signed)(Mult
*((signed)P
.InstVerIter(*this)->InstalledSize
-
282 (signed)Pkg
.CurrentVer()->InstalledSize
));
283 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
288 if (Pkg
.State() == pkgCache::PkgIterator::NeedsUnpack
&&
291 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
296 if (Pkg
->CurrentVer
!= 0 && P
.InstallVer
== 0)
298 iUsrSize
-= (signed)(Mult
*Pkg
.CurrentVer()->InstalledSize
);
303 // DepCache::AddStates - Add the package to the state counter /*{{{*/
304 // ---------------------------------------------------------------------
305 /* This routine is tricky to use, you must make sure that it is never
306 called twice for the same package. This means the Remove/Add section
307 should be as short as possible and not encompass any code that will
308 calld Remove/Add itself. Remember, dependencies can be circular so
309 while processing a dep for Pkg it is possible that Add/Remove
310 will be called on Pkg */
311 void pkgDepCache::AddStates(const PkgIterator
&Pkg
,int Add
)
313 StateCache
&State
= PkgState
[Pkg
->ID
];
315 // The Package is broken
316 if ((State
.DepState
& DepInstMin
) != DepInstMin
)
320 if (Pkg
.State() != PkgIterator::NeedsNothing
)
324 if (Pkg
->CurrentVer
== 0)
326 if (State
.Mode
== ModeDelete
&&
327 (State
.iFlags
| Purge
) == Purge
&& Pkg
.Purge() == false)
330 if (State
.Mode
== ModeInstall
)
335 // Installed, no upgrade
336 if (State
.Status
== 0)
338 if (State
.Mode
== ModeDelete
)
341 if ((State
.iFlags
& ReInstall
) == ReInstall
)
347 // Alll 3 are possible
348 if (State
.Mode
== ModeDelete
)
350 if (State
.Mode
== ModeKeep
)
352 if (State
.Mode
== ModeInstall
)
356 // DepCache::BuildGroupOrs - Generate the Or group dep data /*{{{*/
357 // ---------------------------------------------------------------------
358 /* The or group results are stored in the last item of the or group. This
359 allows easy detection of the state of a whole or'd group. */
360 void pkgDepCache::BuildGroupOrs(VerIterator
const &V
)
362 unsigned char Group
= 0;
364 for (DepIterator D
= V
.DependsList(); D
.end() != true; D
++)
366 // Build the dependency state.
367 unsigned char &State
= DepState
[D
->ID
];
369 /* Invert for Conflicts. We have to do this twice to get the
370 right sense for a conflicts group */
371 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
374 // Add to the group if we are within an or..
378 if ((D
->CompareOp
& Dep::Or
) != Dep::Or
)
381 // Invert for Conflicts
382 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
387 // DepCache::VersionState - Perform a pass over a dependency list /*{{{*/
388 // ---------------------------------------------------------------------
389 /* This is used to run over a dependency list and determine the dep
390 state of the list, filtering it through both a Min check and a Policy
391 check. The return result will have SetMin/SetPolicy low if a check
392 fails. It uses the DepState cache for it's computations. */
393 unsigned char pkgDepCache::VersionState(DepIterator D
,unsigned char Check
,
394 unsigned char SetMin
,
395 unsigned char SetPolicy
)
397 unsigned char Dep
= 0xFF;
399 while (D
.end() != true)
401 // Compute a single dependency element (glob or)
402 DepIterator Start
= D
;
403 unsigned char State
= 0;
404 for (bool LastOR
= true; D
.end() == false && LastOR
== true; D
++)
406 State
|= DepState
[D
->ID
];
407 LastOR
= (D
->CompareOp
& Dep::Or
) == Dep::Or
;
410 // Minimum deps that must be satisfied to have a working package
411 if (Start
.IsCritical() == true)
412 if ((State
& Check
) != Check
)
415 // Policy deps that must be satisfied to install the package
416 if (IsImportantDep(Start
) == true &&
417 (State
& Check
) != Check
)
424 // DepCache::DependencyState - Compute the 3 results for a dep /*{{{*/
425 // ---------------------------------------------------------------------
426 /* This is the main dependency computation bit. It computes the 3 main
427 results for a dependencys, Now, Install and Candidate. Callers must
428 invert the result if dealing with conflicts. */
429 unsigned char pkgDepCache::DependencyState(DepIterator
&D
)
431 unsigned char State
= 0;
433 if (CheckDep(D
,NowVersion
) == true)
435 if (CheckDep(D
,InstallVersion
) == true)
437 if (CheckDep(D
,CandidateVersion
) == true)
443 // DepCache::UpdateVerState - Compute the Dep member of the state /*{{{*/
444 // ---------------------------------------------------------------------
445 /* This determines the combined dependency representation of a package
446 for its two states now and install. This is done by using the pre-generated
447 dependency information. */
448 void pkgDepCache::UpdateVerState(PkgIterator Pkg
)
450 // Empty deps are always true
451 StateCache
&State
= PkgState
[Pkg
->ID
];
452 State
.DepState
= 0xFF;
454 // Check the Current state
455 if (Pkg
->CurrentVer
!= 0)
457 DepIterator D
= Pkg
.CurrentVer().DependsList();
458 State
.DepState
&= VersionState(D
,DepNow
,DepNowMin
,DepNowPolicy
);
461 /* Check the candidate state. We do not compare against the whole as
462 a candidate state but check the candidate version against the
464 if (State
.CandidateVer
!= 0)
466 DepIterator D
= State
.CandidateVerIter(*this).DependsList();
467 State
.DepState
&= VersionState(D
,DepInstall
,DepCandMin
,DepCandPolicy
);
470 // Check target state which can only be current or installed
471 if (State
.InstallVer
!= 0)
473 DepIterator D
= State
.InstVerIter(*this).DependsList();
474 State
.DepState
&= VersionState(D
,DepInstall
,DepInstMin
,DepInstPolicy
);
478 // DepCache::Update - Figure out all the state information /*{{{*/
479 // ---------------------------------------------------------------------
480 /* This will figure out the state of all the packages and all the
481 dependencies based on the current policy. */
482 void pkgDepCache::Update(OpProgress
*Prog
)
492 // Perform the depends pass
494 for (PkgIterator I
= PkgBegin(); I
.end() != true; I
++,Done
++)
496 if (Prog
!= 0 && Done%20
== 0)
497 Prog
->Progress(Done
);
498 for (VerIterator V
= I
.VersionList(); V
.end() != true; V
++)
500 unsigned char Group
= 0;
502 for (DepIterator D
= V
.DependsList(); D
.end() != true; D
++)
504 // Build the dependency state.
505 unsigned char &State
= DepState
[D
->ID
];
506 State
= DependencyState(D
);
508 // Add to the group if we are within an or..
511 if ((D
->CompareOp
& Dep::Or
) != Dep::Or
)
514 // Invert for Conflicts
515 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
520 // Compute the pacakge dependency state and size additions
529 Prog
->Progress(Done
);
532 // DepCache::Update - Update the deps list of a package /*{{{*/
533 // ---------------------------------------------------------------------
534 /* This is a helper for update that only does the dep portion of the scan.
535 It is mainly ment to scan reverse dependencies. */
536 void pkgDepCache::Update(DepIterator D
)
538 // Update the reverse deps
539 for (;D
.end() != true; D
++)
541 unsigned char &State
= DepState
[D
->ID
];
542 State
= DependencyState(D
);
544 // Invert for Conflicts
545 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
548 RemoveStates(D
.ParentPkg());
549 BuildGroupOrs(D
.ParentVer());
550 UpdateVerState(D
.ParentPkg());
551 AddStates(D
.ParentPkg());
555 // DepCache::Update - Update the related deps of a package /*{{{*/
556 // ---------------------------------------------------------------------
557 /* This is called whenever the state of a package changes. It updates
558 all cached dependencies related to this package. */
559 void pkgDepCache::Update(PkgIterator
const &Pkg
)
561 // Recompute the dep of the package
566 // Update the reverse deps
567 Update(Pkg
.RevDependsList());
569 // Update the provides map for the current ver
570 if (Pkg
->CurrentVer
!= 0)
571 for (PrvIterator P
= Pkg
.CurrentVer().ProvidesList();
572 P
.end() != true; P
++)
573 Update(P
.ParentPkg().RevDependsList());
575 // Update the provides map for the candidate ver
576 if (PkgState
[Pkg
->ID
].CandidateVer
!= 0)
577 for (PrvIterator P
= PkgState
[Pkg
->ID
].CandidateVerIter(*this).ProvidesList();
578 P
.end() != true; P
++)
579 Update(P
.ParentPkg().RevDependsList());
584 // DepCache::MarkKeep - Put the package in the keep state /*{{{*/
585 // ---------------------------------------------------------------------
587 void pkgDepCache::MarkKeep(PkgIterator
const &Pkg
,bool Soft
)
589 // Simplifies other routines.
590 if (Pkg
.end() == true)
593 /* Reject an attempt to keep a non-source broken installed package, those
595 if (Pkg
.State() == PkgIterator::NeedsUnpack
&&
596 Pkg
.CurrentVer().Downloadable() == false)
599 /* We changed the soft state all the time so the UI is a bit nicer
601 StateCache
&P
= PkgState
[Pkg
->ID
];
603 P
.iFlags
|= AutoKept
;
605 P
.iFlags
&= ~AutoKept
;
607 // Check that it is not already kept
608 if (P
.Mode
== ModeKeep
)
611 // We dont even try to keep virtual packages..
612 if (Pkg
->VersionList
== 0)
615 P
.Flags
&= ~Flag::Auto
;
620 if (Pkg
->CurrentVer
== 0)
623 P
.InstallVer
= Pkg
.CurrentVer();
632 // DepCache::MarkDelete - Put the package in the delete state /*{{{*/
633 // ---------------------------------------------------------------------
635 void pkgDepCache::MarkDelete(PkgIterator
const &Pkg
, bool rPurge
)
637 // Simplifies other routines.
638 if (Pkg
.end() == true)
641 // Check that it is not already marked for delete
642 StateCache
&P
= PkgState
[Pkg
->ID
];
643 P
.iFlags
&= ~(AutoKept
| Purge
);
647 if ((P
.Mode
== ModeDelete
|| P
.InstallVer
== 0) &&
648 (Pkg
.Purge() == true || rPurge
== false))
651 // We dont even try to delete virtual packages..
652 if (Pkg
->VersionList
== 0)
658 if (Pkg
->CurrentVer
== 0 && (Pkg
.Purge() == true || rPurge
== false))
663 // This was not inverted before, but I think it should be
664 P
.Flags
&= ~Flag::Auto
;
671 // DepCache::MarkInstall - Put the package in the install state /*{{{*/
672 // ---------------------------------------------------------------------
674 void pkgDepCache::MarkInstall(PkgIterator
const &Pkg
,bool AutoInst
,
680 // Simplifies other routines.
681 if (Pkg
.end() == true)
684 /* Check that it is not already marked for install and that it can be
686 StateCache
&P
= PkgState
[Pkg
->ID
];
687 P
.iFlags
&= ~AutoKept
;
688 if (P
.InstBroken() == false && (P
.Mode
== ModeInstall
||
689 P
.CandidateVer
== (Version
*)Pkg
.CurrentVer()))
691 if (P
.CandidateVer
== (Version
*)Pkg
.CurrentVer() && P
.InstallVer
== 0)
696 // See if there is even any possible instalation candidate
697 if (P
.CandidateVer
== 0)
700 // We dont even try to install virtual packages..
701 if (Pkg
->VersionList
== 0)
704 /* Target the candidate version and remove the autoflag. We reset the
705 autoflag below if this was called recursively. Otherwise the user
706 should have the ability to de-auto a package by changing its state */
710 P
.Mode
= ModeInstall
;
711 P
.InstallVer
= P
.CandidateVer
;
712 P
.Flags
&= ~Flag::Auto
;
713 if (P
.CandidateVer
== (Version
*)Pkg
.CurrentVer())
720 if (AutoInst
== false)
723 DepIterator Dep
= P
.InstVerIter(*this).DependsList();
724 for (; Dep
.end() != true;)
727 DepIterator Start
= Dep
;
730 for (bool LastOR
= true; Dep
.end() == false && LastOR
== true; Dep
++,Ors
++)
732 LastOR
= (Dep
->CompareOp
& Dep::Or
) == Dep::Or
;
734 if ((DepState
[Dep
->ID
] & DepInstall
) == DepInstall
)
738 // Dep is satisfied okay.
742 /* Check if this dep should be consider for install. If it is a user
743 defined important dep and we are installed a new package then
744 it will be installed. Otherwise we only worry about critical deps */
745 if (IsImportantDep(Start
) == false)
747 if (Pkg
->CurrentVer
!= 0 && Start
.IsCritical() == false)
750 /* If we are in an or group locate the first or that can
751 succeed. We have already cached this.. */
752 for (; Ors
> 1 && (DepState
[Start
->ID
] & DepCVer
) != DepCVer
; Ors
--)
755 /* This bit is for processing the possibilty of an install/upgrade
756 fixing the problem */
757 SPtrArray
<Version
*> List
= Start
.AllTargets();
758 if ((DepState
[Start
->ID
] & DepCVer
) == DepCVer
)
760 // Right, find the best version to install..
761 Version
**Cur
= List
;
762 PkgIterator P
= Start
.TargetPkg();
763 PkgIterator
InstPkg(*Cache
,0);
765 // See if there are direct matches (at the start of the list)
766 for (; *Cur
!= 0 && (*Cur
)->ParentPkg
== P
.Index(); Cur
++)
768 PkgIterator
Pkg(*Cache
,Cache
->PkgP
+ (*Cur
)->ParentPkg
);
769 if (PkgState
[Pkg
->ID
].CandidateVer
!= *Cur
)
775 // Select the highest priority providing package
776 if (InstPkg
.end() == true)
778 pkgPrioSortList(*Cache
,Cur
);
779 for (; *Cur
!= 0; Cur
++)
781 PkgIterator
Pkg(*Cache
,Cache
->PkgP
+ (*Cur
)->ParentPkg
);
782 if (PkgState
[Pkg
->ID
].CandidateVer
!= *Cur
)
789 if (InstPkg
.end() == false)
791 MarkInstall(InstPkg
,true,Depth
+ 1);
793 // Set the autoflag, after MarkInstall because MarkInstall unsets it
794 if (P
->CurrentVer
== 0)
795 PkgState
[InstPkg
->ID
].Flags
|= Flag::Auto
;
801 /* For conflicts we just de-install the package and mark as auto,
802 Conflicts may not have or groups */
803 if (Start
->Type
== Dep::Conflicts
|| Start
->Type
== Dep::Obsoletes
)
805 for (Version
**I
= List
; *I
!= 0; I
++)
807 VerIterator
Ver(*this,*I
);
808 PkgIterator Pkg
= Ver
.ParentPkg();
811 PkgState
[Pkg
->ID
].Flags
|= Flag::Auto
;
818 // DepCache::SetReInstall - Set the reinstallation flag /*{{{*/
819 // ---------------------------------------------------------------------
821 void pkgDepCache::SetReInstall(PkgIterator
const &Pkg
,bool To
)
826 StateCache
&P
= PkgState
[Pkg
->ID
];
828 P
.iFlags
|= ReInstall
;
830 P
.iFlags
&= ~ReInstall
;
836 // DepCache::SetCandidateVersion - Change the candidate version /*{{{*/
837 // ---------------------------------------------------------------------
839 void pkgDepCache::SetCandidateVersion(VerIterator TargetVer
)
841 pkgCache::PkgIterator Pkg
= TargetVer
.ParentPkg();
842 StateCache
&P
= PkgState
[Pkg
->ID
];
847 if (P
.CandidateVer
== P
.InstallVer
)
848 P
.InstallVer
= (Version
*)TargetVer
;
849 P
.CandidateVer
= (Version
*)TargetVer
;
857 // StateCache::Update - Compute the various static display things /*{{{*/
858 // ---------------------------------------------------------------------
859 /* This is called whenever the Candidate version changes. */
860 void pkgDepCache::StateCache::Update(PkgIterator Pkg
,pkgCache
&Cache
)
863 VerIterator Ver
= CandidateVerIter(Cache
);
865 // Use a null string or the version string
866 if (Ver
.end() == true)
869 CandVersion
= Ver
.VerStr();
871 // Find the current version
873 if (Pkg
->CurrentVer
!= 0)
874 CurVersion
= Pkg
.CurrentVer().VerStr();
876 // Strip off the epochs for display
877 CurVersion
= StripEpoch(CurVersion
);
878 CandVersion
= StripEpoch(CandVersion
);
880 // Figure out if its up or down or equal
881 Status
= Ver
.CompareVer(Pkg
.CurrentVer());
882 if (Pkg
->CurrentVer
== 0 || Pkg
->VersionList
== 0 || CandidateVer
== 0)
886 // StateCache::StripEpoch - Remove the epoch specifier from the version /*{{{*/
887 // ---------------------------------------------------------------------
889 const char *pkgDepCache::StateCache::StripEpoch(const char *Ver
)
895 for (const char *I
= Ver
; *I
!= 0; I
++)
902 // Policy::GetCandidateVer - Returns the Candidate install version /*{{{*/
903 // ---------------------------------------------------------------------
904 /* The default just returns the highest available version that is not
905 a source and automatic. */
906 pkgCache::VerIterator
pkgDepCache::Policy::GetCandidateVer(PkgIterator Pkg
)
908 /* Not source/not automatic versions cannot be a candidate version
909 unless they are already installed */
910 VerIterator
Last(*(pkgCache
*)this,0);
912 for (VerIterator I
= Pkg
.VersionList(); I
.end() == false; I
++)
914 if (Pkg
.CurrentVer() == I
)
917 for (VerFileIterator J
= I
.FileList(); J
.end() == false; J
++)
919 if ((J
.File()->Flags
& Flag::NotSource
) != 0)
922 /* Stash the highest version of a not-automatic source, we use it
923 if there is nothing better */
924 if ((J
.File()->Flags
& Flag::NotAutomatic
) != 0)
926 if (Last
.end() == true)
938 // Policy::IsImportantDep - True if the dependency is important /*{{{*/
939 // ---------------------------------------------------------------------
941 bool pkgDepCache::Policy::IsImportantDep(DepIterator Dep
)
943 return Dep
.IsCritical();