]>
git.saurik.com Git - apt.git/blob - apt-pkg/depcache.cc
05512e179d94d8267059f4b1a035b2c0a1987b37
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();
115 Prog
->OverallProgress(0, file_size
, 1,
116 _("Reading state information"));
118 pkgTagFile
tagfile(&state_file
);
119 pkgTagSection section
;
121 while(tagfile
.Step(section
)) {
122 string pkgname
= section
.FindS("Package");
123 pkgCache::PkgIterator pkg
=Cache
->FindPkg(pkgname
);
124 // Silently ignore unknown packages and packages with no actual
126 if(!pkg
.end() && !pkg
.VersionList().end()) {
127 short reason
= section
.FindI("Install-Reason", 0);
129 PkgState
[pkg
->ID
].Flags
|= pkgCache::Flag::Auto
;
130 if(_config
->FindB("Debug::pkgAutoRemove",false))
131 std::cout
<< "Install-Reason for: " << pkgname
132 << " is " << reason
<< std::endl
;
134 Prog
->OverallProgress(amt
, file_size
, 1,
135 _("Reading state information"));
137 Prog
->OverallProgress(file_size
, file_size
, 1,
138 _("Reading state information"));
145 bool pkgDepCache::writeStateFile(OpProgress
*prog
)
148 string state
= _config
->FindDir("Dir::State") + "pkgstates";
150 if(_config
->FindB("Debug::pkgAutoRemove",false))
151 std::clog
<< "pkgDepCache::writeStateFile()" << std::endl
;
153 if(!StateFile
.Open(state
, FileFd::WriteEmpty
))
154 return _error
->Error(_("Failed to write StateFile %s"),
157 std::ostringstream ostr
;
158 for(pkgCache::PkgIterator pkg
=Cache
->PkgBegin(); !pkg
.end();pkg
++) {
160 if(PkgState
[pkg
->ID
].Flags
& pkgCache::Flag::Auto
) {
161 if(_config
->FindB("Debug::pkgAutoRemove",false))
162 std::clog
<< "AutoInstal: " << pkg
.Name() << std::endl
;
163 ostr
.str(string(""));
164 ostr
<< "Package: " << pkg
.Name()
165 << "\nInstall-Reason: 1\n\n";
166 StateFile
.Write(ostr
.str().c_str(), ostr
.str().size());
172 // DepCache::CheckDep - Checks a single dependency /*{{{*/
173 // ---------------------------------------------------------------------
174 /* This first checks the dependency against the main target package and
175 then walks along the package provides list and checks if each provides
176 will be installed then checks the provides against the dep. Res will be
177 set to the package which was used to satisfy the dep. */
178 bool pkgDepCache::CheckDep(DepIterator Dep
,int Type
,PkgIterator
&Res
)
180 Res
= Dep
.TargetPkg();
182 /* Check simple depends. A depends -should- never self match but
183 we allow it anyhow because dpkg does. Technically it is a packaging
184 bug. Conflicts may never self match */
185 if (Dep
.TargetPkg() != Dep
.ParentPkg() ||
186 (Dep
->Type
!= Dep::Conflicts
&& Dep
->Type
!= Dep::Obsoletes
))
188 PkgIterator Pkg
= Dep
.TargetPkg();
189 // Check the base package
190 if (Type
== NowVersion
&& Pkg
->CurrentVer
!= 0)
191 if (VS().CheckDep(Pkg
.CurrentVer().VerStr(),Dep
->CompareOp
,
192 Dep
.TargetVer()) == true)
195 if (Type
== InstallVersion
&& PkgState
[Pkg
->ID
].InstallVer
!= 0)
196 if (VS().CheckDep(PkgState
[Pkg
->ID
].InstVerIter(*this).VerStr(),
197 Dep
->CompareOp
,Dep
.TargetVer()) == true)
200 if (Type
== CandidateVersion
&& PkgState
[Pkg
->ID
].CandidateVer
!= 0)
201 if (VS().CheckDep(PkgState
[Pkg
->ID
].CandidateVerIter(*this).VerStr(),
202 Dep
->CompareOp
,Dep
.TargetVer()) == true)
206 if (Dep
->Type
== Dep::Obsoletes
)
209 // Check the providing packages
210 PrvIterator P
= Dep
.TargetPkg().ProvidesList();
211 PkgIterator Pkg
= Dep
.ParentPkg();
212 for (; P
.end() != true; P
++)
214 /* Provides may never be applied against the same package if it is
215 a conflicts. See the comment above. */
216 if (P
.OwnerPkg() == Pkg
&& Dep
->Type
== Dep::Conflicts
)
219 // Check if the provides is a hit
220 if (Type
== NowVersion
)
222 if (P
.OwnerPkg().CurrentVer() != P
.OwnerVer())
226 if (Type
== InstallVersion
)
228 StateCache
&State
= PkgState
[P
.OwnerPkg()->ID
];
229 if (State
.InstallVer
!= (Version
*)P
.OwnerVer())
233 if (Type
== CandidateVersion
)
235 StateCache
&State
= PkgState
[P
.OwnerPkg()->ID
];
236 if (State
.CandidateVer
!= (Version
*)P
.OwnerVer())
240 // Compare the versions.
241 if (VS().CheckDep(P
.ProvideVersion(),Dep
->CompareOp
,Dep
.TargetVer()) == true)
251 // DepCache::AddSizes - Add the packages sizes to the counters /*{{{*/
252 // ---------------------------------------------------------------------
253 /* Call with Mult = -1 to preform the inverse opration */
254 void pkgDepCache::AddSizes(const PkgIterator
&Pkg
,signed long Mult
)
256 StateCache
&P
= PkgState
[Pkg
->ID
];
258 if (Pkg
->VersionList
== 0)
261 if (Pkg
.State() == pkgCache::PkgIterator::NeedsConfigure
&&
265 // Compute the size data
266 if (P
.NewInstall() == true)
268 iUsrSize
+= (signed)(Mult
*P
.InstVerIter(*this)->InstalledSize
);
269 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
274 if (Pkg
->CurrentVer
!= 0 &&
275 (P
.InstallVer
!= (Version
*)Pkg
.CurrentVer() ||
276 (P
.iFlags
& ReInstall
) == ReInstall
) && P
.InstallVer
!= 0)
278 iUsrSize
+= (signed)(Mult
*((signed)P
.InstVerIter(*this)->InstalledSize
-
279 (signed)Pkg
.CurrentVer()->InstalledSize
));
280 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
285 if (Pkg
.State() == pkgCache::PkgIterator::NeedsUnpack
&&
288 iDownloadSize
+= (signed)(Mult
*P
.InstVerIter(*this)->Size
);
293 if (Pkg
->CurrentVer
!= 0 && P
.InstallVer
== 0)
295 iUsrSize
-= (signed)(Mult
*Pkg
.CurrentVer()->InstalledSize
);
300 // DepCache::AddStates - Add the package to the state counter /*{{{*/
301 // ---------------------------------------------------------------------
302 /* This routine is tricky to use, you must make sure that it is never
303 called twice for the same package. This means the Remove/Add section
304 should be as short as possible and not encompass any code that will
305 calld Remove/Add itself. Remember, dependencies can be circular so
306 while processing a dep for Pkg it is possible that Add/Remove
307 will be called on Pkg */
308 void pkgDepCache::AddStates(const PkgIterator
&Pkg
,int Add
)
310 StateCache
&State
= PkgState
[Pkg
->ID
];
312 // The Package is broken
313 if ((State
.DepState
& DepInstMin
) != DepInstMin
)
317 if (Pkg
.State() != PkgIterator::NeedsNothing
)
321 if (Pkg
->CurrentVer
== 0)
323 if (State
.Mode
== ModeDelete
&&
324 (State
.iFlags
| Purge
) == Purge
&& Pkg
.Purge() == false)
327 if (State
.Mode
== ModeInstall
)
332 // Installed, no upgrade
333 if (State
.Status
== 0)
335 if (State
.Mode
== ModeDelete
)
338 if ((State
.iFlags
& ReInstall
) == ReInstall
)
344 // Alll 3 are possible
345 if (State
.Mode
== ModeDelete
)
347 if (State
.Mode
== ModeKeep
)
349 if (State
.Mode
== ModeInstall
)
353 // DepCache::BuildGroupOrs - Generate the Or group dep data /*{{{*/
354 // ---------------------------------------------------------------------
355 /* The or group results are stored in the last item of the or group. This
356 allows easy detection of the state of a whole or'd group. */
357 void pkgDepCache::BuildGroupOrs(VerIterator
const &V
)
359 unsigned char Group
= 0;
361 for (DepIterator D
= V
.DependsList(); D
.end() != true; D
++)
363 // Build the dependency state.
364 unsigned char &State
= DepState
[D
->ID
];
366 /* Invert for Conflicts. We have to do this twice to get the
367 right sense for a conflicts group */
368 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
371 // Add to the group if we are within an or..
375 if ((D
->CompareOp
& Dep::Or
) != Dep::Or
)
378 // Invert for Conflicts
379 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
384 // DepCache::VersionState - Perform a pass over a dependency list /*{{{*/
385 // ---------------------------------------------------------------------
386 /* This is used to run over a dependency list and determine the dep
387 state of the list, filtering it through both a Min check and a Policy
388 check. The return result will have SetMin/SetPolicy low if a check
389 fails. It uses the DepState cache for it's computations. */
390 unsigned char pkgDepCache::VersionState(DepIterator D
,unsigned char Check
,
391 unsigned char SetMin
,
392 unsigned char SetPolicy
)
394 unsigned char Dep
= 0xFF;
396 while (D
.end() != true)
398 // Compute a single dependency element (glob or)
399 DepIterator Start
= D
;
400 unsigned char State
= 0;
401 for (bool LastOR
= true; D
.end() == false && LastOR
== true; D
++)
403 State
|= DepState
[D
->ID
];
404 LastOR
= (D
->CompareOp
& Dep::Or
) == Dep::Or
;
407 // Minimum deps that must be satisfied to have a working package
408 if (Start
.IsCritical() == true)
409 if ((State
& Check
) != Check
)
412 // Policy deps that must be satisfied to install the package
413 if (IsImportantDep(Start
) == true &&
414 (State
& Check
) != Check
)
421 // DepCache::DependencyState - Compute the 3 results for a dep /*{{{*/
422 // ---------------------------------------------------------------------
423 /* This is the main dependency computation bit. It computes the 3 main
424 results for a dependencys, Now, Install and Candidate. Callers must
425 invert the result if dealing with conflicts. */
426 unsigned char pkgDepCache::DependencyState(DepIterator
&D
)
428 unsigned char State
= 0;
430 if (CheckDep(D
,NowVersion
) == true)
432 if (CheckDep(D
,InstallVersion
) == true)
434 if (CheckDep(D
,CandidateVersion
) == true)
440 // DepCache::UpdateVerState - Compute the Dep member of the state /*{{{*/
441 // ---------------------------------------------------------------------
442 /* This determines the combined dependency representation of a package
443 for its two states now and install. This is done by using the pre-generated
444 dependency information. */
445 void pkgDepCache::UpdateVerState(PkgIterator Pkg
)
447 // Empty deps are always true
448 StateCache
&State
= PkgState
[Pkg
->ID
];
449 State
.DepState
= 0xFF;
451 // Check the Current state
452 if (Pkg
->CurrentVer
!= 0)
454 DepIterator D
= Pkg
.CurrentVer().DependsList();
455 State
.DepState
&= VersionState(D
,DepNow
,DepNowMin
,DepNowPolicy
);
458 /* Check the candidate state. We do not compare against the whole as
459 a candidate state but check the candidate version against the
461 if (State
.CandidateVer
!= 0)
463 DepIterator D
= State
.CandidateVerIter(*this).DependsList();
464 State
.DepState
&= VersionState(D
,DepInstall
,DepCandMin
,DepCandPolicy
);
467 // Check target state which can only be current or installed
468 if (State
.InstallVer
!= 0)
470 DepIterator D
= State
.InstVerIter(*this).DependsList();
471 State
.DepState
&= VersionState(D
,DepInstall
,DepInstMin
,DepInstPolicy
);
475 // DepCache::Update - Figure out all the state information /*{{{*/
476 // ---------------------------------------------------------------------
477 /* This will figure out the state of all the packages and all the
478 dependencies based on the current policy. */
479 void pkgDepCache::Update(OpProgress
*Prog
)
489 // Perform the depends pass
491 for (PkgIterator I
= PkgBegin(); I
.end() != true; I
++,Done
++)
493 if (Prog
!= 0 && Done%20
== 0)
494 Prog
->Progress(Done
);
495 for (VerIterator V
= I
.VersionList(); V
.end() != true; V
++)
497 unsigned char Group
= 0;
499 for (DepIterator D
= V
.DependsList(); D
.end() != true; D
++)
501 // Build the dependency state.
502 unsigned char &State
= DepState
[D
->ID
];
503 State
= DependencyState(D
);
505 // Add to the group if we are within an or..
508 if ((D
->CompareOp
& Dep::Or
) != Dep::Or
)
511 // Invert for Conflicts
512 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
517 // Compute the pacakge dependency state and size additions
526 Prog
->Progress(Done
);
529 // DepCache::Update - Update the deps list of a package /*{{{*/
530 // ---------------------------------------------------------------------
531 /* This is a helper for update that only does the dep portion of the scan.
532 It is mainly ment to scan reverse dependencies. */
533 void pkgDepCache::Update(DepIterator D
)
535 // Update the reverse deps
536 for (;D
.end() != true; D
++)
538 unsigned char &State
= DepState
[D
->ID
];
539 State
= DependencyState(D
);
541 // Invert for Conflicts
542 if (D
->Type
== Dep::Conflicts
|| D
->Type
== Dep::Obsoletes
)
545 RemoveStates(D
.ParentPkg());
546 BuildGroupOrs(D
.ParentVer());
547 UpdateVerState(D
.ParentPkg());
548 AddStates(D
.ParentPkg());
552 // DepCache::Update - Update the related deps of a package /*{{{*/
553 // ---------------------------------------------------------------------
554 /* This is called whenever the state of a package changes. It updates
555 all cached dependencies related to this package. */
556 void pkgDepCache::Update(PkgIterator
const &Pkg
)
558 // Recompute the dep of the package
563 // Update the reverse deps
564 Update(Pkg
.RevDependsList());
566 // Update the provides map for the current ver
567 if (Pkg
->CurrentVer
!= 0)
568 for (PrvIterator P
= Pkg
.CurrentVer().ProvidesList();
569 P
.end() != true; P
++)
570 Update(P
.ParentPkg().RevDependsList());
572 // Update the provides map for the candidate ver
573 if (PkgState
[Pkg
->ID
].CandidateVer
!= 0)
574 for (PrvIterator P
= PkgState
[Pkg
->ID
].CandidateVerIter(*this).ProvidesList();
575 P
.end() != true; P
++)
576 Update(P
.ParentPkg().RevDependsList());
581 // DepCache::MarkKeep - Put the package in the keep state /*{{{*/
582 // ---------------------------------------------------------------------
584 void pkgDepCache::MarkKeep(PkgIterator
const &Pkg
,bool Soft
)
586 // Simplifies other routines.
587 if (Pkg
.end() == true)
590 /* Reject an attempt to keep a non-source broken installed package, those
592 if (Pkg
.State() == PkgIterator::NeedsUnpack
&&
593 Pkg
.CurrentVer().Downloadable() == false)
596 /* We changed the soft state all the time so the UI is a bit nicer
598 StateCache
&P
= PkgState
[Pkg
->ID
];
600 P
.iFlags
|= AutoKept
;
602 P
.iFlags
&= ~AutoKept
;
604 // Check that it is not already kept
605 if (P
.Mode
== ModeKeep
)
608 // We dont even try to keep virtual packages..
609 if (Pkg
->VersionList
== 0)
612 P
.Flags
&= ~Flag::Auto
;
617 if (Pkg
->CurrentVer
== 0)
620 P
.InstallVer
= Pkg
.CurrentVer();
629 // DepCache::MarkDelete - Put the package in the delete state /*{{{*/
630 // ---------------------------------------------------------------------
632 void pkgDepCache::MarkDelete(PkgIterator
const &Pkg
, bool rPurge
)
634 // Simplifies other routines.
635 if (Pkg
.end() == true)
638 // Check that it is not already marked for delete
639 StateCache
&P
= PkgState
[Pkg
->ID
];
640 P
.iFlags
&= ~(AutoKept
| Purge
);
644 if ((P
.Mode
== ModeDelete
|| P
.InstallVer
== 0) &&
645 (Pkg
.Purge() == true || rPurge
== false))
648 // We dont even try to delete virtual packages..
649 if (Pkg
->VersionList
== 0)
655 if (Pkg
->CurrentVer
== 0 && (Pkg
.Purge() == true || rPurge
== false))
660 // This was not inverted before, but I think it should be
661 P
.Flags
&= ~Flag::Auto
;
668 // DepCache::MarkInstall - Put the package in the install state /*{{{*/
669 // ---------------------------------------------------------------------
671 void pkgDepCache::MarkInstall(PkgIterator
const &Pkg
,bool AutoInst
,
677 // Simplifies other routines.
678 if (Pkg
.end() == true)
681 /* Check that it is not already marked for install and that it can be
683 StateCache
&P
= PkgState
[Pkg
->ID
];
684 P
.iFlags
&= ~AutoKept
;
685 if (P
.InstBroken() == false && (P
.Mode
== ModeInstall
||
686 P
.CandidateVer
== (Version
*)Pkg
.CurrentVer()))
688 if (P
.CandidateVer
== (Version
*)Pkg
.CurrentVer() && P
.InstallVer
== 0)
693 // See if there is even any possible instalation candidate
694 if (P
.CandidateVer
== 0)
697 // We dont even try to install virtual packages..
698 if (Pkg
->VersionList
== 0)
701 /* Target the candidate version and remove the autoflag. We reset the
702 autoflag below if this was called recursively. Otherwise the user
703 should have the ability to de-auto a package by changing its state */
707 P
.Mode
= ModeInstall
;
708 P
.InstallVer
= P
.CandidateVer
;
709 P
.Flags
&= ~Flag::Auto
;
710 if (P
.CandidateVer
== (Version
*)Pkg
.CurrentVer())
717 if (AutoInst
== false)
720 DepIterator Dep
= P
.InstVerIter(*this).DependsList();
721 for (; Dep
.end() != true;)
724 DepIterator Start
= Dep
;
727 for (bool LastOR
= true; Dep
.end() == false && LastOR
== true; Dep
++,Ors
++)
729 LastOR
= (Dep
->CompareOp
& Dep::Or
) == Dep::Or
;
731 if ((DepState
[Dep
->ID
] & DepInstall
) == DepInstall
)
735 // Dep is satisfied okay.
739 /* Check if this dep should be consider for install. If it is a user
740 defined important dep and we are installed a new package then
741 it will be installed. Otherwise we only worry about critical deps */
742 if (IsImportantDep(Start
) == false)
744 if (Pkg
->CurrentVer
!= 0 && Start
.IsCritical() == false)
747 /* If we are in an or group locate the first or that can
748 succeed. We have already cached this.. */
749 for (; Ors
> 1 && (DepState
[Start
->ID
] & DepCVer
) != DepCVer
; Ors
--)
752 /* This bit is for processing the possibilty of an install/upgrade
753 fixing the problem */
754 SPtrArray
<Version
*> List
= Start
.AllTargets();
755 if ((DepState
[Start
->ID
] & DepCVer
) == DepCVer
)
757 // Right, find the best version to install..
758 Version
**Cur
= List
;
759 PkgIterator P
= Start
.TargetPkg();
760 PkgIterator
InstPkg(*Cache
,0);
762 // See if there are direct matches (at the start of the list)
763 for (; *Cur
!= 0 && (*Cur
)->ParentPkg
== P
.Index(); Cur
++)
765 PkgIterator
Pkg(*Cache
,Cache
->PkgP
+ (*Cur
)->ParentPkg
);
766 if (PkgState
[Pkg
->ID
].CandidateVer
!= *Cur
)
772 // Select the highest priority providing package
773 if (InstPkg
.end() == true)
775 pkgPrioSortList(*Cache
,Cur
);
776 for (; *Cur
!= 0; Cur
++)
778 PkgIterator
Pkg(*Cache
,Cache
->PkgP
+ (*Cur
)->ParentPkg
);
779 if (PkgState
[Pkg
->ID
].CandidateVer
!= *Cur
)
786 if (InstPkg
.end() == false)
788 MarkInstall(InstPkg
,true,Depth
+ 1);
790 // Set the autoflag, after MarkInstall because MarkInstall unsets it
791 if (P
->CurrentVer
== 0)
792 PkgState
[InstPkg
->ID
].Flags
|= Flag::Auto
;
798 /* For conflicts we just de-install the package and mark as auto,
799 Conflicts may not have or groups */
800 if (Start
->Type
== Dep::Conflicts
|| Start
->Type
== Dep::Obsoletes
)
802 for (Version
**I
= List
; *I
!= 0; I
++)
804 VerIterator
Ver(*this,*I
);
805 PkgIterator Pkg
= Ver
.ParentPkg();
808 PkgState
[Pkg
->ID
].Flags
|= Flag::Auto
;
815 // DepCache::SetReInstall - Set the reinstallation flag /*{{{*/
816 // ---------------------------------------------------------------------
818 void pkgDepCache::SetReInstall(PkgIterator
const &Pkg
,bool To
)
823 StateCache
&P
= PkgState
[Pkg
->ID
];
825 P
.iFlags
|= ReInstall
;
827 P
.iFlags
&= ~ReInstall
;
833 // DepCache::SetCandidateVersion - Change the candidate version /*{{{*/
834 // ---------------------------------------------------------------------
836 void pkgDepCache::SetCandidateVersion(VerIterator TargetVer
)
838 pkgCache::PkgIterator Pkg
= TargetVer
.ParentPkg();
839 StateCache
&P
= PkgState
[Pkg
->ID
];
844 if (P
.CandidateVer
== P
.InstallVer
)
845 P
.InstallVer
= (Version
*)TargetVer
;
846 P
.CandidateVer
= (Version
*)TargetVer
;
854 // StateCache::Update - Compute the various static display things /*{{{*/
855 // ---------------------------------------------------------------------
856 /* This is called whenever the Candidate version changes. */
857 void pkgDepCache::StateCache::Update(PkgIterator Pkg
,pkgCache
&Cache
)
860 VerIterator Ver
= CandidateVerIter(Cache
);
862 // Use a null string or the version string
863 if (Ver
.end() == true)
866 CandVersion
= Ver
.VerStr();
868 // Find the current version
870 if (Pkg
->CurrentVer
!= 0)
871 CurVersion
= Pkg
.CurrentVer().VerStr();
873 // Strip off the epochs for display
874 CurVersion
= StripEpoch(CurVersion
);
875 CandVersion
= StripEpoch(CandVersion
);
877 // Figure out if its up or down or equal
878 Status
= Ver
.CompareVer(Pkg
.CurrentVer());
879 if (Pkg
->CurrentVer
== 0 || Pkg
->VersionList
== 0 || CandidateVer
== 0)
883 // StateCache::StripEpoch - Remove the epoch specifier from the version /*{{{*/
884 // ---------------------------------------------------------------------
886 const char *pkgDepCache::StateCache::StripEpoch(const char *Ver
)
892 for (const char *I
= Ver
; *I
!= 0; I
++)
899 // Policy::GetCandidateVer - Returns the Candidate install version /*{{{*/
900 // ---------------------------------------------------------------------
901 /* The default just returns the highest available version that is not
902 a source and automatic. */
903 pkgCache::VerIterator
pkgDepCache::Policy::GetCandidateVer(PkgIterator Pkg
)
905 /* Not source/not automatic versions cannot be a candidate version
906 unless they are already installed */
907 VerIterator
Last(*(pkgCache
*)this,0);
909 for (VerIterator I
= Pkg
.VersionList(); I
.end() == false; I
++)
911 if (Pkg
.CurrentVer() == I
)
914 for (VerFileIterator J
= I
.FileList(); J
.end() == false; J
++)
916 if ((J
.File()->Flags
& Flag::NotSource
) != 0)
919 /* Stash the highest version of a not-automatic source, we use it
920 if there is nothing better */
921 if ((J
.File()->Flags
& Flag::NotAutomatic
) != 0)
923 if (Last
.end() == true)
935 // Policy::IsImportantDep - True if the dependency is important /*{{{*/
936 // ---------------------------------------------------------------------
938 bool pkgDepCache::Policy::IsImportantDep(DepIterator Dep
)
940 return Dep
.IsCritical();